HBase RowKey用于分层数据

时间:2015-04-14 21:19:06

标签: hbase nosql

我想建议设计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行,英国没有国家概念,因此英国记录中缺少州等级

要求是搜索以下场景:

|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: 例, US:101:102:103:104:105:106:107
  2. 我想的其他选择是创建一个二级索引,但由于我计划使用Hbase作为我的Web应用程序的后端,因此必须在性能结束时进一步探索它。

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

1 个答案:

答案 0 :(得分:1)

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

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

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

如果您的LevelCode ID是规范化整数并且您想使用它们来过滤数据,那么您应该考虑添加一个ID系列(值为整数列),这样您就可以扫描该系列并过滤掉您所关注的内容不需要SingleColumnValueFilter

如果你有空闲时间,请看看Amandeep Khurana的伟大Introduction to HBase schema design


关于实时答案

如果您需要提供查询的实时答案,那么在给定大量数据的情况下,您的方法将无法正常运行。 HBase是一个数据存储,而不是一个搜索引擎,它可以在庞大的数据集中运行搜索和分析工作,但它们不是实时的。

通过适当的设计,HBase可以作为简单搜索的实时后端,但在设计表时应遵循这些咒语:

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

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

请注意,您的一些查询合并了多个字段(“All Atheist for USA”或“LATITUDE&gt; 30和LONGITUDE&lt; 101”),在这些情况下,您还需要为它们和每个字段提供二级索引它们的组合,如果你想用HBase处理它们会使事情变得复杂得多。

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

也许你会发现elasticsearch对你的任务有用:快速,易学,灵活,可靠,可扩展,并且有很多语言的API。