Надгробие — это удаленная запись в реплике распределенного хранилища данных . [1] Надгробие необходимо, поскольку распределенные хранилища данных используют конечную согласованность , когда только подмножество узлов, где хранятся данные, должно ответить, прежде чем операция будет считаться успешной.
Если информация удаляется в конечном счете-согласованном распределенном хранилище данных, «конечная» часть конечной согласованности заставляет информацию просачиваться через структуру узлов, где некоторые узлы могут быть недоступны во время удаления. Но особенность конечной согласованности вызывает проблему в случае удаления, так как узел, который был недоступен в то время, будет пытаться «обновить» другие узлы, которые больше не имеют удаленной записи, предполагая, что они пропустили вставку информации. Поэтому вместо удаления информации распределенное хранилище данных создает (обычно временную) запись-надгробие, которая не возвращается в ответ на запросы. [1]
Чтобы не заполнять хранилище данных бесполезной информацией, существует политика полного удаления надгробий. Для этого система проверяет возраст надгробия и удаляет его по истечении заданного времени. В Apache Cassandra это прошедшее время задается параметром GCGraceSeconds
[ 1] , а процесс называется Compaction. [2] Compaction потребляет системные ресурсы, а также замедляет вычислительную мощность. [2] [3]
Из-за отложенного удаления удаленная информация будет отображаться как пустая, после того как содержимое некоторых столбцов ряда записей будет удалено. После уплотнения неиспользуемые столбцы будут удалены из этих записей. [4] [ самоизданный источник ]
Таким образом, "конечный" в конечной согласованности: если клиент читает из реплики, которая не получила обновление с достаточно низким ConsistencyLevel, он потенциально увидит старые данные. [...] Есть еще одна часть проблемы: как мы узнаем, когда безопасно удалять надгробия? [...] [Он] определил константу GCGraceSeconds и заставил каждый узел отслеживать возраст надгробия локально. Как только он устареет больше константы, его можно будет очистить от мусора во время уплотнения (см. MemtableSSTable).
Чтобы представить это в контексте примера, предположим, что мы только что создали 10 строк данных с тремя столбцами в каждой. Если половина столбцов позже будет удалена, а сжатие еще не произошло, эти столбцы будут отображаться в запросах get_range_slices как пустые. Используя RangeSlicesQuery, как описано в предыдущем разделе, мы получим 10 возвращенных результатов, но только пять из них будут иметь значения. Что еще более важно, вызовы get (через ColumnQuery) по умолчанию предполагают, что извлекаемый вами столбец существует в хранилище. Поэтому, если вы вызываете get для надгробных данных, возвращается null (примечание: это отличается от предыдущих версий Hector, где базовое исключение NotFoundException распространялось вверх по стеку).