Odyssey – Scalable PostgreSQL connection pooler
github.com
github.com
Shameless plug. We have recently forked pgbouncer to add multicore support[0]. We are running in production for couple of weeks and the performance is great.
Our design is very straightforward. Instead of touching the current code, we've extended it by a manager, that spins workers, which are essentially forks of pgbouncer itself (one per core, or whatever you specify in the settings), and then distributes the connections between the clients and the workers. So if you decide not to use the multiprocessing part, you can just turn it off and you will be running the same old pgbouncer you are used to. It also allows for the code to be merged to the original code base without any significant changes.
Many solve this by running multiple instances of PGB (usually each on a dedicated processor) and use some kind of load balancing (haproxy, DNS, ...) to balance the connections.
This fork removes the need for the load balancing as it does it out of the box.
BTW this is only an issue if you’ve many connections to Postgres. We have thousands servers[0] connecting in and also run a citus[1] where the queries are distributed to many workers (with addition of citus MX that now allows each server to behave as a coordinator)[2].
At a small scale you are fine with the default postgres though.
[0] https://cloud.google.com/customers/pex/
[1] https://www.citusdata.com/customers/pex
[2] https://www.citusdata.com/blog/2016/09/22/announcing-citus-m...
That is, if you don't create a new DB connection for each HTTP request, but instead create one (or a few) connections at webserver startup time, which can serve all coming requests?
However client pooling can only optimize the single client that it runs on. Server side pooling allows it to optimize all the connections. If you are running a small deployment with couple of clients, then you truly don't need to use any server side pooling. Not that you won't benefit from it, but it may be a bit more hassle than needed.
A separate pooler makes sense here because it'll let Rails imagine it has how many ever thousands of connections it needs open, but map them to real connections only when usage actually happens.
This is easier than taking over connection management manually in the code, which the only other option.
The Rails will checkout a connection for you, but it won't necessarily start a transaction if you don't ask it to. Think there's some magic involved there, but generally transactions don't start unless necessary or they're initiated by code.
0 - https://www.postgresql.org/docs/current/static/protocol-mess...
Glibness aside, this has a few more interesting options, like configuration at a user-db level.
that's my biggest issue with pgbouncer, is there a docker image for it?
i tested this on my local machine and if i drop a connection while it is inside a transaction it closes the server connection.
client close:
2018-05-30 15:28:42.068 21702 LOG C-0x7f9728816a10: DB/USER@[::1]:64342 closing because: client close request (age=85)
2018-05-30 15:28:42.068 21702 LOG S-0x7f972980a190: DB/USER@127.0.0.1:5432 closing because: unclean server (age=85)
client unexpected death: 2018-05-30 15:33:57.197 21702 LOG C-0x7f9728816a10: DB/USER@[::1]:64376 closing because: client unexpected eof (age=15)
2018-05-30 15:33:57.198 21702 LOG S-0x7f972980a190: DB/USER@127.0.0.1:5432 closing because: unclean server (age=10)
i guess it sucks that it doesn't reuse the connection but presumably this shouldn't happen that often that it would actually be a problem.FWIW we use it in exactly that way to serve many thousands of rps with no issues.
Connection Pooling as a Service, why does this not exist? What factors could cause this to be a bad idea? Need for proximity? Network speeds? Security?
Each AWS location, each Google Cloud location.. and that’s not considering those that are colocating their own kit.
Interesting idea though, but you’d end up having to bundle it with DBaaS, at which point you’ve got the pressure and stress of having to look after everyone else’s data.
In short, yes to all.
Specifically, fallacy [1] numbers 1, 2, 3, 4, and 7. Maybe number 5.
None of those are necessarily insurmountable. However, given how relatively lightweight a connection pooler is to operate, especially compared with Postgres itself, it doesn't seem like an attractive target to "outsource".
[1] https://en.wikipedia.org/wiki/Fallacies_of_distributed_compu...
And no usage examples?