Apache Cassandra Failover and Load Balancing
I have 3-node cluster, my RF=3, W=ONE and R=QUORUM, once a node is down, another two node can work properly, if the downed node comes back, it also get update.
To solve load balancing, only need to change one line of the codes(from last tutorial) to :
//load balancing build a connection pool
cassandraHostConfigurator = new CassandraHostConfigurator("192.168.0.1:9160,192.168.0.2:9160,192.168.0.3:9160");
Hector will do load balancing internally.
To solve failover problem: please check here.
Be aware of the relationship between Replication factor and Consistency Level, please check here.
W+R > N. N is replication factor
I'm using cassandra(1.1.5), so I modified
http://ac31004.blogspot.ca/2010/08/consistencylevel-in-hector-and.html's code to:
import me.prettyprint.cassandra.service.OperationType;
import me.prettyprint.hector.api.ConsistencyLevelPolicy;
import me.prettyprint.hector.api.HConsistencyLevel;
// W+R > N . where N is Replication Factor
public final class MyConsistencyLevel implements ConsistencyLevelPolicy
{
@Override
public HConsistencyLevel get(OperationType op)
{
switch (op)
{
case READ:
return HConsistencyLevel.QUORUM;
case WRITE:
return HConsistencyLevel.ONE;
default:
return HConsistencyLevel.QUORUM;
}
}
@Override
public HConsistencyLevel get(OperationType op, String cfName)
{
return HConsistencyLevel.QUORUM;
}
}
Add or modify those code in CassandraTest.java(you can find it in last tutorial.)
ConsistencyLevelPolicy consistencyLevelPolicy = new MyConsistencyLevel();
Keyspace kpo = HFactory.createKeyspace(keySpace, cluster);
// set CL
kpo.setConsistencyLevelPolicy(consistencyLevelPolicy);
Tuesday, September 25, 2012
Apache Cassandra Java Program(Hector)
Hector is a high level java client for apache cassandra.
If you want to know more features of it, click here.
I'll show you the java code for connecting to cassandra database.
The following codes for inserting and reading.
Main.java
import java.util.concurrent.LinkedBlockingQueue;
public class Main
{
private static LinkedBlockingQueue queue = new LinkedBlockingQueue();
private static int numThreads;
public static void main(String[] args)
{
String host = "192.168.0.1";
int port = 9160;
//cluster number
String cluster = "Test Cluster";
//keyspace name
String keySpace = "keyspace_demo";
//column family
String colFamily = "colFamily_demo";
for(int i = 10; i <20 i="i">20>
{
queue.offer(i);
}
CassandraTest cassandraTest = new CassandraTest();
cassandraTest.run();
}
}
CassandraTest.java
public class Main
{
private static LinkedBlockingQueue
private static int numThreads;
public static void main(String[] args)
{
String host = "192.168.0.1";
int port = 9160;
//cluster number
String cluster = "Test Cluster";
//keyspace name
String keySpace = "keyspace_demo";
//column family
String colFamily = "colFamily_demo";
for(int i = 10; i <20 i="i">20>
queue.offer(i);
}
CassandraTest cassandraTest = new CassandraTest();
cassandraTest.run();
}
}
import java.util.concurrent.LinkedBlockingQueue;
import me.prettyprint.cassandra.model.ConfigurableConsistencyLevel; import me.prettyprint.cassandra.serializers.IntegerSerializer; import me.prettyprint.cassandra.serializers.StringSerializer; import me.prettyprint.cassandra.service.CassandraHostConfigurator; import me.prettyprint.hector.api.Cluster; import me.prettyprint.hector.api.HConsistencyLevel; import me.prettyprint.hector.api.Keyspace; import me.prettyprint.hector.api.beans.HColumn; import me.prettyprint.hector.api.exceptions.HectorException; import me.prettyprint.hector.api.factory.HFactory; import me.prettyprint.hector.api.mutation.Mutator; import me.prettyprint.hector.api.query.ColumnQuery; import me.prettyprint.hector.api.query.QueryResult;
public class CassandraTest { private final String host; private final int port; private final String cCluster; private final String keySpace; private final String mode; private String colFamily; private String columnName = "number"; private LinkedBlockingQueuequeue; private CassandraHostConfigurator cassandraHostConfigurator; private Cluster cluster; private Mutator mutator; private ColumnQuery columnQuery; private QueryResult > result; public CassandraTest(String _host, int _port, String _cCluster, String _keySpace, String _colFamily, LinkedBlockingQueue _queue) { host = _host; port = _port; cCluster = _cCluster; keySpace = _keySpace; colFamily = _colFamily; queue = _queue; setup(); } private void setup() { cassandraHostConfigurator = new CassandraHostConfigurator(host+":"+port); cluster = HFactory.getOrCreateCluster(cCluster, cassandraHostConfigurator); Keyspace kpo = HFactory.createKeyspace(keySpace, cluster); mutator = HFactory.createMutator(kpo, IntegerSerializer.get()); columnQuery = HFactory.createColumnQuery(kpo, IntegerSerializer.get(), StringSerializer.get(), IntegerSerializer.get()); } //read and write public void run() { while(queue.isEmpty() == false) { int i = queue.poll(); try { int numberValue = 0; // read from column family try { columnQuery.setColumnFamily(colFamily).setKey(i).setName(pcm); result = columnQuery.execute(); // get the column value numberValue = result.get().getValue(); } catch (Exception e) { } // write into column family mutator.insert(i, colFamily, HFactory.createColumn(columnName, (numberValue + 1))); } catch (HectorException e) { System.out.println("HectorException-" + i + ": " + e.getMessage()); } } } }
Apache Cassandra Cluster Setup
Apache Cassandra Cluster Setup
This tutorial is to build a 3-node cassandra cluster.
Step1: Download apache-cassandra and install it on your operating system.[more details in the previous tutorial]
Step2: Modify configuration fils, cassandra.yaml.
You can find it is under ../conf/cassandra.yaml
There are only three things you need to focus on if you just want to build a simple cassandra cluster:
1. listen_address
2. rpc_address
3. seeds
we'll take a glance at those one by one.
1. listen_address, Here is the description about it:
# Address to bind to and tell other Cassandra nodes to connect to. You
# _must_ change this if you want multiple nodes to be able to
# communicate!
#
# Leaving it blank leaves it up to InetAddress.getLocalHost(). This
# will always do the Right Thing *if* the node is properly configured
# (hostname, name resolution, etc), and the Right Thing is to use the
# address associated with the hostname (it might not be).
#
# Setting this to 0.0.0.0 is always wrong.
listen_address:
So, leave listen_address blank is a good choice.
2. rpc_address, here is the description:
# Address to broadcast to other Cassandra nodes
# Leaving this blank will set it to the same value as listen_address
# broadcast_address: 1.2.3.4
# The address to bind the Thrift RPC service to -- clients connect
# here. Unlike ListenAddress above, you *can* specify 0.0.0.0 here if
# you want Thrift to listen on all interfaces.
#
# Leaving this blank has the same effect it does for ListenAddress,
# (i.e. it will be based on the configured hostname of the node).
rpc_address:
After reading the description, leave it blank it good.
3. seeds, this part you have to edit it, the description of it:
# any class that implements the SeedProvider interface and has a
# constructor that takes a Map of parameters will do.
seed_provider:
# Addresses of hosts that are deemed contact points.
# Cassandra nodes use this list of hosts to find each other and learn
# the topology of the ring. You must change this if you are running
# multiple nodes!
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
# seeds is actually a comma-delimited list of addresses.
# Ex: ",,"
- seeds: "127.0.0.1"
You only need to change the last line "- seeds: "127.0.0.1", if your 3 IP address are 192.168.0.1, 192.168.0.2, and 192.168.0.3, your last line should be
- seeds:"192.168.0.1, 192.168.0.2, 192.168.0.3"
Step3: restart cassandra, and be sure that the port can access to other servers.
you can turn iptables off using the command in terminal:
# sudo service iptables stop
you can turn iptables off using the command in terminal:
# sudo service iptables stop
Step4: Now to check whether it works, using Cassandra-CLI(command line interface):
# ../bin/nodetool -h 192.168.1.0.1 -p 7199 ring
Address DC Rack Status State Load Owns Token 127605887595351923798765477786913079296 192.168.0.1 DC1 r1 Up Normal 17.3 MB 33.33% 0 192.168.0.2 DC1 r1 Up Normal 17.4 MB 33.33% 42535295865117307932921825928971026432 192.168.0.3 DC1 r1 Up Normal 37.2 MB 33.33% 85070591730234615865843651857942052864
Step5: Write new info to your cassandra database, and check all servers get the same date.
Tuesday, September 18, 2012
Install Apache Cassandra on CentOS
Install Apache
Cassandra on CentOS:
1. Download
cassandra:
# cd /opt
#wget ftp://apache.sunsite.ualberta.ca/pub/apache/cassandra/1.1.5/apache-cassandra-1.1.5-bin.tar.gz
2.Create
dirctories for the following keywords in cassandra.yaml file :
data_file_directories
commitlog_directory
saved_caches_directory
# sudo mkdir -p /var/lib/cassandra/data
# sudo mkdir -p /var/log/cassandra
# sudo mkdir -p /var/lib/cassandra/saved_caches
It is better to use separate disks for commitlog and data
# sudo mkdir -p /dev/shm/cassandra/commitlog
modify configuration file(cassandra.yaml), make sure the
directories you just created match with the path in the configuration file.
Edit the log4j-server.properties, make sure the path is correct as created from above commands.
log4j.appender.R.File=/var/log/cassandra/system.log
Edit the log4j-server.properties, make sure the path is correct as created from above commands.
log4j.appender.R.File=/var/log/cassandra/system.log
3. Create softlink
# ln -s
apache-cassandra-1.1.5 /opt/cassandra
4. Make cassandra as a service,
# sudo vim /etc/init.d/cassandra
and copy&paste the following script into
/etc/init.d/cassandra
-------------------------------------------------------
#!/bin/bash
# init script for Cassandra.
# chkconfig: 2345 90 10
# description: Cassandra
# script slightly modified from
#
http://blog.milford.io/2010/06/installing-apache-cassandra-on-centos/
. /etc/rc.d/init.d/functions
CASS_HOME=/opt/cassandra
CASS_BIN=$CASS_HOME/bin/cassandra
CASS_LOG=/var/log/cassandra/system.log
CASS_USER="root"
CASS_PID=/var/run/cassandra.pid
if [ ! -f $CASS_BIN ]; then
echo "File
not found: $CASS_BIN"
exit 1
fi
RETVAL=0
start() {
if [ -f $CASS_PID ] && checkpid `cat $CASS_PID`; then
echo "Cassandra
is already running."
exit 0
fi
echo -n $"Starting
$prog: "
daemon --user $CASS_USER $CASS_BIN -p $CASS_PID >> $CASS_LOG 2>&1
usleep 500000
RETVAL=$?
if [ "$RETVAL" = "0" ]; then
echo_success
else
echo_failure
fi
echo
return $RETVAL
}
stop() {
# check if the process is already stopped
by seeing if the pid file exists.
if [ ! -f $CASS_PID ]; then
echo "Cassandra
is already stopped."
exit 0
fi
echo -n $"Stopping
$prog: "
if kill `cat $CASS_PID`; then
RETVAL=0
echo_success
else
RETVAL=1
echo_failure
fi
echo
[ $RETVAL = 0 ]
}
status_fn() {
if [ -f $CASS_PID ] && checkpid `cat $CASS_PID`; then
echo "Cassandra
is running."
exit 0
else
echo "Cassandra
is stopped."
exit 1
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status_fn
;;
restart)
stop
usleep 500000
start
;;
*)
echo $"Usage:
$prog {start|stop|restart|status}"
RETVAL=3
esac
exit $RETVAL
------------------------------------------------------
//end of service script
start or stop cassandra service
# sudo chmod +x /etc/init.d/cassandra
# sudo service cassandra start
# sudo service cassandra stop
bring cassandra alive when reboot:
# sudo chmod +x /etc/init.d/cassandra
# sudo chkconfig --add cassandra
# sudo chkconfig cassandra on
REFERENCE:
Subscribe to:
Posts (Atom)