Connection pool architecture - Netflix/dyno GitHub Wiki
Dyno was largely inspired from Astyanax which is the connection pool library for talking to Cassandra. Dyno was written as a generic connection pool library which is highly configurable and pluggable. It is also agnostic to the client protocol underneath. Hence one can use Dyno with different plugins underneath such as Jedis, Memcached, HttpClient, Thrift etc.
With the first release of Dyno, we have the plugin impl for Jedis Client for talking to a Redis based Dynomite system.
Plugins based off of Redisson are coming soon.
Other possible plugins
- spy memcached plugin for Dyno.
- Dyno can also be used with HttpClient to do load balancing and connection pooling of connections to another http based services like ElasticSearch, Riak et all.
###Dyno Jedis Client This is the top level client that is used by callers to execute operations against a Dynomite cluster backed by Redis. It uses the Jedis Client underneath which encapsulates a single connection to a single Dynomite node (also running Redis on that node).
Main responsibilities include
- Provide basic implementation for the Redis commands using the Jedis client
- Delegate the Redis command executable to the ConnectionPool component which can use failover, load balancing etc to execute the command.
Here is an example
public Map<String, String> hgetAll(final String key) {
return connPool.executeWithFailover(new BaseKeyOperation<Map<String, String>>(key, OpName.HGETALL) {
@Override
public Map<String, String> execute(Jedis client, ConnectionContext state) {
return client.hgetAll(key);
}
});
}
###ConnectionPoolConfiguration This is the main module for configuring everything in Dyno. More details on config can be found Configuration
###HostSupplier Simple component that provides a list of Hosts. At Netflix we use the EurekaHostsSupplier as a default since Dynomite integrates well with our internal Eureka Service.
Please plug in your own to get started with Dyno. Here is the simple interface to implement.
/**
* Return a collection of dynomite hosts for the connection pool
* @return Collection<Host>
*/
public Collection<Host> getHosts();
###HostSelectionStrategy This is the load balancer in Dyno. Used for selecting what HostConnectionPool to use when executing a request. 2 main strategies exist - RoundRobin and TokenAware. Note that this component needs to use a TokenMapSupplier which refreshes it's state with the Dynomite server side topology. This helps the component map a given operation / key to a backend Dynomite node.
###ConnectionPoolMonitor This is the component that tracks metrics / counters for all the operations in Dyno.
- It gives insight into success/errors for each of the Dyno operations as dictated by clients such as Dyno Jedis Client.
- It also gives insight into the functioning of the connection pool components. As a default, Dyno uses an impl based off Servo which is wired to send metrics to our internal metrics system.
Here are a couple options to get your metrics flowing to your system
- Implement the ConnectionPoolMonitor.java interface
- Extend this CountingConnectionPoolMonitorImpl.java class
This component runs in the background and monitors feedback given to it when executing operations against a HostConnectionPool. It employs a sophisticated rate tracking mechanism which can be configured to various degrees of sensitivity, which can then be used to track large spikes in errors.
Once the component determines that the error rate for a HostConnectionPool is too high, it then sends a markAsDown() and reconnect() signal to the pool. A pool which is down will no longer accept requests till it is properly reconnected.
Also while a host connection pool is being reconnected, other active replica hosts for that token range will take over requests for this pool. This is all done by Dyno.
###HostConnectionPool This is a pool of connections to a single Dynomite node.
Main responsibilities
- Priming connections on connection pool startup / library init - see ConnectionPoolConfiguration maxConnsPerHost
- Managing shared thread safe access to connections to the backend node. Note that for the SyncConnectionPoolImpl only one request can access a connection at a time. Hence this components maintains a queue of available connections. ** When a connection is requested, the component waits on the queue for the specified amt of time - connectTimeout ** When a connection is returned, it is added back to the pool so that it can be re-used for other requests.
- Reconnecting the pool when requested by the ConnectionPoolHealthTracker
###ConnectionPool This is the core of the library that brings everything together. It co-ordinates all the other components together to enable execution of commands against a backend system like Dynomite.
Main responsibilities include
- Use provided configuration to control behavior of each of the component it co-ordinates.
- Accept input from an external HostSupplier, and init HostConnectionPool(s) for each host.
- Manage HostConnectionPool(s) as Hosts go in and out of the Dynomite ring.
- Accept requests from the DynoJedisClient component and execute them with configurable retries.
- Use HostSelectionStrategy (RoundRobin or TokenAware) to select HostConnectionPool when executing a request from DynoJedisClient
- Provide metrics / stats about operation execution and operations on the connection pools.
- Provide feedback to the ConnectionPoolHealthTracker for HostConnectionPool(s) with high error rates