閱讀240 返回首頁    go 阿裏雲 go 技術社區[雲棲]


HBase設計:看上去很美

緣起

隨著hadoop係列的興起,基於HDFS的大規模KV存儲係統HBase也進入“大規模使用階段”。網上的Hbase資料很多,學習成本正在下降。從公開的資料看,國外facebook、國內taobao均宣稱在線上環境大規模使用hbase。一切都讓人很興奮。於是,在項目中引入Hbase做存儲,最終卻選擇放棄。

HBase設計:看上去很美

HBase是模仿google bigtable的開源產品,又是hadoop的衍生品,hadoop作為離線計算係統已經得到業界的普遍認可,並經過N多公司大規模使用的驗證,自然地認為Hbase也將隨之獲得成功。

《HBase: The Definitive Guide》第8章講述hbase的架構,從架構上看,其架構很完美:

LSM - 解決磁盤隨機寫問題(順序寫才是王道);

HFile - 解決數據索引問題(隻有索引才能高效讀);

WAL - 解決數據持久化(麵對故障的持久化解決方案);

zooKeeper - 解決核心數據的一致性和集群恢複;

Replication - 引入類似MySQL的數據複製方案,解決可用性;

此外還有:自動分拆Split、自動壓縮(compaction,LSM的伴生技術)、自動負載均衡、自動region遷移。

看上去如此美好,完全無需人工幹預,貌似隻要將Hbase搭建好,一切問題Hbase都將應對自如。麵對如此完美的係統,不動心很難。

但是,如此完美的係統或許也意味著背後的複雜性是不容忽略的。hbase的代碼量也不是一星半點的。假如係統工作不正常,誰來解決?這是至關重要的。

性能與測試

Hbase係統自身提供了性能測試工具:./bin/hbase org.apache.hadoop.hbase.PerformanceEvaluation,該工具提供了隨機讀寫、多客戶端讀寫等性能測試功能。根據工具測試的結果看,hbase的性能不算差。

對於hbase這樣的係統長期穩定運行比什麼都重要。然而,這或許就不那麼"完美"。

測試版本:hbase 0.94.1、 hadoop 1.0.2、 jdk-6u32-linux-x64.bin、snappy-1.0.5.tar.gz

測試hbase搭建:14台存儲機器+2台master、DataNode和regionserver放在一起。

hbase env配置:


  1. View Code
  2. ulimit -n 65536
  3. export HBASE_OPTS="$HBASE_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode"
  4. export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS -Xmx20g -Xms20g -Xmn512m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSIn
  5. itiatingOccupancyFraction=60 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:$HBASE_HOME/logs/gc-$(hostname)-hbase.lo
  6. g"

