如何设计hbase表

时间:2018-01-16 07:20:12

标签: hbase

我打算为JSON数据设计Hbase表。

由于我不太了解Hbase概念,我想知道下面提到的JSON类型的Design表的最佳方法是什么。

虚线是Json数据中的逻辑部门: 这意味着A记录有一个uid的rowkey,然后BOLD中的请求部分,Italics&中的响应部分。分类。在分类下,有一个类似于Array的结构。 我正在考虑为每个逻辑组创建3个列族。但是如何将类似数组的结构(“问题原因”)存储到HBASE表中。除了Binary之外还有什么特定的数据类型吗?

{
        "uid": "abc2342",
-----------------------------------

        "req1": sometext,
        "res1": sometext,
        "matter": "point1",
        "body": "point2",
-------------------------------------
        "response": null,
                "validity": null
---------------------------------------

    "classification": "Problems",
        "Problem reasons": [
            "Address Not found",
            "Invalid Phone Number",
            "Invalid Email"
        ]
    },

3 个答案:

答案 0 :(得分:2)

HBase只有二进制。您将不得不自己序列化和反序列化数据。 HBase Bytes课程可以为您提供帮助(例如Bytes.toBytes((short) 5))。对于阵列,考虑到您如何计划查询,您将不得不弄清楚哪种格式最适合您。存储字符串数组的一种简单方法是使用字符串本身不允许的分隔符将它们连接起来。您也可以将其转储为JSON。

schema is the key的另一个重要考虑因素。通常,您希望拥有一个统一的随机密钥,这样您就不会得到可能降低性能的热点。获得它的一个简单方法是散列您的字符串键并使用散列的字节。

column families

  

从物理上讲,所有列族成员都存储在文件系统中。由于调谐和存储规范是在列族级别完成的,因此建议所有列族成员具有相同的通用访问模式和大小特征。

IBM有一个很好的document,有一些经验法则:

  

HBase表由列族组成,列族是列的逻辑和物理分组。一个系列中的列与另一个系列中的列分开存储。如果您有不经常查询的数据,请将该数据分配给单独的列族。

     

每行重复列族和列限定符名称。因此,请尽可能缩短名称,以减少HBase存储和读取的数据量。例如,使用f:q而不是mycolumnfamily:mycolumnqualifier。

     

由于列族存储在单独的HFile中,因此请尽可能减少列族数。您还希望减少列族数,以减少MemStore刷新的频率以及压缩的频率。并且,通过使用尽可能少的列系列,您可以改善LOAD时间并减少磁盘消耗。

答案 1 :(得分:2)

我假设您的结构是每个用户有一个请求,一个响应和几个问题。

如果是这样,只需将UID设为rowkey即可。 Rowkey设计是HBase架构设计中最重要的部分。这是因为HBase根据rowkey对数据进行分片,并控制您查找数据的方式。为避免热点,您可能希望将UID的哈希前置到密钥的前面。例如,您可以将密钥设为hash(UID):UIDf97h23:user123

现在谈谈你的下一个问题。 HBase只存储字节。它并不关心这些字节是什么。由程序决定你存储的字节意味着什么。除了计数器之外,HBase不知道数据类型,但我们将忽略这些数据类型。

这个表看起来相当简单,所以我将其余的JSON字段分别放入一个列中。对于数组,我已经完成了列中的分隔列表,即Address Not found,Invalid Phone Number,Invalid Email。无论何时使用这样的方案,都要确保在数据中使分隔符非法,或者使用转义方案。

在大多数情况下,我认为没有理由选择单独的列族。您似乎每行都有少量数据,并且您没有提到不同的访问模式,这使我假设您在查询UID时主要只是获取每个字段。如果确实如此,您甚至可以使用一列“JSON”来存储您的json字符串。这样做的缺点是需要序列化和反序列化JSON。

有关您的用例的更多信息将有助于指导设计。 比如:

  • 您能否一般性地描述您使用此数据库解决的问题?

  • 您是否总是阅读所有专栏,或只是一些?

  • 您期望总共有多少行?

  • 您是否经常追加新记录或更新现有记录?

  • 读写的组合是什么?

  • 性能要求是什么?

答案 2 :(得分:2)

HBase是一个愚蠢的野兽,你必须这样对待它。它只是一个低级别的索引存储。

您应遵循一条规则 - 您的架构应以访问方式存储,而不是存储。 根据其他注释,您应该使用req1生成您的rowkey。

但请注意! req1必须分布良好,而不是二进制顺序值。如果必须,请使用种子。

如果使用rowkey整体访问JSON对象 - 那么只需将所有内容转储到二进制字符串中,BSON或某些序列化程序就足够了。如果不同时更新的数量并不重要。

如果您希望能够使用密钥或同时添加/更改值来仅引用数据子集,则应将它们拆分出来。

根据您的示例,您可以轻松地将值拆分为3个列系列:

  1. 请求(列类似 req:req1 req:uid 等等)
  2. 响应(列类似 res:validity 等等)
  3. 分类
  4. 在分类列族中,您可以将值拆分为最低级别:

    • 列cl:分类可以识别分类类型
    • 如果您的分类列表合理且有限,则可以按分类命名列族 - 列族问题
    • 然后您可以将数组值添加为列值或列名称:
      • 问题:1 => "地址未找到"
      • 问题:addressnotfound => 1 - 这种方法的主要好处是它可以很好地处理并发更新。
      • cl:reason1 => "地址未找到"