2013-10-15 65 views
3

我正在嘗試使用Java編寫遠程HBase客戶端。以下是供參考的代碼:HBase Java客戶端不起作用(MasterNotRunningException異常)

package ttumdt.app.connector; 


import org.apache.hadoop.conf.Configuration; 
import org.apache.hadoop.hbase.HBaseConfiguration; 
import org.apache.hadoop.hbase.MasterNotRunningException; 
import org.apache.hadoop.hbase.ZooKeeperConnectionException; 
import org.apache.hadoop.hbase.client.HBaseAdmin; 
import org.apache.hadoop.hbase.client.HTable; 
import org.apache.hadoop.hbase.client.Result; 
import org.apache.hadoop.hbase.client.ResultScanner; 
import org.apache.hadoop.hbase.client.Scan; 
import org.apache.hadoop.hbase.filter.BinaryComparator; 
import org.apache.hadoop.hbase.filter.CompareFilter; 
import org.apache.hadoop.hbase.filter.Filter; 
import org.apache.hadoop.hbase.filter.FilterList; 
import org.apache.hadoop.hbase.filter.RowFilter; 
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; 
import org.apache.hadoop.hbase.util.Bytes; 

import java.io.IOException; 
import java.util.Arrays; 
import java.util.HashSet; 
import java.util.Set; 

public class HBaseClusterConnector { 
    private final String MASTER_IP = "10.138.168.185"; 
    private final String ZOOKEEPER_PORT = "2181"; 

    final String TRAFFIC_INFO_TABLE_NAME = "TrafficLog"; 
    final String TRAFFIC_INFO_COLUMN_FAMILY = "TimeStampIMSI"; 

    final String KEY_TRAFFIC_INFO_TABLE_BTS_ID = "BTS_ID"; 
    final String KEY_TRAFFIC_INFO_TABLE_DATE = "DATE"; 
    final String COLUMN_IMSI = "IMSI"; 
    final String COLUMN_TIMESTAMP = "TIME_STAMP"; 

    private final byte[] columnFamily = Bytes.toBytes(TRAFFIC_INFO_COLUMN_FAMILY); 
    private final byte[] qualifier= Bytes.toBytes(COLUMN_IMSI); 

    private Configuration conf = null; 

    public HBaseClusterConnector() throws MasterNotRunningException, ZooKeeperConnectionException { 
     conf = HBaseConfiguration.create(); 
     conf.set("hbase.zookeeper.quorum",MASTER_IP); 
     conf.set("hbase.zookeeper.property.clientPort",ZOOKEEPER_PORT); 
     HBaseAdmin.checkHBaseAvailable(conf); 
    } 

    /** 
    * This filter will return list of IMSIs for a given btsId and ime interval 
    * @param btsId : btsId for which the query has to run 
    * @param startTime : start time for which the query has to run 
    * @param endTime : end time for which the query has to run 
    * @return returns IMSIs as set of Strings 
    * @throws IOException 
    */ 
    public Set<String> getInfoPerBTSID(String btsId, String date, 
             String startTime, String endTime) 
      throws IOException { 
     Set<String> imsis = new HashSet<String>(); 

     //ToDo : better exception handling 
     HTable table = new HTable(conf, TRAFFIC_INFO_TABLE_NAME); 
     Scan scan = new Scan(); 

     scan.addColumn(columnFamily,qualifier); 
     scan.setFilter(prepFilter(btsId, date, startTime, endTime)); 

     // filter to build where timestamp 

     Result result = null; 
     ResultScanner resultScanner = table.getScanner(scan); 

     while ((result = resultScanner.next())!= null) { 
      byte[] obtainedColumn = result.getValue(columnFamily,qualifier); 
      imsis.add(Bytes.toString(obtainedColumn)); 
     } 

     resultScanner.close(); 

     return imsis; 
    } 

    //ToDo : Figure out how valid is this filter code?? How comparison happens 
    // with eqaul or grater than equal etc 


