我们有一个 Hbase 表,其中它们的行键是通过连接站点 + 文章来准备的,即,如果我有销售 100,200,300 篇文章的站点 A。我的行键分别是 A100、A200、A300。现在我们只想使用文章编号扫描 hbase 表。可以存在于多个站点中。我们尝试使用子字符串比较器执行扫描。但这需要很长时间。任何人都可以为相同的场景提出更好的加盐或行键设计。
1 回答
在您能够交换 SiteId 和 ArticleId 之前,似乎无法通过简单的 rowkey 重新设计来解决此问题,但在这种情况下,您将遇到通过 SiteId 搜索的相同问题。这种行为的原因是 HBase 无论如何都无法通过键的中间或最后部分优化搜索,它必须进行全面扫描。
您可能会想到的一些解决方案:
1. 使用条件为每个站点执行多个并发搜索rowkey == SiteIdArticleId
。如果您的站点数量相对较少,这将很快奏效。
2. 做一个custom secondary index
。第二个索引表,AtricleId 作为 rowkey,SiteIds 作为卖出值。
3.使用Apache Phoenix
可以开箱即用的二级索引。(但首先检查它是否适合需要)
在第二种情况下,您可以从索引表中通过键执行获取,而不是从第一次获取中的每个单元格从零到多次获取。这将很快工作,但需要一些空间开销。
第二个选项更详细:
假设您的表已整理SiteToArticle
,第二张表已整理ArticleToSite
当您执行写入操作时,您会像往常一样将两个表写入第一个表,然后再写入第二个表{"rowkey"=ArticleId, "SiteId"=siteId}
当您进行读取时,首先您从 读取ArticleToSite
,然后使用 key 遍历每个SiteId
create new getSiteId: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);