1 主要區別
- Hbase適合大量插入同時又有讀的情況
- Hbase的瓶頸是硬盤傳輸速度,Oracle的瓶頸是硬盤尋道時間。
Hbase本質上只有一種操作,就是插入,其更新操作是插入一個帶有新的時間戳的行,而刪除是插入一個帶有插入標記的行。
其主要操作是收集內存中一批數據,然后批量的寫入硬盤,所以其寫入的速度主要取決於硬盤傳輸的速度。
Oracle則不同,因為他經常要隨機讀寫,這樣硬盤磁頭需要不斷的尋找數據所在,所以瓶頸在於硬盤尋道時間。
- Hbase很適合尋找按照時間排序top n的場景
- 索引不同造成行為的差異。
- Oracle 既可以做OLTP又可以做OLAP,但在某種極端的情況下(負荷十分之大),就不適合了。
2 Hbase的局限:
- 只能做簡單的Key value查詢,復雜的sql統計做不到。
- 只能在row key上做快速查詢。
3 傳統數據庫的行式存儲
在數據分析的場景里面,我們經常是以某個列作為查詢條件,返回的結果經常也只是某些列,不是全部的列。
行式數據庫在這種情況下的I/O性能會很差,
以Oracle為例,Oracle會有一個很大的數據文件,
- 在這個數據文件中,划分了很多block,然后在每個block中放入行,
- 行是一行一行放進去,擠在一起,然后把block塞滿,當然也會預留一些空間,用於將來update。
這種結構的缺點是:
當我們讀某個列的時候,比如我們只需要讀紅色標記的列的時候,不能只讀這部分數據,我必須把整個block讀取到內存中,然后再把這些列的數據取出來,
換句話說,我為了讀表中某些列的數據,我必須把整個列的行讀完,才可以讀到這些列。
如果這些列的數據很少,比如1T的數據中只占了100M, 為了讀100M數據卻要讀取1TB的數據到內存中去,則顯然是不划算。
3.1 B+索引
Oracle中采用的數據訪問技術主要是B數索引:
從樹的跟節點出發,可以找到葉子節點,其記錄了key值對應的那行的位置。
對B樹的操作:
B樹插入——分裂節點
B數刪除——合並節點
4 列式存儲
- 同一個列的數據會擠在一起,比如擠在block里,當我需要讀某個列的時候,只需要把相關的文件或塊讀到內存中去,整個列就會被讀出來,這樣I/O會少很多。
- 同一個列的數據的格式比較類似,這樣可以做大幅度的壓縮。這樣節省了存儲空間,也節省了I/O,因為數據被壓縮了,這樣讀的數據量隨之也少了。
行式數據庫適合OLTP,反倒列式數據庫不適合OLTP。
4.1 BigTable的LSM(Log Struct Merge)索引
在Hbase中日志即數據,數據就是日志,他們是一體化的。
為什么這么說了,因為Hbase的更新時插入一行,刪除也是插入一行,然后打上刪除標記,則不就是日志嗎?
在Hbase中,有Memory Store,還有Store File,其實每個Memory Store和每個Store File就是對每個列族附加上一個B+樹(有點像Oracle的索引組織表,數據和索引是一體化的), 也就是圖的下面是列族,上面是B+樹,當進行數據的查詢時,首先會在內存中memory store的B+樹中查找,如果找不到,再到Store File中去找。
如果找的行的數據分散在好幾個列族中,那怎么把行的數據找全呢?那就需要找好幾個B+樹,這樣效率就比較低了。所以盡量讓每次insert的一行的列族都是稀疏的,只在某一個列族上有值,其他列族沒有值,