#database-design #cassandra #nosql
#database-design #cassandra #nosql
Вопрос:
Я пишу приложение, которое должно отслеживать «объекты». В частности, когда «объект» (большой двоичный объект размером 1 кб) поступает на уровень приложения, он сохраняется в C * для будущего использования. Говоря о числах, я ожидаю получить 10-50 миллиардов отдельных объектов, поэтому ожидаемый размер данных составляет от 10 до 50 ТБ.
Приложение может видеть один и тот же объект несколько раз в течение переменного временного окна (например, день или месяц). Приложение «потребляет» эти объекты, когда применяются некоторые условия (они не используются немедленно), поэтому с каждым объектом связан счетчик на уровне приложения. Я не могу терпеть недостаточный / избыточный подсчет, поэтому счетчики C * — это большое нет, и я полагаюсь на правильную «блокировку» на уровне приложения. Я в основном гарантирую, что каждый объект правильно подсчитан, набирая «правильное» количество «глобальных блокировок» и штрафов, но меня это устраивает. Когда приложение завершает обработку одного объекта, связанный счетчик достигает нуля, и я уверен, что этот объект больше никогда не будет использоваться, поэтому его можно безопасно удалить (с точки зрения приложения). зрения).
Однако проблема в том, что у меня нет абсолютно никаких гарантий, что:
- Если объект X был замечен 5 раз за месяц, то все эти 5 объектов будут обработаны подряд.
- Если объект X был замечен 5 раз за месяц, то этот объект будет обработан 5 раз подряд.
На самом деле, оба утверждения — это одно и то же: я не могу свести обработку к очереди, классическому антишаблону Cassandra, потому что счетчик не сразу обнулится.
Действительно, эти 5 объектов будут (более реалистично) обрабатываться по одному за раз с некоторой неопределенной задержкой между ними. Таким образом, если у объекта X есть 5 «счетчиков», когда обрабатывается один объект X, я должен обновить счетчик и установить его на 4, и «ждать», пока не будут обработаны все оставшиеся 4 объекта X, по одному за раз.
Это худшая «гибридная» модель, которую я видел до сих пор, в том смысле, что она использует худший из двух миров: модель часто обновляемых столбцов и модель защиты от шаблонов очередей.
Я хотел бы удалить все эти объекты, чтобы освободить место для хранения, и я пытаюсь найти модель, которая не будет слишком сильно зависеть от шаблона записи приложения.
Из того, что я видел до сих пор, если бы я мог найти способ собирать объекты в таблице, которые можно было бы удалить в конце, я бы выполнял только частые обновления, потому что удаление полностью удалит таблицу и позволит избежать всех удалений и беспорядка с надгробиями (при условии, что при удалении надгробий не делаются снимкитаблица). Затем я бы создал новую таблицу для обработки следующей группы данных (что-то вроде постоянного имени таблицы, за которым следует увеличивающееся монотонное число, чтобы избежать повторного использования одного и того же имени таблицы с течением времени, например TBLNAME0
, TBLNAME1
и т. Д.).
Это, очевидно, принесло бы некоторые преимущества приложению, но привело бы к некоторым потенциальным несоответствиям в схеме. Думая о распределенной вещи, если один или несколько узлов не работают, я бы получил большие возможности испортить данные, и, очевидно, это то, чего я хотел бы избежать.
С другой стороны, если я не удаляю всю таблицу и придерживаюсь удаления, надгробия могут привести к огромным штрафам за чтение для приложения.
Говоря о частоте удаления / удаления, я бы ожидал, что в среднем таблица будет удаляться один или два раза в день, и я бы ожидал, что более 10 миллионов удалений в день будут выполняться регулярно.
Q1: отбрасывать или не отбрасывать? (Я голосую за дроп).
Q2: Действительно ли Кассандра подходит для этого? Есть какие-нибудь предложения о том, что еще можно использовать?
Ответ №1:
… Я ожидаю получить 10-50 миллиардов различных объектов, поэтому ожидаемый размер данных составляет от 10 до 50 ТБ…
С таким большим набором данных, как бы вы могли перенести данные в новую таблицу в любое приемлемое время?
Я рекомендую вам удалить объекты. Если эти надгробия не расположены в широком ряду, то штраф за чтение, чтобы получить живые клетки, будет не таким большим. Так что создание таблицы с разумным ключом раздела определенно было бы плюсом.
По моему опыту, для частого обновления столбцов увеличение commitlog_total_space_in_mb и memtable_total_space_in_mb помогает избежать частых сбросов memtable в sstable. Это уменьшает уплотнение и давление gc.
Если вы предоставили более подробную информацию о предлагаемой схеме и примере наиболее частых операторов CQL, которые вы ожидаете выполнить, люди могут получить лучшее представление о том, что вы собираетесь делать.
Комментарии:
1. Я не ожидаю повторного использования каких-либо данных, поэтому никаких перетасовок данных или чего-либо еще. У меня уже нет широких рядов, но обновление freq означает, что удалять надгробия будет сложнее, потому что они будут лежать на разных sstables. Я не понимаю, почему наличие «большого» пространства журнала фиксации может уменьшить промывку и сжатие, потому что обычно это
memtable_total_space_in_mb
узкое место.2. Поскольку, если данные, которые не были сброшены с memtable на диск, превышают доступное пространство журнала фиксации, memtable необходимо сбросить. Даже когда сама memtable, возможно, не достигла предела. Это делается для того, чтобы убедиться, что данные переданы в sstable, прежде чем пространство журнала фиксации будет использовано повторно.
3. Да, я знаю, но
memtable_total_space_in_mb
это настоящее узкое место, а не пространство журнала фиксации. 300 ГБ пространства журнала фиксации (очень распространенное IMHO) огромно по сравнению с (редким) 30 ГБ общего пространства memtable. Разве вы не согласны?4. Я абсолютно согласен с этим. Но я не знал, что у вашего узла есть такая (или в каком-то соотношении) настройка. Но суть моего комментария заключалась в том, чтобы попытаться уменьшить поток из memtable в sstable для часто обновляющегося варианта использования столбцов.