535 PGCon 2019 Borodin Odyssey
535 PGCon 2019 Borodin Odyssey
535 PGCon 2019 Borodin Odyssey
▌ Working on
› disaster recovery system WAL-G
› connection pooler Odyssey
› interested in anything related to indexing
3
Yandex and PostgreSQL
▌ Yandex.Mail
› some hundreds of millions of users
› 1+ trillion rows, 1+ million requests per second
▌ Yandex.Cloud
› ~2Pb of Postgres (May 2019)
And many other services like taxi, maps, weather forecast, carsharing,
food delivery etc.
4
Cluster in the cloud
Network
WAL Object
RW Queries Storage
Backup
RO Queries
5
Node in a cluster
Connection Pooler
6
Why should we pool
connections?
Why should we pool connections?
▌ 1 backend == 1 process
8
Why should we pool connections?
▌ 1 backend == 1 process
▌ Caches per backend
› Relations cache
› Compiled PL\pgSQL
› Plans
9
Why should we pool connections?
▌ 1 backend == 1 process
▌ Caches per backend
› Relations cache
› Compiled PL\pgSQL
› Plans
▌ HA node fencing
10
OLTP throughput
11
Where can we pool connections?
1 Application-side pool
4 DB built-in pooling
7 Combinations
Application-side connection pooler
App backend
13
Backend under load balancer
14
In multiple availability zones
DC1
DC2
15
Proxy poolers
▌ Pgpool II
▌ Crunchy-Proxy
› Diverse functionality beyond pooling
› Only session pooling
▌ PgBouncer
› Lightweight tool
› Transaction pooling
16
▎PgBouncer FTW
on our workload
Houston,
we have a problem
Diagnostics is complicated
miscdb01d/postgres M # SELECT client_addr, count(*)
client_addr | count
-------------+-------
127.0.0.1 | 127
::1 | 136
(2 rows)
Time: 2.209 ms
miscdb01d/postgres M #
19
Diagnostics is complicated
Hard to trace
› Network problems
› Client driver problems
Hard to trace events of single session
20
application_name_add_host
-[ RECORD 1 ]----+------------------------------------------------
client_addr | 127.0.0.1
client_port | 42051
Time: 2.716 ms
miscdb01d/postgres M #
21
application_name_add_host
22
max_client_pool_conn
key | value
-------------------+-------
max_client_conn | 20000
default_pool_size | 500
min_pool_size | 0
reserve_pool_size | 0
23
max_client_pool_conn
24
max_client_pool_conn
----------------------+-------
max_client_conn | 20000
max_client_pool_conn | 4000
default_pool_size | 500
min_pool_size | 0
reserve_pool_size | 0
25
Pgbouncer cannot connect to server
26
Pgbouncer cannot connect to server
2017-03-13 10:48:23.995 24408 ERROR S: login failed: FATAL: too many connections for role
"YYY"
>>> try:
... print(e.pgcode)
...
None
>>>
27
What’s going on?
29
▎We need more gold PgBouncers
HAProxy
Client
HAProxy PgBouncer
PgBouncer PostgreSQL
PgBouncer
31
HAProxy
+ Pros - Cons
https://lwn.net/Articles/542629/
33
SO_REUSEPORT
Clients PgBouncer
PgBouncer
PgBouncer PostgreSQL
34
SO_REUSEPORT
35
TLS
36
TLS
37
TLS
38
TLS
39
TLS
40
Cascading PgBouncers
Client
TLS
PgBouncer :6432
PgBouncer
PgBouncer PgBouncer :7432
PgBouncer PostgreSQL
PgBouncer
PgBouncer
PgBouncer
PgBouncer
PgBouncer
PgBouncer
PgBouncer
41
Cascading PgBouncers
› Maintenance is difficult
› No control over distribution of load by instances of PgBouncers
42
Looks OK.
How to open source this?
Cancel running query
github.com/pgbouncer/pgbouncer/pull/79
44
What do we want?
45
Odyssey
Compilation
47
Internal architecture
main()
thread accept()
worker pool
system
worker
router servers
thread
attach/detach
console cron server
client
coroutine
coroutine
48
Multithreading
49
Multithreading details
50
Odyssey features
51
Enhanced transaction pooling
52
Odyssey features
› Replication support
Clients can migrate FROM your cloud managed services
53
Odyssey features
54
Odyssey features
› Error forwarding
Easier to handle overload
55
Logging and error forwarding
client_fwd_error off
$ psql "dbname=test host=localhost port=6432"
psql: ERROR: odyssey: c9259d96414b9: failed to connect to
remote server sce469f2305d9
client_fwd_error on
$ psql "dbname=test host=localhost port=6432"
psql: FATAL: odyssey: cbde3e23d9aa2: database "test"
does not exist
56
Logging and error forwarding
4249 17 Jun 17:32:27.604 info [cbde3e23d9aa2 none] (startup) new client connection [::1]:50676
4249 17 Jun 17:32:27.604 info [cbde3e23d9aa2 none] (startup) route 'test.pmwkaa' to 'default.default'
4249 17 Jun 17:32:27.604 info [cbde3e23d9aa2 sa6a53e6ec6d7] (setup) new server connection
127.0.0.1:5432
4249 17 Jun 17:32:27.607 error [cbde3e23d9aa2 sa6a53e6ec6d7] (startup) FATAL 3D000 database "test"
57
Logging and error forwarding
client_fwd_error off
$ psql "dbname=test host=localhost port=6432"
psql: ERROR: odyssey: c9259d96414b9: failed to connect to
remote server sce469f2305d9
client_fwd_error on
$ psql "dbname=test host=localhost port=6432"
psql: FATAL: odyssey: cbde3e23d9aa2: database "test"
does not exist
58
Route settings
storage "postgres_server" {
type "remote"
host "127.0.0.1"
port 5432
tls "disable"
59
Route settings
database "test" {
user "test" {
storage "postgres_server"
authentication "none"
client_max 100
pool "transaction"
pool_size 10
pool_cancel yes
pool_rollback yes
}
user default {
authentication "block"
}
}
60
Route settings
database default {
user default {
authentication "block"
}
}
61
pgbench Odyssey RPS PgBouncer RPS
0
1 worker 2 workers 4 workers 8 workers
*Benchmark results depend on software, hardware and weather on the moon. Do not trust them.
**We optimized scaling, not throughput. 62
How we test
63
How we test
64
Roadmap
› SCRAM authentication
› Forward read-only queries to replica
› Online restart
› Pause server
› …
› Pull requests are welcome!
65
Andrey Borodin
[email protected]
x4mmm