Что именно происходит при достижении предела захоронения

Согласно журналу Кассандры (см. Ниже), запросы прерываются из-за слишком большого количества запросов. tombstones присутствовать Это происходит потому, что раз в неделю я очищаю (удаляю) строки со слишком низким счетчиком. Это "удаляет" сотни тысяч строк (помечает их как таковые tombstone.)

Это совсем не проблема, если в этой таблице вновь появится удаленная строка, потому что узел был отключен во время процесса очистки, поэтому я установил gc grace time для одной затронутой таблицы - до 10 часов (вместо 10 дней по умолчанию), поэтому захороненные строки могут быть окончательно удалены относительно быстро.

Несмотря на это, я должен был установить tombstone_failure_threshold чрезвычайно высоко, чтобы избежать нижеуказанного исключения. (сто миллионов, а не сто тысяч). Мой вопрос: нужно ли это? Я абсолютно не знаю, какие типы запросов прерываются; вставляет, выбирает, удаляет?

Если это просто некоторые избранные прерывания, это не такая уж большая проблема. Но это предполагает, что abort означает "ограниченный" в том смысле, что запрос останавливается преждевременно и возвращает все живые данные, которые ему удалось собрать до того, как было найдено слишком много надгробий.

Ну, спросить это проще; что происходит, когда tombstone_failure_threshold превышен?

INFO [HintedHandoff:36] 2014-02-12 17:44:22,355 HintedHandOffManager.java (line 323) Started hinted handoff for host: fb04ad4c-xxxx-4516-8569-xxxxxxxxx with IP: /XX.XX.XXX.XX
ERROR [HintedHandoff:36] 2014-02-12 17:44:22,667 SliceQueryFilter.java (line 200) Scanned over 100000 tombstones; query aborted (see tombstone_fail_threshold)
ERROR [HintedHandoff:36] 2014-02-12 17:44:22,668 CassandraDaemon.java (line 187) Exception in thread Thread[HintedHandoff:36,1,main]
org.apache.cassandra.db.filter.TombstoneOverwhelmingException
    at org.apache.cassandra.db.filter.SliceQueryFilter.collectReducedColumns(SliceQueryFilter.java:201)
    at org.apache.cassandra.db.filter.QueryFilter.collateColumns(QueryFilter.java:122)
    at org.apache.cassandra.db.filter.QueryFilter.collateOnDiskAtom(QueryFilter.java:80)
    at org.apache.cassandra.db.filter.QueryFilter.collateOnDiskAtom(QueryFilter.java:72)
    at org.apache.cassandra.db.CollationController.collectAllData(CollationController.java:297)
    at org.apache.cassandra.db.CollationController.getTopLevelColumns(CollationController.java:53)
    at org.apache.cassandra.db.ColumnFamilyStore.getTopLevelColumns(ColumnFamilyStore.java:1516)
    at org.apache.cassandra.db.ColumnFamilyStore.getColumnFamily(ColumnFamilyStore.java:1335)
    at org.apache.cassandra.db.HintedHandOffManager.doDeliverHintsToEndpoint(HintedHandOffManager.java:351)
    at org.apache.cassandra.db.HintedHandOffManager.deliverHintsToEndpoint(HintedHandOffManager.java:309)
    at org.apache.cassandra.db.HintedHandOffManager.access$300(HintedHandOffManager.java:92)
    at org.apache.cassandra.db.HintedHandOffManager$4.run(HintedHandOffManager.java:530)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

Забыл упомянуть; работает версия Cassandra 2.0.4

1 ответ

Решение

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

Конкретный пример: допустим, у вас есть две строки с ключами кластеризации 1 и 3 и сто тысяч мертвых строк с ключом кластеризации 2, которые расположены между строками 1 и 3 в таблице. Теперь, когда вы выпускаете SELECT запрос, где ключ должен быть>= 1 и < 3, вам придется сканировать 100002 строки вместо ожидаемых двух.

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

Это исключение было введено в недавнем исправлении, впервые доступном в 2.0.2. Вот запись об ошибке, описывающая проблему, которую пытались решить изменения. Раньше все было бы хорошо, пока один из ваших узлов, или, возможно, несколько, внезапно не сломался.

Если это просто некоторые избранные прерывания, это не такая уж большая проблема. Но это предполагает, что abort означает "ограниченный" в том смысле, что запрос останавливается преждевременно и возвращает все живые данные, которые ему удалось собрать до того, как было найдено слишком много надгробий.

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

Вот ссылка на полное решение:

Очистите надгробные камни, убедившись, что gc_grace_seconds настроен на более частый запуск в соответствии с вашим приложением или использует TTL для определенных данных. Например, по умолчанию gc_grace_seconds составляет 864000 (10 дней). Если для ваших данных TTL установлено значение 6 дней, вы можете изменить gc_grace_seconds на 604800 (7 дней), чтобы быстрее удалить надгробные камни.

https://support.datastax.com/hc/en-us/articles/204612559-ReadTimeoutException-seen-when-using-the-java-driver-caused-by-excessive-tombstones

cqlsh:results> alter table example with gc_grace_seconds = 10000;

С Уважением,

Али

Другие вопросы по тегам