Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Масштабирование NoSQL БД
Масштабирование NoSQL баз данных — критически важная тема для разработки высоконагруженных систем. NoSQL имеет свои особенности, отличающие его от реляционных БД.
Типы масштабирования
1. Вертикальное масштабирование (Vertical Scaling)
Увеличение ресурсов на одной машине (CPU, RAM, диск):
Преимущества:
- Простота реализации
- Меньше сложности с синхронизацией
Недостатки:
- Есть физический предел
- Дорого
- Downtime при обновлении
# Это касается инфраструктуры, а не кода
# Просто добавляем больше ресурсов к серверу БД
2. Горизонтальное масштабирование (Horizontal Scaling)
Распределение данных между несколькими машинами — основной подход NoSQL:
Преимущества:
- Линейный рост производительности
- Отказоустойчивость
- Нет физических ограничений
Стратегии горизонтального масштабирования
1. Sharding (Шардирование)
Раздача данных на основе ключа:
from hashlib import md5
class ShardingStrategy:
def __init__(self, num_shards: int):
self.num_shards = num_shards
def get_shard_id(self, user_id: str) -> int:
"""Определяет номер шарда по ID пользователя"""
hash_value = int(md5(user_id.encode()).hexdigest(), 16)
return hash_value % self.num_shards
# Использование
sharding = ShardingStrategy(num_shards=4)
shard_id = sharding.get_shard_id("user_123")
print(f"Направить в шард {shard_id}")
Типы шардирования:
- Range-based — по диапазонам значений
- Hash-based — по хешу ключа
- Directory-based — по таблице маршрутизации
- Geographic — по географическому расположению
class RangeSharding:
"""Шардирование по диапазонам"""
def get_shard(self, user_id: int) -> int:
if 0 <= user_id < 1000000:
return 0
elif 1000000 <= user_id < 2000000:
return 1
elif 2000000 <= user_id < 3000000:
return 2
else:
return 3
2. Репликация (Replication)
Копирование данных на несколько узлов для надёжности и производительности:
# MongoDB репликация (в YAML конфиге)
# rs.initiate({
# _id: "rs0",
# members: [
# { _id: 0, host: "primary:27017" },
# { _id: 1, host: "secondary1:27017" },
# { _id: 2, host: "secondary2:27017" }
# ]
# })
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
client = MongoClient(
'mongodb://primary:27017,secondary1:27017,secondary2:27017',
replicaSet='rs0',
readPreference='secondaryPreferred' # Читаем с replica
)
db = client['myapp']
Типы репликации:
- Master-Slave — один мастер, много реплик (read-only)
- Master-Master — несколько мастеров (конфликты)
- Multi-Master — продвинутая синхронизация
3. Партиционирование (Partitioning)
Разделение данных по логическим критериям:
class PartitionedDataStore:
def __init__(self):
self.partitions = {
'active_users': {},
'inactive_users': {},
'archived_users': {}
}
def store_user(self, user_id: str, user_data: dict):
partition = self._get_partition(user_data)
self.partitions[partition][user_id] = user_data
def _get_partition(self, user_data: dict) -> str:
if user_data.get('last_login_days', float('inf')) < 7:
return 'active_users'
elif user_data.get('last_login_days', float('inf')) < 30:
return 'inactive_users'
else:
return 'archived_users'
Популярные NoSQL БД и их подходы
MongoDB
from pymongo import MongoClient
from pymongo.errors import DuplicateKeyError
client = MongoClient('mongodb://localhost:27017')
db = client['myapp']
# Sharding ключ
db.command('enableSharding', 'myapp')
db.command('shardCollection', 'myapp.users',
key={'user_id': 1}) # user_id — shard key
Redis Cluster
import redis
from redis.cluster import RedisCluster
# Подключение к Redis Cluster
rc = RedisCluster(
startup_nodes=[
{"host": "node1", "port": 6379},
{"host": "node2", "port": 6379},
{"host": "node3", "port": 6379}
],
decode_responses=True
)
rc.set("user:123:name", "John")
value = rc.get("user:123:name")
Cassandra
from cassandra.cluster import Cluster
cluster = Cluster(
contact_points=['192.168.1.1', '192.168.1.2', '192.168.1.3']
)
session = cluster.connect('my_keyspace')
# Cassandra автоматически распределяет данные
session.execute(
'INSERT INTO users (id, name) VALUES (%s, %s)',
('user_123', 'John')
)
Кеширование (Caching Layer)
class CacheLayer:
def __init__(self, cache_client, db_client):
self.cache = cache_client
self.db = db_client
def get_user(self, user_id: str):
# Сначала проверяем кеш
cached = self.cache.get(f'user:{user_id}')
if cached:
return cached
# Если нет — ищем в БД
user = self.db.find_one({'_id': user_id})
# Кешируем результат на 1 час
self.cache.setex(f'user:{user_id}', 3600, user)
return user
Consistency Levels
При распределённых системах появляется CAP теорема:
# MongoDB write concern (уровень консистентности)
db.users.insert_one(
{'name': 'John'},
write_concern={
'w': 3, # Подтверждение от 3 реплик
'j': True # Fsync на диск
}
)
# Redis Sentinel для автофейловера
# sentinel.conf: sentinel monitor mymaster 127.0.0.1 6379 1
Best Practices
- Выбирайте правильный shard key — равномерное распределение данных
- Мониторьте репликацию — lag между мастером и репликами
- Используйте Read Replicas — снижайте нагрузку на мастер
- Backup Strategy — регулярные снимки состояния
- Тестируйте failover — что произойдёт при отказе узла
Масштабирование NoSQL требует понимания как технологии, так и характеристик вашего приложения.