7 HBaseハンドラの使用

HBaseハンドラを使用して、既存のOracle GoldenGateでサポートされているソースからHBase表に移入する方法について説明します。

トピック:

7.1 概要

HBaseは、リレーショナル・データベース管理システム(RDBMS)の機能をほとんどエミュレートできるオープン・ソースのビッグ・データ・アプリケーションです。Hadoopは、大量の非構造化データを格納する目的で設計されています。逆に、データベースに格納され、Oracle GoldenGateを通じて複製されるデータは、高度に構造化されています。HBaseには、データの重要な構造を維持しながら、Hadoop分散ファイル・システム(HDFS)によって提供される水平方向のスケーリングの利点を活かす方法があります。

7.2 詳細な機能

HBaseハンドラは、ソース証跡ファイルから操作を取得し、対応する表をHBaseに作成してから、変更取得データをその表にロードします。

HBase表名

HBaseに作成される表名は、ソース証跡ファイルからの操作の対応する表名にマップされます。表名では、大文字と小文字が区別されます。

HBase表のネームスペース

2部構成の表名(スキーマ名と表名)の場合、スキーマ名はHBase表のネームスペースにマップされます。Catalog.Schema.MyTableのような3部構成の表名の場合、作成されるHBaseネームスペースはCatalog_Schemaとなります。HBase表のネームスペースは大/小文字が区別されます。NULLスキーマ名がサポートされており、デフォルトのHBaseネームスペースにマップされます。

HBase行キー

HBaseには、データベースの主キーと似たHBase行キーという概念があります。HBase行キーは、表の行を示す一意の識別子です。HBaseがサポートするのは1行当たり1つの行キーのみで、空またはNULLにはできません。HBaseハンドラは、主キー値をHBase行キー値にマップします。ソース表に複数の主キーがある場合、主キー値は連結され、パイプ区切り文字(|)で区切られます。HBase行キーの区切り文字を構成できます。

ソース表には、少なくとも1つの主キー列が必要です。主キーのない表を複製すると、HBaseハンドラが異常終了します。

HBaseの列ファミリ

HBaseには、列ファミリという概念があります。列ファミリは、列データをグループ化する方法です。サポートされるのは、1つの列ファミリのみです。HBaseの各列は、1つの列ファミリに属している必要があります。HBaseハンドラには、表ごとに1つの列ファミリがあり、デフォルトはcfです。列ファミリ名を構成できます。ただし、特定の列ファミリ名で表を作成した場合は、HBaseサンプルで列ファミリ名を再構成できません。先にその表を変更または削除しないと、Oracle GoldenGate Replicatプロセスが異常終了します。

7.3 HBaseハンドラの設定および実行

HBaseは、HBaseハンドラ・プロセスと同じ場所に配置して稼働しているか、HBaseハンドラ・プロセスをホストしているネットワークから接続できるマシン上で稼働している必要があります。また、HBaseデータのリポジトリとして機能している、基礎となるHDFSの単一インスタンスまたはクラスタ化されたインスタンスが稼働している必要があります。

ここでは、HBaseハンドラのコンポーネントの構成およびハンドラの実行について説明します。

トピック:

7.3.1 クラスパス構成

HBaseハンドラをHBaseに接続してデータをストリーミングするには、hbase-site.xmlファイルおよびHBaseクライアントjarが、gg.classpath変数で構成されている必要があります。HBaseクライアントjarは、HBaseハンドラが接続するHBaseのバージョンと一致する必要があります。HBaseクライアントjarは、Oracle GoldenGate for Big Data製品に付属しません。

バージョンごとに必要なHBaseクライアントjarのリストは、「HBaseハンドラ・クライアント依存性」を参照してください。

hbase-site.xmlファイルのデフォルトの場所は、HBase_Home/confです。

