使用Docker在Cassandra上为物联网设备准备数据存储 – Part2:集群安装

我成功地在Docker容器中启动了单节点的Cassandra。接下来,我将尝试使用spotify/cassandra:cluster镜像来构建一个Cassandra集群。我将创建一个简单的keyspace和table。

在CoreOS中创建一个供卷的目录。

创建用于挂载到Cassandra容器的卷的目录。在CoreOS上,使用mkdir命令创建目录存在限制。使用cloud-config的write_files指令创建一个适用于三个节点的目录。

#cloud-config
write_files:
...
  - path: /var/lib/cassandra/c1/.README
    owner: core:core
    permissions: 0644
    content: |
      Cassandra cluster c1 directory
  - path: /var/lib/cassandra/c2/.README
    owner: core:core
    permissions: 0644
    content: |
      Cassandra cluster c2 directory
  - path: /var/lib/cassandra/c3/.README
    owner: core:core
    permissions: 0644
    content: |
      Cassandra cluster c3 directory

重新运行CoreOS-Cloudinit。

$ sudo coreos-cloudinit --from-file /var/lib/coreos-install/user_data

计算代币

由于这次要构建一个由3个节点组成的集群,所以首先要计算并生成令牌。

$ python -c 'print [str(((2**64 / 3) * i) - 2**63) for i in range(3)]'
['-9223372036854775808', '-3074457345618258603', '3074457345618258602']

第一个节点

第一个节点将被选为种子节点。如果不指定环境变量CASSANDRA_SEEDS,在安装过程中将使用容器的IP地址。环境变量CASSANDRA_TOKEN将按顺序使用先前计算的令牌。

$ docker pull spotify/cassandra:cluster
$ docker run -d -v /var/lib/cassandra/c1:/var/lib/cassandra \
  -e "CASSANDRA_TOKEN=-9223372036854775808" \
  --name c1 \
  spotify/cassandra:cluster

启动 c1 容器的 bash。

$ docker exec -it c1 /bin/bash

检查种子节点的IP地址。此IP地址将在其他两个节点启动时作为环境变量CASSANDRA_SEEDS使用。

$ hostname --ip-address | cut -f 1 -d ' '
172.17.0.6

使用 netstat 命令检查绑定的 IP 地址。

$ netstat -alnp | grep 9160
tcp        0      0 172.17.0.6:9160         0.0.0.0:*               LISTEN      16/java

使用指定的IP地址进行验证cqlsh的操作。

$ cqlsh 172.17.0.6
Connected to Test Cluster at 172.17.0.6:9160.
[cqlsh 4.1.1 | Cassandra 2.0.10 | CQL spec 3.1.1 | Thrift protocol 19.39.0]
Use HELP for help.
cqlsh>

第二台和第三台节点

第2-3台将指定种子节点至环境变量CASSANDRA_SEEDS并启动。环境变量CASSANDRA_TOKEN也将按照与第一台相同的顺序使用。首先启动第二台节点。

$ docker run -d -v /var/lib/cassandra/c2:/var/lib/cassandra \
  -e "CASSANDRA_SEEDS=172.17.0.6" \
  -e "CASSANDRA_TOKEN=-3074457345618258603" \
  --name c2 \
  spotify/cassandra:cluster

开启第三个节点。

$ docker run -d -v /var/lib/cassandra/c3:/var/lib/cassandra \
  -e "CASSANDRA_SEEDS=172.17.0.6" \
  -e "CASSANDRA_TOKEN=3074457345618258602" \
  --name c3 \
  spotify/cassandra:cluster

请确认集群。

已启动了3个用于Cassandra集群的容器。

$ docker ps|head
CONTAINER ID        IMAGE                       COMMAND                CREATED             STATUS              PORTS                                                                           NAMES
7501f4754cea        spotify/cassandra:cluster   "cassandra-clusterno   4 seconds ago       Up 4 seconds        9160/tcp, 22/tcp, 61621/tcp, 7000/tcp, 7001/tcp, 7199/tcp, 8012/tcp, 9042/tcp   c3
2a9fe6fc4a1b        spotify/cassandra:cluster   "cassandra-clusterno   25 seconds ago      Up 25 seconds       9160/tcp, 22/tcp, 61621/tcp, 7000/tcp, 7001/tcp, 7199/tcp, 8012/tcp, 9042/tcp   c2
aa5335d223bd        spotify/cassandra:cluster   "cassandra-clusterno   3 minutes ago       Up 3 minutes        7000/tcp, 7001/tcp, 7199/tcp, 8012/tcp, 9042/tcp, 9160/tcp, 22/tcp, 61621/tcp   c1

开始c1节点的bash,并显示节点的状态。

$ docker exec -it c1 /bin/bash
$ nodetool status
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address     Load       Tokens  Owns (effective)  Host ID                               Rack
UN  172.17.0.8  64.8 KB    1       50.0%             23df3501-5abe-4b1e-9e26-f24aeb7774a9  rack1
UN  172.17.0.7  115.59 KB  1       50.0%             ee3e867e-f292-444f-90eb-95e3b699d138  rack1
UN  172.17.0.6  124.99 KB  1       50.0%             4def9a7d-90e6-45a3-9752-07305a5e71e1  rack1
DN  172.17.0.5  ?          1       50.0%             45095f6d-490e-48cc-b1c6-c1bfc19d6eb1  rack1

尽管使用fleetctl很方便,但我还没有创建unit文件,所以我会分别确认每个节点的IP地址。

$ docker inspect -f '{{ .NetworkSettings.IPAddress }}' c1
172.17.0.6
$ docker inspect -f '{{ .NetworkSettings.IPAddress }}' c2
172.17.0.7
$ docker inspect -f '{{ .NetworkSettings.IPAddress }}' c3
172.17.0.8

创建keyspace和table以验证集群的功能

在c1节点上进行工作。

$ docker exec -it c1 /bin/bash

我们将编写用于创建keyspace和table以及插入初始数据的脚本。由于设置了复制因子为2,因此将在两个节点上进行冗余备份。

CREATE KEYSPACE test WITH REPLICATION =
 {'class': 'SimpleStrategy', 'replication_factor': 2};

 USE test;

 CREATE TABLE test_table (
  id text,
  test_value text,
  PRIMARY KEY (id)
 );


INSERT INTO test_table (id, test_value) VALUES ('1', 'one');
INSERT INTO test_table (id, test_value) VALUES ('2', 'two');
INSERT INTO test_table (id, test_value) VALUES ('3', 'three');

执行创建的CQL文件。

$ cqlsh -f create_keyspace.cql 172.17.0.6

从c1节点启动cqlsh命令,并执行查询以获取数据。

$ docker exec -it c1 /bin/bash
$ cqlsh 172.17.0.6
cqlsh> use test;
cqlsh:test> SELECT * FROM test_table;

 id | test_value
----+------------
  3 |      three
  2 |        two
  1 |        one

(3 rows)

cqlsh:test>

这一次我们将从另一个c2节点来测试查询。

$ docker exec -it c2 /bin/bash
$ cqlsh 172.17.0.7
Connected to Test Cluster at 172.17.0.7:9160.
[cqlsh 4.1.1 | Cassandra 2.0.10 | CQL spec 3.1.1 | Thrift protocol 19.39.0]
Use HELP for help.
cqlsh> use test;
cqlsh:test> SELECT * FROM test_table;

 id | test_value
----+------------
  3 |      three
  2 |        two
  1 |        one

(3 rows)

cqlsh:test>