【问题标题】:Why HBase rows are said to be stored as lexicographically sorted?为什么说 HBase 行按字典顺序存储?
【发布时间】:2020-05-17 17:47:45
【问题描述】:

基于 HBase documentation,再次遵循 Google BigTable 论文的参考,据说行是使用行键的字典排序存储的。

很明显,当我们在 rowkey 中有一个字符串或者我们将一个字符串转换为字节数组并存储它时,这些行是按字典顺序排序的。事实上,即使将整数转换为字符串,然后再转换为字节数组,也是有意义的。 例如:下面的 hbase shell 将数字作为字符串并存储它

create 'test', 'cf'
put 'test', '1', 'cf:c1', 'xyz1'
put 'test', '2', 'cf:c1', 'xyz2'
put 'test', '11', 'cf:c1', 'xyz11'

scan 'test3'
ROW                                         COLUMN+CELL
 1                                          column=cf:c1, timestamp=1589736288540, value=xyz1
 11                                         column=cf:c1, timestamp=1589736311607, value=xyz11
 2                                          column=cf:c1, timestamp=1589736301167, value=xyz2
3 row(s) in 0.0080 seconds

另一方面,我可以使用 HBase 客户端实用程序(org.apache.hadoop.hbase.util.Bytes,它使用 Big Endian 的东西..)以编程方式将数字转换为字节数组,我看到行是自然排序的,而不是在字典法。对于上面类似的数据和表格,我使用下面的代码将数据放到 HBase 表中。

val put = new Put(Bytes.toBytes(11L))
put.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("c1"), Bytes.toBytes("abc"))
table.put(put)

扫描结果是

hbase(main):014:0> scan 'test2'
ROW                                        COLUMN+CELL
 \x01                                      column=cf:a, timestamp=1589727058289, value=abc \\1
 \x02                                      column=cf:a, timestamp=1589727099714, value=abc \\2
 \x0B                                      column=cf:a, timestamp=1589727147449, value=abc \\11
 {                                         column=cf:a, timestamp=1589733907127, value=abc \\123
 \xF8                                      column=cf:a, timestamp=1589733854179, value=abc \\112312312L
5 row(s) in 0.0080 seconds

我的问题是 -
从整数生成的字节数组的字典顺序与自然顺序相同,这纯属巧合吗我们将长字节数组转换为字节数组的方式实际上是用一些值填充以获得有效的自然排序?
如果不是,为了处理非类型化的行键,我们是说行键是按字典顺序排序的,这样当你与字符串等数据类型混合匹配时,排序有一个预定的顺序?在后一种情况下,在我看来,行键按严格的字典顺序排序是不正确的,因为只是为了满足我们对非类型列(此处为行键)的需求,它是这样构建的..!

基本上,这里的字节编码 -> Bytes.toBytes(long) 保留了 Long 的自然顺序吗?也就是说,函数返回的Array[Byte]的字典顺序会和输入的Long的自然顺序一样吗?

【问题讨论】:

    标签: hbase bigtable lexicographic row-key


    【解决方案1】:

    您的问题的答案是肯定的。但是,如果您混合不同的密钥大小,请小心。例如,如果您使用所有相同大小的键,并且全部使用Bytes.toBytes(long) 生成,它们将保持自然长顺序。如果您混合不同大小的字节数组,情况就不会如此,因为正如您所展示的,例如,一个字节“1”将大约是两个字节“11”。

    对于toBytes(),它使用固定长度的大端编码。假设您使用四个字节,那么排序将是:

    00 00 00 00 (long value 0)
    00 00 00 01 (long value 1)
    00 00 00 02
    ...
    00 00 01 00 (long value 256)
    ...
    

    这将在自然数和密钥生成中进行相同的排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-24
      • 2018-06-13
      • 2012-12-09
      相关资源
      最近更新 更多