У меня есть вопрос, связанный с дизайном схемы HBase.Проблема довольно проста - я храню «уведомления» в hbase, каждое из которых имеет статус («новый», «увиденный» и «прочитанный»).Вот API, которые я должен предоставить:
- Получить все уведомления для пользователя
- Получить все "новые" уведомления для пользователя
- Получить количество всех«новые» уведомления для пользователя
- обновление статуса для уведомления
- обновление статуса для всех уведомлений пользователя
- получение всех «новых» уведомлений по всей базе данных
- Уведомления следует сканировать в обратном хронологическом порядке и разрешать разбиение на страницы.
У меня есть несколько идей, и я хотел посмотреть, является ли одно из них явно лучшим или я пропустил хорошийстратегия целиком.Общим для всех трех, я думаю, что наличие одной строки на уведомление и наличие идентификатора пользователя в ключе строки - путь.Чтобы получить хронологическое упорядочение для нумерации страниц, мне тоже нужно иметь обратную метку времени.Я хотел бы хранить все уведомления в одной таблице (поэтому мне не нужно объединять сортировку для вызова «получить все уведомления для пользователя») и не хочу писать пакетные задания для таблиц вторичного индекса (поскольку обновления дляколичество и статус должны быть в режиме реального времени).
Самый простой способ сделать это - (1) ключ строки "userId_reverseTimestamp" и выполнить фильтрацию статуса на стороне клиента.Это кажется наивным, так как мы будем посылать много ненужных данных по сети.
Следующая возможность - (2) также кодировать статус в ключ строки, поэтому либо «userId_reverseTimestamp_status», а затем выполнить регулярное выражение строки ключафильтрация на сканы.Первая проблема, которую я вижу, - это необходимость удалить строку и скопировать данные уведомления в новую строку при изменении состояния (что, по-видимому, должно происходить ровно дважды за уведомление).Кроме того, поскольку статус является последней частью ключа строки, для каждого пользователя мы будем сканировать множество дополнительных строк.Это большой успех производительности?Наконец, чтобы изменить статус, мне нужно знать, каким был предыдущий статус (для создания ключа строки), иначе мне нужно будет сделать еще одно сканирование.
Последнее, что у меня было, - это (3) имеют два семейства столбцов, одно для статических данных уведомлений и одно в качестве флага для статуса, то есть «s: read» или «s: new» с «s» в качестве cf и статусом в качестве квалификатора.Там будет ровно один на строку, и я могу сделать MultipleColumnPrefixFilter или SkipFilter w / ColumnPrefixFilter против этого cf.Здесь я также должен был бы удалить и создать столбцы при изменении статуса, но это должно быть намного проще, чем копирование целых строк.Мое единственное беспокойство вызывает предупреждение в книге HBase о том, что HBase плохо справляется с «более чем 2 или 3 семействами столбцов» - возможно, если система нуждается в расширении с большим количеством возможностей запросов, стратегия multi-cf не масштабируется.
Таким образом, (1) кажется, что он будет слишком загружен сетью.(2) кажется, что это потратило бы впустую затраты на копирование данных, и (3) могло бы вызвать проблемы со слишком многими семьями.Между (2) и (3), какой тип фильтра должен давать лучшую производительность?В обоих случаях при сканировании будет просматриваться каждая строка для пользователя, который, предположительно, имеет в основном уведомления о прочтении, что будет иметь более высокую производительность.Я думаю, что склоняюсь к (3) - есть ли другие варианты (или настройки), которые я пропустил?