OBKV-HBaseは、弱い整合性読み取りと最寄りデータセンターからの読み取り機能をサポートしています。このドキュメントでは、弱い整合性読み取りと最寄りデータセンターからの読み取りの仕組み、対応バージョン、ルーティングポリシー、使用方法について説明します。
従来の強い整合性読み取りでは、同時アクセスが多い場合や低レイテンシが求められる場合に、性能上のボトルネックが生じることがあります。OBKV-HBaseは、弱い整合性読み取り(Weak Read)と最寄りデータセンターからの読み取り(Near Read)をサポートし、データの整合性とアクセス効率のバランスを柔軟に調整できるようにします。
原理
データベースが複数のデータセンター(例:北京、上海、広州)に展開され、データが複数のレプリカに複製されているシナリオを想像してください。
従来の強い整合性読み取りモードでは、クライアントは優先的にリーダーレプリカ(Leader)からデータを読み取ります。これにより、次の2つの問題が発生します:
- リーダーレプリカに過度な負荷がかかり、パフォーマンスのボトルネックとなりやすい。また、リーダーレプリカに障害が発生すると、そのデータセンター全体が利用不能になる。
- 広州や上海のユーザーがデータを読み取る際にも、北京のデータセンター経由で処理されるため、ネットワーク遅延が増加する。
この問題を解決するため、弱い整合性読み取りと最寄りデータセンターからの読み取りの方式を導入しました:
- 弱い整合性読み取り:クライアントが非リーダーレプリカ(フォロアーやレプリカなど)からデータを読み取ることを許可します。このモードでは、最新の更新が読み取り結果に反映されるまで若干の遅れが生じますが、読み取り性能とシステム可用性を向上させることができます。
- 最寄りデータセンターからの読み取り:クライアントは、自身の地理的位置またはネットワーク距離が最も近いデータセンターのレプリカを優先的に選択してデータを読み取ります。これにより、ネットワーク遅延が低減し、アクセス速度とユーザーエクスペリエンスが向上します。
サポートバージョン
この機能を使用するには、OceanBaseクラスタ、ODP、およびOBKV-HBaseクライアントのバージョン要件を満たす必要があります。
コンポーネント |
サポートバージョン |
|---|---|
| ObServer | 4.4.2.0以降 |
| ODP | 4.3.6.2 |
| OBKV-HBase | 2.5.0 |
直接接続モードの使用手順
ステップ1:OceanBaseクラスタのIDCを設定する
root@sys でOceanBaseクラスタにログインし、以下の手順でOceanBaseクラスタのデータセンター情報を設定します。クラスタには3つのZoneが含まれており、各Zoneに1つのOBServerノードがあると仮定します。例では、各ZoneのIPアドレスはそれぞれ10.0.0.1、10.0.0.2、10.0.0.3です。
z1のリージョンを設定します。REGIONパラメータはZoneが属する地域情報を指定するために使用されます。都市名(大文字小文字を区別)の使用を推奨します。ALTER SYSTEM MODIFY ZONE "z1" SET REGION = "SHANGHAI";z1のデータセンターを設定します。IDCパラメータはZoneが属するデータセンター情報を指定するために使用されます。データセンター名(小文字)の使用を推奨します。ALTER SYSTEM MODIFY ZONE "z1" SET IDC = "zue";
完了後、クラスタの展開状況は次の表のとおりです:
OBServerノードIPアドレス |
Zone |
IDC |
Region |
|---|---|---|---|
| 10.0.0.1 | z1 | zue | SHANGHAI |
| 10.0.0.2 | z2 | xue | SHANGHAI |
| 10.0.0.3 | z3 | yue | HANGZHOU |
ステップ2:クライアントの弱い整合性読み取りパラメータを設定する
パラメータ説明
弱い整合性読み取りを設定するための主要なパラメータは以下のとおりです:
パラメータ |
型 |
大小文字を区別するかどうか |
値 |
デフォルト値 |
説明 |
|---|---|---|---|---|---|
| hbase.htable.read.consistency | String | いいえ | "strong"、"weak" | "strong" |
|
| hbase.htable.client.idc | String | いいえ | 実際のデータセンター名 | "" |
|
| hbase.htable.client.route.policy | String | いいえ | "follower_first"、"follower_only" | "follower_first" |
|
OBKV-HBaseでは、グローバルとステートメントの2つのレベルでパラメータを設定できます。ステートメントレベルの設定がグローバル設定より優先されます。 以下に、具体的な設定方法を示します。
設定ファイルで弱い整合性読み取りのグローバルパラメータを設定する
この方法は、既存のアプリケーションコードを変更せずに、ネイティブHBaseからOBKV-HBaseへ移行する場合に適しています。hbase-site.xml または core-site.xml 設定ファイルに弱い整合性読み取りのグローバルパラメータを設定するだけで、弱い整合性読み取り機能を有効にできます。
以下の例では、hbase-site.xml ファイルで "hbase.htable.read.consistency" を "weak"、"hbase.htable.client.idc" を "idc1"、"hbase.htable.client.route.policy" を "follower_first" に設定することで、クエリ操作が "idc1" データセンターのフォロアーレプリカに優先的にルーティングされ、そこから読み取りが行われるようにします。
<configuration>
<property>
<name>hbase.htable.read.consistency</name>
<value>weak</value>
</property>
<property>
<name>hbase.htable.client.idc</name>
<value>idc1</value>
</property>
<property>
<name>hbase.htable.client.route.policy</name>
<value>follower_first</value>
</property>
</configuration>
コードで弱い整合性読み取りのグローバルパラメータを設定する
この方法は、コードを変更する必要がある業務に適用されます。コード内で弱い整合性読み取りのグローバルパラメータを設定するだけで、弱い整合性読み取り機能を実現できます。以下の例では、configurationで「hbase.htable.client.idc」を「idc1」、「hbase.htable.client.route.policy」を「follower_first」、「hbase.htable.read.consistency」を「weak」と設定することで、クエリ操作を優先的に「idc1」データセンターのフォロアーレプリカにルーティングして読み取りを行わせることができます。
import static com.alipay.oceanbase.hbase.constants.OHConstants.*;
Configuration config = HBaseConfiguration.create();
config.set(HBASE_HTABLE_CLIENT_IDC, "idc1"); // クライアントデータセンター情報の設定
config.set(HBASE_HTABLE_CLIENT_ROUTE_POLICY, "follower_first"); // ルーティングポリシーの設定
config.set(HBASE_HTABLE_READ_CONSISTENCY, "weak"); // 一貫性レベルの設定
コードでステートメントレベルの弱い整合性読み取りパラメータを設定する
この方法は、コードを修正する必要がある業務に適用されます。コード内でステートメントレベルの弱い整合性読み取りパラメータを設定するだけで、弱い整合性読み取り機能を実現できます。
以下に、異なるシナリオでの使用例をいくつか示します:
以下の例では、まず configuration で "hbase.htable.client.idc" を "idc1"、"hbase.htable.client.route.policy" を "follower_first" に設定します。次に、get操作において、setAttributeを使用して "hbase.htable.read.consistency" を "weak" に設定します。これにより、get操作を実行する際には、「idc1」データセンターのフォロアーレプリカに優先的にルーティングされます。
String tableName = "test";
Configuration config = HBaseConfiguration.create();
config.set(HBASE_HTABLE_CLIENT_IDC, "idc1"); // クライアントデータセンター情報の設定
config.set(HBASE_HTABLE_CLIENT_ROUTE_POLICY, "follower_first"); // ルーティングポリシーの設定
Connection hbaseConnection = ConnectionFactory.createConnection(config);
Table table = hbaseConnection.getTable(TableName.valueOf(tableName));
String family = "cf1";
String rowkey = "k1";
Get get = new Get(rowkey.getBytes());
get.setAttribute(HBASE_HTABLE_READ_CONSISTENCY, "weak".getBytes()); // ステートメントレベルの読み取り一貫性の設定
get.addColumn(family.getBytes(), "q1".getBytes());
Result result = table.get(get);
以下の例では、まず configuration で "hbase.htable.client.idc" を "idc1"、"hbase.htable.client.route.policy" を "follower_first" に設定します。その後、list<get> 操作において、setAttributeを使用して "hbase.htable.read.consistency" を "weak" に設定します。これにより、list<get> 操作を実行する際には、優先的に "idc1" データセンターのフォロアーレプリカにルーティングされます。
String tableName = "test";
Configuration config = HBaseConfiguration.create();
config.set(HBASE_HTABLE_CLIENT_IDC, "idc1"); // クライアントデータセンター情報の設定
config.set(HBASE_HTABLE_CLIENT_ROUTE_POLICY, "follower_first"); // ルーティングポリシーの設定
Connection hbaseConnection = ConnectionFactory.createConnection(config);
Table table = hbaseConnection.getTable(TableName.valueOf(tableName));
List<Get> gets = new ArrayList<>();
String family = "cf1";
String rowkey1 = "k1";
// 同一バッチ内のgetでは、すべてに対して弱い整合性読み取りを設定する必要があります。部分的な弱い整合性読み取りはサポートされていません。
Get get1 = new Get(rowkey1.getBytes());
get1.setAttribute(HBASE_HTABLE_READ_CONSISTENCY, "weak".getBytes()); // ステートメントレベルの読み取り整合性の設定
get1.addColumn(family.getBytes(), "q1".getBytes());
String rowkey2 = "k2";
Get get2 = new Get(rowkey2.getBytes());
get2.setAttribute(HBASE_HTABLE_READ_CONSISTENCY, "weak".getBytes()); // ステートメントレベルの読み取り整合性の設定
get2.addColumn(family.getBytes(), "q2".getBytes());
gets.add(get1, get2);
Result[] res = table.get(gets);
例では、まず configuration で "hbase.htable.client.idc" を "idc1"、"hbase.htable.client.route.policy" を "follower_first" に設定します。その後、scan操作でsetAttributeを使用して "hbase.htable.read.consistency" を "weak" に設定します。これにより、scan操作を実行する際には、"idc1" データセンターのフォロアーレプリカに優先的にルーティングされます。
String tableName = "test";
Configuration config = HBaseConfiguration.create();
config.set(HBASE_HTABLE_CLIENT_IDC, "idc1"); // クライアントデータセンター情報の設定
config.set(HBASE_HTABLE_CLIENT_ROUTE_POLICY, "follower_first"); // ルーティングポリシーの設定
Connection hbaseConnection = ConnectionFactory.createConnection(config);
Table table = hbaseConnection.getTable(TableName.valueOf(tableName));
String family = "cf1";
String rowkey = "k1";
Scan scan = new Scan();
scan.withStartRow(rowkey.getBytes());
scan.setAttribute(HBASE_HTABLE_READ_CONSISTENCY, "weak".getBytes()); // ステートメントレベルの読み取り一貫性の設定
scan.addColumn(family.getBytes(), "q1".getBytes());
ResultScanner resultScanner = table.getScanner(scan);
Result result;
while ((result = resultScanner.next()) != null) {
byte[] value = result.getValue(family.getBytes(), "q1".getBytes());
}
ODPモードの使用手順
ステップ1:OceanBaseクラスタのIDCを設定する
root@sysでOceanBaseクラスタにログインし、以下の手順でクラスタのデータセンターとリージョン情報を設定します。クラスタには3つのZoneが含まれ、各Zoneに1つのOBServerノードがあることを前提とします。以下では、z1の設定を例に説明します。
z1のリージョンを設定します。
REGIONパラメータはZoneが属する地域情報を指定するために使用され、都市名(大文字小文字を区別)に設定することを推奨します。ALTER SYSTEM MODIFY ZONE "z1" SET REGION = "SHANGHAI";z1のデータセンターを設定します。
IDCパラメータはZoneが属するデータセンター情報を指定するために使用され、データセンターの実際の名前(小文字)に設定することを推奨します。ALTER SYSTEM MODIFY ZONE "z1" SET IDC = "zue";
完了後、クラスタのデプロイメント情報は次の表のとおりです:
OBServerノードIPアドレス |
Zone |
IDC |
Region |
|---|---|---|---|
| 10.0.0.1 | z1 | zue | SHANGHAI |
| 10.0.0.2 | z2 | xue | SHANGHAI |
| 10.0.0.3 | z3 | yue | HANGZHOU |
ステップ2:ODPの弱い整合性読み取りパラメータを設定する
proxy_idc_nameパラメータを設定することで、ODPがLDCシステム内で属するデータセンターを指定できます。実際のデプロイメントに合わせて、弱い整合性読み取りトラフィックを対応するデータセンターのレプリカに最適にルーティングできます。例えば、すべての弱い整合性読み取りリクエストを優先的にz1があるデータセンターにルーティングする場合、以下の設定を参考にしてください:ALTER PROXYCONFIG SET proxy_idc_name = 'zue';proxy_route_policyパラメータを設定することで、レプリカのルーティングポリシーをさらに指定できます。以下の例は、フォロアーレプリカからの読み取りを優先するものです:ALTER PROXYCONFIG SET proxy_route_policy = 'follower_first';
ステップ3:クライアントの弱い整合性読み取りパラメータを設定する
「直接接続モードの使用手順」の「ステップ2:クライアントの弱い整合性読み取りパラメータを設定する」を参考に、弱い整合性読み取りパラメータを設定します。