Cassandra 安装入门

Cassandra是Apache开源的分布式数据库管理系统,被用于处理大数据量的商用硬件或云设施上。Cassandra提供了高可用,无单点故障的特性。

Cassandra支持不停机的线性扩展机器的方式,增加Read和Write的吞吐量。

每个Cassandra节点在集群中会有相同的角色。数据被分布在各个集群节点上。Cassandra支持复制和多数据中心冗余复制,故障转移,灾难恢复。

单节点

Apache Cassandra要求系统预先安装Java:

1
sudo add-apt-repository -y ppa:webupd8team/java
1
2
sudo apt-get update
sudo apt-get -y install oracle-java8-installer

验证:

1
java -version

安装时请注意Java版本的兼容性问题。

Cassandra的安装,官方推荐的是包管理的方式。以debian为例:

添加仓储:

1
echo "deb http://www.apache.org/dist/cassandra/debian 36x main" | sudo tee -a /etc/apt/sources.list.d/cassandra.list

添加公钥:

1
2
gpg --keyserver pgp.mit.edu --recv-keys 749D6EEC0353B12C
gpg --export --armor 749D6EEC0353B12C | sudo apt-key add -

安装:

1
2
sudo apt-get update
sudo apt-get install cassandra

要注意的是,安装时最好选择覆盖安装,因为有可能你的/etc/cassandra/以前曾经保留了配置。

另外一种方式是deb包安装,推荐到中科大下载安装包:

1
2
wget https://mirrors.ustc.edu.cn/apache/cassandra/debian/pool/main/c/cassandra/cassandra_3.11.1_all.deb
sudo dpkg --force-confmiss -i cassandra_3.11.1_all.deb

卸载:

1
sudo apt-get purge cassandra

安装完成之后,服务会添加到systemd。查看服务的运行情况,一般正常的话都处于Running状态:

1
sudo service cassandra status

查看端口:

1
sudo netstat -plntu

cassandra主进程的子进程会开启几个端口:

端口占用情况

每个port代表着不同的意义:

  • 7000:node间的TCP port
  • 7001:node间利用SSL传输资料的port
  • 7199:JMX
  • 9160: Client端Thrift API用到的port
  • 9042: CQL使用
  • 1024-65355: JMX要求的随机port

cassandra虽然能启动,但不能通过静态ip访问,只能内部访问。打开/etc/cassandra/cassandra.yaml

1
2
3
4
5
cluster_name: 'JCPT Test Cluster'
listen_address: localhost
start_rpc: true
rpc_address: 0.0.0.0
boardcast_rpc_address: 192.168.2.248

cassandra集群安装成功后,使用nodetool连接本机节点:

1
sudo nodetool status

出现下面内容说明正常:

1
2
3
4
5
6
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
UN 127.0.0.1 256.6 KiB 256 100.0% c703e51b-5050-403e-8430-019b768f7dc9 rack1

其中:

U - Cluster is UP
N = Cluster is Normal

现在可以使用cqlsh进行数据库查询了:

1
cqlsh

出现提示说明cassandra的单机节点部署成功了!

docker搭配的多节点

架设环境:3台host(192.168.0.1, 192.168.0.2, 192.168.0.3)
情境:3台独立VM,各架设一个cassandra node,组成cassandra cluster。第1,2台host的node设为seed

下载cassandra image

1
sudo docker pull cassandra

在第一台VM上建立cassandra,指令如下:

1
sudo docker run --restart=always --name cassandra-1 -d -e CASSANDRA_BROADCAST_ADDRESS=192.168.0.1 -p 7000:7000 cassandra

第二台host上:

1
sudo docker run --restart=always --name cassandra-2 -d -e CASSANDRA_BROADCAST_ADDRESS=192.168.0.2 -p 7000:7000 -e CASSANDRA_SEEDS=192.168.0.1,192.168.0.2 cassandra

第三台host:

1
sudo docker run --restart=always --name cassandra-3 -d -e CASSANDRA_BROADCAST_ADDRESS=192.168.0.3 -p 7000:7000 -e CASSANDRA_SEEDS=192.168.0.1,192.168.0.2 cassandra

