HBase から Cloud Bigtable へのデータの移行

この記事では、Apache HBase クラスタから Google Cloud 上の Cloud Bigtable クラスタにデータを移行する際の考慮事項とプロセスについて説明します。

この移行を開始する前に、パフォーマンスへの影響、Bigtable のスキーマ設計、認証と認可の方法に対する影響や、Bigtable の機能セットについて検討する必要があります。

パフォーマンスへの影響

通常のワークロードの場合、Bigtable は、極めて予測可能性の高いパフォーマンスを実現します。すべてが問題なく動作している場合、Bigtable クラスタの各ノードは、クラスタで使用するストレージの種類に応じて、以下のパフォーマンスを実現すると予測されます。

ストレージの種類 読み取り   書き込み スキャン
SSD 6 ms で 10,000 行/秒 または 6 ms で 10,000 行/秒 220 MB/秒
HDD 200 ms で 500 行/秒 または 50 ms で 10,000 行/秒 180 MB/秒

このリストに示されている推定値は、1 KB のデータが格納されている行を基準としています。 また、読み取り専用または書き込み専用のワークロードを前提としています。読み取りと書き込みの両方を行うワークロードの場合は、パフォーマンスが異なります。

これらのパフォーマンスはガイドライン的な数値であって、厳格なルールというわけではありません。 ノードごとのパフォーマンスは、ワークロードや、リクエスト値またはレスポンス値の一般的なサイズによって異なる場合があります。詳細については、Bigtable のパフォーマンスについてをご覧ください。

Bigtable のスキーマ設計

Bigtable のスキーマ設計は、リレーショナル データベースのスキーマ設計とは異なります。スキーマを設計する際は、事前にスキーマの設計に記載されたコンセプトを確認してください。

また、スキーマは推奨のサイズ制限に従う必要があります。 ガイドラインとしては、単一行を 100 MB 未満に、単一値を 10 MB 未満に維持します。シナリオによっては、大きな値の格納が必要な場合もあります。大きな値の抽出は時間とメモリの両方を消費するため、このような値の格納はパフォーマンスに影響を及ぼす場合があります。これに該当するようなシナリオは、ケースバイケースで評価します。

認証と認可

Bigtable のアクセス制御を設計する際は、あらかじめ既存の HBase の認証と認可に関するプロセスを確認しておきます。

Bigtable では Google Cloud の標準の認証メカニズムと Identity and Access Management を使用してアクセスが制御されるため、HBase 上の既存の承認を IAM に変換します。HBase のアクセス制御メカニズムを備えた既存の Hadoop グループを異なるサービス アカウントにマッピングできます。

Bigtable では、プロジェクト、インスタンス、テーブルのレベルでアクセスを制御できます。詳しくは、アクセス制御をご覧ください。

HBase から Bigtable への移行

HBase から Bigtable にデータを移行するには、一連の Hadoop シーケンス ファイルとしてデータをエクスポートします。これは、HBase で使用されるファイル形式で、バイナリの Key-Value ペアで構成されます。

HBase テーブルを Bigtable に移行する手順は次のとおりです。

  1. HBase から詳細を収集します。
  2. HBase テーブルをシーケンス ファイルにエクスポートします。
  3. シーケンス ファイルを Cloud Storage に移行します。
  4. Dataflow を使用して、シーケンス ファイルを Bigtable にインポートします。
  5. 移行を検証します。

移行を計画する: HBase の詳細を収集する

移行の準備を行うには、転送先テーブルの構築に必要な情報として、既存の HBase クラスタから次の情報を収集します。

  • テーブルのリスト
  • 行数
  • セル数
  • 列ファミリーの詳細(有効期間、最大バージョン数など)

次のスクリプトを使用すると、簡単な方法で転送元テーブルからこれらの詳細を収集できます。このスクリプトは HDFS 上に結果を残します。

#!/usr/bin/env bash
# Table Name is the Source HBase Table Name
TABLENAME="$1"
# Export Directory will be located on HDFS
EXPORTDIR="$2"
hadoop fs -mkdir -p ${EXPORTDIR}
hbase shell << EOQ
describe ${TABLENAME}
EOQ | hadoop fs -put - ${EXPORTDIR}/${TABLENAME}-schema.json
hbase shell << EOQ
get_splits ${TABLENAME}
EOQ | hadoop fs -put - ${EXPORTDIR}/${TABLENAME}-splits.txt

HBase テーブルを Cloud Storage にエクスポートする

