環境如下:
Centos6.5
Apache Hadoop2.7.1
Apache Hbase0.98.12
Apache Zookeeper3.4.6
JDK1.7
Ant1.9.5
Maven3.0.5
最近在測Hbase的壓縮,Hadoop安裝了lzo和snappy,插入50條文本數據,每條數據大約4M,來看他們的壓縮率對比,
然后在測的過程中,發現用java客戶端去scan這50條數據時,regionserver頻繁宕機看hbase的log發現並無明顯異常,查看datanode的log發現如下異常:
- java.io.IOException: Premature EOF from inputStream
- at org.apache.hadoop.io.IOUtils.readFully(IOUtils.java:201)
- at org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.doReadFully(PacketReceiver.java:213)
- at org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.doRead(PacketReceiver.java:134)
- at org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.receiveNextPacket(PacketReceiver.java:109)
- at org.apache.hadoop.hdfs.server.datanode.BlockReceiver.receivePacket(BlockReceiver.java:472)
- at org.apache.hadoop.hdfs.server.datanode.BlockReceiver.receiveBlock(BlockReceiver.java:849)
- at org.apache.hadoop.hdfs.server.datanode.DataXceiver.writeBlock(DataXceiver.java:804)
- at org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.opWriteBlock(Receiver.java:137)
- at org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.processOp(Receiver.java:74)
- at org.apache.hadoop.hdfs.server.datanode.DataXceiver.run(DataXceiver.java:251)
- at java.lang.Thread.run(Thread.java:745)
java.io.IOException: Premature EOF from inputStream
at org.apache.hadoop.io.IOUtils.readFully(IOUtils.java:201)
at org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.doReadFully(PacketReceiver.java:213)
at org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.doRead(PacketReceiver.java:134)
at org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.receiveNextPacket(PacketReceiver.java:109)
at org.apache.hadoop.hdfs.server.datanode.BlockReceiver.receivePacket(BlockReceiver.java:472)
at org.apache.hadoop.hdfs.server.datanode.BlockReceiver.receiveBlock(BlockReceiver.java:849)
at org.apache.hadoop.hdfs.server.datanode.DataXceiver.writeBlock(DataXceiver.java:804)
at org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.opWriteBlock(Receiver.java:137)
at org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.processOp(Receiver.java:74)
at org.apache.hadoop.hdfs.server.datanode.DataXceiver.run(DataXceiver.java:251)
at java.lang.Thread.run(Thread.java:745)
截圖如下,好吧,出異常了,就拿這個異常google查找結果,發現並沒有明確的答案,大部分都是說鏈接超時,或者是句柄數滿了,導致鏈接中斷等等,然后就按這些答案,改了若干配置,發現依然沒有生效,這領我感到十分奇怪 ,得出一個錯誤的結論,hbase不支持多種壓縮類型並存的表,然后我去掉了其他類型用來壓縮測試的表,再次測試,發現問題依舊,這再次令我十分詫異,會不會是環境的問題?因為我實在想不出來可能的問題所在了,然后就在本機虛擬機上進行測試,
虛擬機的環境,因為是自己用,所以JDK版本是1.8 和 Centos版本是7,Hbase,Hadoop,Zookeeper版本則保持一致,
搭建完畢后,繼續測試,發現問題依舊,這下令人更迷惑了,看的出來非環境的問題了,不過這次有了點新的線索,由於用的是JDK8,在Hbase的log里面發現出現了大量的full gc日志,意思就是內存嚴重不足,導致垃圾收集時間出現了4,5秒,這下我才有點頭緒,hbase是個吃內存的玩意,內存給的少,確實有可能導致regionserver掛掉,於是我查看hbase的堆內存分配情況,發現是默認的1G,這下確實跟這個有很大關系,50條數據占存儲200M,如果每次scan一次,hbase會將其緩存在cache里面,第二次繼續scan不同壓縮類型的表,會導致內存膨脹,繼而引發,regionserver宕機,而給出的異常提示,並不是非常明確,所以才定位問題比較困難,知道了大概原因所在,然后把hbase的堆內存調到4G,並分發到所有節點上,再次啟動,用java 客戶端,掃描全表測試,這次非常穩定,regionserver沒有出現過再次掛掉的情況。
最后給出測試壓縮的一個結論:總共測了4種壓縮比較,原始數據200M
(1)不用壓縮 占空間 128.1 M
(2)gz壓縮 占920.3 K
(3)snappy壓縮 占 13.2M
(4)lzo壓縮 占8M
以上可以看出,gz的壓縮比最高,lzo次之,snappy第三,當然不同的壓縮適用於不用的業務場景,這里不能就簡簡單單的
總結必須用什么,這里面snappy和lzo在目前大多數互聯網公司用的比較多,所以大家可以根據具體業務,來選擇合適的壓縮方案。



