hadoop hbase hive 常見問題解決
安裝過程中,由於網路終端,導致下面問題:
問題1:安裝停止在獲取安裝鎖
/tmp/scm_prepare_node.tYlmPfrT
usingSSH_CLIENT to get the SCM hostname: 172.16.77.20 33950 22
opening logging file descriptor
正在啟動安裝指令碼...正在獲取安裝鎖...BEGIN flock 4
這段大概過了半個小時,一次解除安裝,一次等了快1個小時,終於過去了,
問題2:不能選擇主機
問題3:DNS反向解析PTR localhost:
描述:
DNS反向解析錯誤,不能正確解析Cloudera Manager Server主機名
日誌:
Detecting Cloudera Manager Server...
Detecting Cloudera Manager Server...
BEGIN host -t PTR 192.168.1.198
198.1.168.192.in-addr.arpa domain name pointerlocalhost.
END (0)
using localhost as scm server hostname
BEGIN which python
/usr/bin/python
END (0)
BEGIN python -c 'import socket; import sys; s = socket.socket(socket.AF_INET);s.settimeout(5.0); s.connect((sys.argv[1], int(sys.argv[2]))); s.close();'localhost 7182
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "<string>", line 1, in connect
socket.error: [Errno 111] Connection refused
END (1)
could not contact scm server at localhost:7182, giving up
waiting for rollback request
解決方案:
將連不上的機器 /usr/bin/host 檔案刪掉,執行下面命令:
1. sudo mv/usr/bin/host /usr/bin/host.bak
複製程式碼
說明:
不明白cloudera的初衷,這裡已經得到 ClouderaManager Server的ip了,卻還要把ip解析成主機名來連線
由於DNS反向解析沒有配置好,根據Cloudera ManagerServer 的ip解析主機名卻得到了localhost,造成之後的連線錯誤
這裡的解決方案是直接把/usr/bin/host刪掉,這樣ClouderaManager就會直接使用 ip進行連線,就沒有錯了
參考:
問題 4 NTP:
問題描述:
Bad Health --Clock Offset
The host's NTP service did not respond to a request forthe clock offset.
解決:
配置NTP服務
步驟參考:
CentOS配置NTP Server:
國內常用NTP伺服器地址及IP
修改配置檔案:
[[email protected] ~]# vim /etc/ntp.conf
# Use public servers from the pool.ntp.org project.
server s1a.time.edu.cn prefer
server s1b.time.edu.cn
server s1c.time.edu.cn
restrict 172.16.1.0 mask 255.255.255.0 nomodify <===放行區域網來源
啟動ntp
#service ntpd restart <===啟動ntp服務
客戶端同步時間(work02,work03):
ntpdate work01
說明:NTP服務啟動需要大約五分鐘時間,服務啟動之前,若客戶端同步時間,則會出現錯誤“no server suitable for synchronization found”
定時同步時間:
在work02和 work03上配置crontab定時同步時間
crontab -e
00 12 * * * root /usr/sbin/ntpdate 192.168.56.121 >> /root/ntpdate.log2>&1
問題 2.2
描述:
Clock Offset
· Ensure that thehost's hostname is configured properly.
· Ensure that port7182 is accessible on the Cloudera Manager Server (check firewall rules).
· Ensure that ports9000 and 9001 are free on the host being added.
· Check agent logsin /var/log/cloudera-scm-agent/ on the host being added (some of the logs canbe found in the installation details).
問題定位:
在對應host(work02、work03)上執行 'ntpdc -c loopinfo'
[[email protected] work]# ntpdc -c loopinfo
ntpdc: read: Connection refused
解決:
開啟ntp服務:
三臺機器都開機啟動 ntp服務
chkconfig ntpd on
問題 5 heartbeat:
錯誤資訊:
Installation failed. Failed to receive heartbeat from agent.
解決:關閉防火牆
問題 6 Unknow Health:
Unknow Health
重啟後:Request to theHost Monitor failed.
service --status-all| grep clo
機器上檢視scm-agent狀態:cloudera-scm-agentdead but pid file exists
解決:重啟服務
service cloudera-scm-agent restart
service cloudera-scm-server restart
問題 7 canonial name hostnameconsistent:
Bad Health
The hostname and canonical name for this host are notconsistent when checked from a Java process.
canonical name:
4092 Monitor-HostMonitor throttling_loggerWARNING (29 skipped) hostname work02 differs from the canonical namework02.xinzhitang.com
解決:修改hosts 使FQDN和 hostname相同
ps:雖然解決了但是不明白為什麼主機名和主機別名要一樣
/etc/hosts
192.168.1.185 work01 work01
192.168.1.141 work02 work02
192.168.1.198 work03 work03
問題 8 Concerning Health:
Concerning Health Issue
-- Network Interface Speed --
描述:The host has 2 network interface(s) that appear to beoperating at less than full speed. Warning threshold: any.
詳細:
This is a host health test that checks for networkinterfaces that appear to be operating at less than full speed.
A failure of this health test may indicate that network interface(s) may beconfigured incorrectly and may be causing performance problems. Use the ethtoolcommand to check and configure the host's network interfaces to use the fastestavailable link speed and
duplex mode.
解決:
本次測試修改了 Cloudera Manager 的配置,應該不算是真正的解決
問題10 IOException thrown while collecting data from host: No route to host
原因:agent開啟了防火牆
解決:service iptables stop
問題11
2、Clouderarecommendssetting /proc/sys/vm/swappiness to 0. Current setting is 60. Use thesysctlcommand to change this setting at runtime and edit /etc/sysctl.conf forthissetting to be saved after a reboot. You may continue with installation, butyoumay run into issues with Cloudera Manager reporting that your hostsareunhealthy because they are swapping. The following hosts are affected:
解決:
# echo 0>/proc/sys/vm/swappiness (toapply for now)
# sysctl-wvm.swappiness=0 (to makethis persistentacross reboots)
問題12 時鐘不同步(同步至中科大時鐘伺服器202.141.176.110)
# echo "0 3 * **/usr/sbin/ntpdate 202.141.176.110;/sbin/hwclock–w">>/var/spool/cron/root
# service crondrestart
# ntpdate202.141.176.110
問題13 The host's NTPservice didnot respond to a request for the clock offset.
#service ntpdstart
# ntpdc -cloopinfo (thehealth will be good if this command executed successfully)
問題14 The Cloudera ManagerAgentis not able to communicate with this role's web server.
一種原因是元資料資料庫無法連線,請檢查資料庫配置:
問題15 Hive MetastoreServer無法啟動,修改Hive元資料資料庫配置(當我們修改主機名後即應修改元資料資料庫配置):
問題排查方式
- 一般的錯誤,檢視錯誤輸出,按照關鍵字google
- 異常錯誤(如namenode、datanode莫名其妙掛了):檢視hadoop($HADOOP_HOME/logs)或hive日誌
hadoop錯誤
問題16 datanode無法正常啟動
新增datanode後,datanode無法正常啟動,程序一會莫名其妙掛掉,檢視namenode日誌顯示如下:
Text程式碼
2013-06-21 18:53:39,182 FATALorg.apache.hadoop.hdfs.StateChange: BLOCK* NameSystem.getDatanode: Data nodex.x.x.x:50010 is attempting to report storage ID DS-1357535176-x.x.x.x-50010-1371808472808.Node y.y.y.y:50010 is expected to serve this storage.
原因分析:
拷貝hadoop安裝包時,包含data與tmp資料夾(見本人《hadoop安裝》一文),未成功格式化datanode
解決辦法:
Shell程式碼
rm -rf /data/hadoop/hadoop-1.1.2/data
rm -rf /data/hadoop/hadoop-1.1.2/tmp
hadoop datanode -format
問題17 safe mode
Text程式碼
2013-06-2010:35:43,758 ERROR org.apache.hadoop.security.UserGroupInformation:PriviledgedActionException as:hadoopcause:org.apache.hadoop.hdfs.server.namenode.SafeModeException: Cannot renewlease for DFSClient_hb_rs_wdev1.corp.qihoo.net,60020,1371631589073. Name nodeis in safe mode.
解決方案:
Shell程式碼
hadoopdfsadmin -safemode leave
問題18 連線異常
Text程式碼
2013-06-21 19:55:05,801 WARNorg.apache.hadoop.hdfs.server.datanode.DataNode: java.io.IOException: Call tohomename/x.x.x.x:9000 failed on local exception: java.io.EOFException
可能原因:
- namenode監聽127.0.0.1:9000,而非0.0.0.0:9000或外網IP:9000
- iptables限制
解決方案:
- 檢查/etc/hosts配置,使得hostname繫結到非127.0.0.1的IP上
- iptables放開埠
問題19 namenode id
Text程式碼
ERROR org.apache.hadoop.hdfs.server.datanode.DataNode:java.io.IOException: Incompatible namespaceIDs in/var/lib/hadoop-0.20/cache/hdfs/dfs/data: namenode namespaceID = 240012870;datanode namespaceID = 1462711424 .
問題:Namenode上namespaceID與datanode上namespaceID不一致。
問題產生原因:每次namenode format會重新建立一個namenodeId,而tmp/dfs/data下包含了上次format下的id,namenode format清空了namenode下的資料,但是沒有清空datanode下的資料,所以造成namenode節點上的namespaceID與 datanode節點上的namespaceID不一致。啟動失敗。
解決辦法:參考該網址http://blog.csdn.net/wh62592855/archive/2010/07/21/5752199.aspx 給出兩種解決方法,我們使用的是第一種解決方法:即:
(1)停掉叢集服務
(2)在出問題的datanode節點上刪除data目錄,data目錄即是在hdfs-site.xml檔案中配置的 dfs.data.dir目錄,本機器上那個是/var/lib/hadoop-0.20/cache/hdfs/dfs/data/(注:我們當時在所有的datanode和namenode節點上均執行了該步驟。以防刪掉後不成功,可以先把data目錄儲存一個副本).
(3)格式化namenode.
(4)重新啟動叢集。
問題解決。
這種方法帶來的一個副作用即是,hdfs上的所有資料丟失。如果hdfs上存放有重要資料的時候,不建議採用該方法,可以嘗試提供的網址中的第二種方法。
問題20 目錄許可權
start-dfs.sh執行無錯,顯示啟動datanode,執行完後無datanode。檢視datanode機器上的日誌,顯示因dfs.data.dir目錄許可權不正確導致:
Text程式碼
expected: drwxr-xr-x,current:drwxrwxr-x
解決辦法:
檢視dfs.data.dir的目錄配置,修改許可權即可。
hive錯誤
問題21 NoClassDefFoundError
Could not initialize class java.lang.NoClassDefFoundError: Could not initializeclass org.apache.hadoop.hbase.io.HbaseObjectWritable
將protobuf-***.jar新增到jars路徑
Xml程式碼
//$HIVE_HOME/conf/hive-site.xml
hive.aux.jars.path
file:///data/hadoop/hive-0.10.0/lib/hive-hbase-handler-0.10.0.jar,file:///data/hadoop/hive-0.10.0/lib/hbase-0.94.8.jar,file:///data/hadoop/hive-0.10.0/lib/zookeeper-3.4.5.jar,file:///data/hadoop/hive-0.10.0/lib/guava-r09.jar,file:///data/hadoop/hive-0.10.0/lib/hive-contrib-0.10.0.jar,file:///data/hadoop/hive-0.10.0/lib/protobuf-java-2.4.0a.jar
問題22 hive動態分割槽異常
[Fatal Error] Operator FS_2 (id=2): Number of dynamic partitions exceededhive.exec.max.dynamic.partitions.pernode
Shell程式碼
hive> sethive.exec.max.dynamic.partitions.pernode = 10000;
問題23 mapreduce程序超記憶體限制——hadoop Java heap space
vim mapred-site.xml新增:
Xml程式碼
//mapred-site.xml
mapred.child.java.opts
-Xmx2048m
Shell程式碼
#$HADOOP_HOME/conf/hadoop_env.sh
exportHADOOP_HEAPSIZE=5000
問題24 hive檔案數限制
[Fatal Error] total number of created files now is 100086, which exceeds 100000
Shell程式碼
hive> sethive.exec.max.created.files=655350;
問題25 hive 5.metastore連線超時
Text程式碼
FAILED:SemanticException org.apache.thrift.transport.TTransportException:java.net.SocketTimeoutException: Read timed out
解決方案:
Shell程式碼
hive>set hive.metastore.client.socket.timeout=500;
問題26 hive 6.java.io.IOException: error=7, Argument list too long
Text程式碼
Task withthe most failures(5):
-----
Task ID:
task_201306241630_0189_r_000009
URL:
http://namenode.godlovesdog.com:50030/taskdetails.jsp?jobid=job_201306241630_0189&tipid=task_201306241630_0189_r_000009
-----
DiagnosticMessages for this Task:
java.lang.RuntimeException:org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error whileprocessing row (tag=0){"key":{"reducesinkkey0":"164058872","reducesinkkey1":"djh,S1","reducesinkkey2":"20130117170703","reducesinkkey3":"xxx"},"value":{"_col0":"1","_col1":"xxx","_col2":"20130117170703","_col3":"164058872","_col4":"xxx,S1"},"alias":0}
atorg.apache.hadoop.hive.ql.exec.ExecReducer.reduce(ExecReducer.java:270)
at org.apache.hadoop.mapred.ReduceTask.runOldReducer(ReduceTask.java:520)
atorg.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:421)
atorg.apache.hadoop.mapred.Child$4.run(Child.java:255)
atjava.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
atorg.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1149)
atorg.apache.hadoop.mapred.Child.main(Child.java:249)
Caused by:org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error whileprocessing row (tag=0){"key":{"reducesinkkey0":"164058872","reducesinkkey1":"xxx,S1","reducesinkkey2":"20130117170703","reducesinkkey3":"xxx"},"value":{"_col0":"1","_col1":"xxx","_col2":"20130117170703","_col3":"164058872","_col4":"djh,S1"},"alias":0}
atorg.apache.hadoop.hive.ql.exec.ExecReducer.reduce(ExecReducer.java:258)
... 7 more
Caused by:org.apache.hadoop.hive.ql.metadata.HiveException: [Error 20000]: Unable toinitialize custom script.
atorg.apache.hadoop.hive.ql.exec.ScriptOperator.processOp(ScriptOperator.java:354)
atorg.apache.hadoop.hive.ql.exec.Operator.process(Operator.java:474)
atorg.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:800)
atorg.apache.hadoop.hive.ql.exec.SelectOperator.processOp(SelectOperator.java:84)
atorg.apache.hadoop.hive.ql.exec.Operator.process(Operator.java:474)
atorg.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:800)
atorg.apache.hadoop.hive.ql.exec.ExtractOperator.processOp(ExtractOperator.java:45)
at org.apache.hadoop.hive.ql.exec.Operator.process(Operator.java:474)
atorg.apache.hadoop.hive.ql.exec.ExecReducer.reduce(ExecReducer.java:249)
... 7 more
Caused by:java.io.IOException: Cannot run program "/usr/bin/python2.7":error=7, 引數列表過長
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1042)
atorg.apache.hadoop.hive.ql.exec.ScriptOperator.processOp(ScriptOperator.java:313)
... 15 more
Caused by:java.io.IOException: error=7, 引數列表過長
atjava.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.(UNIXProcess.java:135)
atjava.lang.ProcessImpl.start(ProcessImpl.java:130)
atjava.lang.ProcessBuilder.start(ProcessBuilder.java:1023)
... 16 more
FAILED:Execution Error, return code 20000 fromorg.apache.hadoop.hive.ql.exec.MapRedTask. Unable to initialize custom script.
問題27 hive 6.runtime error
Shell程式碼
hive> show tables;
FAILED: Error in metadata: java.lang.RuntimeException:Unable to instantiate org.apache.hadoop.hive.metastore.HiveMetaStoreClient
FAILED: Execution Error, return code 1 fromorg.apache.hadoop.hive.ql.exec.DDLTask
問題排查:
Shell程式碼
hive -hiveconf hive.root.logger=DEBUG,console
Text程式碼
13/07/15 16:29:24 INFO hive.metastore: Trying to connectto metastore with URI thrift://xxx.xxx.xxx.xxx:9083
13/07/15 16:29:24 WARN hive.metastore: Failed to connectto the MetaStore Server...
org.apache.thrift.transport.TTransportException:java.net.ConnectException: 拒絕連線
。。。
MetaException(message:Could not connect to meta storeusing any of the URIs provided. Most recent failure:org.apache.thrift.transport.TTransportException: java.net.ConnectException: 拒絕連線
嘗試連線9083埠,netstat檢視該埠確實沒有被監聽,第一反應是hiveserver沒有正常啟動。檢視hiveserver程序卻存在,只是監聽10000埠。
檢視hive-site.xml配置,hive客戶端連線9083埠,而hiveserver預設監聽10000,找到問題根源了
解決辦法:
Shell程式碼
hive --service hiveserver -p 9083
//或修改$HIVE_HOME/conf/hive-site.xml的hive.metastore.uris部分
//將埠改為10000
using /usr/lib/hive as HIVE_HOME
using /var/run/cloudera-scm-agent/process/193-hive-HIVEMETASTOREas HIVE_CONF_DIR
using /usr/lib/hadoop as HADOOP_HOME
using/var/run/cloudera-scm-agent/process/193-hive-HIVEMETASTORE/yarn-conf asHADOOP_CONF_DIR
ERROR: Failed to find hive-hbase storage handler jars toadd in hive-site.xml. Hive queries that use Hbase storage handler may not workuntil this is fixed.
Wed Oct 22 18:48:53 CST 2014
JAVA_HOME=/usr/java/jdk1.7.0_45-cloudera
using /usr/java/jdk1.7.0_45-cloudera as JAVA_HOME
using 5 as CDH_VERSION
using /usr/lib/hive as HIVE_HOME
using /var/run/cloudera-scm-agent/process/193-hive-HIVEMETASTOREas HIVE_CONF_DIR
using /usr/lib/hadoop as HADOOP_HOME
using/var/run/cloudera-scm-agent/process/193-hive-HIVEMETASTORE/yarn-conf asHADOOP_CONF_DIR
ERROR: Failed to find hive-hbase storage handler jars toadd in hive-site.xml. Hive queries that use Hbase storage handler may not workuntil this is fixed.
Wed Oct 22 18:48:55 CST 2014
JAVA_HOME=/usr/java/jdk1.7.0_45-cloudera
using /usr/java/jdk1.7.0_45-cloudera as JAVA_HOME
using 5 as CDH_VERSION
using /usr/lib/hive as HIVE_HOME
using/var/run/cloudera-scm-agent/process/193-hive-HIVEMETASTORE as HIVE_CONF_DIR
using /usr/lib/hadoop as HADOOP_HOME
using/var/run/cloudera-scm-agent/process/193-hive-HIVEMETASTORE/yarn-conf asHADOOP_CONF_DIR
ERROR: Failed to find hive-hbase storage handler jars toadd in hive-site.xml. Hive queries that use Hbase storage handler may not workuntil this is fixed.
Wed Oct 22 18:48:58 CST 2014
JAVA_HOME=/usr/java/jdk1.7.0_45-cloudera
using /usr/java/jdk1.7.0_45-cloudera as JAVA_HOME
using 5 as CDH_VERSION
using /usr/lib/hive as HIVE_HOME
using/var/run/cloudera-scm-agent/process/193-hive-HIVEMETASTORE as HIVE_CONF_DIR
using /usr/lib/hadoop as HADOOP_HOME
using/var/run/cloudera-scm-agent/process/193-hive-HIVEMETASTORE/yarn-conf asHADOOP_CONF_DIR
ERROR: Failed to find hive-hbase storage handler jars toadd in hive-site.xml. Hive queries that use Hbase storage handler may not workuntil this is fixed.
JAVA_HOME=/usr/java/jdk1.7.0_45-cloudera
using /usr/java/jdk1.7.0_45-cloudera as JAVA_HOME
using 5 as CDH_VERSION
using /usr/lib/hive as HIVE_HOME
using /var/run/cloudera-scm-agent/process/212-hive-metastore-create-tables as HIVE_CONF_DIR
using /usr/lib/hadoop as HADOOP_HOME
using /var/run/cloudera-scm-agent/process/212-hive-metastore-create-tables/yarn-conf as HADOOP_CONF_DIR
ERROR: Failed to find hive-hbase storage handler jars to add in hive-site.xml. Hive queries that use Hbase storage handler may not work until this is fixed.
檢視 /usr/lib/hive 是否正常
正常的
下午3點21:09.801 FATAL org.apache.hadoop.hbase.master.HMaster
Unhandled exception. Starting shutdown.
java.io.IOException: error or interruptedwhile splitting logs in[hdfs://master:8020/hbase/WALs/slave2,60020,1414202360923-splitting] Task =installed = 2 done = 1 error = 1
atorg.apache.hadoop.hbase.master.SplitLogManager.splitLogDistributed(SplitLogManager.java:362)
atorg.apache.hadoop.hbase.master.MasterFileSystem.splitLog(MasterFileSystem.java:409)
atorg.apache.hadoop.hbase.master.MasterFileSystem.splitMetaLog(MasterFileSystem.java:301)
atorg.apache.hadoop.hbase.master.MasterFileSystem.splitMetaLog(MasterFileSystem.java:292)
atorg.apache.hadoop.hbase.master.HMaster.splitMetaLogBeforeAssignment(HMaster.java:1070)
atorg.apache.hadoop.hbase.master.HMaster.finishInitialization(HMaster.java:854)
atorg.apache.hadoop.hbase.master.HMaster.run(HMaster.java:606)
atjava.lang.Thread.run(Thread.java:744)
下午3點46:12.903 FATAL org.apache.hadoop.hbase.master.HMaster
Unhandled exception. Starting shutdown.
java.io.IOException: error or interruptedwhile splitting logs in[hdfs://master:8020/hbase/WALs/slave2,60020,1414202360923-splitting] Task =installed = 1 done = 0 error = 1
atorg.apache.hadoop.hbase.master.SplitLogManager.splitLogDistributed(SplitLogManager.java:362)
atorg.apache.hadoop.hbase.master.MasterFileSystem.splitLog(MasterFileSystem.java:409)
atorg.apache.hadoop.hbase.master.MasterFileSystem.splitMetaLog(MasterFileSystem.java:301)
atorg.apache.hadoop.hbase.master.MasterFileSystem.splitMetaLog(MasterFileSystem.java:292)
atorg.apache.hadoop.hbase.master.HMaster.splitMetaLogBeforeAssignment(HMaster.java:1070)
atorg.apache.hadoop.hbase.master.HMaster.finishInitialization(HMaster.java:854)
atorg.apache.hadoop.hbase.master.HMaster.run(HMaster.java:606)
atjava.lang.Thread.run(Thread.java:744)
解決方法:
在hbase-site.xml加入一條,讓啟動hbase叢集時不做hlog splitting
<property>
<name>hbase.master.distributed.log.splitting</name>
<value>false</value>
</property>
[[email protected] ~]# hadoop fs -mv/hbase/WALs/slave2,60020,1414202360923-splitting/ /test
[[email protected] ~]# hadoop fs -ls /test
2014-10-28 14:31:32,879 INFO[hconnection-0xd18e8a7-shared--pool2-t224] (AsyncProcess.java:673) - #3,table=session_service_201410210000_201410312359, attempt=14/35 failed 1383 ops,last exception: org.apache.hadoop.hbase.RegionTooBusyException:org.apache.hadoop.hbase.RegionTooBusyException: Above memstore limit,regionName=session_service_201410210000_201410312359,7499999991,1414203068872.08ee7bb71161cb24e18ddba4c14da0f2.,server=slave1,60020,1414380404290, memstoreSize=271430320,blockingMemStoreSize=268435456
atorg.apache.hadoop.hbase.regionserver.HRegion.checkResources(HRegion.java:2561)
atorg.apache.hadoop.hbase.regionserver.HRegion.batchMutate(HRegion.java:1963)
at org.apache.hadoop.hbase.regionserver.HRegionServer.doBatchOp(HRegionServer.java:4050)
atorg.apache.hadoop.hbase.regionserver.HRegionServer.doNonAtomicRegionMutation(HRegionServer.java:3361)
atorg.apache.hadoop.hbase.regionserver.HRegionServer.multi(HRegionServer.java:3265)
atorg.apache.hadoop.hbase.protobuf.generated.ClientProtos$ClientService$2.callBlockingMethod(ClientProtos.java:26935)
at org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:2175)
at org.apache.hadoop.hbase.ipc.RpcServer$Handler.run(RpcServer.java:1879)
INFO |
org.apache.hadoop.hbase.regionserver.MemStoreFlusher |
Waited 90779ms on a compaction to clean up 'too many store files'; waited long enough... proceeding with flush of session_service_201410210000_201410312359,7656249951,1414481868315.bbf0a49fb8a9b650a584769ddd1fdd89. |
MemStoreFlusher例項生成時會啟動MemStoreFlusher.FlushHandler執行緒例項,
此執行緒個數通過hbase.hstore.flusher.count配置,預設為1
一臺機器硬碟滿,一臺機器硬碟不滿的情況:
群集中有 26,632 個副本不足的塊塊。群集中共有 84,822 個塊。百分比 副本不足的塊: 31.40%。 警告閾值:10.00%。
群集中有 27,278 個副本不足的塊塊。群集中共有 85,476 個塊。百分比 副本不足的塊: 31.91%。 警告閾值:10.00%。
下午4點08:53.847 |
INFO |
org.apache.hadoop.hbase.regionserver.DefaultStoreFlusher |
Flushed, sequenceid=45525, memsize=124.2 M, hasBloomFilter=true, into tmp file hdfs://master:8020/hbase/data/default/session_service_201410260000_201410312359/a3b64675b0069b8323665274e2f95cdc/.tmp/b7fa4f5f85354ecc96aa48a09081f786 |
下午4點08:53.862 |
INFO |
org.apache.hadoop.hbase.regionserver.HStore |
Added hdfs://master:8020/hbase/data/default/session_service_201410260000_201410312359/a3b64675b0069b8323665274e2f95cdc/f/b7fa4f5f85354ecc96aa48a09081f786, entries=194552, sequenceid=45525, filesize=47.4 M |
下午4點09:00.378 |
WARN |
org.apache.hadoop.ipc.RpcServer |
(responseTooSlow): {"processingtimems":39279,"call":"Scan(org.apache.hadoop.hbase.protobuf.generated.ClientProtos$ScanRequest)","client":"192.168.5.9:41284","starttimems":1414656501099,"queuetimems":0,"class":"HRegionServer","responsesize":16,"method":"Scan"} |
下午4點09:00.379 |
WARN |
org.apache.hadoop.ipc.RpcServer |
RpcServer.respondercallId: 33398 service: ClientService methodName: Scan size: 209 connection: 192.168.5.9:41284: output error |
下午4點09:00.380 |
WARN |
org.apache.hadoop.ipc.RpcServer |
RpcServer.handler=79,port=60020: caught a ClosedChannelException, this means that the server was processing a request but the client went away. The error message was: null |
下午4點09:00.381 |
INFO |
org.apache.hadoop.hbase.regionserver.HRegion |
Finished memstore flush of ~128.1 M/134326016, currentsize=2.4 M/2559256 for region session_service_201410260000_201410312359,6406249959,1414571385831.a3b64675b0069b8323665274e2f95cdc. in 8133ms, sequenceid=45525, compaction requested=false |
下 |
問題28 hbase hbase.hregion.max.filesize應該設定多少合適
預設值:256M
說明:Maximum HStoreFile size. If any one of a column families'HStoreFiles has grown to exceed this value, the hosting HRegion is splitin two.
HStoreFile的最大值。如果任何一個Column Family(或者說HStore)的HStoreFiles的大小超過這個值,那麼,其所屬的HRegion就會Split成兩個。
調優:
hbase中hfile的預設最大值(hbase.hregion.max.filesize)是256MB,而google的bigtable論文中對tablet的最大值也推薦為100-200MB,這個大小有什麼祕密呢?
眾所周知hbase中資料一開始會寫入memstore,當memstore滿64MB以後,會flush到disk上而成為storefile。當storefile數量超過3時,會啟動compaction過程將它們合併為一個storefile。這個過程中會刪除一些timestamp過期的數 據,比如update的資料。而當合並後的storefile大小大於hfile預設最大值時,會觸發split動作,將它切分成兩個region。
lz進行了持續insert壓力測試,並設定了不同的hbase.hregion.max.filesize,根據結果得到如下結論:值越小,平均吞吐量越大,但吞吐量越不穩定;值越大,平均吞吐量越小,吞吐量不穩定的時間相對更小。
為什麼會這樣呢?推論如下:
a 當hbase.hregion.max.filesize比較小時,觸發split的機率更大,而split的時候會將region offline,因此在split結束的時間前,訪問該region的請求將被block住,客戶端自我block的時間預設為1s。當大量的region同時發生split時,系統的整體訪問服務將大受影響。因此容易出現吞吐量及響應時間的不穩定現象
b 當hbase.hregion.max.filesize比較大時,單個region中觸發split的機率較小,大量region同時觸發split的 機率也較小,因此吞吐量較之小hfile尺寸更加穩定些。但是由於長期得不到split,因此同一個region內發生多次compaction的機會增 加了。compaction的原理是將原有資料讀一遍並重寫一遍到hdfs上,然後再刪除原有資料。無疑這種行為會降低以io為瓶頸的系統的速度,因此平 均吞吐量會受到一些影響而下降。
綜合以上兩種情況,hbase.hregion.max.filesize不宜過大或過小,256MB或許是一個更理想的經驗引數。對於離線型的應用,調整為128MB會更加合適一些,而線上應用除非對split機制進行改造,否則不應該低於256MB
問題29hbase autoflush=false的影響
無論是官方還是很多blog都提倡為了提高hbase的寫入速度而在應用程式碼中設定autoflush=false,然後lz認為在線上應用中應該謹慎進行該設定。原因如下:
a autoflush=false的原理是當客戶端提交delete或put請求時,將該請求在客戶端快取,直到資料超過2M(hbase.client.write.buffer決定)或使用者執行了hbase.flushcommits()時才向regionserver提交請求。因此即使htable.put()執行返回成功,也並非說明請求真的成功了。假如還沒有達到該快取而client崩潰,該部分資料將由於未傳送到regionserver而丟失。這對於零容忍的線上服務是不可接受的。
b autoflush=true雖然會讓寫入速度下降2-3倍,但是對於很多線上應用來說這都是必須開啟的,也正是hbase為什麼讓它預設值為true的原因。當該值為true時,每次請求都會發往regionserver,而regionserver接收到 請求後第一件事就是寫hlog,因此對io的要求是非常高的,為了提高hbase的寫入速度,應該儘可能高地提高io吞吐量,比如增加磁碟、使用raid 卡、減少replication因子數等
問題 30 hbase從效能的角度談table中family和qualifier的設定
對於傳統關係型資料庫中的一張table,在業務轉換到hbase上建模時,從效能的角度應該如何設定family和qualifier呢?
最極端的,①每一列都設定成一個family,②一個表僅有一個family,所有列都是其中的一個qualifier,那麼有什麼區別呢?
從讀的方面考慮:
family越多,那麼獲取每一個cell資料的優勢越明顯,因為io和網路都減少了。
如果只有一個family,那麼每一次讀都會讀取當前rowkey的所有資料,網路和io上會有一些損失。
當然如果要獲取的是固定的幾列資料,那麼把這幾列寫到一個family中比分別設定family要更好,因為只需一次請求就能拿回所有資料。
從寫的角度考慮:
首先,記憶體方面來說,對於一個Region,會為每一個表的每一個Family分配一個Store,而每一個Store,都會分配一個MemStore,所以更多的family會消耗更多的記憶體。
其次,從flush和compaction方面說,目前版本的hbase,在flush和compaction都是以region為單位的,也就是說當一個family達到flush條件時,該region的所有family所屬的memstore都會flush一次,即使memstore中只有很少的資料也會觸發flush而生成小檔案。這樣就增加了compaction發生的機率,而compaction也是以region為單位的,這樣就很容易發生compaction風暴從而降低系統的整體吞吐量。
第三,從split方面考慮,由於hfile是以family為單位的,因此對於多個family來說,資料被分散到了更多的hfile中,減小了split發生的機率。這是把雙刃劍。更少的split會導致該region的體積比較大,由於balance是以region的數目而不是大小為單位來進行的,因此可能會導致balance失效。而從好的方面來說,更少的split會讓系統提供更加穩定的線上服務。而壞處我們可以通過在請求的低谷時間進行人工的split和balance來避免掉。
因此對於寫比較多的系統,如果是離線應該,我們儘量只用一個family好了,但如果是線上應用,那還是應該根據應用的情況合理地分配family。
問題31 hbase.regionserver.handler.count
RegionServer端開啟的RPC監聽器例項個數,也即RegionServer能夠處理的IO請求執行緒數。預設是10.
此引數與記憶體息息相關。該值設定的時候,以監控記憶體為主要參考。
對於 單次請求記憶體消耗較高的Big PUT場景(大容量單次PUT或設定了較大cache的scan,均屬於BigPUT)或ReigonServer的記憶體比較緊張的場景,可以設定的相對較小。
對於 單次請求記憶體消耗低,TPS(TransactionPerSecond,每秒事務處理量)要求非常高的場景,可以設定的相對大些。
hive 查詢日誌
2014-11-06 12:39:50,825 Stage-1 map =100%, reduce = 100%, Cumulative CPU1206.39 sec
2014-11-06 12:39:51,873 Stage-1 map =100%, reduce = 100%, Cumulative CPU1206.39 sec
MapReduce Total cumulative CPU time: 20minutes 6 seconds 390 msec
Ended Job = job_1414723034537_0042
Loading data to tabledefault.session_service_t4
chgrp: changing ownership of'/user/hive/warehouse/session_service_t4/000000_0': User does not belong tohive
Table default.session_service_t4 stats:[num_partitions: 0, num_files: 1, num_rows: 0, total_size: 4191, raw_data_size:0]
MapReduce Jobs Launched:
Job 0: Map: 556 Reduce: 1 Cumulative CPU: 1206.39 sec HDFSRead: 36584800 HDFS Write: 4191 SUCCESS
Total MapReduce CPU Time Spent: 20 minutes6 seconds 390 msec
OK
Time taken: 642.531 seconds
2013-05-20 17:39:00,153 ERRORcom.sunchangming.searchlog.CopyAppLogs: err on 2013051918_api_access_65.gz
java.io.IOException: Filesystem closed
at org.apache.hadoop.hdfs.DFSClient.checkOpen(DFSClient.java:319)
at org.apache.hadoop.hdfs.DFSClient.getFileInfo(DFSClient.java:1026)
atorg.apache.hadoop.hdfs.DistributedFileSystem.getFileStatus(DistributedFileSystem.java:524)
at org.apache.hadoop.fs.FileSystem.exists(FileSystem.java:768)
at com.sunchangming.searchlog.CopyAppLogs.copyFile(CopyAppLogs.java:51)
at com.sunchangming.searchlog.CopyAppLogs.access$000(CopyAppLogs.java:18)
at com.sunchangming.searchlog.CopyAppLogs$1.run(CopyAppLogs.java:194)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
atjava.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
然後我就查,為什麼呢。我剛剛用final FileSystem dfs =FileSystem.get(getConf()); 得到它啊。
後來發現,我是一個多執行緒的程式。FileSystem.get(getConf())返回的可能是一個cache中的結果,它並不是每次都建立一 個新的例項。這就意味著,如果每個執行緒都自己去get一個檔案系統,然後使用,然後關閉,就會有問題。因為你們關閉的可能是同一個物件。而別人還在用它!
所以最好是在main函式中就建立好filesystem物件然後在不同函式之間來回傳遞吧。在main函式用用try…finally關閉它。
多執行緒程式中,如果你確保在你的get和close之間不會有別人呼叫get,也沒問題。
hbase調優
HBase效能優化的四個要點
1hbase.hregion.max.filesize應該設定多少合適
預設值:256M
說明:Maximum HStoreFile size. If any one of a columnfamilies' HStoreFiles has grown to exceed this value, the hosting HRegion issplit in two.
HStoreFile的最大值。如果任何一個Column Family(或者說HStore)的HStoreFiles的大小超過這個值,那麼,其所屬的HRegion就會Split成兩個。
調優:
hbase中hfile的預設最大值(hbase.hregion.max.filesize)是256MB,而google的bigtable論文中對tablet的最大值也推薦為100-200MB,這個大小有什麼祕密呢?
眾所周知hbase中資料一開始會寫入memstore,當memstore滿64MB以後,會flush到disk上而成為storefile。 當storefile數量超過3時,會啟動compaction過程將它們合併為一個storefile。這個過程中會刪除一些timestamp過期的 資料,比如update的資料。而當合並後的storefile大小大於hfile預設最大值時,會觸發split動作,將它切分成兩個region。
lz進行了持續insert壓力測試,並設定了不同的hbase.hregion.max.filesize,根據結果得到如下結論:值越小,平均吞吐量越大,但吞吐量越不穩定;值越大,平均吞吐量越小,吞吐量不穩定的時間相對更小。
為什麼會這樣呢?推論如下:
a 當hbase.hregion.max.filesize比較小時,觸發split的機率更大,而split的時候會將region offline,因此在split結束的時間前,訪問該region的請求將被block住,客戶端自我block的時間預設為1s。當大量的region同時發生split時,系統的整體訪問服務將大受影響。因此容易出現吞吐量及響應時間的不穩定現象
b 當hbase.hregion.max.filesize比較大時,單個region中觸發split的機率較小,大量region同時觸發split的 機率也較小,因此吞吐量較之小hfile尺寸更加穩定些。但是由於長期得不到split,因此同一個region內發生多次compaction的機會增 加了。compaction的原理是將原有資料讀一遍並重寫一遍到hdfs上,然後再刪除原有資料。無疑這種行為會降低以io為瓶頸的系統的速度,因此平 均吞吐量會受到一些影響而下降。
綜合以上兩種情況,hbase.hregion.max.filesize不宜過大或過小,256MB或許是一個更理想的經驗引數。對於離線型的應用,調整為128MB會更加合適一些,而線上應用除非對split機制進行改造,否則不應該低於256MB
2autoflush=false的影響
無論是官方還是很多blog都提倡為了提高hbase的寫入速度而在應用程式碼中設定autoflush=false,然後lz認為在線上應用中應該謹慎進行該設定。原因如下:
a autoflush=false的原理是當客戶端提交delete或put請求時,將該請求在客戶端快取,直到資料超過2M(hbase.client.write.buffer決定)或使用者執行了hbase.flushcommits()時才向regionserver 提交請求。因此即使htable.put()執行返回成功,也並非說明請求真的成功了。假如還沒有達到該快取而client崩潰,該部分資料將由於未傳送到regionserver而丟失。這對於零容忍的線上服務是不可接受的。
b autoflush=true雖然會讓寫入速度下降2-3倍,但是對於很多線上應用來說這都是必須開啟的,也正是hbase為什麼讓它預設值為true的 原因。當該值為true時,每次請求都會發往regionserver,而regionserver接收到請求後第一件事就是寫hlog,因此對io的要 求是非常高的,為了提高hbase的寫入速度,應該儘可能高地提高io吞吐量,比如增加磁碟、使用raid卡、減少replication因子數等
3 從效能的角度談table中family和qualifier的設定
對於傳統關係型資料庫中的一張table,在業務轉換到hbase上建模時,從效能的角度應該如何設定family和qualifier呢?
最極端的,①每一列都設定成一個family,②一個表僅有一個family,所有列都是其中的一個qualifier,那麼有什麼區別呢?
從讀的方面考慮:
family越多,那麼獲取每一個cell資料的優勢越明顯,因為io和網路都減少了。
如果只有一個family,那麼每一次讀都會讀取當前rowkey的所有資料,網路和io上會有一些損失。
當然如果要獲取的是固定的幾列資料,那麼把這幾列寫到一個family中比分別設定family要更好,因為只需一次請求就能拿回所有資料。
從寫的角度考慮:
首先,記憶體方面來說,對於一個Region,會為每一個表的每一個Family分配一個Store,而每一個Store,都會分配一個MemStore,所以更多的family會消耗更多的記憶體。
其次,從flush和compaction方面說,目前版本的hbase,在flush和compaction都是以region為單位的,也就是 說當一個family達到flush條件時,該region的所有family所屬的memstore都會flush一次,即使memstore中只有很少的資料也會觸發flush而生成小檔案。這樣就增加了compaction發生的機率,而compaction也是以region為單位的,這樣就很容 易發生compaction風暴從而降低系統的整體吞吐量。
第三,從split方面考慮,由於hfile是以family為單位的,因此對於多個family來說,資料被分散到了更多的hfile中,減小了 split發生的機率。這是把雙刃劍。更少的split會導致該region的體積比較大,由於balance是以region的數目而不是大小為單位來 進行的,因此可能會導致balance失效。而從好的方面來說,更少的split會讓系統提供更加穩定的線上服務。而壞處我們可以通過在請求的低谷時間進行人工的split和balance來避免掉。
因此對於寫比較多的系統,如果是離線應該,我們儘量只用一個family好了,但如果是線上應用,那還是應該根據應用的情況合理地分配family。
4hbase.regionserver.handler.count
RegionServer端開啟的RPC監聽器例項個數,也即RegionServer能夠處理的IO請求執行緒數。預設是10.
此引數與記憶體息息相關。該值設定的時候,以監控記憶體為主要參考。
對於 單次請求記憶體消耗較高的Big PUT場景(大容量單次PUT或設定了較大cache的scan,均屬於BigPUT)或ReigonServer的記憶體比較緊張的場景,可以設定的相對較小。
對於 單次請求記憶體消耗低,TPS(TransactionPerSecond,每秒事務處理量)要求非常高的場景,可以設定的相對大些。
1.2 Row Key
HBase中row key用來檢索表中的記錄,支援以下三種方式:
· 通過單個row key訪問:即按照某個row key鍵值進行get操作;
· 通過row key的range進行scan:即通過設定startRowKey和endRowKey,在這個範圍內進行掃描;
· 全表掃描:即直接掃描整張表中所有行記錄。
在HBase中,row key可以是任意字串,最大長度64KB,實際應用中一般為10~100bytes,存為byte[]位元組陣列,一般設計成定長的。
row key是按照字典序儲存,因此,設計row key時,要充分利用這個排序特點,將經常一起讀取的資料儲存到一塊,將最近可能會被訪問的資料放在一塊。
舉個例子:如果最近寫入HBase表中的資料是最可能被訪問的,可以考慮將時間戳作為row key的一部分,由於是字典序排序,所以可以使用Long.MAX_VALUE –timestamp作為row key,這樣能保證新寫入的資料在讀取時可以被快速命中。
1.3 Column Family
不要在一張表裡定義太多的column family。目前Hbase並不能很好的處理超過2~3個column family的表。因為某個columnfamily在flush的時候,它鄰近的column family也會因關聯效應被觸發flush,最終導致系統產生更多的I/O。感興趣的同學可以對自己的HBase叢集進行實際測試,從得到的測試結果資料驗證一下。
1.4 In Memory
建立表的時候,可以通過HColumnDescriptor.setInMemory(true)將表放到RegionServer的快取中,保證在讀取的時候被cache命中。
1.5 Max Version
建立表的時候,可以通過HColumnDescriptor.setMaxVersions(int maxVersions)設定表中資料的最大版本,如果只需要儲存最新版本的資料,那麼可以設定setMaxVersions(1)。
1.6 Time To Live
建立表的時候,可以通過HColumnDescriptor.setTimeToLive(inttimeToLive)設定表中資料的儲存生命期,過期資料將自動被刪除,例如如果只需要儲存最近兩天的資料,那麼可以設定 setTimeToLive(2* 24 * 60 * 60)。
1.7 Compact & Split
在HBase中,資料在更新時首先寫入WAL 日誌(HLog)和記憶體(MemStore)中,MemStore中的資料是排序的,當MemStore累計到一定閾值時,就會建立一個新的 MemStore,並且將老的MemStore新增到flush佇列,由單獨的執行緒flush到磁碟上,成為一個StoreFile。於此同時,系統會在zookeeper中記錄一個redo point,表示這個時刻之前的變更已經持久化了(minorcompact)。
StoreFile是隻讀的,一旦建立後就不可以再修改。因此Hbase的更新其實是不斷追加的操作。當一個Store中的StoreFile達到一定的閾值後,就會進行一次合併(majorcompact),將對同一個key的修改合併到一起,形成一個大的StoreFile,當StoreFile的大小達到一定閾值後,又會對 StoreFile進行分割(split),等分為兩個StoreFile。
由於對錶的更新是不斷追加的,處理讀請求時,需要訪問Store中全部的StoreFile和MemStore,將它們按照row key進行合併,由於StoreFile和MemStore都是經過排序的,並且StoreFile帶有記憶體中索引,通常合併過程還是比較快的。
實際應用中,可以考慮必要時手動進行majorcompact,將同一個row key的修改進行合併形成一個大的StoreFile。同時,可以將StoreFile設定大些,減少split的發生。
2.2 HTable引數設定
2.2.1 Auto Flush
通過呼叫HTable.setAutoFlush(false)方法可以將HTable寫客戶端的自動flush關閉,這樣可以批量寫入資料到 HBase,而不是有一條put就執行一次更新,只有當put填滿客戶端寫快取時,才實際向HBase服務端發起寫請求。預設情況下auto flush是開啟的。
2.2.2 Write Buffer
通過呼叫HTable.setWriteBufferSize(writeBufferSize)方法可以設定HTable客戶端的寫buffer大小,如果新設定的buffer小於當前寫buffer中的資料時,buffer將會被flush到服務端。其中,writeBufferSize的單位是 byte位元組數,可以根據實際寫入資料量的多少來設定該值。
2.2.3 WAL Flag
在HBae中,客戶端向叢集中的RegionServer提交資料時(Put/Delete操作),首先會先寫WAL(Write Ahead Log)日誌(即HLog