Redis – How to Setup a Six Node Redis Test Cluster in Ubuntu on Windows 10

I work on several applications that use Redis. In production those applications all use six node Redis clusters that run on Linux. However, my developer workstation is a Windows 10 machine on which I only have a single node instance of Redis running. I really wanted to have a six node Redis cluster to test against in my Windows 10 development environment, the problem is that the utilities that come with Redis that allow you to setup a multiple node test cluster on a single machine, are all written to work on Linux.

Since I can’t do anything about the fact that my workstation is a Windows 10 machine, it turns out the solution was quite simple, use the Ubuntu subsystem.

In this article I will walk you through setting up a six node Redis test cluster running on Windows 10 using the Ubuntu subsystem.

Install Ubuntu Subsystem

The first step is to go to the Windows Store, search for Ubuntu, and when you find the latest version of the Ubuntu App install it:

Once the Ubuntu subsystem is installed, you can launch the app from the windows start menu by typing “Ubuntu”:

Install Redis on Ubuntu

Fix SSL Issue

One issue you may run into when trying to download Ruby packages from within the Ubuntu subsystem is an SSL issue. The solution is to run the following commands:

First, remove the source if it exists:

gem sources -r https://rubygems.org/

Second, add the source again but with “http”:

gem sources -a http://rubygems.org/

Install Redis

Ensure all packages are up to date:

apt-get update

Install Ruby:

apt-get install ruby

Download Redis:

wget https://download.redis.io/releases/redis-5.0.12.tar.gz --no-check-certificate

Unzip the package into the /opt folder:

tar -zxvf redis-5.0.12.tar.gz /opt

Navigate to the Redis folder:

cd /opt/redis-5.0.12

Build the Redis executable:

apt install make

apt install make-guile

apt install gcc

apt install build-essential

make MALLOC=libc 

apt install redis-tools

Create Redis Cluster

Navigate to the “create-cluster” folder:

cd /opt/redis-5.0.12/utils/create-cluster

Edit the “create-cluster” script:

vi create-cluster

Modify the cluster start port from “PORT=30000” to be “PORT=7000”:

#!/bin/bash

# Settings
PORT=7000
TIMEOUT=2000
NODES=6
REPLICAS=1

Note: This is a personal preference, to have the starting port set to 7000, so it is up to you if you want to change it or not.

Start the six nodes:

./create-cluster start

When the six nodes are started, the ports 7001 to 7006 will be used.

Starting 7001
Starting 7002
Starting 7003
Starting 7004
Starting 7005
Starting 7006

Now we are ready to configure the six nodes as a cluster.

Create the cluster:

./create-cluster create

You should see the following output as the cluster configuration is generated:

>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:7005 to 127.0.0.1:7001
Adding replica 127.0.0.1:7006 to 127.0.0.1:7002
Adding replica 127.0.0.1:7004 to 127.0.0.1:7003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: cf10723420c411b32ebcd7a50a724fa1bb00add0 127.0.0.1:7001
   slots:[0-5460] (5461 slots) master
M: f563c0cc983f181d8fde839f3508d52f1905b96e 127.0.0.1:7002
   slots:[5461-10922] (5462 slots) master
M: 36f2de71920d07030b93e4e1bd7c49afc1a26276 127.0.0.1:7003
   slots:[10923-16383] (5461 slots) master
S: fd872ad38d305ab067a86eacc33775b362feed0e 127.0.0.1:7004
   replicates f563c0cc983f181d8fde839f3508d52f1905b96e
S: 3115b82336b10f57de1a6936cff93a8e45df777f 127.0.0.1:7005
   replicates 36f2de71920d07030b93e4e1bd7c49afc1a26276
S: 17bb709ba3af5311e44fc408d3f44979bae1f1dc 127.0.0.1:7006
   replicates cf10723420c411b32ebcd7a50a724fa1bb00add0

You will be prompted to accept the configuration that is displayed, if everything looks correct answer “yes”

Can I set the above configuration? (type 'yes' to accept): yes

Then you should see the following output as the cluster configuration is applied:

>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: cf10723420c411b32ebcd7a50a724fa1bb00add0 127.0.0.1:7001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 17bb709ba3af5311e44fc408d3f44979bae1f1dc 127.0.0.1:7006
   slots: (0 slots) slave
   replicates cf10723420c411b32ebcd7a50a724fa1bb00add0
