Skip to content

필사 모드: MapReduceとHBaseの連携および開発方法

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

Background

HBaseはHadoop上で動作するリアルタイムデータベースですが、リレーショナルDBのような高水準のDMLは提供しません。NoSQLであっても、パフォーマンスとスケーラビリティに焦点を当てた結果、非常にシンプルなAPIのみを開発者に提供しています。PUT、GET、SCAN、DELETE、INCREMENTとそれらから派生したいくつかの操作がすべてです。リレーショナルDBでよく使われるSecondary IndexやJOINは提供されず、Transactionも行単位でのみ提供されます。そのため、row-keyと呼ばれる唯一のキーの設計を一度間違えると、データの照会や集計の際にテーブル全体を走査する(Full Scan)必要が出てくる可能性があります。Full Scanを並列処理することも容易ではありません。シングルスレッドで実行する場合、データサイズが小さければFull Scanでも問題ありませんが、データサイズがTBレベルまで増加すると数日かかることもあります。良い方法ではありません。

幸いなことに、このFull Scanを高速に行う方法があります。それはMapReduceを使用することです。HBaseはHadoopのMapReduceのデータソースとして使用できます。MapReduceは古い技術ではありますが、バッチ処理用としての利用には問題がなく、HBase公式ドキュメントでも[HBaseとMapReduceの連携](https://hbase.apache.org/book.html#mapreduce)方法を案内しています。

Goal

MapReduceプログラムの中で最もシンプルな、テーブルの行数を計算するプログラムを作成します。

Steps

HBase Cluster

当然ながら、HBaseクラスタが必要です。また、MapReduceジョブを実行するためのYARNコンポーネントも必要です。HBaseのインストール方法は[こちら](https://www.youngju.dev/blog/202302/hbase_fully_distributed_mode_install)を参照してください。

現在のクラスタは、マスターノード1台、ワーカーノード3台で構成されています。

開発環境の構築

IntelliJでNew Projectを作成します。

MapReduceプログラムの作成

MapReduceプログラムを作成するには、一般的にDriver、Mapper、Reducerの3つが必要ですが、Row Counterプログラムの場合はReducerが不要なため、DriverとMapperのみを作成します。

Driverの作成

public class RowCounterJob {

private static final String zookeeper_quorum = "latte01,latte02,latte03";

private static final String zookeeper_port = "2181";

public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {

// HBase関連のconfig登録

Configuration config = HBaseConfiguration.create();

config.set("hbase.zookeeper.quorum", zookeeper_quorum);

config.set("hbase.zookeeper.property.clientPort", zookeeper_port);

// Job作成

Job job = new Job(config, "RowCounter");

job.setJarByClass(RowCounterJob.class);

Scan scan = new Scan();

// Full Scanを行う際、scanオブジェクトを以下のように設定する必要があります。

scan.setCaching(500);

scan.setCacheBlocks(false);

// Table Mapper登録

TableMapReduceUtil.initTableMapperJob(

"usertable", // テーブル名

scan,

RowCounterMapper.class, // Mapper Classの登録

Text.class,

IntWritable.class,

job

);

job.setOutputFormatClass(NullOutputFormat.class);

job.setNumReduceTasks(1);

// jobの送信

boolean b = job.waitForCompletion(true);

if(!b){

throw new IOException("error with job");

}

}

}

Mapperの作成

public class RowCounterMapper extends TableMapper<Text, IntWritable> {

public enum Counters {ROWS}

@Override

protected void map(ImmutableBytesWritable key, Result value, Mapper<ImmutableBytesWritable, Result, Text, IntWritable>.Context context) throws IOException, InterruptedException {

context.getCounter(Counters.ROWS).increment(1);

}

}

必要なライブラリ

現在構築されたHadoopとHBaseのバージョンを確認します。

HBase: 2.5.3

Hadoop: 3.3.2

HBaseのバージョンによって必要なライブラリ名が異なります。

`hbase-client`と`hbase-mapreduce`が必要です。

MapReduce JARのビルドおよび生成方法

MapReduceジョブを実行するには、必要なすべてのdependencyが含まれた1つのJARファイルを生成する必要があります。

Mavenの`maven-assembly-plugin`を使用してもよいですが、便宜上IntelliJが提供するArtifacts機能を使用します。

左上のFileからProject StructureからArtifactsからADDからJARからFrom Modules with dependenciesをクリックします。

次に、Main Classを見つけて「extract to the target JAR」を選択し、新しいartifactを生成します。

上部のBuildからBuild Artifactを押してビルドを進めます。

プロジェクトルートディレクトリのOutからartifacts配下に移動すると、JARファイルが生成されていることを確認できます。

JARファイルの実行方法

該当ファイルをHBaseとYARNを実行できるサーバーに転送します。筆者はローカルPCのpublic keyを`latte01`のauthorized_keysに登録してあったため、以下のscpコマンドでファイルを転送できました。

scp hbase-mapreduce-test.jar latte01:<path you want to move>

MapReduceジョブの送信方法。

HADOOP_CLASSPATH=`hbase classpath` hadoop jar hbase-mapreduce-test.jar RowCounterJob

上記のコマンドで実行した際、以下のエラーメッセージが発生し、ジョブが送信されませんでした。

Exception in thread "main" java.lang.IllegalAccessError: class org.apache.hadoop.hdfs.web.HftpFileSystem cannot access its superinterface org.apache.hadoop.hdfs.web.TokenAspect$TokenManagementDelegator

https://stackoverflow.com/questions/62880009/error-through-remote-spark-job-java-lang-illegalaccesserror-class-org-apache-h によると、fat JARを作成する際にhadoop-hdfsライブラリが問題を引き起こすようなので、artifact生成時に該当ライブラリを削除しました。

同じエラーが発生したため、HBaseに標準で含まれているrow counterが正常に動作するか確認してみました。

hbase org.apache.hadoop.hbase.mapreduce.RowCounter <table name>

そもそもYARNクラスタに問題があったようです。

HDFS上に`/user/hdfs`、`/user/hbase`、`/user/root`ディレクトリを作成します。

hdfs dfs -mkdir /user

hdfs dfs -mkdir /user/hdfs

hdfs dfs -mkdir /user/hbase

hdfs dfs -mkdir /user/root

hdfs dfs -chown hbase:supergroup /user/hbase

hdfs dfs -chown hdfs:supergroup /user/hdfs

userディレクトリを作成しても、以下のエラーが発生しました。

023-06-10 16:11:13,539 ERROR [main] org.apache.hadoop.mapreduce.v2.app.MRAppMaster: Error starting MRAppMaster

java.lang.ClassCastException: org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$GetFileInfoRequestProto cannot be cast to com.google.protobuf.Message

at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:232)

https://ngela.tistory.com/66 によると、Hadoopのバージョンによってprotobufが異なることで発生する問題とのことです。

HadoopとHBaseをバージョンに合わせて再インストールし、再度試みます。

HBase: 2.5.3

Hadoop: 2.10.2

Zookeeper: 3.5.7

Hadoop 2.10.2再インストール時のconfig

export HADOOP_IDENT_STRING=$USER

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64

export HDFS_NAMENODE_USER=root

export HDFS_SECONDARYNAMENODE_USER=root

export HDFS_DATANODE_USER=root

export YARN_RESOURCEMANAGER_USER=root

export YARN_NODEMANAGER_USER=root

<!-- Site specific YARN configuration properties -->

latte02

latte03

latte04

NameNodeのフォーマット後、HDFSを起動

NameNodeで以下を実行します。

hadoop namenode -format

Hadoop、YARNコンポーネントを起動します。

start-all.sh

NameNodeとResource Managerが正常に起動したことを確認しました。

HBaseを起動します。

HBaseの起動

start-hbase.sh

YCSBのダウンロードおよび実行

curl -O --location https://github.com/brianfrankcooper/YCSB/releases/download/0.17.0/ycsb-0.17.0.tar.gz

tar xfvz ycsb-0.17.0.tar.gz

cd ycsb-0.17.0

mkdir latte_hbase

vim hbase-site.xml

vim testoption

recordcount=10000000

operationcount=1000000

HBase shellに接続して`usertable`を作成します。

hbase(main):001:0> n_splits = 30

HBase recommends (10 * number of regionservers)

hbase(main):002:0> create 'usertable', 'family', {SPLITS => (1..n_splits).map {|i| "user#{1000+i*(9999-1000)/n_splits}"}}

bin/ycsb load hbase20 -P workloads/workloada -P latte_hbase/testoptions -cp latte_hbase/ -p table=usertable -p columnfamily=family -p recordcount=10000000 -p operationcount=1000000 -threads 10

リクエスト数が1K近くまで増加したことを確認できます。

再度Row Count MapReduceを実行

hbase org.apache.hadoop.hbase.mapreduce.RowCounter usertable

MapReduceジョブが正常に実行されました。

2023-06-10 19:13:18,891 INFO [main] mapreduce.Job (Job.java:monitorAndPrintJob(1643)) - Job job_1686391929383_0001 running in uber mode : false

2023-06-10 19:13:18,894 INFO [main] mapreduce.Job (Job.java:monitorAndPrintJob(1650)) - map 0% reduce 0%

2023-06-10 19:13:51,888 INFO [main] mapreduce.Job (Job.java:monitorAndPrintJob(1650)) - map 6% reduce 0%

2023-06-10 19:13:52,948 INFO [main] mapreduce.Job (Job.java:monitorAndPrintJob(1650)) - map 16% reduce 0%

2023-06-10 19:13:53,966 INFO [main] mapreduce.Job (Job.java:monitorAndPrintJob(1650)) - map 26% reduce 0%

2023-06-10 19:13:59,063 INFO [main] mapreduce.Job (Job.java:monitorAndPrintJob(1650)) - map 35% reduce 0%

2023-06-10 19:14:00,097 INFO [main] mapreduce.Job (Job.java:monitorAndPrintJob(1650)) - map 39% reduce 0%

2023-06-10 19:14:01,118 INFO [main] mapreduce.Job (Job.java:monitorAndPrintJob(1650)) - map 52% reduce 0%

HBaseCounters

BYTES_IN_REMOTE_RESULTS=14106802

BYTES_IN_RESULTS=59441193

MILLIS_BETWEEN_NEXTS=282081

NOT_SERVING_REGION_EXCEPTION=0

REGIONS_SCANNED=31

REMOTE_RPC_CALLS=22

REMOTE_RPC_RETRIES=0

ROWS_FILTERED=44

ROWS_SCANNED=374127

RPC_CALLS=88

RPC_RETRIES=0

org.apache.hadoop.hbase.mapreduce.RowCounter$RowCounterMapper$Counters

ROWS=374127

File Input Format Counters

Bytes Read=0

File Output Format Counters

Bytes Written=0

374,127個の行があることを確認しました。

自作のrow counter MapReduceを実行します。

hadoop jar hbase-mapreduce-test.jar RowCounterJob

以下のように同じ結果が出力されました。

23/06/10 19:40:03 INFO mapreduce.Job: map 87% reduce 0%

23/06/10 19:40:04 INFO mapreduce.Job: map 94% reduce 0%

23/06/10 19:40:05 INFO mapreduce.Job: map 97% reduce 0%

23/06/10 19:40:06 INFO mapreduce.Job: map 100% reduce 0%

RowCounterMapper$Counters

ROWS=374127

File Input Format Counters

Bytes Read=0

File Output Format Counters

Bytes Written=0

Reference

- https://hbase.apache.org/book.html#mapreduce

- https://github.com/brianfrankcooper/YCSB

クイズ

MapReduceとHBaseの連携および開発方法

当然ながら、HBaseクラスタが必要です。また、MapReduceジョブを実行するためのYARNコンポーネントも必要です。HBaseのインストール方法はこちらを参照してください。

現在のクラスタは、マスターノード1台、ワーカーノード3台で構成されています。

IntelliJでNew Projectを作成します。

MapReduceプログラムを作成するには、一般的にDriver、Mapper、Reducerの3つが必要ですが、Row

Counterプログラムの場合はReducerが不要なため、DriverとMapperのみを作成します。 Driverの作成

Mapperの作成 必要なライブラリ 現在構築されたHadoopとHBaseのバージョンを確認します。 HBase: 2.5.3

Hadoop: 3.3.2 HBaseのバージョンによって必要なライブラリ名が異なります。

hbase-clientとhbase-mapreduceが必要です。

該当ファイルをHBaseとYARNを実行できるサーバーに転送します。筆者はローカルPCのpublic

keyをlatte01のauthorized_keysに登録してあったため、以下のscpコマンドでファイルを転送できました。

MapReduceジョブの送信方法。

上記のコマンドで実行した際、以下のエラーメッセージが発生し、ジョブが送信されませんでした。

현재 단락 (1/173)

HBaseはHadoop上で動作するリアルタイムデータベースですが、リレーショナルDBのような高水準のDMLは提供しません。NoSQLであっても、パフォーマンスとスケーラビリティに焦点を当てた結果、非...

작성 글자: 0원문 글자: 8,509작성 단락: 0/173