У нас есть таблица Hbase, в которой ключ строки подготовлен путем объединения сайта и статьи, т. е. если у меня есть сайт A, который продает 100 200 300 артикулов. Мои строки - A100, A200, A300 соответственно. Теперь мы хотим просканировать таблицу hbase, используя только артикул. Который может присутствовать на нескольких сайтах. Мы попытались выполнить сканирование с помощью компаратора подстрок. Но это занимает много времени. Может ли кто-нибудь предложить лучший дизайн соления или рядного ключа для того же сценария.
1 ответ
Не похоже, что эта проблема может быть решена простым изменением дизайна строки, пока вы не сможете поменять местами SiteId и ArticleId, но в этом случае у вас будет такая же проблема с поиском по SiteId. Причина такого поведения в том, что HBase никак не может оптимизировать поиск по средней или последней части ключей и вынужден делать полное сканирование.
Некоторые решения, которые вы могли бы придумать:
1. Сделайте несколько одновременных поисков по одному на каждый сайт с условием rowkey == SiteIdArticleId
. Это будет работать быстро, если у вас относительно небольшое количество сайтов.
2. Выполните custom secondary index
. Вторая индексная таблица с AtricleId в качестве ключа строки и SiteId в качестве значений продажи.
3. Используйте Apache Phoenix
, который может выполнять вторичное индексирование "из коробки". (Но сначала проверьте, подходит ли он вам)
Во втором случае вы можете выполнить получение по ключу из индексной таблицы, а затем от нуля до нескольких значений для каждой ячейки из первого получения. Это будет работать довольно быстро, но потребует некоторого пространства.
Подробнее о втором варианте:
Предположим, что ваша таблица собрана SiteToArticle
, а вторая таблица собрана ArticleToSite
Когда вы делаете записи, вы пишете в обе таблицы, в первую, как обычно, и во вторую, как {"rowkey"=ArticleId, "SiteId"=siteId}
Когда вы выполняете чтение, сначала вы читаете из ArticleToSite
, затем выполняете итерацию по каждому SiteId
, создаете новый get с ключом SiteId:ArticleId
и выполняете второй пакет get. Код может выглядеть примерно так:
byte[] articleId = "ArticleId".getBytes();
Get get = new Get(articleId).readAllVersions();
Table t = connection.getTable(TableName.valueOf("ArticleToSite"));
List<Get> gets = new ArrayList<>();
for (Cell c : t.get(get).getColumnCells("CF".getBytes(), "SiteId".getBytes())) {
byte[] key = Bytes.add(CellUtil.cloneValue(c), ":".getBytes(), articleId);
gets.add(new Get(key));
}
return connection.getTable(TableName.valueOf("SiteToArticle")).get(gets);
Похожие вопросы
Новые вопросы
hbase
HBase - это база данных Hadoop (столбчатая). Используйте его, когда вам нужен случайный доступ в режиме реального времени для чтения / записи ваших больших данных. Целью этого проекта является размещение очень больших таблиц - миллиарды строк и миллионы столбцов - поверх кластеров товарного оборудования.
get
для каждого сайта.