hadoop-logo
ようこそ Tech blogへ!
「これからHadoopを勉強しよう」という方はまず下記のページから

サイトの移行に伴って画像が表示されないなどの不具合が生じています

HBase 2.x でのテーブルエクスポート

HBase

HBaseのエクスポート機能

HBase にはバックアップを取る方法がいくつか存在しますが、その一つにテーブルをファイル(SequenceFile 形式)にエクスポートする機能があります。この機能を用いてテーブルをバックアップしておき、インポートして復旧することが可能です。エクスポート機能はバージョン (versions)と時間範囲(starttime, endtime) を指定できるので、特定の時間のデータだけのバックアップが可能です。しかしエクスポート機能はMapReduceを用いて実装されていたため、実行中はクラスターに負荷がかかっていました。

エクスポート機能はかなり以前から実装されている機能ですが、HBase 2.x では MapReduce以外にHBaseのコプロセッサーが利用できるようになりました。

Apache HBase ™ Reference Guide

コプロセッサーは大まかにいうと RDBMS のストアドプロシージャーのような機能で、リージョンサーバー上で処理を実行します。このコプロセッサー版のエクスポート機能を使うメリットとして

  • MapReduceの起動コストがないため、リージョン数にもよるが、数が少なければ早い(軽い)
  • MapReduceを使わないため、実行中にクラスターのリソースが消費されない

というメリットがあります。逆に、コプロセッサー版には

  • 耐障害性がない

というデメリットがあります。リージョン数が増えたときのスケーラビリティも気になりますね。主に自分用ですが、参考までにHBase のドキュメントを意訳してみました。

 エンドポイント(コプロセッサー)ベースのエクスポートMapReduceベースのエクスポート
HBaseのバージョン要件2.0以降0.2.1以降
Mavenの依存関係hbase-endpointhbase-mapreduce (2.0以降)、hbase-server (2.0未満)
ダンプ前の要件ターゲットのテーブルでコプロセッサーをマウントしておくMapReduceフレームワークをデプロイ
読み込みの遅延低い: リージョンから直接データを読み込む普通: 通常のRPCスキャン
読み込みのスケーラビリティリージョンの数に依存Mapperの数に依存 (TableInputFormatBase#getSplitを参照)
タイムアウト操作のタイムアウト。hbase.client.operation.timeout により設定スキャンのタイムアウト。hbase.client.scanner.timeout.periodによって設定
パーミッションの要件読み込み、実行読み込み
フォールトトレランスなしMapReduceに依存

エクスポート機能の注意点として、デフォルトではセルに複数のバージョンがあったとしても、最新のバージョンのみがエクスポートされるということです。複数のバージョンを指定する場合は引数で指定する必要があるのでご注意ください。

CDH6.1でHBaseのエクスポート機能を試す

CDH 6.x の HBase は 2.x にリベースされているので、従来の MapReduce を使用する方法と、コプロセッサーを使用する方法の両方を試してみました。なお、テスト環境では数行のテーブルでおこない、大規模環境では実施していません。

MapReduce版のエクスポート

hbase org.apache.hadoop.hbase.mapreduce.Export を利用します。

構文: sudo -u hbase hbase org.apache.hadoop.hbase.mapreduce.Export <テーブル名> <出力ディレクトリ> [<バージョン数> [<starttime> [<endtime>]]]
#sudo -u hbase hbase org.apache.hadoop.hbase.mapreduce.Export testtable /tmp/export1

(略)

19/01/27 23:01:44 INFO mapreduce.Job:  map 0% reduce 0%
19/01/27 23:01:50 INFO mapreduce.Job:  map 100% reduce 0%
19/01/27 23:01:50 INFO mapreduce.Job: Job job_1548603599999_0004 completed successfully
19/01/27 23:01:50 INFO mapreduce.Job: Counters: 46
	File System Counters
		FILE: Number of bytes read=0
		FILE: Number of bytes written=258490
		FILE: Number of read operations=0
		FILE: Number of large read operations=0
		FILE: Number of write operations=0
		HDFS: Number of bytes read=160
		HDFS: Number of bytes written=189
		HDFS: Number of read operations=6
		HDFS: Number of large read operations=0
		HDFS: Number of write operations=2
		HDFS: Number of bytes read erasure-coded=0
	Job Counters 
		Launched map tasks=1
		Rack-local map tasks=1
		Total time spent by all maps in occupied slots (ms)=3678
		Total time spent by all reduces in occupied slots (ms)=0
		Total time spent by all map tasks (ms)=3678
		Total vcore-milliseconds taken by all map tasks=3678
		Total megabyte-milliseconds taken by all map tasks=3766272
	Map-Reduce Framework
		Map input records=1
		Map output records=1
		Input split bytes=160
		Spilled Records=0
		Failed Shuffles=0
		Merged Map outputs=0
		GC time elapsed (ms)=92
		CPU time spent (ms)=3630
		Physical memory (bytes) snapshot=349978624
		Virtual memory (bytes) snapshot=2660401152
		Total committed heap usage (bytes)=318767104
		Peak Map Physical memory (bytes)=349978624
		Peak Map Virtual memory (bytes)=2660401152
	HBase Counters
		BYTES_IN_REMOTE_RESULTS=66
		BYTES_IN_RESULTS=66
		MILLIS_BETWEEN_NEXTS=678
		NOT_SERVING_REGION_EXCEPTION=0
		NUM_SCANNER_RESTARTS=0
		NUM_SCAN_RESULTS_STALE=0
		REGIONS_SCANNED=1
		REMOTE_RPC_CALLS=1
		REMOTE_RPC_RETRIES=0
		ROWS_FILTERED=0
		ROWS_SCANNED=1
		RPC_CALLS=1
		RPC_RETRIES=0
	File Input Format Counters 
		Bytes Read=0
	File Output Format Counters 
		Bytes Written=189
# hdfs dfs -ls /tmp/export1
Found 2 items
-rw-r--r--   2 hbase supergroup          0 2019-01-27 23:01 /tmp/export1/_SUCCESS
-rw-r--r--   2 hbase supergroup        189 2019-01-27 23:01 /tmp/export1/part-m-00000

見慣れた MapReduce ジョブ(正確には Map-only ジョブ)と共に、指定したディレクトリにファイルが出力されました。

コプロセッサー版のエクスポート

hbase org.apache.hadoop.hbase.coprosessor.Export を利用します。

構文: sudo -u hbase hbase org.apache.hadoop.hbase.coprocessor.Export <テーブル名> <出力ディレクトリ> [<バージョン数> [<starttime> [<endtime>]]]

何も考えずにCDH6.1 の環境で実行したところ、コプロセッサーが登録されていないというエラーになりました。

org.apache.hadoop.hbase.exceptions.UnknownProtocolException: No registered coprocessor service found for ExportService in region testtable,,1548658833253.8ab1d1ea5687507486e6bab2a202a832.

コプロセッサーの登録は hbase shell から行うことができます。

構文: > alter ‘テーブル名’, {METHOD=>’table_att’, ‘coprocessor’=>’コプロセッサーのJarファイルへのパス|クラス名(org.apache.hadoop.hbase.coprocessor.Export)|優先度 (1)|}

検証環境では Jar ファイルが /usr/lib/hbase/hbase-endpoint.jar にあったため、hdfsの /tmp にアップロードし、その後シェルからコプロセッサーを登録したところ別のエラーが..

hbase(main):006:0> alter 'testtable', {METHOD=>'table_att', 'coprocessor'=>'hdfs://namenode1/tmp/hbase-endpoint.jar|org.apache.hadoop.hbase.coprocessor.Export|1|}

ERROR: org.apache.hadoop.hbase.DoNotRetryIOException: hdfs://namenode/tmp/hbase-endpoint.jar Set hbase.table.sanity.checks to false at conf or table descriptor if you want to bypass sanity checks
	at org.apache.hadoop.hbase.master.HMaster.warnOrThrowExceptionForFailure(HMaster.java:2232)
	at org.apache.hadoop.hbase.master.HMaster.sanityCheckTableDescriptor(HMaster.java:2079)
 :
org.apache.hadoop.hbase.DoNotRetryIOException: hdfs://namenode/tmp/hbase-endpoint.jar Set hbase.table.sanity.checks to false at conf or table descriptor if you want to bypass sanity checks

「hbase.table.sanity.check を False に設定せよ」という指示に従い、Cloudera Manager で hbase の 安全バルブにこの値を設定します。

変更を保存して関連サービスを再起動し、再度チャレンジ。

hbase(main):005:0> alter 'testtable', {METHOD=>'table_att', 'coprocessor'=>'hdfs://namenode/tmp/hbase-endpoint.jar|org.apache.hadoop.hbase.coprocessor.Export|1|'}
Updating all regions with the new schema...
1/1 regions updated.
Done.
Took 2.3746 seconds                                                                                                                                                                                 >

# sudo -u hbase hbase org.apache.hadoop.hbase.coprocessor.Export testtable /tmp/export_x
Java HotSpot(TM) 64-Bit Server VM warning: Using incremental CMS is deprecated and will likely be removed in a future release

(略)

19/01/28 00:52:37 INFO zookeeper.ZooKeeper: Initiating client connection, connectString=server1:2181 sessionTimeout=30000 watcher=org.apache.hadoop.hbase.zookeeper.ReadOnlyZKClient$$Lambda$14/811905937@25cd3c69
19/01/28 00:52:37 INFO zookeeper.ClientCnxn: Opening socket connection to server server1/X.Y.Z.Z:2181. Will not attempt to authenticate using SASL (unknown error)
19/01/28 00:52:37 INFO zookeeper.ClientCnxn: Socket connection established, initiating session, client: /X.Y.Z.Z:44460, server: server1/X.Y.Z.Z:2181
19/01/28 00:52:37 INFO zookeeper.ClientCnxn: Session establishment complete on server server1/X.Y.Z.Z:2181, sessionid = 0x1688ff533a30c23, negotiated timeout = 30000
19/01/28 00:52:38 INFO zookeeper.ZooKeeper: Session: 0x1688ff533a30c23 closed
19/01/28 00:52:38 INFO zookeeper.ClientCnxn: EventThread shut down
# hdfs dfs -ls /tmp/export_x
Found 1 items
-rw-r--r--   2 hbase supergroup        159 2019-01-28 00:52 /tmp/export_x/export-542cbce54de963ef0f0e5b0ced68d642

今度は成功です。

エクスポート時のバージョン、starttime、endtimeの指定が可能です。Version: 複数世代の指定。デフォルトは最新世代のみ。
Starttime: 開始時間(指定した時間が含まれる)。デフォルトは 0 (一番古い)
Endtime: 終了時間(指定した時間は含まれない)。デフォルトはすごい大きな値(ログ参照)

オプションを指定しない場合はそれぞれ「最新バージョンのみ」、「先頭」、「最大時間」が設定されます。ログの出力は次の通り。

[training@localhost ~]$ sudo -u hbase hbase org.apache.hadoop.hbase.mapreduce.Export etest /tmp/etest1
2019-01-29 21:59:17,430 INFO [main] mapreduce.Export: versions=1, starttime=0, endtime=9223372036854775807, keepDeletedCells=false

MapReduceの出力結果の「Record」行を見ることにより出力された件数がわかります。

Map-Reduce Framework
Map input records=2
Map output records=2

出力したファイルのインポート

エクスポートしたファイルをそれぞれインポートして復旧してみました。なお、エクスポート機能はデータのみ(メタ情報:テーブル情報はエクスポートしない)なので、インポート前にテーブルを作成する必要があります。

構文: hbase org.apache.hadoop.hbase.mapreduce.Import <テーブル名> <エクスポートしたディレクトリ>
新規テーブルを2つ作成し、それぞれインポートした結果です。
hbase(main):001:0> create 'restore_mr', 'cf1'
Created table restore_mr
Took 1.1899 seconds                                                                                                                                                                                 
=> Hbase::Table - restore_mr
hbase(main):002:0> create 'restore_co', 'cf1'
Created table restore_co
Took 0.7550 seconds                                                                                                                                                                                 
=> Hbase::Table - restore_co
hbase(main):003:0> 
# sudo -u hbase hbase org.apache.hadoop.hbase.mapreduce.Import restore_mr /tmp/export1

(略)

19/01/28 02:45:03 INFO mapreduce.Job: Job job_1548603599999_0005 running in uber mode : false
19/01/28 02:45:03 INFO mapreduce.Job:  map 0% reduce 0%
19/01/28 02:45:08 INFO mapreduce.Job:  map 100% reduce 0%
19/01/28 02:45:09 INFO mapreduce.Job: Job job_1548603599999_0005 completed successfully
19/01/28 02:45:09 INFO mapreduce.Job: Counters: 33
	File System Counters
		FILE: Number of bytes read=0
		FILE: Number of bytes written=258213
		FILE: Number of read operations=0
		FILE: Number of large read operations=0
		FILE: Number of write operations=0
		HDFS: Number of bytes read=328
		HDFS: Number of bytes written=0
		HDFS: Number of read operations=3
		HDFS: Number of large read operations=0
		HDFS: Number of write operations=0
		HDFS: Number of bytes read erasure-coded=0
	Job Counters 
		Launched map tasks=1
		Data-local map tasks=1
		Total time spent by all maps in occupied slots (ms)=3658
		Total time spent by all reduces in occupied slots (ms)=0
		Total time spent by all map tasks (ms)=3658
		Total vcore-milliseconds taken by all map tasks=3658
		Total megabyte-milliseconds taken by all map tasks=3745792
	Map-Reduce Framework
		Map input records=1
		Map output records=1
		Input split bytes=139
		Spilled Records=0
		Failed Shuffles=0
		Merged Map outputs=0
		GC time elapsed (ms)=106
		CPU time spent (ms)=3210
		Physical memory (bytes) snapshot=334405632
		Virtual memory (bytes) snapshot=2641289216
		Total committed heap usage (bytes)=277872640
		Peak Map Physical memory (bytes)=334405632
		Peak Map Virtual memory (bytes)=2641289216
	File Input Format Counters 
		Bytes Read=189
	File Output Format Counters 
		Bytes Written=0
#

コプロセッサーを使って出力したファイルのインポート

# sudo -u hbase hbase org.apache.hadoop.hbase.mapreduce.Import restore_co /tmp/export_x

(略)

19/01/28 02:45:26 INFO mapreduce.Job: Running job: job_1548603599999_0006
19/01/28 02:45:34 INFO mapreduce.Job: Job job_1548603599999_0006 running in uber mode : false
19/01/28 02:45:34 INFO mapreduce.Job:  map 0% reduce 0%
19/01/28 02:45:39 INFO mapreduce.Job:  map 100% reduce 0%
19/01/28 02:45:40 INFO mapreduce.Job: Job job_1548603599999_0006 completed successfully
19/01/28 02:45:40 INFO mapreduce.Job: Counters: 33
	File System Counters
		FILE: Number of bytes read=0
		FILE: Number of bytes written=258214
		FILE: Number of read operations=0
		FILE: Number of large read operations=0
		FILE: Number of write operations=0
		HDFS: Number of bytes read=326
		HDFS: Number of bytes written=0
		HDFS: Number of read operations=3
		HDFS: Number of large read operations=0
		HDFS: Number of write operations=0
		HDFS: Number of bytes read erasure-coded=0
	Job Counters 
		Launched map tasks=1
		Data-local map tasks=1
		Total time spent by all maps in occupied slots (ms)=3584
		Total time spent by all reduces in occupied slots (ms)=0
		Total time spent by all map tasks (ms)=3584
		Total vcore-milliseconds taken by all map tasks=3584
		Total megabyte-milliseconds taken by all map tasks=3670016
	Map-Reduce Framework
		Map input records=1
		Map output records=1
		Input split bytes=167
		Spilled Records=0
		Failed Shuffles=0
		Merged Map outputs=0
		GC time elapsed (ms)=123
		CPU time spent (ms)=3100
		Physical memory (bytes) snapshot=323035136
		Virtual memory (bytes) snapshot=2636824576
		Total committed heap usage (bytes)=281018368
		Peak Map Physical memory (bytes)=323035136
		Peak Map Virtual memory (bytes)=2636824576
	File Input Format Counters 
		Bytes Read=159
	File Output Format Counters 
		Bytes Written=0

# hbase shell
Java HotSpot(TM) 64-Bit Server VM warning: Using incremental CMS is deprecated and will likely be removed in a future release
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/usr/lib/zookeeper/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/usr/lib/hbase/lib/client-facing-thirdparty/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
HBase Shell
Use "help" to get list of supported commands.
Use "exit" to quit this interactive shell.
For Reference, please visit: http://hbase.apache.org/2.0/book.html#shell
Version 2.1.0-cdh6.x-SNAPSHOT, rUnknown, Sat Jan 26 23:45:19 PST 2019
Took 0.0061 seconds                                                                                                                                                                                 
hbase(main):001:0> scan 'restore_mr'
ROW                                                COLUMN+CELL                                                                                                                                      
 r1                                                column=cf1:a, timestamp=1548658853935, value=ccc                                                                                                 
 r1                                                column=cf1:b, timestamp=1548658864109, value=eee                                                                                                 
1 row(s)
Took 0.4302 seconds                                                                                                                                                                                 
hbase(main):002:0> scan 'restore_co'
ROW                                                COLUMN+CELL                                                                                                                                      
 r1                                                column=cf1:a, timestamp=1548658853935, value=ccc                                                                                                 
 r1                                                column=cf1:b, timestamp=1548658864109, value=eee                                                                                                 
1 row(s)
Took 0.3316 seconds         
hbase(main):003:0> 

まとめ

環境によって2種類のエクスポート機能を使い分けられるのは便利ですね。ただ、コプロセッサー版を使うには少々ハードルが高そうです。

コメント