测试3个host是否正常:

测试剧本:在cassandra-1建立 test_keyspace,在 cassandra-2使用 test_keyspace 建立 test_table,最后在 cassandra-3 查询 test_table

进入 cassandra-1:

1
sudo docker exec -it 3b39bc bash

执行cqlsh,建立keyspace:

1
2
3
4
cqlsh > CREATE KEYSPACE test_keyspace WITH REPLICATION = {
'class' : 'SimpleStrategy',
'replication_factor' : 2
};

进入 cassandra-2:

1
sudo docker exec -it fc04 bash

执行:

1
2
3
4
cqlsh:test_keyspace> CREATE TABLE test_table(
id int PRIMARY KEY,
name text
);

进入 cassandra-3:

执行cqlsh查询,

1
2
 cqlsh > use test_keyspace;
cqlsh:test_keyspace> select * from test_table;

目前table是空的,我们加一点数据:

1
2
3
4
5
6
cqlsh:test_keyspace> insert into test_table (id, name) values (1, 'Doraemon');
id | name
----+----------
1 | Doraemon

(1 rows)

回到 cassandra-1,cassandra-2 查询:

1
2
3
4
5
6
7
cqlsh:test_keyspace> select * from test_table;

id | name
----+----------
1 | Doraemon

(1 rows)

如果3个node查询得到一样的数据,就代表成功啦~

二进制部署

除了上面介绍的两种安装方式,本人推荐以压缩包方式部署。

  1. JDK安装

首先确保你的环境需要有Java,下载地址

解压放到/usr/java/jdk1.8.0_151/目录,

  1. 添加用户
1
2
3
groupadd cassandra
useradd -g cassandra cassandra
passwd cassandra
  1. 下载
1
2
3
wget http://mirrors.shuosc.org/apache/cassandra/3.11.1/apache-cassandra-3.11.1-bin.tar.gz
tar -xvf apache-cassandra-3.11.1-bin.tar.gz
cd apache-cassandra-3.11.1
  1. 配置vim conf/cassandra.yaml
1
2
3
4
cluster_name: 'JCPT Test Cluster'
- seeds: "10.112.68.186,10.112.68.192"
listen_address: 10.112.68.186
rpc_address: 10.112.68.186

不同节点listen_address、rpc_address不同,cluster_name和seeds是相同的。

  • JVM配置: conf/cassandra-env.sh(JVM_OPTS)
  • 日志配置:conf/logback.xml

建立数据和日志的存储目录(生产环境数据和日志放在不同分期)

1
2
3
4
5
6
mkdir data
mkdir data/data
mkdir data/commitlog
mkdir data/saved_caches
mkdir data/hints
mkdir logs
  1. 启动
1
2
./bin/cassandra -f (前端启动)
./bin/cassandra
  1. 查看集群状态
1
2
./bin/nodetool status
./bin/nodetool describecluster

多节点

cassandra默认有两种启动模式, local和remote模式,可以在/etc/cassandra-env.sh中查看和修改。默认使用local模式。要想通过nodetool命令连接本机节点时,要更改为remote模式。

添加LOCAL_JMX=false和修改 -Dcom.sun.management.jmxremote.authenticate=false,当然你可以开启加密方式。配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
LOCAL_JMX=false
if [ "x$LOCAL_JMX" = "x" ]; then
LOCAL_JMX=yes
fi
# Specifies the default port over which Cassandra will be available for
# JMX connections.
# For security reasons, you should not expose this port to the internet. Firewall it if needed.
JMX_PORT="7199"
if [ "$LOCAL_JMX" = "yes" ]; then
JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.local.port=$JMX_PORT"
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
else
JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.remote.port=$JMX_PORT"
# if ssl is enabled the same port cannot be used for both jmx and rmi so either
# pick another value for this property or comment out to use a random port (though see CASSANDRA-7087 for origins)
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT"
# turn on JMX authentication. See below for further options
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
# jmx ssl options
#JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.ssl=true"
#JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.ssl.need.client.auth=true"
#JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.ssl.enabled.protocols=<enabled-protocols>"
#JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.ssl.enabled.cipher.suites=<enabled-cipher-suites>"
#JVM_OPTS="$JVM_OPTS -Djavax.net.ssl.keyStore=/path/to/keystore"
#JVM_OPTS="$JVM_OPTS -Djavax.net.ssl.keyStorePassword=<keystore-password>"
#JVM_OPTS="$JVM_OPTS -Djavax.net.ssl.trustStore=/path/to/truststore"
#JVM_OPTS="$JVM_OPTS -Djavax.net.ssl.trustStorePassword=<truststore-password>"
fi

