【问题标题】:HBase RowKey for Hierarchical data用于分层数据的 HBase RowKey
【发布时间】:2017-09-16 17:27:21
【问题描述】:

我想有一个关于设计 Hbase 表/RowKey 以实现高效搜索的建议

这里是一个样本数据集:

|   Column Families |   Column Qualifiers   |   Row 1               |   Row 2           |   Row 3       |
---------------------------------------------------------------------------------------------------------
|   Country         |           Code        |   US                  |                   |   UK          |
|
|                   |           Full Name   |United States of America|                  |United Kingdom |
|                   |           Capital     |Washington, DC         |                   |London         |
|                   |           Leader      | President             |   President       |Prime minister |

|State              |                       |   Texas               |                   |               |
|District           |                       |Houston                |LA                 |               |
|County             |                       |Harris                 |Harris             |   Cambridge   |
|City               |                       |Houston city           |Duke City          |               |
|Road               |                       |Bellare                |                   |Downing Street |
|Family             |                       |Doe                    |Wade               |               |

|Person             |       Name            |John Doe               |Doo                |Smith          |
|                   |       Location        |35.00 N, 99.00 W       |31.00 N , 100.00 W |               |
|                   |       Gender          |                       |Female             |Male           |
|                   |       Religion        |Atheist                |Maya               |Christian      |

注意:在上面的示例数据集中,列限定符仅针对第一个和最后一个列族进行了详细说明,以避免数据混乱。

数据概览: 它是一个分层数据集,但任何级别的信息都可能丢失 例子, 第 2 行没有国家信息 第 3 行,UK 没有 State 的概念,因此 UK 记录将缺少 State 层次结构

要求是搜索以下场景:

|Search Criteria                    |Returned Records           |
-----------------------------------------------------------------
|All records                        |3 count, Row1, Row2 & Row3 |
|Country = USA                      |1 Record, Row 1            |
|Gender = Male                      |1 Record, Row 3            |
|County = Harris                    |2 records, Row 1 & Row 2   |
|LATITUDE > 30 and LONGITUDE < 101  |2 records, Row 1 & Row 2   |
|All Atheist for USA                |1 record, Row1             |

提出的设计方案:

1。为每个级别创建八个列族,因为可以添加需要在每个级别搜索的信息(例如,领导姓名、职位、时区、级别城市、县、区、国家的区域等)

|Level one      |Country    |
|Level two      |State      |
|Level three    |District   |
|Level four     |County     |
|Level Five     |City       |
|Level Six      |Road       |
|Level Seven    |Family     |
|Level Eight    |Person     |
  1. 将 Rowkey 设计为复合键,所有级别代码的组合,因为搜索可以在任何级别 Level1Code:Level2Code:Level3Code:Level4Code:Level5Code:Level6Code:Level7Code:Level8Code: 例子, 美国:101:102:103:104:105:106:107

我正在考虑的其他替代方法是创建二级索引,但由于我计划使用 Hbase 作为我的 Web 应用程序的后端,因此必须在性能方面进一步探索它。

提前感谢您分享您的专业知识!

【问题讨论】:

    标签: hbase nosql


    【解决方案1】:

    关于列族的数量,我会坚持尽可能少的族数 (HBase docs)。鉴于您的情况,我将尝试使用 2 个家庭:一个用于位置数据,另一个用于与人员相关的数据,这样您就可以按位置搜索而无需阅读有关此人的任何信息,反之亦然。提醒一下,如果你只扫描一个家庭来加快速度,你只能检索那个家庭的数据,所以在这种情况下,如果你在美国寻找人,你将无法得到他们的名字,除非你也添加其他家庭,如果是这样的话,拥有多个家庭没有任何好处。如果您的数据需要不同的配置(TTL、版本、压缩...),或者如果它们可以独立查询而不需要来自其他系列的数据,则使用多个系列。

    最后,这一切都取决于您最常见的查询以及何时需要减少读取的数据量:假设您根据地理位置执行大量查询,在这种情况下,我会移动 Lat & Long 列给自己的家人,以避免阅读其他任何内容。

    关于复合行键:我不太确定您的 LevelCode id 来自哪里,它们是存储在其他地方的标准化值吗?如果您将它们作为字符串存储在您的行键中,您的行键看起来会很大(任何字符都需要 1 个字节,如果您有大的 LevelCode id,您将以 +60 字节的行键结尾),请注意在 HBase 中每个单元格都包含行键 + 列族 + 列 + 时间戳 + 值,因此,在存储方面将是一个相当大的开销,而查询时的性能提升并不多。

    如果您的 LevelCode id 是标准化整数,并且您想使用它们来过滤数据,也许您应该考虑添加一个 ids 系列(将值作为整数列),这样您就可以只扫描该系列并过滤掉您所做的不需要SingleColumnValueFilter

    如果您有空闲时间,可以看看 Amandeep Khurana 的 Introduction to HBase schema design


    关于实时答案

    如果您需要为查询提供实时答案,鉴于大量数据,您的方法都不会很好地工作。 HBase 是一个数据存储,而不是搜索引擎,它可以在巨大的数据集中运行搜索和分析作业,但它们不是实时的。

    如果设计得当,HBase 可以作为简单搜索的实时后端,但在设计表格时应遵循以下原则:

    • 不惜一切代价避免全面扫描,即使它们有过滤器。全扫描 = 读取每一行 = 不适合实时。
    • 写入速度很快。根据需要对数据进行非规范化并写入尽可能多的数据,以加快数据检索速度。

    这意味着如果您需要实时检索预期运行的每个查询,您都需要二级索引。您的所有扫描查询都应该至少有一个起始行键,这需要将相同的数据写入不同行键下的多个表(甚至通过为每种索引类型使用前缀来写入同一个表,我不推荐这种做法,它使分裂变得非常困难,并且可能会出现热点问题)。

    请注意,您的某些查询结合了多个字段(“All Atheist for USA”或“LATITUDE > 30 and LONGITUDE

    我倾向于不建议切换到其他系统,因为通常事情可以通过或多或少的努力完成,但是,根据您的用例,我认为最好选择一个负责索引的搜索引擎通过它自己。

    也许您会发现elasticsearch 对您的任务很有用:它快速、易于学习、灵活、可靠、可扩展,并且拥有适用于多种语言的良好 API。

    【讨论】:

    • 谢谢鲁本。目前它不是真正的时间需求,并且想了解“将所有东西都放在一个家庭并依赖行/列过滤器”是什么意思
    • 仅供参考,家庭信息也可能丢失。另外,您是否鼓励采用这种格式 Level1Code:Level2Code:Level3Code:Level4Code:Level5Code:Level6Code:Level7Code:Level8Code: example, US:101:102:103:104:105:106:107 的 RowKey?关于表重组还有其他建议吗?
    • 既然您说您将使用它作为您的网络应用程序的后端,我认为您需要实时响应。我已经更新了我的答案以添加更多信息,如果您需要我更具体地了解任何主题,请查看并告诉我:)
    • Rubén,我要衷心感谢您的 cmets。让我进一步探讨这个问题并回复您。再次感谢您的宝贵时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多