リーダー認識ルーティング

このページでは、Spanner におけるリーダー認識ルーティングとその使い方について説明しています。Spanner は、レイテンシを減らしデータベースのパフォーマンスを高めるために、リーダー認識ルーティングを使って、デュアルリージョンおよびマルチリージョン構成のインスタンスにおける読み書きトランザクションを動的にルーティングします。リーダー認識ルーティングはデフォルトで有効になっています。

読み書きトランザクションの Spanner ルーティング

Spanner は、データの可用性を高めて地理的な局所性を確保するために、データを複製します。Spanner のデュアルリージョンおよびマルチリージョンのインスタンス構成では、デュアルリージョンおよびマルチリージョンのインスタンス構成内の 1 つのリージョンがリーダー リージョンとして指定され、そこにデータベースのリーダー レプリカが含まれます。デュアルリージョンまたはマルチリージョンのインスタンス構成を使用し、クライアントがリーダー以外のリージョンからデータベースに対して読み書きトランザクションを発行する場合、書き込みは常にリーダー リージョンで処理されてから、非リーダー リージョンに返送されます。そのため、リーダー以外のリージョンから commit される読み書きトランザクションは、正常に commit されるために、リーダー レプリカとの間で複数回の往復通信が必要になります。

リーダー認識ルーティングは、読み書きトランザクションをインテリジェントにルーティングすることで、レイテンシを改善する仕組みです。リーダー認識ルーティングが有効になっている場合、書き込みがリーダー リージョンから発生しなくても、セッション作成リクエストはリーダー リージョンにルーティングされ、リーダー リージョンのある Spanner API フロントエンドに配置されます。このルーティング メカニズムにより、リーダー以外のリージョン(クライアント アプリケーションが存在するところ)とリーダー リージョン間のネットワークの往復数が 2 に削減され、読み書きトランザクションのレイテンシが改善されます。

リーダー認識ルーティングを有効にした Spanner ルーティングのスクリーンショットをとります。 図 1. リーダー認識ルーティングを有効にした Spanner ルーティングの例。

リーダー認識ルーティングが無効になっている場合、クライアント アプリケーションはまず、クライアント アプリケーションが存在するリージョン(リーダー以外のリージョン)内の Spanner API フロントエンド サービスにリクエストをルーティングします。次に、クライアント アプリケーション リージョンの Spanner API フロントエンドから、リーダー リージョンの Spanner サーバー(SpanServer)との間で 3 回以上の往復が行われて、書き込みが commit され、レイテンシが増加します。これらの追加の往復は、セカンダリ インデックス、制約チェック、書き込みの読み取りをサポートするために必要です。

リーダー認識ルーティングが無効になっている Spanner ルーティングのスクリーンショットをとります。 図 2. リーダー認識ルーティングを無効にした Spanner ルーティングの例。

ユースケース

リーダー認識ルーティングを使用することで、次のユースケースではレイテンシが低くなるというメリットがあります。

  • 一括更新: リーダー以外のリージョンから Dataflow インポートの実行やバックグラウンド変更(たとえばバッチ DML の実行)を行う。
  • 対障害耐性と可用性の向上: リーダーとリーダー以外のリージョンの両方にクライアント アプリケーションをデプロイし、リーダー以外のリージョンから書き込みを開始することで、リージョンの障害に対応できるようにする。
  • グローバル アプリケーション: 世界中に分散したリージョンにクライアント アプリケーションをデプロイし、それぞれのリージョンでデータを commit する。

制限事項

クライアント アプリケーションがリーダー リージョンの外部にデプロイされており、データを読み取ることなく値を書き込む場合(「盲目的書き込み」)、リーダー認識ルーティングが有効になっていると、レイテンシの回帰が発生する場合があります。これは、リーダー認識ルーティングが有効な場合、リーダー以外のクライアント アプリケーションとリーダー リージョンの Spanner API フロントエンドの間でリージョン間の往復(beginTransaction リクエストと commit リクエスト)が 2 回発生するためです。ただし、リーダー認識ルーティングが無効の場合、読み取りなしの書き込みでは、commit リクエストに対して 1 回のリージョン間往復しか必要とされません(beginTransaction はローカル Spanner API フロントエンドで処理されます)。たとえば、新しく作成したテーブルにファイルデータを一括読み込みする場合、トランザクションがテーブルからデータを読み取らないようになります。アプリケーションで読み取りなしに書き込みオペレーションを頻繁に commit する場合は、リーダー認識ルーティングを無効にすることを検討してください。詳細については、リーダー認識ルーティングを無効にするをご覧ください。

リーダー認識ルーティングを使用する

Spanner クライアント ライブラリでは、リーダー認識ルーティングはデフォルトで有効になっています。

リーダー認識ルーティングを有効にして、読み書きリクエストを処理することをおすすめします。これを無効にすることで、パフォーマンスの違いを比較できます。

リーダー認識ルーティングを有効にする

Spanner クライアント ライブラリを使用して、リーダー認識ルーティングを手動で有効にできます。

C++

RouteToLeaderOption 構造を使用して、リーダー認識ルーティングを有効にしてクライアント アプリケーションを構成します。

