Files
hse-2026/materials/08-scaling/seminar/kv/readme.md
T
2026-11-04 19:23:39 +03:00

125 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Шардирование на примере простого key-value-хранилища
Этот пример показывает, как разделить данные между несколькими узлами. В стенде работают три простых
key-value-хранилища: каждое принимает ключ и значение и сохраняет их в памяти. Перед ними находится прокси
с единым API. Клиент обращается только к прокси, а тот определяет владельца ключа и пересылает запрос
нужному хранилищу.
В основном режиме прокси вычисляет `SHA-256(key) mod N` и направляет запись и чтение владельцу ключа.
В конце также кратко рассмотрен учебный режим репликации.
## API
- `POST /put?key=<key>` записывает значение из JSON-поля `value`.
- `GET /get?key=<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'
```
После записи новый ключ должен появиться на всех трёх узлах. Это упрощённая учебная реализация:
она не гарантирует согласованность при частичных записях и не обрабатывает отказы как промышленная система.