    private Filter prepFilter (String btsId, String date, 
           String startTime, String endTime) 
    { 
     byte[] tableKey = Bytes.toBytes(KEY_TRAFFIC_INFO_TABLE_BTS_ID); 
     byte[] timeStamp = Bytes.toBytes(COLUMN_TIMESTAMP); 

     // filter to build -> where BTS_ID = <<btsId>> and Date = <<date>> 
     RowFilter keyFilter = new RowFilter(CompareFilter.CompareOp.EQUAL, 
       new BinaryComparator(Bytes.toBytes(btsId+date))); 

     // filter to build -> where timeStamp >= startTime 
     SingleColumnValueFilter singleColumnValueFilterStartTime = 
       new SingleColumnValueFilter(columnFamily, timeStamp, 
         CompareFilter.CompareOp.GREATER_OR_EQUAL,Bytes.toBytes(startTime)); 

     // filter to build -> where timeStamp <= endTime 
     SingleColumnValueFilter singleColumnValueFilterEndTime = 
       new SingleColumnValueFilter(columnFamily, timeStamp, 
         CompareFilter.CompareOp.LESS_OR_EQUAL,Bytes.toBytes(endTime)); 

     FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, Arrays 
       .asList((Filter) keyFilter, 
         singleColumnValueFilterStartTime, singleColumnValueFilterEndTime)); 
     return filterList; 
    } 


    public static void main(String[] args) throws IOException { 
     HBaseClusterConnector flt = new HBaseClusterConnector(); 
     Set<String> imsis= flt.getInfoPerBTSID("AMCD000784", "26082013","104092","104095"); 
     System.out.println(imsis.toString()); 
    } 
} 

我目前使用Cloudera快速啓動虛擬機來測試此操作。

的問題是;如果我在VM上運行這個非常好的代碼,它的工作原理絕對沒錯但是如果從外部運行,則會失敗並顯示以下錯誤。我懷疑它與虛擬機設置有關,而不是其他任何東西。請注意,我已經檢查過是否可以從主機連接到VM的節點管理器/作業跟蹤器,並且它工作得很好。當我從主機操作系統運行代碼而不是在虛擬機上運行代碼時;我得到下面的錯誤:

2013-10-15 18:16:04.185 java[652:1903] Unable to load realm info from SCDynamicStore 
Exception in thread "main" org.apache.hadoop.hbase.MasterNotRunningException: Retried 1 times 
    at org.apache.hadoop.hbase.client.HBaseAdmin.<init>(HBaseAdmin.java:138) 
    at org.apache.hadoop.hbase.client.HBaseAdmin.checkHBaseAvailable(HBaseAdmin.java:1774) 
    at ttumdt.app.connector.HBaseClusterConnector.<init>(HBaseClusterConnector.java:47) 
    at ttumdt.app.connector.HBaseClusterConnector.main(HBaseClusterConnector.java:117) 
    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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 

Process finished with exit code 1 

請注意,主節點實際上正在運行。該zookeper日誌顯示,它已經建立了與主機操作系統的連接:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

6:16:03.274 PM INFO org.apache.zookeeper.server.ZooKeeperServer  

Client attempting to establish new session at /10.138.169.81:50567 

6:16:03.314 PM INFO org.apache.zookeeper.server.ZooKeeperServer  

Established session 0x141bc2487440004 with negotiated timeout 60000 for client /10.138.169.81:50567 

6:16:03.964 PM INFO org.apache.zookeeper.server.PrepRequestProcessor  

Processed session termination for sessionid: 0x141bc2487440004 

6:16:03.996 PM INFO org.apache.zookeeper.server.NIOServerCnxn 

Closed socket connection for client /10.138.169.81:50567 which had sessionid 0x141bc2487440004 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

但我看到在碩士或RegionServer的日誌中沒有任何活動的痕跡。

請注意,我的主機操作系統是Mac OSX版10.7.5

由於每間可用資源;這應該工作得很好;儘管一些人建議簡單的HBase java客戶端永遠不會工作。我很困惑;並熱切地等待指針!請回復

回答

0

HBase Java客戶端肯定可以工作!

最可能的解釋是您的客戶端由於某種原因無法看到主設備運行的計算機。

一個可能的解釋是,雖然您使用IP地址連接到Zookeeper,但HBase客戶端正嘗試使用其主機名連接到主服務器。

因此,如果確保在主機文件(在客戶端上)中有與運行主服務器的機器的主機名相匹配的條目,這可以解決問題。

檢查您是否可以從客戶端計算機訪問<主機名>:60010的主Web UI。

0

不同的端口上啓動hiveserver2,然後嘗試連接

命令hiveserver2連接不同的端口上(確保蜂巢路徑):

hive --service hiveserver2 --hiveconf hive.server2.thrift.port=13000