1. 程式人生 > >HBase資料匯入(一)importtsv工具匯入文字檔案到Hbase

HBase資料匯入(一)importtsv工具匯入文字檔案到Hbase

剛安裝好Hbase,如果不知道怎麼安裝,請參見我這篇博文,首先想到的就是能夠匯入大量資料,然後查詢玩玩。

怎麼匯入呢,瞭解到可以從文字檔案匯入,那就先測試一下吧,在這之前先要配置一下Hadoop。

配置步驟:

1 首先要修改Hadoop的配置檔案hadoop-env.sh:

vim /usr/hadoop/hadoop/conf/hadoop-env.sh,增加下面的Hbase的配置項

#jiyiqin add for Hbase data import
export HBASE_HOME=/usr/HBase/hbase
export HADOOP_CLASSPATH=$HBASE_HOME/hbase-0.94.20.jar:$HBASE_HOME/hbase-0.94.20-tests.jar:$HBASE_HOME/conf:${HBASE_HOME}/lib/zookeeper-3.4.5.jar:${HBASE_HOME}/lib/guava-11.0.2.jar
自己開啟自己的Hbase的目錄看看你的這些jar檔案是不是這些版本,如果不是就自己改一下。

2 然後就是將Hbase下面相關的jar檔案拷貝到Hadoop對應的目錄下面:

  257  cp /usr/HBase/hbase/hbase-0.94.20.jar /usr/hadoop/hadoop/lib/
  258  cp /usr/HBase/hbase/hbase-0.94.20-tests.jar /usr/hadoop/hadoop/lib/
  259  cp /usr/HBase/hbase/conf/hbase-site.xml /usr/hadoop/hadoop/conf/

還有一個檔案也要拷貝,如果不拷貝,一會執行importtsv命令匯入資料的時候會報異常:
13/05/23 09:41:05 INFO zookeeper.ClientCnxn: Opening socket connection to server /192.168.1.137:2181
13/05/23 09:41:06 WARN client.ZooKeeperSaslClient: SecurityException: java.lang.SecurityException: 無法定位登入配置 occurred when trying to find JAAS configuration.
13/05/23 09:41:06 INFO client.ZooKeeperSaslClient: Client will not SASL-authenticate because the default JAAS configuration section 'Client' could not be found. If you are not using SASL, you may ignore this. On the other hand, if you expected SASL to work, please fix your JAAS configuration.
13/05/23 09:41:06 INFO zookeeper.RecoverableZooKeeper: The identifier of this process is 
[email protected]
13/05/23 09:41:06 INFO zookeeper.ClientCnxn: Socket connection established to master/192.168.1.137:2181, initiating session 13/05/23 09:41:06 INFO zookeeper.ClientCnxn: Session establishment complete on server master/192.168.1.137:2181, sessionid = 0x13ecf0b470c0004, negotiated timeout = 180000 Exception in thread "main" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.hadoop.hbase.mapreduce.Driver.main(Driver.java:51) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.hadoop.util.RunJar.main(RunJar.java:156) Caused by: java.lang.NoClassDefFoundError: com/google/protobuf/Message at org.apache.hadoop.hbase.io.HbaseObjectWritable.<clinit>(HbaseObjectWritable.java:263) at org.apache.hadoop.hbase.ipc.Invocation.write(Invocation.java:139) at org.apache.hadoop.hbase.ipc.HBaseClient$Connection.sendParam(HBaseClient.java:638) at org.apache.hadoop.hbase.ipc.HBaseClient.call(HBaseClient.java:1001) at org.apache.hadoop.hbase.ipc.WritableRpcEngine$Invoker.invoke(WritableRpcEngine.java:150) at $Proxy5.getProtocolVersion(Unknown Source) at org.apache.hadoop.hbase.ipc.WritableRpcEngine.getProxy(WritableRpcEngine.java:183) at org.apache.hadoop.hbase.ipc.HBaseRPC.getProxy(HBaseRPC.java:335) at org.apache.hadoop.hbase.ipc.HBaseRPC.getProxy(HBaseRPC.java:312) at org.apache.hadoop.hbase.ipc.HBaseRPC.getProxy(HBaseRPC.java:364) at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.getMaster(HConnectionManager.java:682) at org.apache.hadoop.hbase.client.HBaseAdmin.<init>(HBaseAdmin.java:110) at org.apache.hadoop.hbase.mapreduce.ImportTsv.main(ImportTsv.java:352) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.hadoop.util.ProgramDriver$ProgramDescription.invoke(ProgramDriver.java:68) at org.apache.hadoop.util.ProgramDriver.driver(ProgramDriver.java:139) ... 10 more Caused by: java.lang.ClassNotFoundException: com.google.protobuf.Message at java.net.URLClassLoader$1.run(URLClassLoader.java:202) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:247) ... 29 more
cp /usr/HBase/hbase/lib/protobuf-java-2.4.0a.jar /usr/hadoop/hadoop/lib/
其實在這之前我把zookeeper的一個檔案也拷貝過去了,我不知道這個是不是必須的,也沒有再去掉試試,你可以也拷貝過去:

