# How does CQL client know the tablet leader, for any query?

**URL:** <https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423>\
**Category:** General\
**Created:** [January 24, 2022, 3:30am UTC](https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423 "2022-01-24T03:30:44Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![sham\_yuga](https://avatars.discourse-cdn.com/v4/letter/s/cab0a1/32.png) [@sham\_yuga](https://forum.yugabyte.com/u/sham_yuga)\
**Post date:** [January 24, 2022, 3:30am UTC](https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423/1 "2022-01-24T03:30:44Z")

</div>

yugabyte cluster has 2 regions, 3 AZs, 6 node architecture.

4 nodes in central region,  
2 nodes in east region

```
Node1 (Master, TServer) US-east
Node2 (Master, TServer) US-central-1
Node3 (TServer) US-central-1
Node4 (TServer) US-east
Node5 (Master, TServer) US-central-2 (Leader)
Node6 (TServer) US-central-2

```

Application is running in central region.

Application is using YCQL driver(yugabyte gocql client) that is currently configured to send SQL queries to Node2(only)

* * *

As mentioned [here](https://blog.yugabyte.com/yugabyte-db-architecture-diverse-workloads-with-operational-simplicity/):  
_In many cases, this forwarding will be purely local, because both CQL and Redis Cluster clients are **capable of sending requests to the right server** and avoiding an additional network hop._

1. Is the above statement about CQL client referring to yugabyte [gocql client](https://github.com/yugabyte/gocql)? [here](https://pkg.go.dev/github.com/yugabyte/gocql#hdr-Data_center_awareness_and_query_routing) it mentions: “The driver can route queries to nodes that hold data replicas based on partition key (preferring local DC).”

2. if yes, does connection configuration of YCQL driver having connections with all 4 nodes(in central region), makes the client driver capable of knowing the correct tablet server, to send query? improving the query response time

3. if yes, Hoes YCQL driver know, which is the right tablet server to send query request(INSERT/UPDATE/SELECT)?

---

<div class="post-metadata">

**Author:** ![dorian\_yugabyte](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.yugabyte.com/dorian_yugabyte/32/206_2.png) [@dorian\_yugabyte](https://forum.yugabyte.com/u/dorian_yugabyte)\
**Post date:** [January 24, 2022, 8:39am UTC](https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423/2 "2022-01-24T08:39:39Z")

</div>

> [@sham\_yuga](#):
>
> `Node5 (Master, TServer) US-central-2 (Leader)`

Note that `Leader` here is, I’m guessing, for yb-master-leader (where there can be only 1 node).

For normal tables, the leader is picked per-tablet.

> [@sham\_yuga](#):
>
> Application is using YCQL driver(yugabyte gocql client) that is currently configured to send SQL queries to Node2(only)

Please paste the code that you used to initialize the client? Just to be sure.

> [@sham\_yuga](#):
>
> How can a driver know, which tablet server to send the request?

The driver periodically queries this table:

```auto
ycqlsh:system> select * from system.partitions;

```

Where it finds how tables are split, and where the tablets are located.

When you send a query, you pass the partition-keys in a way the driver understands them and hashes them and knows where to send them.

> [@sham\_yuga](#):
>
> if yes, does connection configuration of YCQL driver having connections with all 4 nodes(in central region), makes the client driver capable of knowing the correct tablet server, to send query? improving the query response time

Yes, it queries:

```auto
ycqlsh:system> select * from system.peers;

```

to find the location of all servers. It’s best to provide as many ips on connection time so they it can fallback at first (if node2 is down the driver can’t find out about the other nodes).

> [@sham\_yuga](#):
>
> if yes, Hoes YCQL driver know, which is the right tablet server to send query request(INSERT/UPDATE/SELECT)?

See my answer above. When in doubt, you can read the source code of the driver or read the docs:

> **[gocql package - github.com/gocql/gocql - Go Packages](https://pkg.go.dev/github.com/gocql/gocql#hdr-Data_center_awareness_and_query_routing)**
>
> Package gocql implements a fast and robust Cassandra driver for the Go programming language.

> **[gocql package - github.com/gocql/gocql - Go Packages](https://pkg.go.dev/github.com/gocql/gocql#hdr-Prepared_statements)**
>
> Package gocql implements a fast and robust Cassandra driver for the Go programming language.

---

<div class="post-metadata">

**Author:** ![sham\_yuga](https://avatars.discourse-cdn.com/v4/letter/s/cab0a1/32.png) [@sham\_yuga](https://forum.yugabyte.com/u/sham_yuga)\
**Post date:** [January 24, 2022, 11:46am UTC](https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423/3 "2022-01-24T11:46:07Z")

</div>

@dorian_yugabyte  
For your point: “Note that `Leader` here is, I’m guessing, for yb-master-leader (where there can be only 1 node).”

Yes you are right

---

<div class="post-metadata">

**Author:** ![sham\_yuga](https://avatars.discourse-cdn.com/v4/letter/s/cab0a1/32.png) [@sham\_yuga](https://forum.yugabyte.com/u/sham_yuga)\
**Post date:** [January 24, 2022, 4:10pm UTC](https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423/4 "2022-01-24T16:10:37Z")

</div>

@dorian_yugabyte  
I read the documentation here: [gocql package - github.com/yugabyte/gocql - Go Packages](https://pkg.go.dev/github.com/yugabyte/gocql#hdr-Data_center_awareness_and_query_routing)

1. 

To make the client driver capable of knowing the correct tablet server,  
Do I need to call `gocql.DCAwareRoundRobinPolicy("dc1")` or `gocql.TokenAwareHostPolicy(gocql.DCAwareRoundRobinPolicy("dc1"))`?

1. 

What does token signify in `gocql.TokenAwareHostPolicy()`?

---

<div class="post-metadata">

**Author:** ![dorian\_yugabyte](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.yugabyte.com/dorian_yugabyte/32/206_2.png) [@dorian\_yugabyte](https://forum.yugabyte.com/u/dorian_yugabyte)\
**Post date:** [January 25, 2022, 8:18am UTC](https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423/5 "2022-01-25T08:18:35Z")

</div>

@sham_yuga

Depends on the logic you want the client to follow. I’d suggest to be “connect to local DC with token aware. If the node is down, connect to remote DC with token aware”. Agree?

> [@sham\_yuga](#):
>
> What does token signify in `gocql.TokenAwareHostPolicy()` ?

Explained in the code [https://github.com/gocql/gocql/blob/558dfae50b5d369de77dae132dbfa64968e3abd4/policies.go#L351](https://github.com/gocql/gocql/blob/558dfae50b5d369de77dae132dbfa64968e3abd4/policies.go#L351)

---

<div class="post-metadata">

**Author:** ![sham\_yuga](https://avatars.discourse-cdn.com/v4/letter/s/cab0a1/32.png) [@sham\_yuga](https://forum.yugabyte.com/u/sham_yuga)\
**Post date:** [January 26, 2022, 2:45pm UTC](https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423/6 "2022-01-26T14:45:06Z")

</div>

@dorian_yugabyte  
1)  
When you say: “token aware” , does it mean selection based on partition key?

1. 

Upon setting host selection policy with api `gocql.TokenAwareHostPolicy(gocql.DCAwareRoundRobinPolicy("dc1"))`,  
If the driver observes that specific node(matching partition key) is down, which another node will be picked?

---

<div class="post-metadata">

**Author:** ![dorian\_yugabyte](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.yugabyte.com/dorian_yugabyte/32/206_2.png) [@dorian\_yugabyte](https://forum.yugabyte.com/u/dorian_yugabyte)\
**Post date:** [January 27, 2022, 9:35am UTC](https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423/7 "2022-01-27T09:35:47Z")

</div>

> [@sham\_yuga](#):
>
> When you say: “token aware” , does it mean selection based on partition key?

Yes.

> [@sham\_yuga](#):
>
> If the driver observes that specific node(matching partition key) is down, which another node will be picked?

It should contact directly the node in another DC that has that partition.

---

<div class="post-metadata">

**Author:** ![sham\_yuga](https://avatars.discourse-cdn.com/v4/letter/s/cab0a1/32.png) [@sham\_yuga](https://forum.yugabyte.com/u/sham_yuga)\
**Post date:** [February 9, 2022, 5:30pm UTC](https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423/8 "2022-02-09T17:30:25Z")

</div>

@dorian_yugabyte

Before setting the host selection policy, gocql driver creates a cluster config, as shown in this [example](https://pkg.go.dev/github.com/yugabyte/gocql#hdr-Data_center_awareness_and_query_routing):

`cluster := gocql.NewCluster("192.168.1.1", "192.168.1.2", "192.168.1.3")`

So, In my case we have 6 nodes(4 nodes in Central & 2 nodes in East).

Which node IP needs to passed to `gocql.NewCluster()`?

---

<div class="post-metadata">

**Author:** ![dorian\_yugabyte](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.yugabyte.com/dorian_yugabyte/32/206_2.png) [@dorian\_yugabyte](https://forum.yugabyte.com/u/dorian_yugabyte)\
**Post date:** [February 9, 2022, 5:42pm UTC](https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423/9 "2022-02-09T17:42:56Z")

</div>

> [@sham\_yuga](#):
>
> Which node IP needs to passed to `gocql.NewCluster()` ?

If possible, the IP of all nodes.

---

<div class="post-metadata">

**Author:** ![sham\_yuga](https://avatars.discourse-cdn.com/v4/letter/s/cab0a1/32.png) [@sham\_yuga](https://forum.yugabyte.com/u/sham_yuga)\
**Post date:** [February 9, 2022, 5:48pm UTC](https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423/10 "2022-02-09T17:48:04Z")

</div>

@dorian_yugabyte  
For my 6 node setup(4 nodes in Central & 2 nodes in East),

What is the advantage of having 6 node configuration(  
`gocql.NewCluster("node1-ip","node2-ip","node3-ip","node4-ip","node5-ip","node6-ip")`)  
over single node configuration(  
`gocql.NewCluster("node2-ip-master")`)? before setting host selection policy

---

<div class="post-metadata">

**Author:** ![dorian\_yugabyte](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.yugabyte.com/dorian_yugabyte/32/206_2.png) [@dorian\_yugabyte](https://forum.yugabyte.com/u/dorian_yugabyte)\
**Post date:** [February 10, 2022, 10:48am UTC](https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423/11 "2022-02-10T10:48:58Z")

</div>

> [@sham\_yuga](#):
>
> What is the advantage of having 6 node configuration(  
> `gocql.NewCluster("node1-ip","node2-ip","node3-ip","node4-ip","node5-ip","node6-ip")` )  
> over single node configuration(  
> `gocql.NewCluster("node2-ip-master")` )? before setting host selection policy

Nodes can go down. When you start (or restart) your client service, it will try to connect to 1 node, it will be down, and won’t be able to discover the other nodes. It will think the whole cluster is down.

---

<div class="post-metadata">

**Author:** ![sham\_yuga](https://avatars.discourse-cdn.com/v4/letter/s/cab0a1/32.png) [@sham\_yuga](https://forum.yugabyte.com/u/sham_yuga)\
**Post date:** [February 15, 2022, 1:24pm UTC](https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423/12 "2022-02-15T13:24:51Z")

</div>

@dorian_yugabyte  
For your point: “_Nodes can go down. When you start (or restart) your client service, it will try to connect to 1 node, it will be down, and won’t be able to discover the other nodes._”

For discovery purpose, does every node have information about all other nodes? Because in our setup, node3, node4 & node5 are only YB-TServer’s but not YB-Master.

As per the [documentation](https://docs.yugabyte.com/latest/architecture/concepts/yb-master/), It is YB-Master Service the keeper of system metadata but not YB-TServer

where system-metadata is:

```auto
select * from system.partitions;
select * from system.peers;

```

* * *

So, does it make sense to have this gocql api called as,  
`gocql.NewCluster("node1-ip","node2-ip","node6-ip") `  
instead of  
`gocql.NewCluster("node1-ip","node2-ip","node3-ip","node4-ip","node5-ip","node6-ip")`  
?

---

<div class="post-metadata">

**Author:** ![dorian\_yugabyte](https://yyz1.discourse-cdn.com/flex027/user_avatar/forum.yugabyte.com/dorian_yugabyte/32/206_2.png) [@dorian\_yugabyte](https://forum.yugabyte.com/u/dorian_yugabyte)\
**Post date:** [February 15, 2022, 3:29pm UTC](https://forum.yugabyte.com/t/how-does-cql-client-know-the-tablet-leader-for-any-query/1423/13 "2022-02-15T15:29:50Z")

</div>

> [@sham\_yuga](#):
>
> For discovery purpose, does every node have information about all other nodes? Because in our setup, node3, node4 & node5 are only YB-TServer’s but not YB-Master.

Yes, all nodes know about each other and all tablet locations.

> [@sham\_yuga](#):
>
> `gocql.NewCluster("node1-ip","node2-ip","node6-ip") `

Use: `gocql.NewCluster("as many yb-tserver ips as possible") `