M: 36f2de71920d07030b93e4e1bd7c49afc1a26276 127.0.0.1:7003
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 3115b82336b10f57de1a6936cff93a8e45df777f 127.0.0.1:7005
   slots: (0 slots) slave
   replicates 36f2de71920d07030b93e4e1bd7c49afc1a26276
S: fd872ad38d305ab067a86eacc33775b362feed0e 127.0.0.1:7004
   slots: (0 slots) slave
   replicates f563c0cc983f181d8fde839f3508d52f1905b96e
M: f563c0cc983f181d8fde839f3508d52f1905b96e 127.0.0.1:7002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

The cluster should now be configured and running.

You can view the list of nodes in the cluster by running the following command:

redis-cli -p 7001 cluster nodes
17bb709ba3af5311e44fc408d3f44979bae1f1dc 127.0.0.1:7006@17006 slave cf10723420c411b32ebcd7a50a724fa1bb00add0 0 1625887492326 6 connected
36f2de71920d07030b93e4e1bd7c49afc1a26276 127.0.0.1:7003@17003 master - 0 1625887492326 3 connected 10923-16383
3115b82336b10f57de1a6936cff93a8e45df777f 127.0.0.1:7005@17005 slave 36f2de71920d07030b93e4e1bd7c49afc1a26276 0 1625887492126 5 connected
cf10723420c411b32ebcd7a50a724fa1bb00add0 127.0.0.1:7001@17001 myself,master - 0 1625887492000 1 connected 0-5460
fd872ad38d305ab067a86eacc33775b362feed0e 127.0.0.1:7004@17004 slave f563c0cc983f181d8fde839f3508d52f1905b96e 0 1625887492025 4 connected
f563c0cc983f181d8fde839f3508d52f1905b96e 127.0.0.1:7002@17002 master - 0 1625887492025 2 connected 5461-10922

That is it, the cluster is now ready!

Useful Cluster Commands

Here are some common commands you will use when working with your new Redis cluster.

Starting a cluster

Here is the start cluster command:

./create-cluster start

When the cluster is started successfully you should see the following output:

root@mycomputer:/opt/redis-5.0.12/utils/create-cluster# ./create-cluster start
Starting 7001
Starting 7002
Starting 7003
Starting 7004
Starting 7005
Starting 7006

Stopping a cluster

Here is the stop cluster command:

./create-cluster stop

When the cluster is stopped you should see the following output:

root@mycompouter:/opt/redis-5.0.12/utils/create-cluster# ./create-cluster stop
Stopping 7001
Stopping 7002
Stopping 7003
Stopping 7004
Stopping 7005
Stopping 7006

Removing a cluster

If you need to remove the existing cluster for some reason you can run the following command:

./create-cluster clean

References

Cassandra – How to Run DataStax Enterprise in Ubuntu on Windows 10

Previously I had been working with open source Apache Cassandra, but now I mostly work with DataStax Enterprise (DSE) Cassandra. The one downside is that since my developer workstation is Windows 10, only Apache Cassandra is supported on Windows, while DSE Cassandra is not.

In the past when I had Linux only software I wanted to run on my workstation, I typically used a VM, usually running Virtual Box. However, after trying out the Ubuntu Subsystem and installing DSE Cassandra in it, we found it to be a much more convenient way of running DSE Cassandra locally.

The following instructions are just a summary of information I put together from multiple sources to get DSE Cassandra working for me, which includes work arounds for several little gotchas, so I hope this saves you some time!

Note: At the time I wrote these instructions I was using the following versions:

  • DSE – 5.1.22
  • Ubuntu Subsystem – 20.04 LTS

Setup DSE in Ubuntu Subsystem

Install Ubuntu Subsystem

From the Microsoft Store in Windows 10, select and install a version of Ubuntu, such as:

Once installed, from the Windows Start menu type “Ubuntu” and open the app.

A Ubuntu command prompt will be opened, which you will use for the rest of these instructions.

Install Java

DSE 5+ requires Java 8, so you will need to ensure you have Java 8 installed.

Install OpenJdk 8:

sudo apt-get install openjdk-8-jdk

Add JAVA_HOME environment variable:

export JAVA_HOME=/usr/bin/java

Deal with Certificate Issue

Before you start you will need to deal with a certificate issue that will cause problems when apt-get tries to download packages from the DataStax repository.

Edit the following file:

vi /etc/apt/apt.conf.d/apt.conf

Now paste in the following code:

// Do not verify peer certificate
Acquire::https::Verify-Peer "false";
// Do not verify that certificate name matches server name
Acquire::https::Verify-Host "false";

Install DSE Cassandra

Now you can start installing DSE Cassandra. If you want more details you can refer to the official instructions, however all the steps you will need are in the summary below.

Add the DataStax repository so apt-get can download the packages from DataStax.

echo "deb https://debian.datastax.com/enterprise stable main" | sudo tee -a /etc/apt/sources.list.d/datastax.sources.list

Add the repository key.

Note: you will need to ignore the SSL cert check with option -k.

curl -k -L https://debian.datastax.com/debian/repo_key | sudo apt-key add -

Run an apt-get update to make sure all packages are up to date before installing DSE.

sudo apt-get update

Now run the install with apt-get.

sudo apt-get install dse=5.1.22-1 \
    dse-full=5.1.22-1 \
    dse-libcassandra=5.1.22-1 \
    dse-libgraph=5.1.22-1 \
    dse-libhadoop2-client-native=5.1.22-1 \
    dse-libhadoop2-client=5.1.22-1 \
    dse-liblog4j=5.1.22-1 \
    dse-libsolr=5.1.22-1 \
    dse-libspark=5.1.22-1 \
    dse-libtomcat=5.1.22-1

Update the max_map_count setting.

Note: If you do not do this step you will encounter errors when trying to start DSE.

Edit the following file:

vi /etc/sysctl.conf

Add the following line:

vm.max_map_count = 1048575

Run DSE Cassandra

Start DSE.

sudo service dse start

Verify the service has started.

sudo service dse status

You should see the following output if DSE is running.

 * dse is running

As DSE is starting you can tail the logs.

tail -f /var/log/cassandra/debug.log

If you see the following output then DSE has finished the startup process and is ready to use.

INFO  [main] 2021-04-23 10:05:19,264  DseDaemon.java:872 - DSE startup complete.

You can also use the admin tool nodetool to verify the health of Cassandra.

nodetool status

If everything is good, on the far right side you will see the status and the state noted by two letters:

  • U – Is the status, which is “Up
  • N – Is the state, which is “Normal
Datacenter: Cassandra
=====================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving/Stopped
--  Address    Load       Owns (effective)  Host ID                               Token                    Rack
UN  127.0.0.1  272.77 KiB  100.0%            192bc33a-5dbf-4aba-984a-f2388d3496fa  -1965318375701162027    rack1

Connect to DSE Cassandra

Now that we have Cassandra running in our Ubuntu subsystem, the best way to verify everything is working properly is to connect to Cassandra from an application.

First let’s create a new Keyspace and table.

From your Ubuntu command prompt type the command CQLSH to open a query shell.

cqlsh

You should see the following output if the query shell has been opened successfully.

Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | DSE 5.1.20 | CQL spec 3.4.4 | DSE protocol v1]
Use HELP for help.
cqlsh>

Create a new keyspace by executing the following query in your CQLSH shell.

CREATE KEYSPACE UbuntuExample 
WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', 'Cassandra' : 1 };

Switch to the new keyspace with the USE command.

USE UbuntuExample;

Create a table to store some data.

CREATE TABLE examples (
 id int,
 name text,
 PRIMARY KEY(id)
);

Insert a row into the table.

INSERT INTO examples(id,name) VALUES (1,'Example One');

Verify the new row has been added with a select.

SELECT * FROM examples WHERE id = 1;

You should see the following output.

cqlsh:ubuntuexample> SELECT * FROM examples WHERE id = 1;

 id | name
----+-------------
  1 | Example One

(1 rows)

Now let’s connect to Cassandra and run the same select statement using Python. I put together the following script from the DataStax Python Driver example. At the time when I created this example the current driver version was 3.25.

Install the Python Cassandra driver:

pip install cassandra-driver

Copy the following Python code into a file called “cassandra_example.py”.

from cassandra.cluster import Cluster

if __name__ == "__main__":
    cluster = Cluster(['localhost'], port=9042)
    session = cluster.connect('ubuntuexample')
    rows = session.execute('SELECT * FROM examples WHERE id = 1')
    for row in rows:
        print(row.name)

Run the script.

python cassandra_example.py

If our DSE Cassandra install was successful you should see the following response.

Example One

Summary

Overall I have found using the Ubuntu Subsystem to be very convenient for running DSE Cassandra on my developer workstation. I hope these instructions made it a little easier for you to get setup!