hbase-size.xml關鍵配置(根據《HBase: The Definitive Guide》第11章優化):


  1. View Code
  2. <property>
  3. <name>hbase.regionserver.handler.count</name>
  4. <value>16</value>
  5. <description>Count of RPC Listener instances spun up on RegionServers.
  6. Same property is used by the Master for count of master handlers.
  7. Default is 10.
  8. </description>
  9. </property>
  10. <property>
  11. <name>hbase.regionserver.global.memstore.upperLimit</name>
  12. <value>0.35</value>
  13. <description>Maximum size of all memstores in a region server before new
  14. updates are blocked and flushes are forced. Defaults to 40% of heap
  15. </description>
  16. </property>
  17. <property>
  18. <name>hbase.regionserver.global.memstore.lowerLimit</name>
  19. <value>0.3</value>
  20. <description>When memstores are being forced to flush to make room in
  21. memory, keep flushing until we hit this mark. Defaults to 35% of heap.
  22. This value equal to hbase.regionserver.global.memstore.upperLimit causes
  23. the minimum possible flushing to occur when updates are blocked due to
  24. memstore limiting.
  25. </description>
  26. </property>
  27. <property>
  28. <name>hfile.block.cache.size</name>
  29. <value>0.35</value>
  30. <description>
  31. Percentage of maximum heap (-Xmx setting) to allocate to block cache
  32. used by HFile/StoreFile. Default of 0.25 means allocate 25%.
  33. Set to 0 to disable but it's not recommended.
  34. </description>
  35. </property>
  36. <property>
  37. <name>zookeeper.session.timeout</name>
  38. <value>600000</value>
  39. <description>ZooKeeper session timeout.
  40. HBase passes this to the zk quorum as suggested maximum time for a
  41. session (This setting becomes zookeeper's 'maxSessionTimeout'). See
  42. https://hadoop.apache.org/zookeeper/docs/current/zookeeperProgrammers.html#ch_zkSessions
  43. "The client sends a requested timeout, the server responds with the
  44. timeout that it can give the client. " In milliseconds.
  45. </description>
  46. </property>
  47. <property>
  48. <name>hbase.zookeeper.property.tickTime</name>
  49. <value>60000</value>
  50. </property>
  51. <property>
  52. <name>hbase.regionserver.restart.on.zk.expire</name>
  53. <value>true</value>
  54. </property>
  55. <property>
  56. <name>hbase.hregion.majorcompaction</name>
  57. <value>0</value>
  58. <description>The time (in miliseconds) between 'major' compactions of all
  59. HStoreFiles in a region. Default: 1 day(86400000).
  60. Set to 0 to disable automated major compactions.
  61. </description>
  62. </property>
  63. <property>
  64. <name>hbase.hregion.max.filesize</name>
  65. <value>536870912000</value>
  66. <description>
  67. Maximum HStoreFile size. If any one of a column families' HStoreFiles has
  68. grown to exceed this value, the hosting HRegion is split in two.
  69. Default: 1G(1073741824). Set 500G, disable file split!
  70. </description>
  71. </property>

測試一:高並發讀(4w+/s) + 少量寫(允許分拆、負載均衡)

症狀:1-2天後,hbase掛掉(係統性能極差,不到正常的10%)。其實並非全部掛掉,而是某些regionserver掛了,並在幾個小時內引發其他regionserver掛掉。係統無法恢複:單獨啟regionserver無法恢複正常。重啟後正常。

測試二:高並發讀(4w+/s)

症狀:1-2天後,hbase掛掉(係統性能極差,不到正常的10%)。後發現是由於zookeeper.session.timeout設置不正確導致(參見regionserver部分:https://hbase.apache.org/book.html)。重啟後正常。

測試三:高並發讀(4w+/s)

症狀:1-2天後,hbase掛掉(係統性能極差,不到正常的10%)。從log未看出問題,但regionserver宕機,且datanode也宕機。重啟後正常。

測試四:高並發讀(4w+/s)+禁止分拆、禁止majorcompaction、禁止負載均衡(balance_switch命令)

症狀:1-2天後,hbase掛掉(係統性能極差,不到正常的10%)。從log未看出問題,但regionserver宕機,且datanode也宕機。重啟後正常。

測試期間,還發現過:無法獲取".MATE."表的內容(想知道regionserver的分布情況)、hbase無法正確停止、hbase無法正確啟動(日誌恢複失敗,文件錯誤,最終手動刪除日誌重啟)。

其他缺陷

HBase使用JAVA開發,看上去很美的GC使用中代價可不小。Hbase為了保證數據強一致性,每個key隻能由一個regionserver提供服務。在下列情況下,Hbase服務質量都將受損:

1) GC CMS -- CMS回收內存極其耗時,當hbase運行1-2天後,CMS可能耗時10分鍾,這期間該regionserver無法服務。CMS經常被觸發,這意味著hbase的服務經常會因為GC操作而部分暫停!

2) regionserver宕機 - 為了強一致性,每個key隻由一個regionserver提供服務,故當regionserver宕機後,相應的region即無法服務!

3) major compaction、split不可控 - 大量磁盤操作將極大影響服務。(levelDB也需要major compaction,隻是使用更加可控的方式做壓縮,比如一次隻有一個壓縮任務。是否影響服務,待測試)

4) 數據恢複 - 數據恢複期間設置WAL log的相關操作,在數據恢複期間regionserver無法服務!

結論

或許通過研究hbase的源碼可讓hbase穩定運行,但從上述測試結果看:1)hbase還無法穩定長期運行;2)hbase係統很脆弱,故障恢複能力差。基於此,判斷hbase還無法滿足大規模線上係統的運維標準,隻能放棄。考慮到hbase重啟基本可恢複正常,故hbase還是可作為離線存儲係統使用。

替代方案

麵對大規模數據,基於磁盤的存儲係統是必不可少的。google雖然公開了bigtable的設計,但未開源,但google開源了levelDB KV存儲係統庫(https://code.google.com/p/leveldb/)。levelDB采用C++實現,1.7版本的代碼量大概2W,實現了LSM(自動壓縮)、LevelFile(基本同HFile),WAL,提供了簡單的Put、Get、Delete、Write(批量寫、事務功能)等接口。levelDB庫實現了單機單庫的磁盤存儲方案,開發者可根據自己需要開發定製的存儲係統(比如:數據Replication、自動調度、自動恢複、負載均衡等)。

最後更新:2017-04-03 22:30:57

  上一篇:go J.U.C係列-線程安全的理論講解
  下一篇:go android-HttpClient上傳信息(包括圖片)到服務端