修改配置,重启OK。

Replication策略

Cassandra在多个节点存储replica来确保可靠性和容错性。Replication策略决定了replica保存到哪些节点。

replica的总数由replication factor控制。replication factor 1表示一行数据,只会有一个replica,被保存在唯一一个节点上。replication factor 2表示一行数据有两个副本,每个副本保存在不同的节点上。所有的replica同等重要;没有主次replica之分。一般的规则是,replication factor不应该超过集群里的节点数量。不过,可以先增大replication factor,再添加更多节点。如果replication factor配置超过节点数量,写操作会被拒绝。读操作不受影响。

Cassandra内置了两种类型的replication策略:

  • SimpleStrategy:用于单个数据中心。如果有可能以后会有多个数据中心,应该用NetworkTopologyStrategy
  • NetworkTopologyStrategy:对绝大多数部署方式,都强烈推荐该策略,因为今后的扩展更容易

关于每个数据中心应该配置几个replica,一般主要考虑以下两个因素:

  • 保证读操作没有跨数据中心的延时损耗
  • 如何处理硬件故障的情形

对于多数据中心,最常用的两种配置replica的策略是:

  • 每个数据中心2个replica:基于这种配置,对于每个数据中心,即使单个节点故障,还是能够支持consistency level ONE的本地读
  • 每个数据中心3个replica:基于这种配置,对于每个数据中心,即使单个节点故障,还是能够支持consistency level LOCAL_QUORUM的本地读;即使2两个节点故障,还是能够支持consistency level ONE的本地读

cassandra默认建keyspace的时候,需要定制拓扑策略的,默认是SimpleStrategy,修改 conf/cassandra.yaml里面的endpoint_snitch,将其更改为GossipingPropertyFileSnitch。表示多数据中心策略。

  • SimpleSnitch:默认的,单数据中心部署,可以在禁用读修复时提高缓存位置。
  • GossipingPropertyFileSnitch:官方推荐在生产环境下使用,本节点的rack和dc名字保存在cassandra-rackdc.properties,并且会通过gossip这个p2p协议传播到所有节点上去
    如果cassandra-topology.properties文件存在,cassandra会把两个properties文件的结果合并,如果两个properties文件里面有有同一个节点的配置,以cassandra-rackdc.properties的配置为准。
  • PropertyFileSnitch:dc和rack通过显式的定义在cassandra-topology.properties文件里面。
  • Ec2Snitch:适合单个区域(数据中心)的EC2部署。
  • Ec2MultiRegionSnitch:集群跨多个区域(数据中心)的EC2部署。
  • RackInferringSnitch:通过本机IP地址判断节点数据哪个数据中心哪个rack。IP第2段相同为同一个数据中心,IP第3段相同为一个Rack。如下图:

分段rack

安装MX4J集群监控

cassandra监控有许多方案,DataStax的Opscenter是比较耗的监控解决方案。可惜Opscenter6.0版本后已经不再支持开源cassandra版本。Opscenter5.x版本支持到cassandra2.1。最好使用cassandra自身支持的MX4J进行监控。

解压后将mx4j-tools.jar拷贝到cassandra的安装目录的lib文件夹下

1
2
unzip mx4j-3.0.2.zip
cp mx4j-3.0.2/lib/mx4j-tools.jar apache-cassandra-3.11.1/lib/

配置mx4j

编辑 vim /etc/cassandra/cassandra-env.sh,去除注释

1
2
MX4J_ADDRESS="-Dmx4jaddress=10.112.68.186"
MX4J_PORT="-Dmx4jport=8081"

然后重启cassandra

1
systemctl restart cassandra

浏览器输入地址 http://10.112.68.186:8081