redis笔记1:集群

docker 化部署 redis,主从复制、哨兵、集群实践。

redis 集群有三种模式:

  • 主从模式
  • Sentinel模式
  • Cluster模式

技术小结

使用 docker 部署,需要注意所有容器均在同一网段,容器间使用容器名称访问。

主从复制

理论

  • 主可写可读,从只读(否则无法保证数据一致性)。主同步数据到从。一主可带多个从,一从只属一个主。
  • 从服务挂掉不影响其它从。
  • 主挂掉,整个集群不能写,但从依然可读。
  • 主只写,从只读,分工减少主的压力。

实践

三台服务:

1
2
3
4
ttredis 6379
ttredis1 6381
ttredis2 6382
ttredis3 6383

docker-compose.yml文件:

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
version: '2'

services:
ttredis:
image: redis:alpine
container_name: ttredis
restart: always
command: redis-server /usr/local/etc/redis/redis.conf
volumes:
- ./redisdata0:/data
- ./redis0.conf:/usr/local/etc/redis/redis.conf
ports:
- 6379:6379
networks:
- ttredis-net
ttredis1:
image: redis:alpine
container_name: ttredis1
restart: always
command: redis-server /usr/local/etc/redis/redis.conf
volumes:
- ./redisdata1:/data
- ./redis1.conf:/usr/local/etc/redis/redis.conf
ports:
- 6381:6379
networks:
- ttredis-net
ttredis2:
image: redis:alpine
container_name: ttredis2
restart: always
command: redis-server /usr/local/etc/redis/redis.conf
volumes:
- ./redisdata2:/data
- ./redis1.conf:/usr/local/etc/redis/redis.conf
ports:
- 6382:6379
networks:
- ttredis-net
ttredis3:
image: redis:alpine
container_name: ttredis3
restart: always
command: redis-server /usr/local/etc/redis/redis.conf
volumes:
- ./redisdata3:/data
- ./redis1.conf:/usr/local/etc/redis/redis.conf
ports:
- 6383:6379
networks:
- ttredis-net
networks:
ttredis-net:
driver: bridge

说明:
1、创建三个容器,分别为ttredis、ttredis1、ttredis2,第一个为主,使用单独的配置文件。第二第三个为从,使用同一配置,但数据目录不同。
2、注意端口映射,在容器看来,均为6379(默认),只是映射到不同端口。
3、三个容器在同一网络 ttredis-net 中。

主配置文件主要内容:

1
2
3
4
5
6
bind 0.0.0.0
protected-mode yes
port 6379
requirepass 12345678
appendonly yes
appendfilename "appendonly.aof"

从配置文件主要内容:

1
2
3
4
5
6
7
8
9
10
11
12
bind 0.0.0.0
protected-mode yes
port 6379
requirepass 12345678
appendonly yes
appendfilename "appendonly.aof"

# replicaof <masterip> <masterport>
#replicaof 127.0.0.1 6379
# for docker
replicaof ttredis 6379
masterauth 12345678

说明:在从配置文件中,使用 replicaof (注:旧版本为 slaveof)指定主的IP和端口,masterauth 指定主的密码。如是本机,则使用127.0.0.1,本例为容器,故用主的容器名ttredis。由于需要外网机器访问,故绑定 IP 为0.0.0.0。主从密码均为12345678

启动容器并查看状态:

1
2
3
4
5
6
7
8
# docker-compose -f docker-compose.yml up -d

# docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------
ttredis docker-entrypoint.sh redis ... Up 0.0.0.0:6379->6379/tcp
ttredis1 docker-entrypoint.sh redis ... Up 0.0.0.0:6381->6379/tcp
ttredis2 docker-entrypoint.sh redis ... Up 0.0.0.0:6382->6379/tcp

连接主容器并查看集群:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
redis-cli -p 6379 -a 12345678

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.224.2,port=6379,state=online,offset=1386,lag=1
slave1:ip=192.168.224.4,port=6379,state=online,offset=1386,lag=1
master_replid:44d65d402d81131ac37867f352a513093263f0aa
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1386
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1386

测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
127.0.0.1:6379> keys *
(empty list or set)

输入值:
set key1 101
set key2 102
set key3 103
set key4 104
set key5 105


查看:
127.0.0.1:6379> keys *
1) "key5"
2) "key1"
3) "key2"
4) "key3"
5) "key4"

在从查看:

1
2
3
4
5
6
127.0.0.1:6381> keys *
1) "key3"
2) "key1"
3) "key4"
4) "key2"
5) "key5"

在主执行 flushall 命令清空所有数据库,从亦被清空。

哨兵

理论

解决主从复制的缺点,即主挂掉整个集群不可写。哨兵可再选一个主出来。

实践

docker-compose.yml文件:

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
version: '2'

services:
ttredis:
image: redis:alpine
container_name: ttredis
restart: always
#command: redis-server
#command: redis-server --requirepass 12345678 --appendonly yes
command:
- sh
- -c
- |
redis-server /usr/local/etc/redis/redis.conf &
redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./redisdata0:/data
- ./redis0.conf:/usr/local/etc/redis/redis.conf
- ./sentinel.conf:/usr/local/etc/redis/sentinel.conf
ports:
- 6379:6379
- 26379:26379
networks:
- ttredis-net
ttredis1:
image: redis:alpine
container_name: ttredis1
restart: always
#command: redis-server
#command: redis-server --requirepass 12345678 --appendonly yes --replicaof ttredis 6379 --masterauth 12345678
command: redis-server /usr/local/etc/redis/redis.conf
volumes:
- ./redisdata1:/data
- ./redis1.conf:/usr/local/etc/redis/redis.conf
ports:
- 6381:6379
networks:
- ttredis-net
ttredis2:
image: redis:alpine
container_name: ttredis2
restart: always
#command: redis-server
#command: redis-server --requirepass 12345678 --appendonly yes --replicaof ttredis 6379 --masterauth 12345678
command: redis-server /usr/local/etc/redis/redis.conf
volumes:
- ./redisdata2:/data
- ./redis1.conf:/usr/local/etc/redis/redis.conf
ports:
- 6382:6379
networks:
- ttredis-net
ttredis3:
image: redis:alpine
container_name: ttredis3
restart: always
#command: redis-server
#command: redis-server --requirepass 12345678 --appendonly yes --replicaof ttredis 6379 --masterauth 12345678
command: redis-server /usr/local/etc/redis/redis.conf
volumes:
- ./redisdata3:/data
- ./redis1.conf:/usr/local/etc/redis/redis.conf
ports:
- 6383:6379
networks:
- ttredis-net
networks:
ttredis-net:
driver: bridge

与前述相比,ttredis 中,多了 sentinel.conf 的配置。该配置由 redis-sentinel 使用,因此,command 需要执行2个命令,格式如下:

1
2
3
4
5
6
command: 
- sh
- -c
- |
redis-server /usr/local/etc/redis/redis.conf &
redis-sentinel /usr/local/etc/redis/sentinel.conf

sentinel.conf 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
protected-mode no

# The port that this sentinel instance will run on
port 26379
daemonize no
pidfile /var/run/redis-sentinel.pid
logfile ""

dir /tmp

sentinel monitor mymaster ttredis 6379 2
sentinel auth-pass mymaster 12345678

# Default is 30 seconds.
sentinel down-after-milliseconds mymaster 30000
acllog-max-len 128
sentinel parallel-syncs mymaster 1
# Default is 3 minutes.
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

测试:
同上,在主写数据。然后执行docker-compose stop ttredis停用主服务,观察从是否会变成主。
注:暂不成功。

集群

待实践。

理论

实践