# Шардирование на примере простого key-value-хранилища Этот пример показывает, как разделить данные между несколькими узлами. В стенде работают три простых key-value-хранилища: каждое принимает ключ и значение и сохраняет их в памяти. Перед ними находится прокси с единым API. Клиент обращается только к прокси, а тот определяет владельца ключа и пересылает запрос нужному хранилищу. В основном режиме прокси вычисляет `SHA-256(key) mod N` и направляет запись и чтение владельцу ключа. В конце также кратко рассмотрен учебный режим репликации. ## API - `POST /put?key=` записывает значение из JSON-поля `value`. - `GET /get?key=` возвращает значение или `404`, если ключа нет на выбранном узле. - `GET /state` показывает содержимое всех хранилищ. ## Запуск Из корня репозитория: ```bash cd materials/08-scaling/seminar/kv docker compose up -d --build docker compose ps ``` Прокси будет доступен на порту 5005. Хранилища будут доступны на портах 5001, 5002 и 5003. ## Запись и чтение Записать одно значение через прокси: ```bash curl -sS -X POST 'http://localhost:5005/put?key=key-0' \ -H 'Content-Type: application/json' \ -d '{"value":"value-0"}' ``` Прочитать его: ```bash curl -sS 'http://localhost:5005/get?key=key-0' ``` Записать `N` значений с ключами от `key-0` до `key-(N-1)`: ```bash N=20 for ((i = 0; i < N; i++)); do curl -sS -X POST "http://localhost:5005/put?key=key-$i" \ -H 'Content-Type: application/json' \ -d "{\"value\":\"value-$i\"}" echo done ``` ## Проверка распределения Получить состояние всех узлов через прокси: ```bash open 'http://localhost:5005/state' ``` Состояние отдельных хранилищ: ```bash curl -sS 'http://localhost:5001/state' curl -sS 'http://localhost:5002/state' ``` Для текущей конфигурации `key-0` находится на третьем узле: ```bash curl -i 'http://localhost:5003/get?key=key-0' # 200 curl -i 'http://localhost:5002/get?key=key-0' # 404 ``` ## Изменение конфигурации Состав узлов задаётся в `proxy/compose_config.yml`: ```yaml mode: sharding nodes: - name: node1 url: http://kv1:5000 - name: node2 url: http://kv2:5000 - name: node3 url: http://kv3:5000 ``` Конфигурация подключена к контейнеру как файл только для чтения. После её изменения достаточно перезапустить прокси: ```bash docker compose restart proxy ``` Хранилища при этом не перезапускаются, и данные в их памяти сохраняются. ## Режим репликации В режиме `replication` прокси записывает каждое значение во все хранилища. При чтении он опрашивает узлы по очереди и возвращает первый успешный ответ. В отличие от шардирования, данные не разделяются, а копируются. Чтобы включить этот режим, изменить первую строку в `proxy/compose_config.yml`: ```yaml mode: replication ``` Затем перезапустить только прокси и повторить команды записи и чтения: ```bash docker compose restart proxy open 'http://localhost:5005/state' ``` После записи новый ключ должен появиться на всех трёх узлах. Это упрощённая учебная реализация: она не гарантирует согласованность при частичных записях и не обрабатывает отказы как промышленная система.