HBase建表函數提供了四個重載函數,分別是
void createTable(HTableDescriptor desc)void createTable(HTableDescriptor desc, byte[] startKey,byte[] endKey, int numRegions)void createTable(HTableDescriptor desc, byte[][] splitKeys) void createTableAsync(HTableDescriptor desc, byte[][] splitKeys)
這四個函數的相同點是都是根據表描述符來建立表。其中一個不同是錢三個函數式同步建立(也就是表沒建立完,函數不返回)。而帶Async的這個函數式非同步(後台自動建立表)。
第一個函數相對簡單,就是建立一個表,這個表沒有任何region。後三個函數是建立表的時候幫你分配好指定數量的region(提前分配region的好處,瞭解HBase的人都清楚,為了減少Split,這樣能節省不少時間)
第二個函數是使用者指定表的“起始行鍵”、“末尾行鍵”和region的數量,這樣系統自動給你劃分region。根據的region數,來均分所有的行鍵。這個方法的問題是如果你的表的行鍵不是連續的,那樣的話就導致有些region的行鍵不會用到,有些region是全滿的。
所以HBase很人性的給了第三種和第四種方法。這兩個函數是使用者需要自己region的劃分。這個函數的參數splitKeys是一個二維位元組資料,行的最大數表示region劃分數+1,列就表示region和region之間的行鍵。比如:
byte[][] regions = new byte[][] { Bytes.toBytes("A"), Bytes.toBytes("D"), Bytes.toBytes("G"), Bytes.toBytes("K"), Bytes.toBytes("O"), Bytes.toBytes("T") };
就表示有7個region(6+1),具體region表示的行鍵為:
[1] start key: , end key: A[2] start key: A, end key: D[3] start key: D, end key: G[4] start key: G, end key: K[5] start key: K, end key: O[6] start key: O, end key: T[7] start key: T, end key:
這個例子來源於HBase權威指南。
但是後三個函數,再建表時,如果region數過多,會報這個異常:
13/06/24 11:33:49 WARN client.HBaseAdmin: Creating x took too long
java.net.SocketTimeoutException: Call to cloudgis4/192.168.3.7:60000 failed on socket timeout exception: java.net.SocketTimeoutException: 60000 millis timeout while waiting for channel to be ready for read. ch : java.nio.channels.SocketChannel[connected local=/192.168.2.198:37133 remote=cloudgis4/192.168.3.7:60000]at org.apache.hadoop.hbase.ipc.HBaseClient.wrapException(HBaseClient.java:802)at org.apache.hadoop.hbase.ipc.HBaseClient.call(HBaseClient.java:775)at org.apache.hadoop.hbase.ipc.HBaseRPC$Invoker.invoke(HBaseRPC.java:257)at $Proxy4.createTable(Unknown Source)at org.apache.hadoop.hbase.client.HBaseAdmin.createTableAsync(HBaseAdmin.java:405)at org.apache.hadoop.hbase.client.HBaseAdmin.createTable(HBaseAdmin.java:317)at GIS.Update.TestUpdate.testHBase(TestUpdate.java:181)at GIS.Update.TestUpdate.main(TestUpdate.java:267)Caused by: java.net.SocketTimeoutException: 60000 millis timeout while waiting for channel to be ready for read. ch : java.nio.channels.SocketChannel[connected local=/192.168.2.198:37133 remote=cloudgis4/192.168.3.7:60000]at org.apache.hadoop.net.SocketIOWithTimeout.doIO(SocketIOWithTimeout.java:164)at org.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:155)at org.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:128)at java.io.FilterInputStream.read(Unknown Source)at org.apache.hadoop.hbase.ipc.HBaseClient$Connection$PingInputStream.read(HBaseClient.java:299)at java.io.BufferedInputStream.fill(Unknown Source)at java.io.BufferedInputStream.read(Unknown Source)at java.io.DataInputStream.readInt(Unknown Source)at org.apache.hadoop.hbase.ipc.HBaseClient$Connection.receiveResponse(HBaseClient.java:539)at org.apache.hadoop.hbase.ipc.HBaseClient$Connection.run(HBaseClient.java:477)Exception in thread "main" org.apache.hadoop.hbase.client.RegionOfflineException: Only 0 of 1000 regions are online; retries exhausted.at org.apache.hadoop.hbase.client.HBaseAdmin.createTable(HBaseAdmin.java:355)at GIS.Update.TestUpdate.testHBase(TestUpdate.java:181)at GIS.Update.TestUpdate.main(TestUpdate.java:267)
具體就是說建表逾時了,google了好久也沒找到解決辦法。
createTableAsync
但是用第四個函數,儘管報異常,但是還是在後台把表建完,region數也正好