| Преимущества | Ограничения |
|---|---|
| Высокая доступность данных | Сложности с консистентностью данных |
| Высокая производительность системы | Ресурсозатратность |
| Отказоустойчивость | Сложность управления |
| Гибкость в распределении нагрузки |
version: '3'
services:
mongodb1:
image: mongo:latest # docker образ
container_name: mongodb1
restart: always
ports:
- "27017:27017"
networks:
app-network:
ipv4_address: 173.17.0.10
volumes:
- mongodb1-data:/data/db
command:
[
"--replSet",
"rs0",
"--bind_ip_all",
"--port",
"27017"
] #команда для создания реплики
healthcheck:
test: [ "CMD", "mongo", "--eval", "db.adminCommand('ping')" ]
interval: 5s
start_period: 10s
mongodb2:
image: mongo:latest
container_name: mongodb2
restart: always
ports:
- "27018:27018"
networks:
app-network:
ipv4_address: 173.17.0.9
volumes:
- mongodb2-data:/data/db
command:
[
"--replSet",
"rs0",
"--bind_ip_all",
"--port",
"27018"
]
healthcheck:
test: [ "CMD", "mongo", "--eval", "db.adminCommand('ping')" ]
interval: 5s
start_period: 10s
mongodb3:
image: mongo:latest
container_name: mongodb3
restart: always
ports:
- "27019:27019"
networks:
app-network:
ipv4_address: 173.17.0.8
volumes:
- mongodb3-data:/data/db
command:
[
"--replSet",
"rs0",
"--bind_ip_all",
"--port",
"27019"
]
healthcheck:
test: [ "CMD", "mongo", "--eval", "db.adminCommand('ping')" ]
interval: 5s
start_period: 10s
networks:
app-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 173.17.0.0/16
volumes:
mongodb1-data:
mongodb2-data:
mongodb3-data: --replSet устанавливает имя набора реплик равным "rs0" и, собственно, запускает Mongo в режиме репликации, а флаг --bind_ip_all разрешает подключения со всех сетевых интерфейсов.docker-compose up -d docker exec -it mongodb1 mongosh > rs.initiate({_id: "rs0", members: [
{_id: 0, host: "mongodb1:27017"},
{_id: 1, host: "mongodb2:27018"},
{_id: 2, host: "mongodb3:27019"}
]}) redis_1:
image: "redis:latest"
container_name: redis_1
ports:
- "6379"
volumes:
- redis_1_data:/data
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
networks:
app-network:
ipv4_address: 173.17.0.2
redis_2:
image: "redis:latest"
container_name: redis_2
ports:
- "6379"
volumes:
- redis_2_data:/data
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
networks:
app-network:
ipv4_address: 173.17.0.3
redis_3:
image: "redis:latest"
container_name: redis_3
ports:
- "6379"
volumes:
- redis_3_data:/data
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
networks:
app-network:
ipv4_address: 173.17.0.4
redis_4:
image: "redis:latest"
container_name: redis_4
ports:
- "6379"
volumes:
- redis_4_data:/data
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
networks:
app-network:
ipv4_address: 173.17.0.5
redis_5:
image: "redis:latest"
container_name: redis_5
ports:
- "6379"
volumes:
- redis_5_data:/data
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
networks:
app-network:
ipv4_address: 173.17.0.6
redis_6:
image: "redis:latest"
container_name: redis_6
ports:
- "6379"
volumes:
- redis_6_data:/data
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
networks:
app-network:
ipv4_address: 173.17.0.7
volumes:
redis_1_data: {}
redis_2_data: {}
redis_3_data: {}
redis_4_data: {}
redis_5_data: {}
redis_6_data: {} port 6379
cluster-enabled yes #активация кластерного режима
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
docker-compose up -d docker exec -it redis_1
echo "yes" | redis-cli --cluster create 173.17.0.2:6379 173.17.0.3:6379 173.17.0.4:6379 173.17.0.5:6379 173.17.0.6:6379 173.17.0.7:6379 --cluster-replicas 1 redis-cli cluster nodes > mkdir nodejs-api
> cd nodejs-api
> npm init -y
> npm install express mongoose redis
> touch index.js
const express = require('express');
const redis = require('redis');
const app = express();
const PORT = 3000;
const client = redis.createClient();
// работа Redis - достаём данные, если они есть по ссылке /api/products
const cache = (req, res, next) => {
const cacheKey = req.originalUrl;
client.get(cacheKey, (err, data) => {
if (err) throw err;
if (data !== null) {
res.json(JSON.parse(data));
} else {
next();
}
});
};
// сбрасываем кэш в случае обновления данных
const invalidateCache = (cacheKey) => {
client.del(cacheKey, (err, response) => {
if (err) throw err;
console.log(`Cache key "${cacheKey}" invalidated`);
});
};
app.get('/api/products', cache, (req, res) => {
const products = //логика получения данных из MongoDB
// Сохраняем данные по ключу /api/products на 1 минуту
client.setex(req.originalUrl, 120, JSON.stringify(products));
res.json(products);
});
// При обновлении данных - сбрасываем кэш
app.post('/api/products', (req, res) => {
//обновляем данные в MongoDB
invalidateCache('/api/products');
res.json({ message: 'Product data updated successfully' });
});
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});