Понимание Quorum/Vnode (R против PR)
Я проводил несколько экспериментов, чтобы понять Риака. Вот кое-что интересное, что я нашел:
У меня есть кластер из 2 узлов и тип корзины, который имеет n_val
из 2
[root@co-riak002 ~]# riak-admin ring-status
================================== Claimant ===================================
Claimant: 'riak@10.172.48.68'
Status: up
Ring Ready: true
============================== Ownership Handoff ==============================
No pending changes.
============================== Unreachable Nodes ==============================
All nodes are up and reachable
[root@co-riak002 ~]# riak-admin bucket-type create testBucket '{"props":{"n_val":2}}'
testBucket created
[root@co-riak002 ~]# riak-admin bucket-type activate testBucket
testBucket has been activated
И тогда я написал что-то в это:
[root@co-riak002 ~]# curl -XPUT -d '{"bar":"foo"}' -H "Content-Type: application/json" http://localhost:8098/types/testBucket/buckets/stuff/keys/hello?w=2&returnbody=true
[1] 10890
[root@co-riak002 ~]#
[1]+ Done curl -XPUT -d '{"bar":"foo"}' -H "Content-Type: application/json" http://localhost:8098/types/testBucket/buckets/stuff/keys/hello?w=2
Теперь я могу читать это хорошо с обоими r=2
а также pr=2
:
[root@co-riak002 ~]# curl http://localhost:8098/types/testBucket/buckets/stuff/keys/hello?r=2
{"bar":"foo"}
[root@co-riak002 ~]# curl http://localhost:8098/types/testBucket/buckets/stuff/keys/hello?pr=2
{"bar":"foo"}
После того, как я убил один из узлов, r=2
все еще читает нормально но не pr=2
[root@co-riak002 ~]# riak-admin ring-status
================================== Claimant ===================================
Claimant: 'riak@10.172.48.68'
Status: up
Ring Ready: true
============================== Ownership Handoff ==============================
No pending changes.
============================== Unreachable Nodes ==============================
The following nodes are unreachable: ['riak@10.172.48.66']
С r=2
:
[root@co-riak002 ~]# curl http://localhost:8098/types/testBucket/buckets/stuff/keys/hello?r=2
{"bar":"foo"}
С pr=2
:
[root@co-riak002 ~]# curl http://localhost:8098/types/testBucket/buckets/stuff/keys/hello?pr=2
PR-value unsatisfied: 1/2
Я в замешательстве - не должен ли номер кворума r
используется в операции чтения означает число реплик / физических узлов, которые должны согласовать перед возвратом данных? Почему это не работает в этом случае? И почему pr
работает в этом случае, когда это должно означать количество vnodes?
Я довольно новичок в этом пространстве. Очень ценится за любые указатели.
2 ответа
Следует различать " небрежный кворум" и "строгий кворум".
Как вы, вероятно, знаете, хеш-функция применяется к каждому ключу, чтобы вычислить, где этот ключ должен находиться в кластере Riak. Все пространство значений хеш-функции называется "кольцом" и делится поровну между виртуальными узлами (vnode), которые в свою очередь назначаются физическим узлам. Назначение выполняется таким образом, чтобы обеспечить надежность соседних vnode для разных физических узлов, хотя это не всегда возможно. Если репликация включена (т.е. n_val > 1), ключ записывается не только в его целевой vnode, но также и в несколько узлов, которые следуют за vnode в кольце (в большинстве случаев это разные физические узлы - см. Выше). Теперь это основные узлы для этого ключа. Однако в случае небрежного кворума (например, W = 2), если первичный узел недоступен, реплики ключа будут записаны в любой vnode, возможно, даже на тот же физический узел. Это нормально, потому что они будут переданы "правым" узлам, как только проблема будет устранена и первичные узлы станут доступными. Если вы не хотите рисковать записью реплик на тот же физический узел, даже временный, или хотите убедиться, что клиент получает самые последние значения, вы можете явно потребовать, чтобы все или хотя бы некоторые записи выполнялись только к первичным vnodes (PW = 2, "P" означает "основной"). Это происходит за счет высокой доступности, однако. Та же логика работает для чтения.
Надеюсь это поможет.
Я настоятельно рекомендую вам прочитать " Книгу Маленького Риака". Кроме того, онлайн документация отличная.
не должно ли число кворума r, используемое в операции чтения, означать число реплик / физических узлов, которые должны быть согласованы перед возвратом данных?
Не совсем. Кворум чтения (r) - это число узлов, которые должны обеспечить приемлемый ответ. Когда вы читаете с одним узлом вниз, остальная часть кластера (в данном случае оставшийся узел) будет запускать резервные копии для любых отсутствующих vnode по мере необходимости.
Когда приходит ваш запрос на чтение с r=2, так как один vnode в префлисте недоступен, запускается откат. Естественно, этот резервный пустой при первом запуске, поэтому процесс чтения получает notfound от резервного и сохраненный объект от другого.
Хитрость здесь в том, notfound_ok
установка в свойствах корзины или параметров запроса. Если оставить по умолчанию notfound_ok=true
notfound считается действительным ответом, поэтому операция соответствует кворуму, ответ с данными превосходит notfound, и клиент возвращает объект. Это также вызывает восстановление чтения, которое заполняет запасной вариант с этим объектом, так что следующий запрос get получит 2 объекта и никаких не найденных ответов.
Если notfound_ok имеет значение false, первый запрос на чтение увидит только 1 действительный ответ и потерпит неудачу, но восстановление чтения все равно произойдет, поэтому следующий запрос r=2 будет выполнен успешно, так как запасной вариант также содержит данные.
Это правильная тактика использования r=1, notfound_ok=false для операций чтения, чтобы получить высокую доступность и максимально быстрый ответ при сохранении разумных заверений в том, что вы не получите ложные не найденные ответы при сбое узла.