How to manage connections efficiently in any database
本文讨论了如何高效管理数据库连接。下图是 Postgres 的 forking 进程模型,瓶颈在共享内存那块。
优化方法:
- connection pools: 在每个节点都保存一个内存池,workers 从内存池拿连接,而内存池只需要向 master 维持一个连接。缺点是一旦遇上使用 unicorn/puma 这类 forking servers,程序就不是单进程了,内存池就没那么有效。
- minimum viable checkouts: workers 只在必要的时候占用连接池,像 decoding,validating, rate limiting 这些事情就别占用连接时间了。
- PgBouncer & inter-node pooling: 如果连接还是太多了,可以考虑在数据库前面再放一层 proxy,让 proxy 处理这些连接,给后端数据库减负担。
结论:连接即是资源(connection as a resource),程序不能无休止地消耗资源。开发者要清楚每个节点用了多少连接 M ,一共有多少个节点 N, 你的数据库 max_connections 能不能承受 MxN 个连接?如果不能,就得去做上面的优化。如果能,考虑下 graceful restart 时的特殊 case,那时候,连接理论上最差情况会翻倍哟!