HBaseクライアントJARのデフォルトの場所は、HBase_Home/lib/*です。

HBaseハンドラがWindowsで実行されている場合は、Windowsのクラスパス指定構文に従います。

gg.classpathは、説明に従って正確に構成する必要があります。hbase-site.xmlファイルのパスには、ワイルドカードが付加されていないパスのみを使用してください。hbase-site.xmlファイルのパスにワイルドカード(*)を含めると、アクセスできなくなります。逆に、依存関係jarのパスには、そのディレクトリにあるjarファイルがすべて関連するクラスパスに含まれるように、ワイルドカード(*)を含める必要があります。*.jarは使用しないでください。正しく構成されたgg.classpath変数の例を次に示します。

gg.classpath=/var/lib/hbase/lib/*:/var/lib/hbase/conf

7.3.2 HBaseハンドラ構成

HBaseハンドラの構成可能な値は次のとおりです。これらのプロパティは、Javaアダプタ・プロパティ・ファイルにあります(Replicatプロパティ・ファイルにはありません)。

HBaseハンドラの選択を有効にするには、まずgg.handler.jdbc.type=hbaseを指定してハンドラ・タイプを構成してから、次に示す他のHBaseプロパティを構成する必要があります。

表7-1 HBaseハンドラの構成プロパティ

プロパティ 必須/オプション 有効な値 デフォルト 説明

gg.handlerlist

必須

任意の文字列。

なし

HBaseハンドラの名前を指定します。HBaseハンドラ名は、この表にリストしたプロパティ名の一部になります。

gg.handler.name.type

必須

hbase

なし

HBaseハンドラを選択し、変更データ取得をHBaseにストリーミングします

gg.handler.name.hBaseColumnFamilyName

オプション

HBase列ファミリ名として有効な任意の文字列。

cf

列ファミリは、HBaseで列をグループ化するメカニズムです。12.2リリースでは、HBaseハンドラは1つの列ファミリのみサポートします。

gg.handler.name.includeTokens

オプション

true | false

false

trueの使用は、HBaseの出力にトークン値が含まれることを示します。falseを使用すると、トークン値は含まれません。

gg.handler.name.keyValueDelimiter

オプション

任意の文字列。

=

マップにおけるキーと値の間の区切り文字を指定します。たとえば、key=value,key1=value1,key2=value2となります。トークンはマップされた値です。構成値はCDATA[]ラッピングをサポートします。

gg.handler.name.keyValuePairDelimiter

オプション

任意の文字列。

,

マップにおけるキー/値ペアの間の区切り文字を指定します。たとえば、key=value,key1=value1,key2=value2key=value,key1=value1,key2=value2となります。トークンはマップされた値です。構成値はCDATA[]ラッピングをサポートします。

gg.handler.name.encoding

オプション

Javaでサポートされるエンコーディング名または別名脚注1。サポートされるオプションのリストは、https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.htmlを参照してください。

Oracle GoldenGateプロセスをホストしているマシンのネイティブのシステム・エンコーディング

HBaseに書き込まれる値のエンコーディングを決めます。HBase値はバイトとして書き込まれます。

gg.handler.name.pkUpdateHandling

オプション

abend | update | delete-insert

abend

HBaseハンドラが、主キーを変更する更新操作をどのように処理するかに関する構成を指定します。主キーを操作するとHBaseハンドラで問題が起きることがあるので、ユーザーは特に慎重を期する必要があります。

  • abend: プロセスが異常終了することを示します。

  • update: プロセスでこれが通常の更新として扱われることを示します

  • delete-insert: プロセスでこれが削除および挿入として扱われることを示します。この機能が正常に動作するためには、完全な操作前イメージが必要です。そのためには、Oracleデータベースで完全なサプリメンタル・ロギングを使用します。操作前と操作後の完全な行イメージがない場合、挿入データは不完全になります。

gg.handler.name.nullValueRepresentation

オプション

任意の文字列。

NULL

列の値がNULLの場合にHBaseに送信される内容を構成できます。デフォルトはNULLです。構成値はCDATA[]ラッピングをサポートします。

gg.handler.name.authType

オプション

kerberos

なし

このプロパティをkerberosに設定すると、Kerberos認証が有効になります。

gg.handler.name.kerberosKeytabFile

オプション(authType=kerberosの場合は必須)

Kerberos keytabファイルの相対パスまたは絶対パス

-

keytabファイルを使用すると、HDFSハンドラがパスワードにアクセスし、Kerberosセキュリティに対してkinit操作を実行できます。

gg.handler.name.kerberosPrincipal

オプション(authType=kerberosの場合は必須)

user/FQDN@MY.REALMなどの有効なKerberosプリンシパル名。

-

Kerberos認証で用いるKerberosプリンシパル名。

gg.handler.name.hBase98Compatible 

オプション

true | false

false

この構成プロパティをtrueに設定して、HBase 0.98.xおよび0.96.xリリースとの統合を有効にします。

gg.handler.name.rowkeyDelimiter 

オプション

任意の文字列/

|

HBase Rowkeyが生成されるときに、ソース表からの主キー値の間に区切り文字が構成されます。このプロパティは値のCDATA[]ラッピングをサポートし、ユーザーが受信した主キー値を空白と判断される1つ以上の文字で区切る場合に空白を維持します。

gg.handler.name.setHBaseOperationTimestamp

オプション

true | false

false

trueに設定すると、HBaseがサーバー側でタイムスタンプを割り当てるのではなく、HBaseハンドラでHBase操作のタイムスタンプを設定します。このプロパティを使用すると、行削除の直後に再挿入した行がHBaseに表示されないという問題を解決できます(「HBaseハンドラの削除-挿入の問題」を参照)。

gg.handler.name.omitNullValues

オプション

true | false

false

trueに設定すると、nullフィールドが書き込まれなくなります。

脚注1

https://docs.oracle.com/javase/8/docs/technotes/guides/intl/Java国際化のサポートを参照してください。

7.3.3 サンプル構成

Javaアダプタ・プロパティ・ファイルからのHBaseハンドラの構成例を次に示します。

gg.handlerlist=hbase
gg.handler.hbase.type=hbase
gg.handler.hbase.mode=tx
gg.handler.hbase.hBaseColumnFamilyName=cf
gg.handler.hbase.includeTokens=true
gg.handler.hbase.keyValueDelimiter=CDATA[=]
gg.handler.hbase.keyValuePairDelimiter=CDATA[,]
gg.handler.hbase.encoding=UTF-8
gg.handler.hbase.pkUpdateHandling=abend
gg.handler.hbase.nullValueRepresentation=CDATA[NULL]
gg.handler.hbase.authType=none

7.3.4 パフォーマンスに関する考慮事項

トランザクションをコミットするたびに、HBaseハンドラがフラッシュ・コールを実行し、バッファされていたデータをHBaseリージョン・サーバーにフラッシュします。書込み永続性を維持するために、これを実行する必要があります。HBaseリージョン・サーバーへのフラッシュは負荷の高いコールなので、Replicat GROUPTRANSOPSパラメータを使用して、ソース証跡ファイルの複数の小さいトランザクションを、HBaseに適用される1つの大きいトランザクションにグループ化すると、パフォーマンスが大幅に向上することがあります。Replicat構成ファイルで構成構文を追加すると、Replicatベースのバッチ処理を使用できます。

複数のトランザクションからの操作は、大きいトランザクションにまとめられますが、これはトランザクションがコミットされたグループ化されたトランザクションの最後だけです。

7.4 セキュリティ

HBase接続は、Kerberos認証を使用して保護できます。HBaseクラスタを保護するには、HBaseリリースの関連するドキュメントに従ってください。HBaseハンドラは、Kerberosで保護されたクラスタに接続できます。HBase hbase-site.xmlがハンドラのクラスパスにあり、hbase.security.authenticationプロパティをkerberosに、hbase.security.authorizationプロパティをtrueに設定する必要があります。

クラスパスにHDFS core-site.xmlファイルを含むディレクトリが含まれている必要があります。Kerberos認証は、Hadoop UserGroupInformationクラスを使用して実行されます。このクラスは、kinitコマンドを正常に実行するために、kerberosに設定されるHadoop構成プロパティhadoop.security.authenticationに依存しています。

また、HBaseハンドラのJava構成ファイルで次のプロパティを設定する必要があります。

gg.handler.{name}.authType=kerberos
gg.handler.{name}.keberosPrincipalName={legal Kerberos principal name}
gg.handler.{name}.kerberosKeytabFile={path to a keytab file that contains the password for the Kerberos principal so that the Oracle GoldenGate HDFS handler can programmatically perform the Kerberos kinit operations to obtain a Kerberos ticket}.

keytabファイルからKerberosパスワードを復号化できない場合があります。これによって、Kerberos認証が対話型モードにフォール・バックされ、プログラムで呼び出されているため機能しなくなります。この問題の原因は、Java Cryptography Extension (JCE)が、Java Runtime Environment (JRE)にインストールされていないことです。JCEがJREにロードされていることを確認します。http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.htmlを参照してください。

7.5 メタデータ変更イベント

Oracle GoldenGate 12.2は、証跡にメタデータを含み、実行時にメタデータ変更イベントを処理できます。HBaseハンドラも、実行時にメタデータ変更イベントを処理できます。最も一般的なシナリオの1つは、新しい列の追加です。HBaseでの結果としては、メタデータ変更イベントの後に、新しい列とそれに関連するデータがストリーミングされます。

メタデータ変更イベントを有効にするには、レプリケーション・チェーン全体をOracle GoldenGate 12.2にアップグレードする必要があることに注意してください。12.2のHBaseハンドラは、Oracle GoldenGate 12.1以降で生成された証跡ファイルを処理できます。ただし、これらの証跡ファイルには証跡のメタデータが含まれていないため、メタデータ変更イベントを実行時には処理できません。

7.6 その他の考慮事項

HBaseは、過去数回のリリースでクライアント・インタフェースが変更されています。HBase 1.0.0では、推奨されるクライアント・インタフェースが新たに導入され、12.2のHBaseハンドラは、最新の変更に対応するように、新しいインタフェースに移行しました。ただし、これで下位互換性の問題は発生しません。HBaseハンドラは、1.0.0より古いバージョンのHBaseとは互換性がありません。Oracle GoldenGateが、0.99.x以下のバージョンのHBaseとの統合を必要とする場合には、12.1.2.1.xのHBaseハンドラを使用する必要があります。12.1.2.1.xのHBaseハンドラのZIPファイルが必要な場合には、Oracleサポートに連絡してください。

HBaseハンドラの初期設定でよくある問題は、クラスパスです。これを典型的に示しているのが、Java log4jログ・ファイルに出現するClassNotFoundExceptionです。HBaseクライアントjarは、Oracle GoldenGate for Big Dataには付属しません。必要なHBaseクライアントjarを解決する必要があります。「HBaseハンドラ・クライアント依存性」には、サポートされている各バージョンのHBaseクライアントjarのリストがあります。hbase-site.xml、または1つ以上の必須のクライアントJARがクラスパスに含まれていません。HBaseハンドラのクラスパスの構成については、「クラスパス構成」を参照してください。

7.7 HBaseハンドラのトラブルシューティング

HBaseハンドラのトラブルシューティングは、Java log4jファイルの内容から始まります。Javaロギング構成にある指示に従って、Java log4jログ・ファイルを正しく生成するようにランタイムを構成してください。

トピック:

7.7.1 Javaクラスパス

Javaクラスパスの問題が一般的です。Java log4jログ・ファイルのClassNotFoundExceptionは、クラスパスに問題があることを示しています。Java log4jログ・ファイルを使用して、この問題のトラブルシューティングを行うことができます。ログ・レベルをDEBUGに設定すると、gg.classpathオブジェクトで参照されているjarそれぞれがログ・ファイルに記録されます。DEBUGレベルのロギングを有効にし、ログ・ファイルで次のようなメッセージを探すと、必要な依存関係jarがすべて解決されることを確認できます。

2015-09-29 13:04:26 DEBUG ConfigClassPath:74 -  ...adding to classpath:
 url="file:/ggwork/hbase/hbase-1.0.1.1/lib/hbase-server-1.0.1.1.jar"

7.7.2 HBase接続プロパティ

HDFS hbase-site.xmlファイル(デフォルト設定を含んでいる)の内容は、ロギング・レベルを DEBUGまたはTRACEに設定している場合に、Java log4jログ・ファイルに出力されます。このファイルには、HBaseへの接続プロパティが示されます。Javaのlog4jログ・ファイルで次のものを検索します。

2015-09-29 13:04:27 DEBUG HBaseWriter:449 - Begin - HBase configuration object contents for connection troubleshooting. 
Key: [hbase.auth.token.max.lifetime] Value: [604800000].

一般的に、hbase-site.xmlファイルがクラスパスに含まれていないか、hbase-site.xmlファイルのパスが正しくありません。この場合、HBaseハンドラはHBaseへの接続を確立できず、Oracle GoldenGateプロセスは異常終了します。Java log4jログでは、次のエラーが報告されます。

2015-09-29 12:49:29 ERROR HBaseHandler:207 - Failed to initialize the HBase handler.
org.apache.hadoop.hbase.ZooKeeperConnectionException: Can't connect to ZooKeeper

クラスパスに正しくhbase-site.xmlファイルが含まれており、HBaseが稼働していることを確認してください。

7.7.3 ハンドラ構成のロギング

Javaのlog4jログ・ファイルには、HBaseハンドラの構成状態に関する情報が含まれています。この情報は、INFOログ・レベルで出力されます。次に、サンプルの出力を示します。

2015-09-29 12:45:53 INFO HBaseHandler:194 - **** Begin HBase Handler - Configuration Summary ****
  Mode of operation is set to tx.
  HBase data will be encoded using the native system encoding.
  In the event of a primary key update, the HBase Handler will ABEND.
  HBase column data will use the column family name [cf].
  The HBase Handler will not include tokens in the HBase data.
  The HBase Handler has been configured to use [=] as the delimiter between keys and values.
  The HBase Handler has been configured to use [,] as the delimiter between key values pairs.
  The HBase Handler has been configured to output [NULL] for null values.
Hbase Handler Authentication type has been configured to use [none]

7.7.4 HBaseハンドラの削除-挿入の問題

gg.handler.name.setHBaseOperationTimestamp=true構成プロパティなしでHBaseハンドラを使用している場合、ソース・データベースがHBaseの表内のデータと同期しなくなることがあります。これは、行の削除に続く、その行の即時再挿入が原因で発生します。HBaseでは、特定のタイムスタンプで識別される、削除用のツームストン・マーカーが作成されます。このツームストン・マーカーは、HBase内の同じ行キーを持つすべての行レコードに削除のマークを付け、これらのレコードにはツームストン・マーカーよりも前か、または同じタイムスタンプが付いています。これは、削除された行がすぐに再挿入されたときに発生します。挿入操作にたまたま削除操作と同じタイムスタンプがあると、その削除操作によって後続の挿入操作が誤って削除されたように見えることがあります。

この問題を回避するには、gg.handler.name.setHbaseOperationTimestamp=trueに設定する必要があり、これは次の2つのことを行います。

  • HBaseハンドラの行操作用のタイムスタンプの設定。

  • 挿入操作がその挿入の後のタイムスタンプを持つことを保証する、削除-挿入操作の検出。

gg.handler.name.setHbaseOperationTimestampのデフォルトはfalseで、これは、HBaseサーバーが行のタイムスタンプを提供することを意味します。これは、同期外れの問題を引き起こす可能性があります。

HBaseハンドラで行操作のタイムスタンプを設定すると、次のような結果になります。

  1. タイムスタンプがクライアント側で設定されているため、複数のアプリケーションが同じHBase表にデータをフィードしている場合に問題が発生する可能性があります。

  2. 削除と再挿入がユースケースの一般的なパターンである場合、HBaseハンドラでは、このシナリオに遭遇するたびにタイムスタンプを1ミリ秒増分する必要があります。

処理をあまり先送りにはできないため、HBaseハンドラでは、プロセスを待機させる前にタイムスタンプを100ミリ秒未来に進めることのみを許し、クライアント側のHBase操作のタイムスタンプと実際の時間との同期が戻るようにしています。ソース・データベースで更新のかわりに削除-挿入が使用される場合、この同期シナリオはよくあることです。このシナリオが一般的な場合、未来に向けて100ミリ秒を超えるHBaseのタイムスタンプが許されないことが処理速度に影響する可能性があります。

7.7.5 Cloudera CDHのHBase互換性

Cloudera CDHは、CDH 5.4.0バージョンでHBase 1.0.0に移行しました。HBase 0.98.x以前との互換性を維持するため、CDHのHBaseクライアントはApache HBase 1.0.0とのバイナリ互換性を放棄しました。これにより、CDHバージョン5.4 - 5.11のCloudera CDH HBaseに接続する場合に、HBaseハンドラとの互換性の問題が発生しました。この問題の解決には、旧0.98 HBaseインタフェースを使用して次の構成パラメータを設定することをお薦めします。

gg.handler.name.hBase98Compatible=true 

この互換性の問題は、Javaリフレクションを使用して解決されます。HBaseハンドラを使用してCDH 5.4xに接続する場合は、HBaseハンドラの構成プロパティを次のように変更する必要があります。

gg.handler.name.hBase98Compatible=false

デフォルト値はfalseなので、プロパティそのものを省略することもできます。