Skip to content

Commit bae1ca8

Browse files
blinkovasmyasnikov
andauthored
[docs] consolidate the coordination nodes content (#12314)
Co-authored-by: Aleksey Myasnikov <[email protected]>
1 parent 62a3099 commit bae1ca8

23 files changed

+942
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Coordination node
2+
3+
A coordination node is an object in {{ ydb-short-name }} that allows client applications to coordinate their actions in a distributed manner. Typical use cases for coordination nodes include:
4+
5+
* Distributed [semaphores](https://en.wikipedia.org/wiki/Semaphore_(programming)) and [mutexes](https://en.wikipedia.org/wiki/Mutual_exclusion).
6+
* Service discovery.
7+
* Leader election.
8+
* Task queues.
9+
* Publishing small amounts of data with the ability to receive change notifications.
10+
* Ephemeral locking of arbitrary entities not known in advance.
11+
12+
## Semaphores {#semaphore}
13+
14+
Coordination nodes allow you to create and manage semaphores within them. Typical operations with semaphores include:
15+
16+
* Create.
17+
* Acquire.
18+
* Release.
19+
* Describe.
20+
* Subscribe.
21+
* Delete.
22+
23+
A semaphore can have a counter that limits the number of simultaneous acquisitions, as well as a small amount of arbitrary data attached to it.
24+
25+
{{ ydb-short-name }} supports two types of semaphores: persistent and ephemeral. A persistent semaphore must be created before acquisition and will exist either until it is explicitly deleted or until the coordination node in which it was created is deleted. Ephemeral semaphores are automatically created at the moment of their first acquisition and deleted at the last release, which is convenient to use, for example, in distributed locking scenarios.
26+
27+
{% note info %}
28+
29+
Semaphores in {{ ydb-short-name }} are **not** recursive. Thus, semaphore acquisition and release are idempotent operations.
30+
31+
{% endnote %}
32+
33+
## Usage {#usage}
34+
35+
Working with coordination nodes and semaphores is done through [dedicated methods in {{ ydb-short-name }} SDK](../../reference/ydb-sdk/coordination.md).
36+
37+
## Similar systems {#similar-systems}
38+
39+
{{ ydb-short-name }} coordination nodes can solve tasks that are traditionally performed using systems such as [Apache Zookeeper](https://zookeeper.apache.org/), [etcd](https://etcd.io/), [Consul](https://www.consul.io/), and others. If a project uses {{ ydb-short-name }} for data storage along with one of these third-party systems for coordination, switching to {{ ydb-short-name }} coordination nodes can reduce the number of systems that need to be operated and maintained.
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
items:
2-
- { name: Directory, href: dir.md }
3-
- { name: Table, href: table.md }
4-
- { name: View, href: view.md }
5-
- { name: Topic, href: ../topic.md }
2+
- { name: Directories, href: dir.md }
3+
- { name: Tables, href: table.md }
4+
- { name: Views, href: view.md }
5+
- { name: Topics, href: ../topic.md }
6+
- { name: Coordination nodes, href: coordination-node.md }
67
- { name: Secrets, href: secrets.md }
78
- { name: External tables, href: external_table.md }
89
- { name: External data source, href: external_data_source.md }

ydb/docs/en/core/concepts/glossary.md

+8
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,14 @@ A **consumer** is an entity that reads messages from a topic.
209209

210210
**Replica object** is a mirror copy of the replicated object, automatically created by an [asynchronous replication instance](#async-replication-instance). Replica objects are typically read-only.
211211

212+
### Coordination node {#coordination-node}
213+
214+
A **coordination node** is a schema object that allows client applications to create semaphores for coordinating their actions. Learn more about [coordination nodes](./datamodel/coordination-node.md).
215+
216+
#### Semaphore {#semaphore}
217+
218+
A **semaphore** is an object within a [coordination node](#coordination-node) that provides a synchronization mechanism for distributed applications. Semaphores can be persistent or ephemeral and support operations like creation, acquisition, release, and monitoring. Learn more about [semaphores in {{ ydb-short-name }}](./datamodel/coordination-node.md#semaphore).
219+
212220
### YQL {#yql}
213221

214222
**YQL ({{ ydb-short-name }} Query Language)** is a high-level language for working with the system. It is a dialect of [ANSI SQL](https://en.wikipedia.org/wiki/SQL). There's a lot of content covering YQL, including a [tutorial](../dev/yql-tutorial/index.md), [reference](../yql/reference/syntax/index.md), and [recipes](../recipes/yql/index.md).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Configuration publication
2+
3+
Let's consider a scenario where we need to publish a small configuration for multiple application instances that should promptly react to its changes.
4+
5+
This scenario can be implemented using semaphores in [{{ ydb-short-name }} coordination nodes](../../reference/ydb-sdk/coordination.md) as follows:
6+
7+
1. A semaphore is created (for example, named `my-service-config`).
8+
1. The updated configuration is published through `UpdateSemaphore`.
9+
1. Application instances call `DescribeSemaphore` with `WatchData=true`. In the result, the `Data` field will contain the current version of the configuration.
10+
1. When the configuration changes, `OnChanged` is called. In this case, application instances make a similar `DescribeSemaphore` call and receive the updated configuration.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Distributed lock
2+
3+
Consider a scenario where it is necessary to ensure that only one instance of a client application accesses a shared resource at any given time. To achieve this, the semaphore mechanism in [{{ ydb-short-name }} coordination nodes](../../reference/ydb-sdk/coordination.md) can be utilized.
4+
5+
## Semaphore lease mechanism
6+
7+
In contrast to local multithreaded programming, clients in distributed systems do not directly acquire locks or semaphores. Instead, they lease them for a specified duration, which can be periodically renewed. Due to reliance on physical time which can vary between machines, clients and the server might encounter situations where multiple clients believe they have acquired the same semaphore simultaneously, even if the server's perspective differs. To reduce the likelihood of such occurrences, it is crucial to configure automatic time synchronization beforehand, both on servers hosting client applications and on the {{ ydb-short-name }} side, ideally using a unified time source.
8+
9+
Therefore, while distributed locking through such mechanisms cannot guarantee the complete absence of simultaneous resource access, it can significantly lower the probability of such events. This approach serves as an optimization to prevent unnecessary competition among clients for a shared resource. Absolute guarantees against concurrent resource requests сould be implemented on the resource side.
10+
11+
## Code example
12+
13+
{% list tabs %}
14+
15+
- Go
16+
17+
```go
18+
for {
19+
if session, err := db.Coordination().CreateSession(ctx, path); err != nil {
20+
return fmt.Errorf("cannot create session: %v", err);
21+
}
22+
23+
if lease, err := session.AcquireSemaphore(ctx,
24+
semaphore,
25+
coordination.Exclusive,
26+
options.WithEphemeral(true),
27+
); err != nil {
28+
// the session is likely lost, try to create a new one and get the lock in it
29+
session.Close(ctx);
30+
continue;
31+
}
32+
33+
// lock acquired, start processing
34+
select {
35+
case <-lease.Context().Done():
36+
}
37+
38+
// lock released, end processing
39+
}
40+
```
41+
42+
{% endlist %}

ydb/docs/en/core/recipes/ydb-sdk/index.md

+7
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ Table of contents:
2525
- [Inserting data](upsert.md)
2626
- [Bulk upsert of data](bulk-upsert.md)
2727
- [Setting up the transaction execution mode](tx-control.md)
28+
- Coordination
29+
30+
- [Distributed lock](distributed-lock.md)
31+
- [Service discovery](service-discovery.md)
32+
- [Configuration publication](config-publication.md)
33+
- [Leader election](leader-election.md)
34+
2835
- [Troubleshooting](debug.md)
2936

3037
- [Enable logging](debug-logs.md)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Leader election
2+
3+
Consider a scenario where multiple application instances need to elect a leader among themselves and be aware of the current leader at any given time.
4+
5+
This scenario can be implemented using semaphores in [{{ ydb-short-name }} coordination nodes](../../reference/ydb-sdk/coordination.md) as follows:
6+
7+
1. A semaphore is created (for example, named `my-service-leader`) with `Limit=1`.
8+
1. All application instances call `AcquireSemaphore` with `Count=1`, specifying their endpoint in the `Data` field.
9+
1. Only one application instance's call will complete quickly, while others will be queued. The application instance whose call completes successfully becomes the current leader.
10+
1. All application instances call `DescribeSemaphore` with `WatchOwners=true` and `IncludeOwners=true`. The result's `Owners` field will contain at most one element, from which the current leader's endpoint can be determined via its `Data` field.
11+
1. When the leader changes, `OnChanged` is called. In this case, application instances make a similar `DescribeSemaphore` call to learn about the new leader.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Service discovery
2+
3+
Consider a scenario where application instances are dynamically started and publish their endpoints, while other clients need to receive this list and respond to its changes.
4+
5+
This scenario can be implemented using semaphores in [{{ ydb-short-name }} coordination nodes](../../reference/ydb-sdk/coordination.md) as follows:
6+
7+
1. Create a semaphore (for example, named `my-service-endpoints`) with `Limit=Max<ui64>()`.
8+
1. All application instances call `AcquireSemaphore` with `Count=1`, specifying their endpoint in the `Data` field.
9+
1. Since the semaphore limit is very high, all `AcquireSemaphore` calls should complete quickly.
10+
1. At this point, publication is complete, and application instances only need to respond to session stops by republishing themselves through a new session.
11+
1. Clients call `DescribeSemaphore` with `IncludeOwners=true` and optionally with `WatchOwners=true`. In the result, the `Owners` field's `Data` will contain the endpoints of registered application instances.
12+
1. When the list of endpoints changes, `OnChanged` is called. In this case, clients make a similar `DescribeSemaphore` call and receive the updated list.

ydb/docs/en/core/recipes/ydb-sdk/toc_i.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ items:
3939
href: bulk-upsert.md
4040
- name: Setting up the transaction execution mode
4141
href: tx-control.md
42+
- name: Coordination
43+
items:
44+
- name: Distributed lock
45+
href: distributed-lock.md
46+
- name: Leader election
47+
href: leader-election.md
48+
- name: Service discovery
49+
href: service-discovery.md
50+
- name: Configuration publication
51+
href: config-publication.md
4252
- name: Troubleshooting
4353
items:
4454
- name: Overview

0 commit comments

Comments
 (0)