Apache Flinkは、リアルタイムデータストリームとバッチ処理タスクを処理するために特別に設計されたオープンソースのストリーム処理フレームワークです。その効率的なストリーム処理能力により、Hadoopエコシステムが補完され、リアルタイムデータ処理能力と低遅延のデータ分析が提供されます。Flinkはさまざまなデータソースからのリアルタイムデータを処理できるため、ユーザーは同一のデータアーキテクチャ内で複雑なストリームデータおよびバッチ処理タスクを実行できます。
本記事では、コミュニティ版Flinkを使用してOBKV-HBaseに直接アクセスする方法を紹介します。コードの変更は不要です。
前提条件
Flinkを使用してOBKV-HBaseにアクセスする前に、以下の条件が満たされていることを確認してください。
- OBKV-HBase Javaクライアントはバージョン2.2.1および1.2.1以降、ネイティブなFlinkアクセス機能をサポートしています。OBKV-HBase Javaクライアントのバージョン2.2.1を使用することを推奨します。FlinkのメインストリームバージョンはデフォルトでHBase 2.xを使用します。
- OceanBaseデータベースのバージョンはV4.4.1以上である必要があります。
- コミュニティ版Flinkを使用する場合は、組み込みのHBaseバージョンの導入を避けてください。
テーブル作成
コミュニティ版Flinkを使用してOBKV-HBaseワイドテーブルにアクセスする場合、テーブルの作成方法は以下の2つです:
- HBase Admin createTableインターフェース を使用してテーブルを作成します。
- SQLを使用してテーブルを作成します。SQLでテーブルを作成する場合は、OBKV-HBaseのテーブル作成ルールに従って作成する必要があります。ルールについては、OBKV-HBaseデータ操作の例 を参照してください。
OBKV-HBaseクライアント接続パラメータの設定
OBKV-HBaseクライアント接続パラメータは、OceanBaseクラスタとの接続を確立するために使用されます。OBKV-HBaseでは、パブリッククラウドとプライベートデプロイメントの方式によって、クライアント接続パラメータの設定方法が異なります。プライベートデプロイメントのOceanBaseクラスタについては、直接接続モードの設定に従って設定する必要がありますが、パブリッククラウドのOBKVサービスについては、クラウドモードに従って設定する必要があります。具体的なOBKV-HBaseクライアント接続クラスタのチュートリアルについては、OBKV-HBaseクライアントを使用したクラスタへの接続を参照してください。
どちらのデプロイメント方式であっても、すべての構成パラメータは以下の2つの方法で設定できます:
- 設定ファイル
hbase-site.xmlに設定します。 - Hadoop Configurationの
setメソッドを使用し、コード内でConnectionの初期化前に設定します。 Flinkのバージョンが1.13から1.20の間であることを確認します。
直接接続モードの設定
直接接続モードは、プライベートデプロイメントのOceanBaseクラスタに適用されます。Configurlを使用してOceanBaseクラスタに直接接続し、ConfigurlはOceanBaseデータベースの基盤となるサーバーの実際のアドレスを取得するために使用されます。
注意
paramURLに含まれるXMLの特殊文字&は、設定ファイル内では&と記述してください。エスケープしないとXMLの解析に失敗します。
方法1:
hbase-site.xml設定ファイルに以下のパラメータを設定します:<!-- 現在のクラスタを次のように仮定します。 ClusterName:obkvcluster TenantName:obkv DataBaseName: test UserName:root UserPassWord: SYS_USER_NAME : sysroot SYS_USER_PASSWD: --> <configuration> <!-- OceanBase HBase実装クラスの置換 --> <property> <name>hbase.client.connection.impl</name> <value>com.alipay.oceanbase.hbase.util.OHConnectionImpl</value> </property> <!-- OceanBase接続設定 --> <property> <!-- obconfig serverからRSlistのURLを取得する。詳細は後述のConfig URLの取得に関する内容を参照 --> <name>hbase.oceanbase.paramURL</name> <value>PARAM_URL</value> </property> <property> <!-- 形式はuserName@tenantName#clusterName --> <name>hbase.oceanbase.fullUserName</name> <value>root@obkv#obkvcluster</value> </property> <property> <!-- fullUserNameで指定したユーザーがOceanBaseにアクセスするためのパスワード --> <name>hbase.oceanbase.password</name> <value></value> </property> <property> <!-- システムテナント配下のユーザー名。ルーティングテーブルにアクセスする権限を持つのはシステムテナント配下のユーザーのみです --> <name>hbase.oceanbase.sysUserName</name> <value>sysroot</value> </property> <property> <!-- システムテナント配下のユーザーパスワード --> <name>hbase.oceanbase.sysPassword</name> <value></value> </property> </configuration>方法2:コード内でHadoop Configurationにパラメータを設定し、
setメソッドを使用して、コード内でConnectionを初期化する前に設定します:
/*
* 現在のクラスタを次のように仮定します。
* ClusterName:obkvcluster
* TenantName:obkv
* DataBaseName: test
* UserName:root
* UserPassWord:
* SYS_USER_NAME : sysroot
* SYS_USER_PASSWD:
*/
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.client.connection.impl", "com.alipay.oceanbase.hbase.util.OHConnectionImpl")
conf.set("hbase.oceanbase.fullUserName", "root@obkv#obkvcluster");
conf.set("hbase.oceanbase.password", "");
// obconfig serverからRSlistのURLを取得する。詳細は後述のConfig URLの取得に関する内容を参照
conf.set("hbase.oceanbase.paramURL", "");
conf.set("hbase.oceanbase.sysUserName", "sysroot");
conf.set("hbase.oceanbase.sysPassword", "");
クラウドモードの設定
クラウドモードは、パブリッククラウドにデプロイされたOceanBaseクラスタに適用されます。ODPを介してOceanBaseクラスタに接続します。
方法1:
hbase-site.xml設定ファイルに以下のパラメータを設定します:<!-- 現在のクラスタは以下のように仮定します。 DataBaseName: test UserName:root <configuration> --> <!-- OceanBase HBase実装クラスの置換 --> <property> <name>hbase.client.connection.impl</name> <value>com.alipay.oceanbase.hbase.util.OHConnectionImpl</value> </property> <!-- OceanBase接続設定 --> <configuration> <property> <name>hbase.oceanbase.fullUserName</name> <value>root</value> </property> <property> <name>hbase.oceanbase.password</name> <value></value> </property> <property> <!-- ODPアドレスの取得については後述を参照 --> <name>hbase.oceanbase.odpAddr</name> <value></value> </property> <property> <name>hbase.oceanbase.odpPort</name> <value>3307</value> </property> <property> <name>hbase.oceanbase.odpMode</name> <value>true</value> </property> <property> <name>hbase.oceanbase.database</name> <value>test</value> </property> </configuration>方法2:コード内でHadoop Configurationにパラメータを設定し、
setメソッドを使用して、コード内のConnection初期化前に設定します:
/*
* 現在のクラスタは以下のように仮定します。
* DataBaseName: test
* UserName:root
*/
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.client.connection.impl", "com.alipay.oceanbase.hbase.util.OHConnectionImpl")
conf.set(HBASE_OCEANBASE_FULL_USER_NAME, "root");
// ユーザーパスワード
conf.set(HBASE_OCEANBASE_PASSWORD, "");
// ODPアドレスの詳細は備考を参照
conf.set(HBASE_OCEANBASE_ODP_ADDR, "");
// OBKVのポートは3307です(固定)
conf.setInt(HBASE_OCEANBASE_ODP_PORT, "3307");
// クラウドではODPモードを使用します(固定)
conf.setBoolean(HBASE_OCEANBASE_ODP_MODE, true);
// データベースの名前
conf.set(HBASE_OCEANBASE_DATABASE, "test");
使用例
ディメンションテーブルの作成
ディメンションテーブル(Dimension Table)は、データウェアハウスやデータ分析において重要な概念であり、日付、時間、場所、人物など頻繁に変更されない属性情報を格納し、ファクトテーブルに文脈や属性情報を提供します。
コミュニティ版FlinkとOBKV Flinkコネクターでは、ディメンションテーブルの作成方法が異なります。詳細については、以下を参照してください:
- コミュニティ版Flinkを使用してOBKV-HBaseワイドテーブルにアクセスする場合は、ディメンションテーブルの作成を参照してください。
- OBKV Flinkコネクターを使用してOBKV-HBaseワイドテーブルにアクセスする場合は、ディメンションテーブルの作成を参照してください。
ファクトテーブルの作成
ファクトテーブル(Fact Table)は、データウェアハウスおよびデータ分析におけるもう一つの重要な概念であり、業務プロセス中に発生する各取引や操作の詳細情報および関連する数値情報を格納します。
- コミュニティ版Flinkを使用してOBKV-HBaseワイドテーブルにアクセスする場合は、ファクトテーブルの作成を参照してください。
- OBKV Flinkコネクタを使用してOBKV-HBaseワイドテーブルにアクセスする場合は、ファクトテーブルの作成を参照してください。
依存関係の追加
OBKV-HBase の依存関係を追加します:
<!-- OBKV-HBase 依存関係には、hbase-client と hadoop-common が含まれています -->
<dependency>
<groupId>com.oceanbase</groupId>
<artifactId>obkv-hbase-client</artifactId>
<version>2.2.1</version>
</dependency>
Flink SQL を使用する場合は、競合を避けるため、以下の依存関係を除外する必要があります:
<!-- Flink Connector HBase 依存関係 -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-hbase-2.2</artifactId>
<version>{flink.connector.hbase.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
</exclusion>
</exclusions>
</dependency>
Flinkによる読み書きの例
このセクションでは、Flinkの2つの異なる読み書き方法、すなわちDataStreamとFlink SQLを紹介します。
Flink DataStreamによる読み書き
サンプルテーブルグループとテーブルを作成します:
-- テーブルグループを作成
CREATE TABLEGROUP `flink_test` SHARDING = 'ADAPTIVE';
-- テーブルを作成
CREATE TABLE `flink_test$cf1` (
`K` varbinary(1024) NOT NULL,
`Q` varbinary(256) NOT NULL,
`T` bigint(20) NOT NULL,
`V` varbinary(1024) DEFAULT NULL,
PRIMARY KEY (`K`, `Q`, `T`)
) TABLEGROUP = `flink_test` partition by key(`K`) partitions 17;
CREATE TABLE `flink_test$cf2` (
`K` varbinary(1024) NOT NULL,
`Q` varbinary(256) NOT NULL,
`T` bigint(20) NOT NULL,
`V` varbinary(1024) DEFAULT NULL,
PRIMARY KEY (`K`, `Q`, `T`)
) TABLEGROUP = `flink_test` partition by key(`K`) partitions 17;
Flink DataStreamとHBase Java APIを組み合わせて読み書きを行います。読み書きの例は以下のとおりです:
StreamExecutionEnvironment env =
StreamExecutionEnvironment.getExecutionEnvironment();
env.fromElements("row1", "row2")
.flatMap(new RichFlatMapFunction<String, String>() {
private transient Table table;
@Override
public void open(org.apache.flink.configuration.Configuration parameters) throws Exception {
Connection connection = ConnectionFactory.createConnection(ObHTableTestUtil.newConfiguration());
table = connection.getTable(org.apache.hadoop.hbase.TableName.valueOf("flink_test"));
}
@Override
public void flatMap(String s, Collector<String> out) throws Exception {
// Write to HBase
Put put = new Put(Bytes.toBytes(s));
put.addColumn(Bytes.toBytes(family1), Bytes.toBytes(column1), Bytes.toBytes("cf1_" + s +"_value"));
put.addColumn(Bytes.toBytes(family2), Bytes.toBytes(column2), Bytes.toBytes("cf2_" + s + "_value"));
table.put(put);
// Read from HBase
Get get = new Get(Bytes.toBytes(s));
Result result = table.get(get);
String family1Value = Bytes.toString(result.getValue(Bytes.toBytes(family1), Bytes.toBytes(column1)));
String family2Value = Bytes.toString(result.getValue(Bytes.toBytes(family2), Bytes.toBytes(column2)));
// collect get result
out.collect(String.format("Get result from cf1: Row: %s, Qualifier: %s, Value: %s", Bytes.toString(result.getRow()), column1, family1Value));
out.collect(String.format("Get result from cf2: Row: %s, Qualifier: %s, Value: %s", Bytes.toString(result.getRow()), column2, family2Value));
}
@Override
public void close() throws Exception {
table.close();
}
}).print();
Flink SQLによる読み書き
サンプルテーブルグループとテーブルを作成します:
CREATE TABLEGROUP `student_info` SHARDING = 'ADAPTIVE';
CREATE TABLEGROUP `student_hobby` SHARDING = 'ADAPTIVE';
CREATE TABLEGROUP `all_student_info` SHARDING = 'ADAPTIVE';
CREATE TABLE `student_info$cf1` (
`K` varbinary(1024) NOT NULL,
`Q` varbinary(256) NOT NULL,
`T` bigint(20) NOT NULL,
`V` varbinary(1024) DEFAULT NULL,
PRIMARY KEY (`K`, `Q`, `T`)
) TABLEGROUP = `student_info` partition by key(`K`) partitions 17;
CREATE TABLE `student_hobby$cf1` (
`K` varbinary(1024) NOT NULL,
`Q` varbinary(256) NOT NULL,
`T` bigint(20) NOT NULL,
`V` varbinary(1024) DEFAULT NULL,
PRIMARY KEY (`K`, `Q`, `T`)
) TABLEGROUP = `student_hobby` partition by key(`K`) partitions 17;
CREATE TABLE `all_student_info$cf1` (
`K` varbinary(1024) NOT NULL,
`Q` varbinary(256) NOT NULL,
`T` bigint(20) NOT NULL,
`V` varbinary(1024) DEFAULT NULL,
PRIMARY KEY (`K`, `Q`, `T`)
) TABLEGROUP = `all_student_info` partition by key(`K`) partitions 17;
OBKV-HBaseを使用してテーブルマッピングを作成する際、zookeeper.quorumに実際の接続先を指定する必要はありません。ただし、このパラメータには空でない任意の文字列を設定する必要があります。Flink SQLは、student_info テーブルと student_hobby テーブルへの書き込み操作を通じて、ディメンションテーブルの操作をシミュレートします。例:
-- FlinkとHBaseのテーブルstudent_infoのマッピングを作成
CREATE TABLE student_info (
id INT,
cf1 ROW<name STRING, age INT>,
PRIMARY KEY (id) NOT ENFORCED
) WITH (
'connector' = 'hbase-2.2',
'table-name' = 'student_info',
'zookeeper.quorum' = 'any_string'
);
-- FlinkとHBaseのテーブルstudent_hobbyのマッピングを作成
CREATE TABLE student_hobby (
id INT,
cf1 ROW<hobby STRING>,
PRIMARY KEY (id) NOT ENFORCED
) WITH (
'connector' = 'hbase-2.2',
'table-name' = 'student_hobby',
'zookeeper.quorum' = 'any_string'
);
-- student_infoとstudent_hobbyにデータを挿入
INSERT INTO student_info VALUES
(1001, ROW('Lily', 13)),
(1002, ROW('John', 12)),
(1003, ROW('David', 13));
INSERT INTO student_hobby VALUES
(1001, ROW('basketball')),
(1002, ROW('badminton')),
(1003, ROW('jogging'));
Flink SQLを使用して、student_info テーブルと student_hobby テーブルからデータを読み取り、結果をall_student_info テーブルにマージして書き込みます:
-- FlinkとHBaseのテーブルall_student_infoのマッピングを作成
CREATE TABLE all_student_info (
id INT,
cf1 ROW<name STRING, age INT, hobby STRING>,
PRIMARY KEY (id) NOT ENFORCED
) WITH (
'connector' = 'hbase-2.2',
'table-name' = 'all_student_info',
'zookeeper.quorum' = 'any_string'
);
-- all_student_infoにデータを挿入
INSERT INTO all_student_info
SELECT
si.id AS id,
ROW(si.cf1.name, si.cf1.age, sh.cf1.hobby) AS cf1
FROM
student_info AS si
LEFT JOIN
student_hobby AS sh ON si.id = sh.id;