移行対象の HBase テーブルの基本情報を把握できたら、テーブルをシーケンス ファイルにエクスポートして、そのファイルを Cloud Storage に移行する必要があります。オンライン データの移行処理を開始する前に、次の手順を実行して、クラスタが Google Cloud にアクセスするための前提条件を満たしていることを確認します。

  • Cloud Storage コネクタをインストールする

    distcp を使用してオンライン データを移行する場合は、Cloud Storage コネクタをインストールして構成する必要があります。まず、移行するデータを管理する HDFS ファイル システムを確認します。次に、Hadoop クラスタ内のどのクライアント ノードが、このファイル システムにアクセスできるかを判定します。最後に、クライアント ノードにコネクタをインストールします。インストール手順の詳細については、Cloud Storage コネクタのインストールをご覧ください。

  • Cloud SDK をインストールする

    distcp または gsutil のいずれかを使用してデータを移行するには、移行が開始される Hadoop クラスタのクライアント ノードに Cloud SDK をインストールします。インストール手順の詳細については、Cloud SDK のドキュメントをご覧ください。

HBase テーブルを HDFS にエクスポートする

次に、移行する HBase テーブルを Hadoop クラスタのいずれかの場所にエクスポートします。HBase テーブルの名前が [MY_NEW_TABLE] であるとします。ターゲット ディレクトリは、HDFS のユーザー ディレクトリの下にあります。 次のコマンドを使用して、HBase テーブルをシーケンス ファイルとしてエクスポートします。

TABLENAME="my-new-table"
EXPORTDIR=/usr/[USERNAME]/hbase-${TABLENAME}-export
hadoop fs -mkdir -p ${EXPORTDIR}
MAXVERSIONS=2147483647
cd ${HBASE_HOME}
bin/hbase org.apache.hadoop.hbase.mapreduce.Export my-new-table \
    /user/hbase-${TABLENAME} \
    -export ${MAXVERSIONS}
bin/hbase org.apache.hadoop.hbase.mapreduce.Export \
    -Dmapred.output.compress=true \
    -Dmapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec \
    -DRAW_SCAN=true \
    -Dhbase.client.scanner.caching=100 \
    -Dmapred.map.tasks.speculative.execution=false \
    -Dmapred.reduce.tasks.speculative.execution=false \
    ${TABLENAME} ${EXPORTDIR} ${MAXVERSIONS}

HDFS から Cloud Storage へシーケンス ファイルを移行する

次のステップでは、シーケンス ファイルを Cloud Storage バケットに移動します。データのサイズ、ファイル数、データのソース、および使用可能な帯域幅に応じて、Transfer Appliance、distcpgsutil、Storage Transfer Service から適切なオプションを選択してシーケンス ファイルを Cloud Storage に移動できます。

Transfer Appliance の使用

次に該当する場合は Transfer Appliance を使用してデータを移行します。

  • スケジュールに沿って送信帯域幅を制御する必要がある場合。
  • データのサイズが 20 TB を超えている場合。

このオプションを使用すると、Google で追加のネットワークを購入したり、プロビジョニングしたりする必要はありません。エンドツーエンドの転送時間(アプライアンスの発送時間、リハイドレートなど)は平均 100 Mbps です。

Transfer Appliance でデータを移行するには、シーケンス ファイルをアプライアンスにコピーしてから Google に戻します。Google によって Google Cloud にデータが読み込まれます。詳細については、Transfer Appliance のドキュメントをご覧ください。

distcp の使用

次に該当する場合は、distcp を使用してデータを移行します。

  • 100 Mbps 以上の帯域幅を移行に利用できる場合。
  • Cloud Storage コネクタと Cloud SDK をソースの Hadoop 環境にインストールできる場合。
  • データ移行を実施するための新規の Hadoop ジョブの管理を許容できる場合。
  • データのサイズが 20 TB 未満の場合。

distcp を使用してデータを移動するには、Cloud Storage コネクタを使用して構成された Hadoop クラスタのクライアント ノードを使用して MapReduce ジョブを送信し、シーケンス ファイルを Cloud Storage にコピーします。

hadoop distcp hdfs://[NAMENODE]:[NAMENODE_PORT]/[SOURCE_DIRECTORY] \
gs://[BUCKET]/DESTINATION_DIRECTORY]

gsutil の使用

次に該当する場合は、gsutil を使用してデータを移行します。

  • 100 Mbps 以上の帯域幅を移行に利用できる場合。
  • ソースの Hadoop 環境に Cloud SDK をインストールできる場合。
  • データ移行を実施するための新規の Hadoop ジョブの管理を許容できない場合。
  • データのサイズが 10 TB 未満の場合。

gsutil を使用してデータを移動するには、Hadoop クラスタのクライアント ノードを使用してデータ移行を開始します。

TABLENAME="my-new-table"
EXPORTDIR=/usr/[USERNAME]/hbase-${TABLENAME}-export
gsutil -m cp -r  ${EXPORTDIR} gs://[BUCKET]

Storage Transfer Service の使用

次に該当する場合は、Storage Transfer Service を使用してデータを移行します。

  • データソースが Amazon S3 バケット、HTTP / HTTPS の場所、または Cloud Storage バケットである場合。
  • データのサイズが 10 TB 未満の場合。

