Hector (API)
| Company type | Software library |
|---|---|
| Industry | Software development |
| Founder | Ran Tavory |
| Products | Java client API for Apache Cassandra |
| Website | github |
Hector serves as an advanced client API for Apache Cassandra, designed to replace the Cassandra Java Client or Thrift. Developed by Ran Tavory, Hector provides an object-oriented layer that overcomes the limitations found in the native Thrift client. It incorporates enterprise-grade functionalities such as connection pooling, failover mechanisms, JMX integration, and employs the Command design pattern. By fully wrapping the Thrift API, Hector streamlines development by enabling users to interact exclusively with its client while still allowing access to the underlying API during migration. The library is accessible through a Maven repository, simplifying its adoption in Java projects.
History
Ran Tavory created Hector to enhance Cassandra's original low-level Thrift (protocol) interface by delivering a more resilient and high-level API solution. Distributed under the MIT License, it supports extensive use and customization, making it suitable for diverse commercial applications.
Features
Hector presents a sophisticated object-oriented API for Cassandra, heavily influenced by the Cassandra-java-client and centered around the Keyspace interface. It incorporates connection pooling to manage numerous simultaneous read/write operations efficiently, preventing socket exhaustion in high-demand environments.
Designed with Cassandra’s distributed nature in mind, Hector includes failover capabilities with several policies:
| Policy | Description |
|---|---|
FAIL_FAST |
Immediately fails upon encountering an error |
ON_FAIL_TRY_ONE_NEXT_AVAILABLE |
Tries one alternative host before failing |
ON_FAIL_TRY_ALL_AVAILABLE |
Attempts all available hosts prior to failure |
Operational monitoring is enhanced through exposure of runtime metrics via JMX, encompassing connection statistics and error counts. Load balancing is implemented using the LoadBalancingPolicy interface, offering two options: the default LeastActiveBalancingPolicy, which directs requests to pools with minimal active connections to maximize cluster efficiency, and RoundRobinBalancingPolicy, which distributes requests evenly in a cyclic order.
Furthermore, Hector adopts the command design pattern, enabling users to concentrate on business-specific logic while it manages infrastructure-related concerns.
Availability metrics
Through JMX, Hector supplies counters related to availability and performance metrics, supporting improved system monitoring and management.
Load balancing
Hector’s customizable load balancing approaches include:
LeastActiveBalancingPolicy: allocates requests to connection pools with the fewest active sessions, enhancing cluster resource distribution.RoundRobinBalancingPolicy: applies a simple round-robin method for evenly spreading incoming requests.
Pooling
The ExhaustedPolicy dictates how the client connection pool behaves, featuring three distinct modes:
| Type | Description |
|---|---|
WHEN_EXHAUSTED_FAIL |
Immediately fails when no clients remain available |
WHEN_EXHAUSTED_GROW |
Dynamically expands the pool to accommodate increased demand |
WHEN_EXHAUSTED_BLOCK |
Waits until a client becomes free before proceeding (default setting) |
Code examples
Sample code demonstrating a basic distributed hashtable implementation utilizing Cassandra: <syntaxhighlight lang="java">
/**
* Store a value associated with a key
*/
public void insert(final String key, final String value) throws Exception {
execute(new Command(){
public Void execute(final Keyspace ks) throws Exception {
ks.insert(key, createColumnPath(COLUMN_NAME), bytes(value));
return null;
}
});
}
/**
* Fetch a string value by key; returns null if absent.
*/
public String get(final String key) throws Exception {
return execute(new Command(){
public String execute(final Keyspace ks) throws Exception {
try {
return string(ks.getColumn(key, createColumnPath(COLUMN_NAME)).getValue());
} catch (NotFoundException e) {
return null;
}
}
});
}
/**
* Remove a key entry from Cassandra
*/
public void delete(final String key) throws Exception {
execute(new Command(){
public Void execute(final Keyspace ks) throws Exception {
ks.remove(key, createColumnPath(COLUMN_NAME));
return null;
}
});
}
</syntaxhighlight>