awesome-everything EN
↑ Обратно к восхождению

Распределённые системы

Кворумы: чтение конфигов и кода

Суть Читайте реальные конфигурации уровней согласованности и проверку пересечения кворума, предсказывайте, гарантирует ли каждая последнюю запись, и выбирайте самый рычажный фикс.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 14 min

Баги кворума живут в строках уровня согласованности вашего кода доступа к данным, а не в самой базе. Прочитайте каждый конфиг и сниппет, сделайте арифметику R + W против N и выберите фикс, который сделал бы senior-инженер первым.

Цель

Отработайте цикл, который вы запускаете, когда прилетает тикет про устаревшее чтение: найдите R и W в коде, проверьте, действительно ли R + W > N для replication factor этого keyspace, и потянитесь к фиксу, который восстанавливает пересечение, а не прячет его.

Сниппет 1 — раздельная согласованность чтения и записи

# keyspace создан WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': 3 }
session.execute(
    SimpleStatement(
        "UPDATE accounts SET payout = %s WHERE id = %s",
        consistency_level=ConsistencyLevel.QUORUM,   # W = 2 при RF=3
    ),
    (new_payout, account_id),
)
balance = session.execute(
    SimpleStatement(
        "SELECT payout FROM accounts WHERE id = %s",
        consistency_level=ConsistencyLevel.ONE,        # R = 1
    ),
    (account_id,),
).one()
Викторина

Запись — QUORUM (W=2), а чтение — ONE (R=1) при RF=3. Гарантирует ли это, что чтение увидит последний payout, и в чём фикс?

Сниппет 2 — хелпер проверки пересечения

def guarantees_latest_read(n: int, r: int, w: int) -> bool:
    # True тогда и только тогда, когда чтение гарантированно видит последнюю запись
    return r + w > n

# вызвано для плана нового keyspace, RF = 4
print(guarantees_latest_read(n=4, r=2, w=2))   # что напечатает и безопасно ли это?
Викторина

При N=4 с R=2, W=2 что напечатает guarantees_latest_read и верный ли это ответ?

Сниппет 3 — путь записи sloppy quorum

def write_quorum(coordinator, key, value, n=3, w=2):
    home = coordinator.preference_list(key, n)        # N назначенных реплик
    live = [node for node in home if node.is_reachable()]
    acks = [node.store(key, value) for node in live]
    if len(acks) >= w:
        return "OK (strict quorum)"
    # недостаточно назначенных реплик доступно -> sloppy quorum
    for sub in coordinator.next_healthy_ring_nodes():
        acks.append(sub.store_hint(key, value, intended_owner=...))
        if len(acks) >= w:
            return "OK (sloppy quorum)"               # подтверждено, но где?
    return "FAIL"
Викторина

Когда это возвращает 'OK (sloppy quorum)' во время partition, каково следствие для согласованности конкурентного строгого QUORUM-чтения с домашних реплик?

Сниппет 4 — флаг чтения DynamoDB

# DynamoDB, репликация управляется; согласованность чтения вы выбираете на запрос
resp = table.get_item(
    Key={"id": account_id},
    ConsistentRead=False,   # по умолчанию: eventually consistent
)
Викторина

Чтение баланса использует ConsistentRead=False. Что даёт переключение на True и чего это стоит — в терминах кворума?

Итог

Любой баг кворума читается одинаково: найдите R и W в строках уровня согласованности, найдите N из replication factor keyspace и проверьте R + W > N со СТРОГИМ неравенством — R=1-чтения за QUORUM-записями и любой чётный сплит вроде R=2,W=2 при N=4 — классические ловушки, дающие в сумме N и тихо допускающие устаревшие чтения. Фикс, восстанавливающий пересечение (обычно поднятие уровня ЧТЕНИЯ), лучше фиксов, которые его прячут. Sloppy quorum подтверждает через узлы-заместители с hint вне множества чтения, поэтому его ‘OK’ приостанавливает пересечение во время partition; а управляемые хранилища выставляют ту же ручку как ConsistentRead, где strong-чтения стоят примерно 2x capacity за гарантию.

Продолжить восхождение ↑Кворумы: соберите хранилище с tunable consistency
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.