領導者感知型轉送

本頁面說明 Spanner 的領導者感知轉送功能,以及使用方式。Spanner 會使用 leader-aware 轉送功能,在雙區域和多區域執行個體設定中動態轉送讀寫交易,以減少延遲時間並提升資料庫效能。系統預設會啟用領導者感知轉送功能。

讀寫交易的 Spanner 轉送

Spanner 會複製資料,提供額外的資料可用性和地理位置。在 Spanner 雙區域和多區域執行個體設定中,雙區域和多區域執行個體設定中的一個區域會指定為領導者區域,並包含資料庫的領導者副本。如果您使用雙區域或多區域執行個體設定,且用戶端從非領導者區域向資料庫發出讀寫交易,則寫入作業一律會在領導者區域中處理,然後傳回非領導者區域。因此,從非領導者區域提交的讀寫交易,需要多次往返領導者副本才能成功提交。

Leader-aware routing 是一種機制,可智慧轉送讀寫交易,縮短這類交易的延遲時間。如果啟用 leader-aware 轉送功能,即使寫入作業並非來自領導者區域,工作階段建立要求也會轉送至領導者區域,以便將 Spanner API 前端與領導者區域對齊。這種轉送機制可將非領導者區域 (用戶端應用程式所在位置) 與領導者區域之間的網路來回次數減少至兩次,進而縮短讀寫交易的延遲時間。

螢幕截圖:已啟用 leader-aware-routing 的 Spanner 轉送。 圖 1. 啟用 leader-aware-routing 的 Spanner 轉送範例。

如果停用領導者感知轉送功能,用戶端應用程式會先將要求轉送至用戶端應用程式區域 (非領導者區域) 內的 Spanner API 前端服務。接著,從用戶端應用程式區域中的 Spanner API 前端,向主要區域中的 Spanner 伺服器 (SpanServer) 進行三次以上的來回通訊,以提交寫入作業,進而增加延遲時間。這些額外的來回作業是為了支援次要索引、限制檢查和讀取寫入作業。

螢幕截圖:停用 leader-aware-routing 的 Spanner 轉送。 圖 2. 停用 leader-aware-routing 的 Spanner 轉送範例。

用途

使用 leader-aware 轉送功能後,下列用途可享有較低延遲時間:

  • 大量更新:從非主要區域執行 Dataflow 匯入作業或背景變更 (例如批次 DML)。
  • 容災能力和可用性提升:在領導者和非領導者區域部署用戶端應用程式,以容忍區域性服務中斷,同時從非領導者區域啟動寫入作業。
  • 全球應用程式:在全球部署用戶端應用程式,並在廣泛的區域位置提交資料。

限制

如果用戶端應用程式部署在領導者區域以外,且您在未讀取資料的情況下寫入值 (「盲目寫入」),則啟用領導者感知轉送功能時,可能會觀察到延遲時間迴歸。這是因為啟用 leader-aware 轉送功能時,非 leader 區域中的用戶端應用程式與 leader 區域中的 Spanner API 前端之間,會有兩次跨區域來回 (beginTransaction 和 commit 要求)。不過,如果停用 leader-aware 轉送功能,只有寫入而沒有讀取作業時,commit 要求只需要一次跨區域來回 (beginTransaction 會在本機 Spanner API 前端處理)。舉例來說,如果您將資料大量載入新建立的資料表,交易就不太可能從資料表讀取資料。如果您經常在應用程式中執行寫入作業,而不讀取資料,建議您停用領導者感知轉送功能。詳情請參閱「停用領導者感知轉送」。

使用 leader-aware 轉送

Spanner 用戶端程式庫預設會啟用 Leader 感知轉送功能。

建議您在啟用 leader-aware 轉送功能的情況下處理讀寫要求。您可以停用這項功能,比較成效差異。

使用地理區域分區功能,將要求轉送至主要節點

使用地理區域分區功能,將資料庫分區至多個資料存放位置時,Spanner 會評估資料庫存放位置 (包括預設存放位置) 使用的所有執行個體設定,然後轉送要求。Spanner 會選取與最靠近用戶端的配置區域位於相同位置的 Cloud Spanner API 前端。這項選擇與該刊登位置或其資料是否用於特定交易無關。Spanner 會按照下列方式轉送讀寫交易:

  • 啟用領導者感知轉送功能:每個配置都有自己的領導者區域 (或雙區域和多區域設定的預設領導者區域)。Spanner 會將讀寫交易轉送至最靠近用戶端的領導者區域中的 Cloud Spanner API 前端。
  • 停用 leader-aware 轉送功能:Spanner 會將讀寫交易轉送至 Cloud Spanner API 前端,該前端位於資料庫所有位置中最接近的服務區域。

啟用 leader-aware 轉送功能

您可以使用 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

停用 leader-aware 轉送

您可以使用 Spanner 用戶端程式庫停用 leader-aware 轉送功能。

C++

使用 RouteToLeaderOption 結構,設定用戶端應用程式,並停用 leader-aware 轉送功能:

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 資料庫連線,並停用 leader 感知轉送功能:

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

後續步驟