Пытаясь ответить на каждый вопрос:
Во-первых, насколько дорога эта операция?
Сжатие должно копировать все в SSTables, которые оно сжимает (за вычетом любых уничтожений из надгробий или перезаписей). Однако это дешевле, чем кажется на первый взгляд, так как при сжатии используется чисто последовательный ввод-вывод, что хорошо и быстро на вращающихся дисках.
Если бы я потребовал уплотнения, когда у нас есть два SSTables на диске, это было бы непомерно, или мне лучше подождать до середины ночи, когда использование прекращается?
Это будет означать, что ваши записи станут значительно дороже; представьте, что каждая запись вызывает новый SSTable; поэтому каждая запись должна была бы сжать все записи, которые предшествовали ей. Стоимость написания N предметов составит N ^ 2.
Лучшей идеей является принятие стратегии сжатия, подобной той, которая используется в дублирующем массиве Acunu: сохраняйте каждый SSTable (он же массив) на «уровне» и уплотняйте их всякий раз, когда на уровне есть два массива, повышая выходной массив до следующий уровень. Можно показать, что амортизируется до O ((log N) / B) последовательных операций ввода-вывода на запись, в то время как число массивов ограничивается O (log N).
Эта схема реализована в Castle, (с открытым исходным кодом) хранилищем для Cassandra. Для получения дополнительной информации см. Здесь:
NB Я работаю на Acunu
Сжатие лучше, если у меня есть несколько (но маленьких) SSTables против нескольких, но очень больших SSTable?
Уплотнение с меньшими SSTables займет меньше времени, но вам придется делать больше из них. Его лошади для курсов, правда. Однако количество и размер SSTable влияют на производительность чтения (см. Следующий вопрос)
Влияет ли наличие большого количества несжатых таблиц SSTable на производительность чтения?
Для чтения по точке, не очень: у Кассандры (и Касла) есть фильтры Блума, чтобы избежать поиска в SSTables, когда он знает, что ключа не будет, и может завершиться рано, когда найдет правильное значение (используя временные метки на значения и SSTables).
Однако с запросами get_slice вы не можете завершить досрочно, поэтому вам придется посещать каждый SSTable, который может содержать значение в вашей строке - поэтому, если у вас есть много, ваши get_slices будут медленнее.
Ситуация еще хуже для get_range_slices, где вы не можете использовать фильтр Блума, и каждый вызов должен посещать каждый SSTable. Производительность этих вызовов будет обратно пропорциональна количеству имеющихся у вас SSTable.
Более того, с тысячами таблиц SSTable частота ложных срабатываний фильтра Блума (~ 1%) начнет ухудшаться, так как при каждом поиске вам придется искать в 10 секундах таблиц SSTable, которые не содержат значения!
Как параллелизм работает с этим: что, если я читаю из этих SSTables, тогда кто-то делает вставку, которая сбрасывает новую Memtable на диск, что, в свою очередь, вызывает уплотнение?
В Cassandra SSTable удаляются с диска, если в памяти больше нет ссылок на него (в соответствии с решением сборщика мусора). Так что чтения не нужно беспокоиться, и старые SSTable будут очищаться лениво.
Спасибо
Tom