I’m very happy to have another interesting blog post by Vlad Mihalcea on the jOOQ blog, this time about his Open Source library FlexyPool. Read his previous jOOQ Tuesdays post on Hibernate here.
Vlad is a Hibernate developer advocate and he’s the author of the popular book High-Performance Java Persistence, and he knows a thing or two about connection pooling.
Back in 2014, I was working as a software architect, and our team was building a real-estate platform which was composed of multiple nodes, as depicted in the following diagram:
This is a classic enterprise architecture layout. The database is replicated to provide better throughout and availability in case of node failures. There are front-end nodes that deliver the website content. There are also many back-end nodes as well, like email schedulers or data import batch processors.
All these nodes require database connectivity, either to a Master node, for read-write transactions or to the Slave nodes, for read-only transactions.
Because acquiring database connections is an expensive process, each system node uses its own connection pool. By reusing physical database connections, the connection acquisition is very fast, therefore reducing the overall transaction response time.
Not only that a connection pool can reduce transaction response time, but it can level up traffic spikes as well. Without a connection pool, during a traffic spike, a front-end nodes might acquire all database connections, leaving the back-end processors with no database connectivity.
The connection pool, having a maximum number of database connections, allows the connections to queue whenever a traffic spike is happening. Therefore, during a traffic spike, the transaction response time will increase due to the queuing mechanism, but this is way better than taking down the whole system.
For these two reasons, the connection pool is a very good choice in many enterprise systems.
Based on the underlying hardware resources, a relational database can only offer a limited number of connections. For this reason, we must be very careful when choosing the pool size for each particular system node.
Connection Pool Sizing
I was the lucky person to get the task of figuring out how many connections should we allocate for each system node in our real-estate platform. Since I graduated Electronics and Telecommunications, I remembered that we learned about a similar problem when having to provision telecommunications networks. Agner Krarup Erlang invented Queuing theory for solving this problem, and I was curious if we could also find the right pool size by applying Erlang queuing models.
I was not the only one trying to apply the Queuing theory principles to software systems. Percona has a very interesting study: Forecasting MySQL Scalability with the actual service time in a system that is affected by a myriad of variables.
In the end, I realized that the best way to tackle this problem is to constant measuring and adjustments. For this reason, I needed a tool to capture database connection metrics, as well as a way to adjust a given connection pool while the enterprise system is running.
And, that’s how FlexyPool was born.
Basically, FlexyPool is a
DataSource Proxy that stands in front of the actual JDBC
DataSource or other proxies (e.g. statement logging).
FlexyPool supports a great variety of stand-alone connection pools:
- Apache DBCP
- Apache DBCP2
- Tomcat CP
- Vibur DBCP
- Bitronix Transaction Manager
- Atomikos TransactionsEssentials
And it collects the following metrics:
- concurrent connections histogram
- concurrent connection requests histogram
- data source connection acquiring time histogram
- connection lease time histogram
- maximum pool size histogram
- total connection acquiring time histogram
- overflow pool size histogram
- retries attempts histogram
For instance, the concurrent connection count metric gives you an insight into how many connections are required by a certain application under a given traffic load:
The connection acquisition metric tells you how much time it takes to obtain a database connection from the pool:
The connection lease time allows you to spot long-running transactions, which are undesirable in high-performance OLTP applications:
For the stand-alone connection pools, FlexyPool can increment the pool size beyond the maximum capacity, as it offers an overflow buffer. The benefit of this overflow buffer is that it allows you to increase the pool size only when the incoming traffic causes a certain connection acquisition timeout.
Although FlexyPool can also monitor Java EE connection pools, it cannot increase the pool size in Java EE environments since the
DataSource is an application server managed resource.
Because enterprise systems evolve, so does the underlying data access patterns. For this reasons, monitoring the underlying database connection usage is a very important metric, which needs to be monitored on a regular basis. FlexyPool builds on top of CodaHale and Dropwizard Metrics, so you can easily integrate it with well-known Application Performance Monitoring tools, such as Graphite or Grafana.
FlexyPool is open-source, and it uses an Apache license 2.0. You can find it the project repository on GitHub, and all the released dependencies are available on Maven Central, so it’s very easy to integrate it in your own project.
FkexyPool is powering many enterprise systems, like Etuovi, Mitch&Mates, and ScentBird. If you decide to use it in your current enterprise system, and you are willing to provide a testimonial, you can win a free copy of my High-Performance Java Persistence book.