Комментарии 10
Почему HBase, а не Cassandra? Рассматривались ли иные NoSQL-базы?
Судя по картинке, в данной архитектуре Zookeeper — это отдельная нода? Если она падает, то все курят бамбук?
Судя по картинке, в данной архитектуре Zookeeper — это отдельная нода? Если она падает, то все курят бамбук?
HBase используется по организационным причинам, в планах есть поработать с Cassandra и если результаты окажутся интересными то переедем на нее.
Zookeeper это кластер из 3-5 нод (где как)
Zookeeper это кластер из 3-5 нод (где как)
А почему Cassandra, а не HBase? Ведь этот вопрос можно задать и в такой формулировке.
Спасибо за публикацию.
А как вы работаете со Scan по частичному ключу в случае «солёных» таблиц?
Чтобы не делать full scan по всей таблице из 100500 миллионов записей.
Из -за того, что ключи подсолены CRC32, данные распределяются по кластеру более-менее равномерно, надо или сделать scan со всеми возможными солями + частичный ключ или… здаравствуй fullscan.
А как вы работаете со Scan по частичному ключу в случае «солёных» таблиц?
Чтобы не делать full scan по всей таблице из 100500 миллионов записей.
Из -за того, что ключи подсолены CRC32, данные распределяются по кластеру более-менее равномерно, надо или сделать scan со всеми возможными солями + частичный ключ или… здаравствуй fullscan.
Рад что понравилось)
Если Вы имеете в виду, что набор интересующих ключей известен, то он просто заворачивается в List<Get> keys и отправляется командой: table.get(keys). Клиент получит адреса попавших в запрос регионов и разошлет им свои кусочки запросов. Получив ответы склеит и вернет Result[]
Если Вы имеете в виду, что набор интересующих ключей известен, то он просто заворачивается в List<Get> keys и отправляется командой: table.get(keys). Клиент получит адреса попавших в запрос регионов и разошлет им свои кусочки запросов. Получив ответы склеит и вернет Result[]
Это как раз просто, имея полный ключ посчитать CRC32, прибавить и сделать список Get
А если ключ составной, и известна только часть ключа, то всё становится гораздо более интересно.
Предположим, что ключ имеет вид «customerId|year|month|day|transactionId», от него считается CRC32 и в БД кладётся «hash|customerId|year|month|day|transactionId»
Задача посчитать сумму транзакций клиента за месяц года. Известная часть ключа «customerId|year|month»
Так как ключи подсолены, данные по транзакциям размазаны по кластеру, put и get идут быстро, но… нельзя уже сделать один scan с префиксом ключа «customerId|year|month» чтобы получить данные по всем транзакциям месяца. Тут или делать сканы по всем возможным значениям хеша +частичный ключ или full scan.
Каким путём лучше идти в этом случае?
А если ключ составной, и известна только часть ключа, то всё становится гораздо более интересно.
Предположим, что ключ имеет вид «customerId|year|month|day|transactionId», от него считается CRC32 и в БД кладётся «hash|customerId|year|month|day|transactionId»
Задача посчитать сумму транзакций клиента за месяц года. Известная часть ключа «customerId|year|month»
Так как ключи подсолены, данные по транзакциям размазаны по кластеру, put и get идут быстро, но… нельзя уже сделать один scan с префиксом ключа «customerId|year|month» чтобы получить данные по всем транзакциям месяца. Тут или делать сканы по всем возможным значениям хеша +частичный ключ или full scan.
Каким путём лучше идти в этом случае?
Если я правильно понял, имеется в виду сделать размер хэша к примеру 1 байт и слать запрос сразу по всем 256 вариантам настроив фильтры вида:
Filter rowFilter=new RowFilter(CompareOp.EQUAL, new BinaryPrefixComparator(«hash|customerId|year|month»));
В принципе возможно, только это будет примерно в 100 раз медленнее работать чем, если запросить заранее известное количество ключей. Если запросов такого рода мало, то наверное имеет смысл. С другой стороны если запросы таковы, что покрывают значительную часть всего диапазона, то может быть эффективнее FullScan — собственно в одном из проектов мы так и делаем.
Если же понятно, что эта информация нужна для всех, то можно повесить сопроцессор на табличку и считать агрегаты по клиенту при записи в отдельной таблице с ключом «hash|customerId|year|month|day».
А вообще, конечно, работать с key-value БД не зная ключа довольно занимательная задача, у нас таких кейсов пока не было)
Filter rowFilter=new RowFilter(CompareOp.EQUAL, new BinaryPrefixComparator(«hash|customerId|year|month»));
В принципе возможно, только это будет примерно в 100 раз медленнее работать чем, если запросить заранее известное количество ключей. Если запросов такого рода мало, то наверное имеет смысл. С другой стороны если запросы таковы, что покрывают значительную часть всего диапазона, то может быть эффективнее FullScan — собственно в одном из проектов мы так и делаем.
Если же понятно, что эта информация нужна для всех, то можно повесить сопроцессор на табличку и считать агрегаты по клиенту при записи в отдельной таблице с ключом «hash|customerId|year|month|day».
А вообще, конечно, работать с key-value БД не зная ключа довольно занимательная задача, у нас таких кейсов пока не было)
Кстати иногда годится еще такой вариант — вместо хэша использовать реверс ключа. Но это ок только если у последних байт равномернное распределение. В вашем примере получается такой ключ:
"iDremotsuc|year|month|day|transactionId"
И запрашивать 256 вариантов тогда не нужно.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Теория и практика использования HBase