void RouteToLeaderOption(std::string const& project_id, std::string const& instance_id,
              std::string const& database_id) {
namespace spanner = ::google::cloud::spanner;

// Create a client with RouteToLeaderOption enabled.
auto client = spanner::Client(
  spanner::MakeConnection(
      spanner::Database(project_id, instance_id, database_id)),
  google::cloud::Options{}.set<spanner::RouteToLeaderOption>(
      spanner::true));

C#

EnableLeaderRouting を使用して、リーダー認識ルーティングを有効にしてクライアント アプリケーションを構成します。

// Create a client with leader-aware routing enabled.
SpannerConnectionStringBuilder builder = new
SpannerConnectionStringBuilder();
Builder.EnableLeaderRouting = true;

Go

ClientConfig を使用して、リーダー認識ルーティングを有効にしてクライアント アプリケーションを構成します。

type ClientConfig struct {
    // DisableRouteToLeader specifies if all the requests of type read-write
    // and PDML need to be routed to the leader region.
    // Default: false
    DisableRouteToLeader false
}

Java

SpannerOptions.Builder を使用して、リーダー認識ルーティングを有効にしてクライアント アプリケーションを構成します。

SpannerOptions options = SpannerOptions.newBuilder().enableLeaderAwareRouting.build();
Spanner spanner = options.getService();
String instance = "my-instance";
String database = "my-database";

Node.js

SpannerOptions を使用して、リーダー認識ルーティングを有効にしてクライアント アプリケーションを構成します。

// Instantiates a client with routeToLeaderEnabled enabled
const spanner = new Spanner({
projectId: projectId,
routeToLeaderEnabled: true;
});

PHP

routeToLeader を使用して、リーダー認識ルーティングを有効にしてクライアント アプリケーションを構成します。

// Instantiates a client with leader-aware routing enabled
use Google\Cloud\Spanner\SpannerClient;

$routeToLeader = true;
$spanner = new SpannerClient($routeToLeader);

Python

route_to_leader_enabled を使用して、リーダー認識ルーティングを有効にしてクライアント アプリケーションを構成します。

spanner_client = spanner.Client(
route_to_leader_enabled=true
)
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)

Ruby

self.new を使用して、リーダー認識ルーティングを有効にしてクライアント アプリケーションを構成します。

def self.new(project_id: nil, credentials: nil, scope: nil, timeout: nil,
     endpoint: nil, project: nil, keyfile: nil, emulator_host: nil,
    lib_name: nil, lib_version: nil, enable_leader_aware_routing: true) ->
    Google::Cloud::Spanner::Project

リーダー認識ルーティングを無効にする

Spanner クライアント ライブラリを使用して、リーダー認識ルーティングを無効にできます。

C++

RouteToLeaderOption 構造を使用して、リーダー認識ルーティングを無効にしてクライアント アプリケーションを構成します。

void RouteToLeaderOption(std::string const& project_id, std::string const& instance_id,
              std::string const& database_id) {
namespace spanner = ::google::cloud::spanner;

// Create a client with RouteToLeaderOption disabled.
auto client = spanner::Client(
  spanner::MakeConnection(
      spanner::Database(project_id, instance_id, database_id)),
  google::cloud::Options{}.set<spanner::RouteToLeaderOption>(
      spanner::false));

C#

EnableLeaderRouting を使用して、リーダー認識ルーティングを無効にしてクライアント アプリケーションを構成します。

// Create a client with leader-aware routing disabled.
SpannerConnectionStringBuilder builder = new
SpannerConnectionStringBuilder();
Builder.EnableLeaderRouting = false;

Go

ClientConfig を使用して、リーダー認識ルーティングを無効にしてクライアント アプリケーションを構成します。

type ClientConfig struct {
    // DisableRouteToLeader specifies if all the requests of type read-write
    // and PDML need to be routed to the leader region.
    // Default: false
    DisableRouteToLeader true
}

Java

SpannerOptions.Builder を使用して、リーダー認識ルーティングを無効にして Spanner データベースへの接続を作成します。

SpannerOptions options = SpannerOptions.newBuilder().disableLeaderAwareRouting.build();
Spanner spanner = options.getService();
String instance = "my-instance";
String database = "my-database";

Node.js

SpannerOptions を使用して、リーダー認識ルーティングを無効にしてクライアント アプリケーションを構成します。

// Instantiates a client with routeToLeaderEnabled disabled
const spanner = new Spanner({
projectId: projectId,
routeToLeaderEnabled: false;
});

PHP

routeToLeader を使用して、リーダー認識ルーティングを無効にしてクライアント アプリケーションを構成します。

// Instantiates a client with leader-aware routing disabled
use Google\Cloud\Spanner\SpannerClient;

$routeToLeader = false;
$spanner = new SpannerClient($routeToLeader);

Python

route_to_leader_enabled を使用して、リーダー認識ルーティングを無効にしてクライアント アプリケーションを構成します。

spanner_client = spanner.Client(
route_to_leader_enabled=false
)
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)

Ruby

self.new を使用して、リーダー認識ルーティングを無効にしてクライアント アプリケーションを構成します。

def self.new(project_id: nil, credentials: nil, scope: nil, timeout: nil,
     endpoint: nil, project: nil, keyfile: nil, emulator_host: nil,
    lib_name: nil, lib_version: nil, enable_leader_aware_routing: false) ->
    Google::Cloud::Spanner::Project

次のステップ