cp /usr/HBase/hbase/lib/zookeeper-3.4.5.jar /usr/hadoop/hadoop/lib/

好了,準備工作做好了。

3 啟動hadoop: start-all.sh

4 啟動hbase:start-hbase.sh

5 在Hbase上新建一個只有一個列族的表:

hbase shell
create 'table2','CF'

6 準備要匯入的文字檔案,並上傳到HDFS:

文字檔案是這樣的(以逗號分割,匯入命令中會指定分割符):

1,jiyiqin,jiangsu
2,wanglihong,taiwan
3,zhoujielun,taiwan
4,liudehua,hongkong
5,liangchaowei,hongkong
6,xijingping,beijing

上傳到HDFS是這樣:

hadoop fs -mkdir /test

hadoop fs -put test.txt /test

hadoop fs -ls /test

7 使用importtsv命令匯入,下面是完整的匯入命令:

[email protected]:~/hadoop/test$ hadoop jar /usr/hadoop/hadoop/lib/hbase-0.94.20.jar importtsv -Dimporttsv.columns=HBASE_ROW_KEY,CF:col1,CF:col2 -Dimporttsv.separator=, table2 /test1/test.txt
如果出現下面的mapreduceu作業執行資訊,並且bad lines=0,就說明正確匯入了:

然後就可以登陸Hbase檢視匯入的資料了:

> hbase shell

> scan 'table2'


其實importtsv匯入資料還有一種方式,分為兩步,第一步要先生成臨時的HFile檔案,當資料量較大時,我上面將的方式會比較慢,而兩步走的方式會快一些,下面是我轉載來的關於這個的說明:

第一步,生成hfile

Script程式碼  收藏程式碼
  1. hadoop jar hbase-version.jar importtsv -Dimporttsv.columns=HBASE_ROW_KEY,c1,c2 -Dimporttsv.bulk.output=tmp hbase_table hdfs_file  
這一步提醒兩個地方,c1,c2列是需要指明列族和列名,例如:cf:1,cf:2,
                    -Dimporttsv.bulk.output=tmp, tmp生成後會在hdfs的/user/hadoop/tmp中
第二步,匯入hbase表,這一步其實是mv的過程,即利用生成好的hfile移到hbase中
Script程式碼  收藏程式碼
  1. hadoop jar hbase-version.jar completebulkload /user/hadoop/tmp/cf hbase_table  
這樣資料是可以正常進入hbase的

當不需要生成臨時檔案,直接bulk load時,
Script程式碼  收藏程式碼
  1. hadoop jar hbase-version.jar importtsv -Dimporttsv.columns=HBASE_ROW_KEY,c1,c2 hbase_table hdfs_file  

值得注意的是,經過測試,在資料量較大時,兩步處理方式比一步匯入方式有效率和穩定性上的優勢:
1. 兩步匯入時,由於是先生成檔案,再複製檔案進入HBase表,對於HBase讀取的效能影響較小,不會出現較大的讀取時間波動;
2. 兩步匯入時,時間上要節約三分之二,等於效率提高60%~70%,map的處理時間較短,只有一個reduce, 一步匯入時,map處理時間較長,沒有reduce. 由於hadoop叢集在配置時,一般會有較多的最大map數設定,較少的最大reduce數設定,那麼這種兩步匯入方式也在一定程度上提升了hadoop叢集併發能力。