У меня есть таблица в Cassandra, где я заполняю некоторые строки тысячами записей (каждая строка содержит более 10000 столбцов). Записи в строках очень часто обновляются, в основном просто поле (которое является целым числом) обновляется разными значениями. Все остальные значения для столбцов остаются неизменными. Мой вопрос: будут ли обновления выполняться на месте? Насколько хороша Cassandra для частого обновления записей?
Возможно ли обновление на месте в Cassandra?
Ответы (3)
Первоначально эти обновления хранятся в структуре данных в памяти, которая называется Memtable. Таблицы памяти сбрасываются в неизменяемые таблицы SST через регулярные промежутки времени.
Таким образом, из различных SSTables будет считана одна широкая строка. Именно во время процесса, называемого «уплотнением», различные таблицы SST будут объединены в одну большую таблицу SST на диске.
Увеличение порогов для сброса Memtables — один из способов оптимизации. Если обновления приходят очень быстро до того, как Memtable сбрасывается на диск, я думаю, что обновление должно быть на месте в памяти, хотя не уверен.
Также каждая операция чтения сначала проверяет Memtables, если данные все еще там, они будут просто возвращены — это максимально быстрый доступ.
Cassandra путь чтения:
When a read request for a row comes in to a node, the row must be combined from all SSTables on that node that contain columns from the row in question
Cassandra путь записи:
Прежде всего, каждое обновление также является последовательной записью для cassandra, поэтому, что касается cassandra, для cassandra не имеет никакого значения, обновляете ли вы или записываете.
Реальный вопрос заключается в том, насколько быстро вам нужно читать эти записи, чтобы они были доступны для чтения? Как предложил @john, сначала все записи записываются в изменяемую CQL Memtable, которая находится в памяти. Таким образом, каждое обновление добавляется как новая последовательная запись в memtable для конкретной таблицы CQL. Параллельно с этим периодически также записывается в `commitlog' (каждые 10 секунд) для долговечности.
Когда Memtable заполняется или достигается общий размер comittlog, cassandra сбрасывает все данные в неизменяемую таблицу отсортированных строк (SSTable). После очистки сжатие — это процедура, при которой все записи PK для новых значений столбца сохраняются, а все предыдущие значения (до обновления) удаляются.
С очисткой часто возникают накладные расходы на частые последовательные записи на диск и уплотнение, что может занять много операций ввода-вывода и серьезно повлиять на производительность cassandra.
Что касается чтения, сначала cassandra попытается прочитать из row cache
(если он включен) или из memtable
. Если там произойдет сбой, он перейдет к bloom filter
, key cache
, partition summary
, partition index
и, наконец, к SSTable в указанном порядке. Когда данные собраны для всех значений столбца, их совокупность в памяти и значения столбца с последней отметкой времени возвращаются клиенту после объединения, и в row cache
делается запись для этого ключа раздела.
Итак, да, когда вы запрашиваете ключ раздела, он будет сканировать все SSTable для этой конкретной таблицы CQL и memtable для всех значений столбцов, которые еще не сбрасываются на диск.
Нет, обновление на месте невозможно.
Как предложил @john, если у вас частые записи, вам следует отложить процесс сброса. Во время сброса несколько операций записи в один и тот же раздел, которые хранятся в MemTable, будут записаны как один раздел во вновь созданной SSTable.
C* подходит для тяжелых операций записи. Однако вам необходимо отслеживать количество SSTables, доступ к которым осуществляется при каждом чтении. Если # слишком велико, вам нужно пересмотреть свою стратегию уплотнения.