sql >> データベース >  >> NoSQL >> HBase

ハウツー:HBase Thriftインターフェースの使用、パート1

    Apache HBaseにアクセスして対話するには、さまざまな方法があります。最も注目すべきは、JavaAPIがほとんどの機能を提供することです。しかし、JavaなしでHBaseを使用したい人もいます。

    これらの人々には2つの主なオプションがあります。1つはThriftインターフェース(2つのオプションの中でより軽量で高速)であり、もう1つはRESTインターフェース(別名Stargate)です。 RESTインターフェースは、HTTP動詞を使用してアクションを実行します。 HTTPを使用することにより、RESTインターフェースは、インターフェースにアクセスできるはるかに幅広い言語とプログラムを提供します。 (RESTインターフェースの詳細については、私の一連のハウツーをご覧ください。)

    この一連のハウツーでは、Thriftインターフェースの使い方を学び、それを行うためのPythonコードサンプルを探索します。この最初の投稿では、HBase Thrift、Thriftの操作、およびThriftに接続するためのボイラープレートコードについて説明します。 2番目の投稿では、一度に複数の行を挿入して取得する方法を示します。 3番目の投稿では、スキャンの使用方法と、RESTとThriftのどちらかを選択する際の考慮事項について説明します。

    完全なコードサンプルは、私のGitHubアカウントにあります。

    HBase Thrift

    Thriftは、言語間のバインディングを作成できるソフトウェアフレームワークです。 HBaseのコンテキストでは、Javaは唯一の第一級市民です。ただし、HBase Thriftインターフェースでは、JavaクライアントとインターフェースするThriftサーバーに接続することで、他の言語がThriftを介してHBaseにアクセスできます。

    ThriftとRESTの両方が機能するには、これらのリクエストを処理するために別のHBaseデーモンが実行されている必要があります。これらのデーモンは、hbase-thriftおよびhbase-restパッケージとともにインストールできます。次の図は、ThriftとRESTがクラスターにどのように配置されているかを示しています。

    ThriftおよびRESTクライアントホストは通常​​、RESTまたはThriftインタラクションのオーバーヘッドを低く抑え、応答性を高く保つために、他のサービス(DataNodeやRegionServerなど)を実行しないことに注意してください。

    これらのデーモンは、HadoopクラスターとHBaseへのアクセスが必要なアプリケーションの両方にアクセスできるノードにインストールして起動してください。 Thriftインターフェースには負荷分散が組み込まれていないため、すべての負荷分散は、DNSラウンドロビン、仮想IPアドレス、またはコードなどの外部ツールを使用して実行する必要があります。 Cloudera Managerを使用すると、HBaseRESTおよびThriftサービスのインストールと管理も非常に簡単になります。 Cloudera Standardで無料でダウンロードして試すことができます!

    Thriftの欠点は、RESTよりもセットアップが難しいことです。 Thriftをコンパイルし、言語固有のバインディングを生成する必要があります。これらのバインディングは、作業している言語のコードを提供するので便利です。RESTのようにXMLやJSONを解析する必要はありません。むしろ、Thriftインターフェースを使用すると、行データに直接アクセスできます。もう1つの優れた機能は、Thriftプロトコルにネイティブのバイナリトランスポートがあることです。データをbase64でエンコードおよびデコードする必要はありません。

    Thriftインターフェースの使用を開始するには、それが実行されているポートを把握する必要があります。 CDHのデフォルトのポートはポート9090です。この投稿では、使用されるホスト変数とポート変数が表示されます。使用する値は次のとおりです。

    host = "localhost"
    port = "9090"
    

    セキュリティを強化するためにKerberosクレデンシャルを使用するようにThriftインターフェースを設定できます。

    コードには、ノードのIPアドレスまたは完全修飾ドメイン名とThriftデーモンを実行しているポートを使用する必要があります。ネットワークの変更に伴って変更される可能性があるため、このURLを変数にすることを強くお勧めします。

    言語バインディング

    Thriftバインディングを作成する前に、Thriftをダウンロードしてコンパイルする必要があります。 Windowsを除いて、私が見つけたThriftのバイナリパッケージはありません。選択したプラットフォームにインストールするには、Thriftの指示に従う必要があります。

    Thriftをインストールしたら、Hbase.thriftファイルを見つける必要があります。 Thriftでサービスとデータ型を定義するには、IDLファイルを作成する必要があります。幸い、HBase開発者はすでに私たちのために1つ作成しています。残念ながら、ファイルはCDHバイナリパッケージの一部として配布されていません。 (これは将来のCDHリリースで修正される予定です。)使用しているHBaseバージョンのソースパッケージをダウンロードする必要があります。このIDLは変更される可能性があるため、必ず正しいバージョンのHBaseを使用してください。圧縮ファイルでは、IDLへのパスはhbase-VERSION / src / main / resources / org / apache / hadoop / hbase / thrift/Hbase.thriftです。

    Thriftは、Java、C ++、Python、PHP、Ruby、C#を含む14を超える言語の言語バインディングの生成をサポートしています。 Pythonのバインディングを生成するには、次のコマンドを使用します。

    thrift -gen py /path/to/hbase/source/hbase-VERSION/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift
    

    次に、Thriftとそのプロトコルに接続するためのすべてのクラスを含む言語のThriftコードを取得する必要があります。このコードは/path/to/thrift/thrift-0.9.0/lib/py/src/にあります。

    HBaseThriftを使用するPythonプロジェクトを作成するために実行したコマンドは次のとおりです。

    $ mkdir HBaseThrift
    $ cd HBaseThrift/
    $ thrift -gen py ~/Downloads/hbase-0.94.2-cdh4.2.0/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift
    $ mv gen-py/* .           
    $ rm -rf gen-py/
    $ mkdir thrift
    $ cp -rp ~/Downloads/thrift-0.9.0/lib/py/src/* ./thrift/
    

    参照できるように、プロジェクトにHbase.thriftファイルのコピーを保持するのが好きです。さまざまな呼び出し、データオブジェクト、および戻りオブジェクトに関する多くの「Javadoc」があります。

    $ cp ~/Downloads/hbase-0.94.2-cdh4.2.0/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift
    

    ボイラープレートコード

    すべてのPythonThriftスクリプトが非常によく似ていることがわかります。それぞれの部分を見ていきましょう。

    from thrift.transport import TSocket
    from thrift.protocol import TBinaryProtocol
    from thrift.transport import TTransport
    from hbase import Hbase
    

    これらは、必要なThriftおよびHBaseモジュールをインポートします。

    # Connect to HBase Thrift server
    transport = TTransport.TBufferedTransport(TSocket.TSocket(host, port))
    protocol = TBinaryProtocol.TBinaryProtocolAccelerated(transport)
    

    これにより、ソケットトランスポートと回線プロトコルが作成され、ThriftクライアントがThriftサーバーに接続して通信できるようになります。

    # Create and open the client connection
    client = Hbase.Client(protocol)
    transport.open()
    
    を作成して開きます

    これらの行は、HBaseとの対話に使用するClientオブジェクトを作成します。このクライアントオブジェクトから、すべてのGetsとPutsを発行します。次に、Thriftサーバーへのソケットを開きます。

    # Do Something
    

    次に、実際にHBaseクライアントを操作します。すべてが構築され、初期化され、接続されます。まず、クライアントの使用を開始します。

    transport.close()
    

    最後に、トランスポートを閉じます。これにより、ソケットが閉じられ、Thriftサーバー上のリソースが解放されます。コピーと貼り付けを簡単にするためのコード全体は次のとおりです。

    from thrift.transport import TSocket
    from thrift.protocol import TBinaryProtocol
    from thrift.transport import TTransport
    from hbase import Hbase
    
    # Connect to HBase Thrift server
    transport = TTransport.TBufferedTransport(TSocket.TSocket(host, port))
    protocol = TBinaryProtocol.TBinaryProtocolAccelerated(transport)
    
    # Create and open the client connection
    client = Hbase.Client(protocol)
    transport.open()
    
    # Do Something
    
    transport.close()
    
    

    HBase ThriftのPython実装では、すべての値が文字列として渡されます。これには、整数のようなバイナリデータが含まれます。すべての列の値はTCellオブジェクトに保持されます。 Hbase.thriftファイルの定義は次のとおりです。

    struct TCell{
      1:Bytes value,
      2:i64 timestamp
    }
    
    

    Pythonコードが生成されたときの文字列への変更に注意してください:

    thrift_spec = (
        None, # 0
        (1, TType.STRING, 'value', None, None, ), # 1
        (2, TType.I64, 'timestamp', None, None, ), # 2
    )
    

    32ビット整数の処理を簡単にするためにヘルパーメソッドを作成しました。文字列間で整数を前後に変更するには、次の2つの方法を使用します。

    # Method for encoding ints with Thrift's string encoding
    def encode(n):
         return struct.pack("i", n)
    
    # Method for decoding ints with Thrift's string encoding
    def decode(s):
         return struct.unpack('i', s)[0]
    

    Thriftでバイナリデータを操作するときは、この注意事項に注意してください。バイナリデータを文字列に、またはその逆に変換する必要があります。

    エラーが発生しました

    Thriftインターフェースのエラーを理解するのは簡単ではありません。たとえば、テーブルが見つからない場合にPythonから発生するエラーは次のとおりです。

    Traceback (most recent call last):
      File "./get.py", line 17, in <module>
        rows = client.getRow(tablename, "shakespeare-comedies-000001")
      File "/mnt/hgfs/jesse/repos/DevHivePigHBaseVM/training_materials/hbase/exercises/python_bleets_thrift/hbase/Hbase.py", line 1038, in getRow
        return self.recv_getRow()
      File "/mnt/hgfs/jesse/repos/DevHivePigHBaseVM/training_materials/hbase/exercises/python_bleets_thrift/hbase/Hbase.py", line 1062, in recv_getRow
        raise result.io
    hbase.ttypes.IOError: IOError(_message='doesnotexist')
    

    ただし、HBase Thriftログファイルを確認できるため、すべてが失われるわけではありません。 CDHでは、このファイルは/var/log/hbase/hbase-hbase-thrift-localhost.localdomain.logにあります。欠落しているテーブルの例では、テーブルが存在しないことを示すエラーがThriftログに表示されます。不便ですが、そこからデバッグできます。

    次回の記事では、行の挿入と取得について説明します。

    ジェシーアンダーソンはCloudera大学のインストラクターです。


    1. MongoDBでコレクションを作成する

    2. Mongodb:show dbsがデータベースを表示しないのはなぜですか?

    3. セロリタスクを一時停止または再開するにはどうすればよいですか?

    4. ZeroMQのように、pubsubメッセージキューをRedisしますが、コールバックを使用します