Redis 是一个开源的、轻量级的、高性能的、基于 键-值 对的缓存与存储系统,非常适合用来缓存和存储服务和消息队列、任务队列等。


Table of Contents

  1. 安装 Redis
  2. Redist 集群介绍
    1. Redis 集群简介
    2. Redis 集群所用 TCP 端口
    3. Redis 集群的主-从模型
  3. 部署 Redis 集群
    1. 启动 Redis 实例
    2. 创建 Redis 集群
  4. 使用 Redis 集群
    1. 查看节点系统信息
    2. 查看集群信息
    3. 查看集群节点信息
Redis ClusterRedis Cluster

安装 Redis

目前最新的稳定版是 5.0.0. CentOS 7 的源中最新版为 3.2.12. 如果不需要新特性, 可以使用官方的版本. 这里我们使用 5.0.0 版本.

1
2
3
4
$ wget http://download.redis.io/releases/redis-5.0.0.tar.gz
$ tar xf redis-5.0.0.tar.gz
$ cd redis-5.0.0 && make -j4
$ make test && sudo make install

Redist 集群介绍

Redis 集群简介

Redis 集群所用 TCP 端口

每一 Redis 集群节点都要两个 TCP 连接。 一个 TCP 端口为数据端口,用于服务客户端, 默认为 6379, 一个为 数据端口 +10000, 用于集群节点间的通信,默认就是 16379, 增量 10000 是固定的。

第二个端口是专门用来节点间通信的集群总结 (Cluster bus),使用一个二进制协议。 Cluster bus 被用来作错误检测,配置更新,故障转移论证等等, 因此客户端应该永远不要使用这一端口,而是使用正常的数据端口。

如果开了防火墙, 需要在防火墙中打开这两个端口, 否则 Redis 集群无法正常工作。

Redis 集群的主-从模型

部署 Redis 集群

要部署 Redis 集群, 我们需要先有已经运行的 Redis 实例, 并且 这些实例处于 Cluster 状态. 这里, 我们会在四个节点上启动8个 Redis 实例.

启动 Redis 实例

安装好 Redis 后, 在 /etc/redis/ 下会有一个 redis.conf 的默认配置文件. 我们可以修改这个配置文件. 要部署一个 Redis 集群, 我们要修改的地方如下:

1
2
3
4
5
6
7
8
9
port 6379
cluster-enabled yes
cluster-config-file node-6379.conf
cluster-node-timeout 5000
protected-mode no
# bind 127.0.0.1
bind MY_IP
## or
bind 0.0.0.0

在 Redis 源码包里有一个脚本 utils/redis_init_script, 可以比较方便地启动和关闭 Redis 服务:

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
29
30
31
32
33
34
35
36
37
REDISPORT=6379
EXEC=/usr/local/bin/redis-server
CLIEXEC=/usr/local/bin/redis-cli

PIDFILE=/var/run/redis_${REDISPORT}.pid
CONF="/etc/redis/${REDISPORT}.conf"

case "$1" in
start)
if [ -f $PIDFILE ]
then
echo "$PIDFILE exists, process is already running or crashed"
else
echo "Starting Redis server..."
$EXEC $CONF
fi
;;
stop)
if [ ! -f $PIDFILE ]
then
echo "$PIDFILE does not exist, process is not running"
else
PID=$(cat $PIDFILE)
echo "Stopping ..."
$CLIEXEC -p $REDISPORT shutdown
while [ -x /proc/${PID} ]
do
echo "Waiting for Redis to shutdown ..."
sleep 1
done
echo "Redis stopped"
fi
;;
*)
echo "Please use start or stop as first argument"
;;
esac

在这里, 我们在4个节点上的 70008000 端口各分别启动一个 redis 实例:

1
2
3
4
5
6
7
8
9
10
11
12
IP=(192.168.60.94 192.168.60.95 192.168.60.96 192.168.60.97)
ports=(7000 8000)
$ for ips in ${IP[*]}; do
for port in ${ports[*]}; do
ssh $ips mkdir -p /var/lib/redis/${port}
cp redis_template.conf $port.conf
cp redis_init.sh redis_$port
sed -i -e "s/6379/$port/g" -e "s/MY_IP/$ips/g" $port.conf && scp $port.conf $ips:/etc/redis/
sed -i "s/6379/$port/g" redis_$port && scp redis_$port $ips:/etc/init.d/
ssh $ips /etc/init.d/redis_${port} start
done
done

启动好 8 个实例后, 我们就可以部署一个 4主4从 的 Redis 集群了.

