Подтвердить что ты не робот

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

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

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

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

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

Ну, проще попросить; что происходит при превышении 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

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

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

Очистите надгробия, убедившись, что 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;

С уважением,

Али