Leader-aware routing

This page describes leader-aware routing in Spanner and how to use it. Spanner uses leader-aware routing to dynamically route read-write transactions in dual-region and multi-region instance configurations to reduce latency and improve performance in your database. Leader-aware routing is enabled by default.

Spanner routing for read-write transactions

Spanner replicates data to provide additional data availability and geographic locality. In Spanner dual-region and multi-region instance configurations , one region in the dual-region and multi-region instance configuration is designated as the leader region and it contains the leader replicas of the database. When you use a dual-region or multi-region instance configuration and your client issues a read-write transaction to your database from a non-leader region, the write is always processed in the leader region and then sent back to the non-leader region. Therefore, read-write transactions committed from a non-leader region require multiple round trips to the leader replica to be committed successfully.

Leader-aware routing is a mechanism that improves latency for read-write transactions by intelligently routing these transactions. If leader-aware routing is enabled, even if the write doesn't originate from the leader region, the session creation requests are routed to the leader region to align the Spanner API frontend with the leader region. This routing mechanism improves latency for read-write transactions by reducing the number of network round trips required between the non-leader region (where the client application is located) and the leader region to two.

Screenshot Spanner routing with leader-aware-routing enabled. Figure 1.Example of Spanner routing with leader-aware-routing enabled.

If leader-aware routing is disabled, the client application first routes the request to a Spanner API frontend service within the client application region (non-leader region). Then, from the Spanner API frontend in the client application region, three or more round trips are made to the Spanner server (SpanServer) in the leader region to commit the write, increasing latency. These additional round trips are needed to support secondary indexes, constraint checks, and read your writes.

Screenshot Spanner routing with leader-aware-routing disabled. Figure 2.Example of Spanner routing with leader-aware-routing disabled.

Use cases

As a result of using leader-aware routing, the following use cases benefits from lower latency:

  • Bulk updates: Executing Dataflow imports or running background changes (for example, batch DMLs ) from a non-leader region.
  • Disaster tolerance and increased availability: Deploying client applications in both leader and non-leader regions to tolerate regional outages while initiating writes from non-leader regions.
  • Global application: Deploying client applications globally with widespread region locations that commit data.

Limitations

If your client application is deployed outside of the leader region and you write values without reading the data ("blind writes"), you might observe latency regression if leader-aware routing is enabled. This is because when leader-aware routing is enabled, there are two inter-region round trips ( beginTransaction and the commit request) between the client application in the non-leader region and the Spanner API frontend in the leader region. However, with leader-aware routing disabled, writes without reads only require one inter-region round trip for the commit request ( beginTransaction is processed in the local Spanner API frontend). For example, if you bulk load file data into a newly created table, the transactions are unlikely to read data from the table. If you frequently commit write operations without reading it in your application, you might want to consider disabling leader-aware routing. For more information, see Disable leader-aware routing .

Use leader-aware routing

Leader-aware routing is enabled by default in the Spanner client libraries.

We recommend processing your read-write requests with leader-aware routing enabled. You can disable it to compare performance differences.

Enable leader-aware routing

You can use the Spanner client libraries to enable leader-aware routing manually.

C++

Use the RouteToLeaderOption structure to configure your client application with leader-aware routing enabled:

  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#

Use EnableLeaderRouting to configure your client application with leader-aware routing enabled:

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

Go

Use ClientConfig to configure your client application with leader-aware routing enabled:

  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

Use SpannerOptions.Builder to configure your client application with leader-aware routing enabled:

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

Node.js

Use SpannerOptions to configure your client application with leader-aware routing enabled:

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

PHP

Use routeToLeader to configure your client application with leader-aware routing enabled:

  // Instantiates a client with leader-aware routing enabled 
 use Google\Cloud\Spanner\SpannerClient; 
 $routeToLeader = true; 
 $spanner = new SpannerClient($routeToLeader); 
 

Python

Use route_to_leader_enabled to configure your client application with leader-aware routing enabled:

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

Ruby

Use self.new to configure your client application with leader-aware routing enabled:

  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 
 

Disable leader-aware routing

You can use the Spanner client libraries to disable leader-aware routing.

C++

Use the RouteToLeaderOption structure to configure your client application with leader-aware routing disabled:

  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#

Use EnableLeaderRouting to configure your client application with leader-aware routing disabled:

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

Go

Use ClientConfig to configure your client application with leader-aware routing disabled:

  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

Use SpannerOptions.Builder to create a connection to a Spanner database with leader aware routing disabled:

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

Node.js

Use SpannerOptions to configure your client application with leader-aware routing disabled:

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

PHP

Use routeToLeader to configure your client application with leader-aware routing disabled:

  // Instantiates a client with leader-aware routing disabled 
 use Google\Cloud\Spanner\SpannerClient; 
 $routeToLeader = false; 
 $spanner = new SpannerClient($routeToLeader); 
 

Python

Use route_to_leader_enabled to configure your client application with leader-aware routing disabled:

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

Ruby

Use self.new to configure your client application with leader-aware routing disabled:

  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 
 

What's next

Design a Mobile Site
View Site in Mobile | Classic
Share by: