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


目录

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

安装 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