2014-01-06 1 views
15

У меня вопрос Кассандры. Вы знаете, как Cassandra обновляет/увеличивает счетчики?как быстро увеличивать счетчики в Кассандре без застоя

Я хочу использовать штурмовой болт (CassandraCounterBatchingBolt из storm-contrib repo on github), который записывается в cassandra. Тем не менее, я не знаю, как некоторые реализации incrementCounterColumn() метод работает .. и есть также ограничения с прилавков Cassandra (от: http://wiki.apache.org/cassandra/Counters), что делает их бесполезными для моего сценария ИМХО:

  • Если сбой записи неожиданно (тайм-аут или потеря соединения с узлом-координатором), клиент не будет знать, была ли выполнена операция. Повтор может привести к превышению количества CASSANDRA-2495.

  • Снятие счетчика по существу ограничено. Например, если вы выдаете очень быстро последовательность «приращение, удалить, приращение» можно за удаление теряться

Во всяком случае, вот мой сценарий:
я обновляю тот же счетчик быстрее обновления распространяются на другие узлы Cassandra.

Пример:
Скажем, у меня есть 3 CASSANDRA узлы. Счетчики на каждый из этих узлов равны 0.
Node1: 0, node2: 0, node3: 0

Приращение приходит: 5 -> Node1: 0, node2: 0, node3: 0

Increment начинается в узле 2 - по-прежнему должен распространяться на node1 и node3
node1: 0, node2: 5, node3: 0

в то же время, другой прирост прибывает до предыдущего приращения
распространяющегося: 3 -> node1: 0, узел2: 5, узел3: 0

Предполагая, 3 начинается в другом узле, чем где 5 начала мы имеем:
Node1: 3, узел2: 5, node3: 0

Теперь, если 3 получает распространяются на другие узлы как приращение, а не как новое значение (и то же самое для 5), то в конечном итоге узлы будут равны 8, и это то, что я хочу.

Если 3 перезаписывает 5 (потому что у него более поздняя метка времени), это проблематично - не то, что я хочу.

Вы знаете, как эти обновления/приращения обрабатываются Cassandra?

Обратите внимание, что для чтения перед записью по-прежнему восприимчивы к одной и той же задачи в зависимости от которого копия узла считанных (Кворум Выполняет все еще может потерпеть неудачу, если распространение не далеко вперед)

Я также думаю, что возможно, класть кеш б/у мой штормовой болт, и Кассандра может решить эту проблему, но это история в другое время.

ответ

17

Счетчики в C * имеют сложное внутреннее представление, которое позволяет избежать большинства (но не всех) проблем подсчета вещей в безликой распределенной системе. Мне нравится думать о них как о закрытых прилавках. Счетчик состоит из нескольких подзаголовков, идентифицированных идентификатором хоста и номером версии. Хост, который принимает операцию счетчика, увеличивает свой собственный счетчик, а также увеличивает версию. Затем он реплицирует все свое состояние счетчика на другие реплики, которые объединяют его со своими состояниями. Когда счетчик считывается, узел, обрабатывающий операцию чтения, определяет значение счетчика, суммируя общее количество отсчетов с каждого хоста.

На каждом узле счетчик увеличивается, как и все остальное в Кассандре, просто пишет. Приращение записывается в таблицу заметок, а локальное значение определяется во время чтения путем слияния всех приращений из таблицы memtable и всех SSTables.

Надеюсь, что объяснение поможет вам поверить мне, когда я говорю, что вам не нужно беспокоиться о приращении счетчиков быстрее, чем может справиться Кассандра. Поскольку каждый узел хранит свой собственный счетчик и никогда не реплицирует операции приращения, нет возможности потерять счеты по условиям гонки, например, как сценарий чтения-изменения-записи. Если Кассандра согласится на запись, вы в значительной степени гарантируете, что она будет считаться.

То, что вам не гарантировано, заключается в том, что счет будет отображаться правильно в любое время, если только. Если приращение записывается на один узел, но значение счетчика, считываемое из другого сразу после этого, не гарантируется, что приращение было реплицировано, и вы также должны учитывать, что произойдет во время сетевого раздела. Это более или менее то же самое с любой записью в Cassandra, это в конечном итоге последовательный характер, и это зависит от того, какие уровни согласованности вы использовали для операций.

Существует также возможность потерянного подтверждения. Если вы делаете приращение и теряете соединение с Cassandra, прежде чем вы сможете получить ответ, вы не сможете узнать, получилась ли ваша запись. И когда вы получите соединение обратно, вы не можете сказать, так как вы не знаете, что счет был до того, как вы увеличили. Это неотъемлемая проблема с системами, которые выбирают доступность по сравнению с последовательностью, и ценой, которую вы платите за многие другие преимущества.

Наконец-то проблема быстрого удаления, приращения, удаления является реальной и что-то, чего вам следует избегать. Проблема в том, что операция приращения существенно воскресит столбец, и если эти операции будут достаточно близки друг к другу, они могут получить одну и ту же метку времени. Кассандра - это строго последняя победа и определяет последний, основанный на отметке времени операции. Если две операции имеют один и тот же штамп времени, выигрывает «больше», что означает тот, который сортируется в строгом порядке байтов. Это реально, но я бы не стал слишком беспокоиться об этом, если вы делаете очень быстрые записи и не удаляете их до того же значения (что, вероятно, является ошибкой в ​​вашей модели данных).

Вот хорошее руководство по внутренностям счетчиков Кассандры: http://www.datastax.com/wp-content/uploads/2011/07/cassandra_sf_counters.pdf

+0

Спасибо за очень подробное объяснение. Отличная ссылка и сообщение! Да, причина, почему последние временные победы выигрывает, - вот почему я задал этот вопрос. Теперь я понимаю, что для счетчиков есть команда приращения (вместо чтения + записи). «Является ли это правдой?» Если я перейду в облако, задержки увеличатся, и чтобы избежать чтения неправильного номера сразу после записи, мне нужно увеличить время, которое я собираю до сохранения в db. Я надеюсь, что инструкция счетчика счетчика существует. – Adrian

+0

Существует инструкция приращения, и вам не нужно читать, прежде чем делать приращение. Если вы делаете приращения с уровнем согласованности QUORUM и читаете с уровнем согласованности QUORUM, вы никогда не должны видеть несоответствий в подсчетах. – Theo

+0

Я должен добавить, что в исключительных обстоятельствах, таких как перегородки и сбои, есть вероятность превышения или подсчета. – Theo

2

Для понимания обновлений/приращений, например, операций записи, я предлагаю вам пройти через Gossip, протокол, используемый Cassandra для связи.В Gossip каждый участник (узел) поддерживает свое состояние с использованием кортежа σ(K) = (V*N), где σ(K) - это состояние K с ключом V и N как номер версии.

Для поддержания единственной версии правды для пакета данных Gossip поддерживает механизм сверки, а именно: Precise & Scuttlebutt (текущий). Согласно Scuttlebutt Reconciliation, перед обновлением любого кортежа они обмениваются данными друг с другом, чтобы проверить, кто держит самую высокую версию (новейшее значение) ключа. Тот, кто держит самую высокую версию, отвечает за операцию записи.

Для получения дополнительной информации читайте это article.

3

Текущая версия счетчиков просто не хорошо подходит для использования, который требует гарантий не более подсчета и непосредственной последовательности.

Операции приращения и декремента, и они не будут сталкиваться друг с другом, и, запрещая любые потерянные мутации или переизданные мутации, даст вам правильный результат.

Возможно, вам будет интересно переписать счетчики Cassandra (https://issues.apache.org/jira/browse/CASSANDRA-6504), и он должен решить все текущие проблемы с получением правильного счета.

Тем временем, если бы мне пришлось реализовать это поверх текущей версии Cassandra, и точное подсчет был существенным, я бы, вероятно, сохранил каждый приращение или декремент как столбец и сделал агрегацию времени чтения результаты при записи контрольной точки, поэтому вам не нужно читать до начала времени, чтобы рассчитать последующие результаты.

Это добавляет большую нагрузку на читаемую сторону, хотя она чрезвычайно эффективна на пути записи, поэтому она может работать или не работать для вашего случая использования.

+0

чтение было только для чтения свежих значений до приращения и записи; теперь, когда я могу увеличиваться, мне не нужно читать сначала, просто inc; Я выполняю чтение, но каждые 30 минут или 20 минут так не очень часто :) – Adrian

 Смежные вопросы

  • Нет связанных вопросов^_^