创建 Redis 集群

在有了 8 个正常运行的 Redis 实例后, 我们要做一些额外的事情来搭建 Redis 集群.
当前我们的 Redis 版本是 5.0.0, 其已经自带了 cluster 命令, 可以很方便地完成这一任务:

1
$ redis-cli --cluster create 192.168.60.94:7000 192.168.60.95:7000 192.168.60.96:7000 192.168.60.97:7000 192.168.60.94:8000 192.168.60.95:8000 192.168.60.96:8000 192.168.60.97:8000 --cluster-replicas 1

如果使用的是 3 or 4 版本, 我们可以使用旧的工具 redis-trib.rb 来完成:

1
2
$ gem install redis
$ ./redis-trib.rb create --replicas 1 192.168.60.94:7000 192.168.60.95:7000 192.168.60.96:7000 192.168.60.97:7000 192.168.60.94:8000 192.168.60.95:8000 192.168.60.96:8000 192.168.60.97:8000

--cluster-replicas 1 or --replicas 1 表示我们想要每个主 redis 实例都有一个从 redis 实例.

Redis-cli 会建议一个 cluster 配置, 如果没问题, 输入 yes, 集群就配置完成了, Redis 实例会进入到集群模式与其他各节点进行通信. 如果一切没有问题, 最后会出现如下的信息:

1
[OK] All 16384 slots covered

这意味着 16384 个 slots 中的每一个都由一个 master 服务着.

使用 Redis 集群

查看节点系统信息

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
$ redis-cli -p 7000 info
# Server
redis_version:5.0.0
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:b70c7303801d62f5
redis_mode:cluster
...
config_file:/etc/redis/7000.conf

# Clients
connected_clients:1
client_recent_max_input_buffer:2
client_recent_max_output_buffer:0
blocked_clients:0

# Memory
used_memory:2679024
used_memory_human:2.55M
used_memory_rss:9224192
used_memory_rss_human:8.80M
...

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1541496914
...

# Stats
total_connections_received:22
total_commands_processed:615
instantaneous_ops_per_sec:1
...

# Replication
role:master
connected_slaves:1
slave0:ip=192.168.60.94,port=8000,state=online,offset=980,lag=0
master_replid:7f97949f8203a2f9532edcdcbf606b48bab1e045
master_replid2:b69c6ebce2c36f14eb2d35ad78892ab12813c5ba
...

# CPU
used_cpu_sys:1.407291
used_cpu_user:1.276415
used_cpu_sys_children:0.001923
used_cpu_user_children:0.000961

# Cluster
cluster_enabled:1

# Keyspace

查看集群信息

1
2
3
4
5
6
7
8
9
10
11
$ redis-cli -p 7000 cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:8
cluster_size:4
cluster_current_epoch:9
cluster_my_epoch:9
...

查看集群节点信息

1
2
3
4
5
6
7
8
9
$ redis-cli --cluster -p 7000 cluster nodes
770a8abf7c80d4c0051205e4613ee273c8d9985d 192.168.60.95:8000@18000 slave 15b29ddac7bd12b5ce5f61b735b1e3d52e4b17eb 0 1541496916709 6 connected
09020f2b4a8394975c2c0bc6f0b13720a19e1cf4 192.168.60.96:7000@17000 master - 0 1541496916508 7 connected 10240-16383
9a8b796820f1cd81aec0271b585fa2b6d9b89fe7 192.168.60.96:8000@18000 slave c011bfaa93a3ce8fefbe07f9509909c81b57dfc3 0 1541496915000 9 connected
15b29ddac7bd12b5ce5f61b735b1e3d52e4b17eb 192.168.60.94:7000@17000 master - 0 1541496917000 3 connected 1024-4095
c011bfaa93a3ce8fefbe07f9509909c81b57dfc3 192.168.60.95:7000@17000 master - 0 1541496917711 5 connected 5120-8191
cfd2797de67a700f5cdb0add60b7d4d947035a5b 192.168.60.97:8000@18000 slave 09020f2b4a8394975c2c0bc6f0b13720a19e1cf4 0 1541496916000 7 connected
6fa54252c757c1d5f14ffd99d42d028608e41b35 192.168.60.94:8000@18000 slave 24bee81ae3fc08ba9262f4153fd56e5f1be5e795 0 1541496918712 9 connected
24bee81ae3fc08ba9262f4153fd56e5f1be5e795 192.168.60.97:7000@17000 myself,master - 0 1541496916000 9 connected 0-1023 4096-5119 8192-10239