Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Redis Cluster on Java for Scaling and High Availability

DZone 's Guide to

Redis Cluster on Java for Scaling and High Availability

Learn more about building a Redis cluster on Java — for scaling and high availability.

· Java Zone ·
Free Resource

Redis cluster

What Is a Redis Cluster?

Scalability and availability are two of the most important qualities of any enterprise-class database.

It’s very unusual that you can exactly predict the maximum amount of resources your database will consume, so scalability is a must in order to deal with periods of unexpectedly high demand. Yet, scalability is useless without availability, which ensures that users will always be able to access the information within the database when they need it.

You may also like: Creating Distributed Java Applications With Redis

Redis is an in-memory data structure store that can be used to implement a non-relational key-value database. However, the bare-bones installation of Redis does not come equipped for maximum performance right off the bat.

In order to improve the scalability and availability of a Redis deployment, you can use Redis Cluster, a method of automatically sharding data across different Redis nodes. Redis Cluster breaks up a very large Redis database into smaller horizontal partitions known as shards that are stored on separate servers.

This makes the Redis database able to accommodate a larger number of requests, and therefore more scalable. What’s more, availability improves because the database can continue operations even when some of the nodes in the cluster have failed.

Before version 3.0, Redis Cluster used asynchronous replication. This meant that, in practice, if a master in Redis Cluster crashes before sending a write to all of its slaves, one of the slaves that did not receive the write can be promoted to master, which will cause the write to be lost.

Since version 3.0, Redis Cluster also has a synchronous replication option in the form of the WAIT command, which blocks the current client until all write commands are successfully completed. While this is not enough to guarantee strong consistency, it does make the data transfer process significantly more secure.

How to Run a Redis Cluster

There are two ways to get Redis Cluster up and running: the easy way and the hard way.

The easy way involves using the  create-cluster bash script, which you can find in the  utils/create-cluster directory in your Redis installation. The following two commands will create a default cluster with 6 nodes, 3 masters, and 3 slaves:

create-cluster start
create-cluster create


Once the cluster is created, you can interact with it. By default, the first node in the cluster starts at port 30001. Stop the cluster with the command:

create-cluster stop


The hard way of running Redis Cluster involves setting up your own configuration files for the cluster. All instances of Redis Cluster must contain at least three master nodes.

Below is an example configuration file for a single node:

port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes


As its name suggests, the  cluster-enabled option enables the cluster mode. The  cluster-config-file option contains a path to the configuration file for the given node.

To create a test Redis Cluster instance with three master nodes and three slave nodes, execute the following commands in your terminal:

mkdir cluster-test
cd cluster-test
mkdir 7000 7001 7002 7003 7004 7005


Within each of these six directories, create a redis.conf configuration file using the example configuration file given above. Then, copy your redis-server executable into the cluster-test directory and use it to launch six different nodes in six different tabs of your terminal.

Connecting to Redis Cluster on Java

Like the base Redis installation, Redis Cluster is not able to work with the Java programming language out of the box. The good news is that there are frameworks that make it easy for you to use Redis Cluster and Java together.

Redisson is a Java client for Redis that includes many common constructs in Java, including a variety of objects, collections, locks, and services. Because Redisson reimplements these constructs in a distributed fashion, they can be shared across multiple applications and servers, allowing them to work with tools like Redis Cluster.

The following code demonstrates the usage of Redisson with Redis Cluster:

package redis.demo;
import org.redisson.Redisson;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;

/**
 * Redis Sentinel Java example
 *
 */
public class Application 
{
    public static void main( String[] args )
    {
        Config config = new Config();
        config.useClusterServers()
              .addNodeAddress("redis://127.0.0.1:6379", "redis://127.0.0.1:6380");

        RedissonClient redisson = Redisson.create(config);

        // operations with Redis based Lock

        // implements java.util.concurrent.locks.Lock
        RLock lock = redisson.getLock("simpleLock");
        lock.lock();

        try {
           // do some actions
        } finally {
           lock.unlock();
        }

        // operations with Redis based Map

        // implements java.util.concurrent.ConcurrentMap
        RMap<String, String> map = redisson.getMap("simpleMap");
        map.put("mapKey", "This is a map value");

        String mapValue = map.get("mapKey");
        System.out.println("stored map value: " + mapValue);

        redisson.shutdown();
    }
}


Redisson is an open-source client that enables Java programmers to work with Redis with minimal stress and complication, making the development process drastically easier and more familiar.

Further Reading

Creating Distributed Java Applications With Redis

Quickstart: How to Use Redis on Java

Java Distributed Caching in Redis

Topics:
java ,redis ,cluster ,scaling ,tutorial ,redisson ,redis cluster

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}