Storage Transfer Service には、データソースとデータシンクの間の転送や同期を容易にするオプションが用意されています。たとえば、次のような操作が可能です。

  • 1 回限りの転送オペレーションまたは定期的な転送オペレーションをスケジュールする。
  • 転送先バケット内に存在しているオブジェクトのうち、転送元に対応するオブジェクトがないものを削除する。
  • 転送したソース オブジェクトを削除する。
  • ファイル作成日、ファイル名フィルタ、データをインポートする時刻に基づいた高度なフィルタを使用して、データソースからデータシンクへの定期的な同期をスケジュールする。

詳細については、こちらの Storage Transfer Service のドキュメントをご覧ください。

転送先テーブルを作成する

次のステップでは、Bigtable に転送先テーブルを作成します。

まず、gcloud コマンドライン ツールを使用して Bigtable クライアント ツール cbt をインストールします。

gcloud components update
gcloud components install cbt

次に、Bigtable で、前の手順の検出作業で取得した適切な列ファミリーを使用してテーブルを作成します。

既存の分割を使用して、転送先テーブルを作成する際にテーブルを事前に分割します。この処理により、一括読み込みのパフォーマンスが向上します。

たとえば、既存の分割が次のとおりであるとします。

'15861', '29374', '38173', '180922', '203294', '335846', '641111', '746477', '807307', '871053', '931689', '1729462', '1952670', '4356485', '4943705', '5968738', '6917370', '8993145', '10624362', '11309714', '12056747', '12772074', '14370672', '16583264', '18835454', '21194008', '22021148', '23702800', '25532516', '55555555'

次に、使用するユーザー アカウントで以下に示すように cbt ツールのデフォルトのプロジェクトと Bigtable インスタンスを設定します。

$ cat > ${HOME}/.cbtrc << EOF
project = [YOUR-GCP-PROJECT]
instance = [BIGTABLE-INSTANCE-NAME]
EOF

転送先テーブルに次のような分割を作成します。

cbt -instance my-instance createtable my-new-table \
splits=15861,29374,38173,180922,203294,335846,641111,746477,807307,871053,931689,\
1729462,1952670,4356485,4943705,5968738,6917370,8993145,10624362,11309714,\
12056747,12772074,14370672,16583264,18835454,21194008,22021148,23702800,\
5532516,55555555

転送先テーブルで、前の手順で検出した列ファミリーと一致する列ファミリーを作成します。 たとえば、cf1cf2 の 2 つの列ファミリーが存在することを検出した場合は、Bigtable で次のように列ファミリー cf1 を作成します。

cbt createfamily my-new-table cf1

次のように列ファミリー cf2 を作成します。

cbt createfamily my-new-table cf2

列ファミリーを作成した後、各列ファミリーのガベージ コレクション ポリシー(対象列ファミリーの値の最長存続期間と最大バージョン数など)を更新することが重要です。Bigtable のネイティブ ツールは HBase とは異なるデフォルト設定を使用するため、HBase のデフォルト設定を HBase テーブルに使用した場合でも、これを実行する必要があります。

cbt setgcpolicy [TABLE] [FAMILY] ( maxage=[D]| maxversions=[N] )

Dataflow を使用して HBase データを Bigtable にインポートする

Bigtable には、2 種類の方法でデータをインポートできます。詳細については、Bigtable ドキュメントのシーケンス ファイルのインポートをご覧ください。

以下のヒントにご留意ください。

  • データ読み込みのパフォーマンスを改善するには、maxNumWorkers を設定するようにしてください。この値によって、インポート ジョブを妥当な時間内に完了するのに十分なコンピューティング能力を使用しつつ、過大な能力の使用によって Bigtable クラスタを圧迫することを回避できるようになります。

  • インポート中は、Bigtable クラスタの CPU 使用率をモニタリングする必要があります。このトピックの詳細については、Bigtable モニタリング ドキュメントの CPU 使用率のセクションをご覧ください。Bigtable クラスタ全体の CPU 使用率が高すぎる場合は、ノードの追加が必要になる可能性があります。クラスタが追加ノード分のパフォーマンスを発揮するまでには、最大 20 分かかることがあります。

Bigtable インスタンスのモニタリングの詳細については、Bigtable インスタンスのモニタリングをご覧ください。

Bigtable 内でインポートされたデータを確認する

インポートされたデータを検証するには、数種類のチェックを使用できます。

  • 行数の一致の確認。Dataflow ジョブは、合計行数をレポートします。この値は、転送元の HBase テーブルの行数と一致している必要があります。
  • 特定の行クエリによるスポットチェック。転送元テーブルから特定の行キーのセットを選択し、転送先テーブルでそれらに対するクエリを実行して、一致していることを確認できます。
cbt lookup [destination-table] [rowkey1]
cbt lookup [destination-table] [rowkey2]

次のステップ