簡體   English   中英

為什么說 HBase 行按字典順序存儲?

[英]Why HBase rows are said to be stored as lexicographically sorted?

基於 HBase文檔,再次遵循 Google BigTable 論文的參考,行被認為是使用行鍵的字典排序存儲的。

很明顯,當我們在 rowkey 中有一個字符串或者如果我們將一個字符串轉換為字節數組並存儲它時,行是按字典順序排序的。 事實上,即使將 integer 轉換為字符串,然后再轉換為字節數組,也是有意義的。 eg:下面的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 Table。

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

我的問題是 -
從整數生成的字節 arrays 的字典順序與自然順序相同是純屬巧合,還是我們將 long 轉換為字節數組的方式實際上是用一些值填充以獲得有效的自然順序?
如果不是,為了處理非類型行鍵,我們是說行鍵按字典順序排序,這樣當你混合和匹配字符串和其他數據類型時,排序有預定的順序? 在后一種情況下,在我看來,行鍵嚴格按照字典順序排序是不正確的,因為只是為了滿足我們對具有非類型化列(此處為行鍵)的需求,它是這樣構建的......!

基本上,這里的字節編碼 -> Bytes.toBytes(long) 是否保留了Long的自然順序? 也就是說,function 返回的Array[Byte]的字典序和作為輸入的Long的自然序一樣嗎?

你的問題的答案是肯定的。 但是,如果您混合使用不同的密鑰大小,請小心。 例如,如果您使用相同大小的所有鍵,並且全部由Bytes.toBytes(long)生成,它們將保持自然的長順序。 如果您混合不同大小的 arrays 字節,情況就不會如此,因為,如您所示,例如,一個字節“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)
...

這將在自然數和密鑰生成中進行相同的排序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM