バルクロードによる大きなデータセットのHBaseロード

こんにちは同僚。

HBaseを使用した経験、つまりバルクロードについてお話ししたいと思います。 これは別のデータ読み込み方法です。 通常のアプローチ(クライアントを介してテーブルに書き込む)とは根本的に異なります。 バルクロードの助けを借りて、大量のデータを非常に迅速にロードできるという意見があります。 これが私が理解しようと決めたものです。



そして、まず最初に。 バルクロードによるロードは、3段階で行われます。











この場合、私はこの技術を感じ、数字でそれを理解する必要がありました。速度はどれくらいで、ファイルの数とサイズにどのように依存しますか。 これらの数値は外部条件に依存しすぎていますが、通常のロードとバルクロードの順序を理解するのに役立ちます。



ソースデータ:



Cloudera CDH4、HBase 0.94.6-cdh4.3.0によって管理されるクラスター。

CentOS / 4CPU / RAM 8GB / HDD 50GB構成の3つの仮想ホスト(ハイパーバイザー上)

テストデータは、合計サイズが2GB、3.5GB、7.1GB、14.2GBのさまざまなサイズのCSVファイルに保存されました

最初に結果について:



バルクロード





速度:





1レコード(行)のサイズ:0.5Kb

MapReduceジョブの初期化時間:70秒

ローカルファイルシステムからHDFSのファイルのダウンロード時間:





クライアントからダウンロード:



ダウンロードは、それぞれ8つのスレッドを持つ2つのホストから実行されました。

クライアントは同時にクラウンで起動し、CPU負荷は40%を超えませんでした

前のケースと同様に、1つのレコード(行)のサイズは0.5Kbでした。







結果は何ですか?







超高速のデータ読み込みの方法として、バルク読み込みについての話をきっかけにこのテストを実装することにしました。 公式ドキュメントでは、ネットワークとCPUの負荷を軽減することについてのみ言及していると言っておく価値があります。 それがそうであっても、私は速度の向上を見ていません。 テストによると、バルクロードは1.5倍しか高速ではありませんが、m / rジョブの初期化を考慮に入れないことを忘れないでください。 また、データはHDFSに配信する必要があり、時間がかかります。

データをロードするもう1つの方法としてバルクロードを扱うだけの価値があると思いますが、アーキテクチャが異なります(場合によっては非常に便利です)。



そして今、実装のために



理論的には、すべてが非常に単純ですが、実際にはいくつかの技術的なニュアンスがあります。



//  Job job = new Job(configuration, JOB_NAME); job.setJarByClass(BulkLoadJob.class); job.setMapOutputKeyClass(ImmutableBytesWritable.class); job.setMapOutputValueClass(Put.class); job.setMapperClass(DataMapper.class); job.setNumReduceTasks(0); job.setInputFormatClass(TextInputFormat.class); job.setOutputFormatClass(HFileOutputFormat.class); FileInputFormat.setInputPaths(job, inputPath); HFileOutputFormat.setOutputPath(job, new Path(outputPath)); HTable dataTable = new HTable(jobConfiguration, TABLE_NAME); HFileOutputFormat.configureIncrementalLoad(job, dataTable); // ControlledJob controlledJob = new ControlledJob( job, null ); JobControl jobController = new JobControl(JOB_NAME); jobController.addJob(controlledJob); Thread thread = new Thread(jobController); thread.start(); . . . //   output setFullPermissions(JOB_OUTPUT_PATH); //  bulk-load LoadIncrementalHFiles loader = new LoadIncrementalHFiles(jobConfiguration); loader.doBulkLoad( new Path(JOB_OUTPUT_PATH), dataTable );
      
      











したがって、hbaseユーザーの代わりにJobを実行するか、出力ファイルに権限を与える必要があります(これはまさに私がやったことです)。







 //    - HTableDescriptor descriptor = new HTableDescriptor( Bytes.toBytes(tableName) ); descriptor.addFamily( new HColumnDescriptor(Constants.COLUMN_FAMILY_NAME) ); HBaseAdmin admin = new HBaseAdmin(config); byte[] startKey = new byte[16]; Arrays.fill(startKey, (byte) 0); byte[] endKey = new byte[16]; Arrays.fill(endKey, (byte)255); admin.createTable(descriptor, startKey, endKey, REGIONS_COUNT); admin.close();
      
      











一般に、それですべてです。 これはやや粗雑なテストであり、トリッキーな最適化は行われないと言いたいので、何か追加することがあれば、喜んで聞きます。



すべてのプロジェクトコードはGitHubで入手できます: github.com/2anikulin/hbase-bulk-load



All Articles