一文搞懂不同方式Redis集群搭建

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 一文搞懂不同方式Redis集群搭建

1 实验环境准备

1.1 构建Redis的Docker镜像

[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker pull redis
[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker images
REPOSITORY                TAG          IMAGE ID       CREATED        SIZE
redis                     latest       f1b6973564e9   4 weeks ago    113MB
复制代码

1.2 准备redis.conf配置文件

[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# ls -al
drwxr-xr-x 4 root             root   110 2月  26 18:40 .
drwxr-xr-x 3 root             root    19 2月  26 12:16 ..
-rw-r--r-- 1 root             root 93724 2月  26 12:27 redis_1.conf
-rw-r--r-- 1 root             root 93724 2月  26 18:39 redis_2.conf
-rw-r--r-- 1 root             root 93724 2月  26 18:40 redis_3.conf
-rw-r--r-- 1 root             root 93724 2月  26 12:17 redis.conf
复制代码

修改配置中的端口:

redis_1.conf

# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6371
复制代码

redis_2.conf

# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6372
复制代码

redis_3.conf

# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6373
复制代码

1.3 使用Docker启动redis镜像

[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker images
REPOSITORY                TAG          IMAGE ID       CREATED        SIZE
redis                     latest       f1b6973564e9   4 weeks ago    113MB
[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker run -p 6371:6371 -v /home/docker/redis/redis_1.conf:/etc/redis/redis.conf -d f1b6973564e9 redis-server /etc/redis/redis.conf
[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker run -p 6372:6372 -v /home/docker/redis/redis_2.conf:/etc/redis/redis.conf -d f1b6973564e9 redis-server /etc/redis/redis.conf
[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker run -p 6373:6373 -v /home/docker/redis/redis_3.conf:/etc/redis/redis.conf -d f1b6973564e9 redis-server /etc/redis/redis.conf
复制代码

命令解释:

docker run   # 运行Docker镜像
-p 6373:6373 # 端口映射,宿主机端口:容器端口
-v /home/docker/redis/redis_3.conf:/etc/redis/redis.conf  # 容器卷挂载,宿主机文件:容器文件
-d f1b6973564e9 # 将要运行的Docker镜像id,-d为后台运行
redis-server /etc/redis/redis.conf  # Docker容器的启动命令,用相应配置文件启动
复制代码

运行结果:

[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                                 NAMES
59839b8a5622   f1b6973564e9   "docker-entrypoint.s…"   4 seconds ago    Up 2 seconds    0.0.0.0:6373->6373/tcp, :::6373->6373/tcp, 6379/tcp   thirsty_elgamal
2d57a6653087   f1b6973564e9   "docker-entrypoint.s…"   17 seconds ago   Up 16 seconds   0.0.0.0:6372->6372/tcp, :::6372->6372/tcp, 6379/tcp   agitated_mcnulty
df262a37be21   f1b6973564e9   "docker-entrypoint.s…"   6 hours ago      Up 6 hours      0.0.0.0:6371->6371/tcp, :::6371->6371/tcp, 6379/tcp   stupefied_moser
复制代码

1.4 查看Docker部署的Redis网络

[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker inspect 59839b8a5622
"Networks": {
    "bridge": {
        ......
        "Gateway": "172.17.0.1",
        "IPAddress": "172.17.0.4",
        ......
    }
}
[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker inspect 2d57a6653087
 "Networks": {
     "bridge": {
         ......
         "Gateway": "172.17.0.1",
         "IPAddress": "172.17.0.3",
         ......
     }
}
[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker inspect df262a37be21
 "Networks": {
     "bridge": {
         ......
         "Gateway": "172.17.0.1",
         "IPAddress": "172.17.0.2",
         ......
     }
}
复制代码

网络拓扑草图:

网络异常,图片无法展示
|


2 集群方式一:主从模式

2.1 修改配置文件

(1)主节点配置文件:redis_1.conf

#75 # bind 127.0.0.1 -::1
    bind 0.0.0.0
# ......
#90 # By default protected mode is enabled. You should disable it only if
#91 # you are sure you want clients from other hosts to connect to Redis
#92 # even if no authentication is configured, nor a specific set of interfaces
#93 # are explicitly listed using the "bind" directive.
#94 protected-mode yes
    protected-mode no
# ......
#901 # requirepass foobared
    requirepass 123456  # 可选
复制代码

(2)从节点1配置文件:redis_2.conf

#75 # bind 127.0.0.1 -::1
    bind 0.0.0.0
#...
#90 # By default protected mode is enabled. You should disable it only if
#91 # you are sure you want clients from other hosts to connect to Redis
#92 # even if no authentication is configured, nor a specific set of interfaces
#93 # are explicitly listed using the "bind" directive.
#94 protected-mode yes
    protected-mode no
#476 #
#477 # replicaof <masterip> <masterport>
    replicaof 172.17.0.2 6371
#479 # If the master is password protected (using the "requirepass" configuration
#480 # directive below) it is possible to tell the replica to authenticate before
#481 # starting the replication synchronization process, otherwise the master will
#482 # refuse the replica request.
#483 #
#484 # masterauth <master-password>
    masterauth 123456  # 可选,根据主节点配置
#485 #
#898 # The requirepass is not compatable with aclfile option and the ACL LOAD
#899 # command, these will cause requirepass to be ignored.
#900 #
#901 # requirepass foobared
    requirepass 123456  # 可选
复制代码

(3)从节点2配置文件:redis_3.conf

#75 # bind 127.0.0.1 -::1
    bind 0.0.0.0
#...
#90 # By default protected mode is enabled. You should disable it only if
#91 # you are sure you want clients from other hosts to connect to Redis
#92 # even if no authentication is configured, nor a specific set of interfaces
#93 # are explicitly listed using the "bind" directive.
#94 protected-mode yes
    protected-mode no
#476 #
#477 # replicaof <masterip> <masterport>
    replicaof 172.17.0.2 6371
#479 # If the master is password protected (using the "requirepass" configuration
#480 # directive below) it is possible to tell the replica to authenticate before
#481 # starting the replication synchronization process, otherwise the master will
#482 # refuse the replica request.
#483 #
#484 # masterauth <master-password>
    masterauth 123456  # 可选,根据主节点配置
#485 #
#898 # The requirepass is not compatable with aclfile option and the ACL LOAD
#899 # command, these will cause requirepass to be ignored.
#900 #
#901 # requirepass foobared
    requirepass 123456  # 可选
复制代码

2.2 重启Redis

[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                                 NAMES
59839b8a5622   f1b6973564e9   "docker-entrypoint.s…"   34 minutes ago   Up 34 minutes   0.0.0.0:6373->6373/tcp, :::6373->6373/tcp, 6379/tcp   thirsty_elgamal
2d57a6653087   f1b6973564e9   "docker-entrypoint.s…"   34 minutes ago   Up 34 minutes   0.0.0.0:6372->6372/tcp, :::6372->6372/tcp, 6379/tcp   agitated_mcnulty
df262a37be21   f1b6973564e9   "docker-entrypoint.s…"   7 hours ago      Up 7 hours      0.0.0.0:6371->6371/tcp, :::6371->6371/tcp, 6379/tcp   stupefied_moser
[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker restart NAMES
Error response from daemon: No such container: NAMES
[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker restart 59839b8a5622
59839b8a5622
[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker restart 2d57a6653087 
2d57a6653087
[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker restart df262a37be21
df262a37be21
复制代码

2.3 可用性测试

主节点测试:

[root@iZ2ze4m2ri7irkf6h6n8zoZ ~]# docker exec -it df262a37be21 /bin/bash 
root@df262a37be21:/data# cd /usr/local/bin/
root@df262a37be21:/usr/local/bin# ./redis-cli -p 6371
127.0.0.1:6371> set name zs
OK
127.0.0.1:6371> set age 23
OK
127.0.0.1:6371> 
复制代码

从节点测试:

[root@iZ2ze4m2ri7irkf6h6n8zoZ ~]# docker exec -it 59839b8a5622 /bin/bash
root@59839b8a5622:/data# cd /usr/local/bin/ 
root@59839b8a5622:/usr/local/bin# ./redis-cli -p 6373
127.0.0.1:6373> get name
"zs"
127.0.0.1:6373> get age
(nil)
127.0.0.1:6373> get age
"23"
127.0.0.1:6373> set address beijing
(error) READONLY You can't write against a read only replica.
复制代码
[root@iZ2ze4m2ri7irkf6h6n8zoZ ~]#  docker exec -it 2d57a6653087 /bin/bash
root@2d57a6653087:/data# cd /usr/local/bin/
root@2d57a6653087:/usr/local/bin# ./redis-cli -p 6372
127.0.0.1:6372> get name
"zs"
127.0.0.1:6372> get age
(nil)
127.0.0.1:6372> get age
"23"
复制代码

2.4 结论

优点:

  • 同一个Master可以同步多个Slaves。
  • 为了分载Master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由Master来完成。即便如此,系统的伸缩性还是得到了很大的提高。
  • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。

缺点:

  • Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。
  • 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
  • Redis的主从复制采用全量复制,复制过程中主机会fork出一个子进程对内存做一份快照,并将子进程的内存快照保存为文件发送给从机,
  • Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。

3 集群方式二:哨兵模式

Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。Sentinel由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。

哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。

网络异常,图片无法展示
|


3.1 修改配置文件

[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# ls -l
-rw-r--r-- 1 root             root 93736 2月  26 19:03 redis_1.conf
-rw-r--r-- 1 root             root 93761 2月  26 19:14 redis_2.conf
-rw-r--r-- 1 root             root 93762 2月  26 19:15 redis_3.conf
-rw-r--r-- 1 root             root 93724 2月  26 12:17 redis.conf
-rw-r--r-- 1 root             root 13768 2月  27 12:36 sentinel_1.conf
-rw-r--r-- 1 root             root 13768 2月  27 12:37 sentinel_2.conf
-rw-r--r-- 1 root             root 13768 2月  27 12:37 sentinel_3.conf
-rw-r--r-- 1 root             root 13768 2月  27 12:23 sentinel.conf
复制代码

sentinel_1.conf

#13 # For example you may use one of the following:
#14 #
#15 # bind 127.0.0.1 192.168.1.1
    bind 0.0.0.0
#16 #
#17 # protected-mode no
    protected-mode no
#18 
#19 # port <sentinel-port>
#20 # The port that this sentinel instance will run on
#21 port 26379
    port 26379
#82 # Note: master name should not include special characters or spaces.
#83 # The valid charset is A-z 0-9 and the three characters ".-_".
    sentinel monitor mymaster 172.17.0.2 6371 2
#85 
#86 # sentinel auth-pass <master-name> <password>
复制代码

sentinel_2.conf

#13 # For example you may use one of the following:
#14 #
#15 # bind 127.0.0.1 192.168.1.1
    bind 0.0.0.0
#16 #
#17 # protected-mode no
    protected-mode no
#18 
#19 # port <sentinel-port>
#20 # The port that this sentinel instance will run on
#21 port 26379
    port 26378
#82 # Note: master name should not include special characters or spaces.
#83 # The valid charset is A-z 0-9 and the three characters ".-_".
    sentinel monitor mymaster 172.17.0.2 6371 2
#85 
#86 # sentinel auth-pass <master-name> <password>
复制代码

sentinel_3.conf

#13 # For example you may use one of the following:
#14 #
#15 # bind 127.0.0.1 192.168.1.1
    bind 0.0.0.0
#16 #
#17 # protected-mode no
    protected-mode no
#18 
#19 # port <sentinel-port>
#20 # The port that this sentinel instance will run on
#21 port 26379
    port 26377
#82 # Note: master name should not include special characters or spaces.
#83 # The valid charset is A-z 0-9 and the three characters ".-_".
    sentinel monitor mymaster 172.17.0.2 6371 2
#85 
#86 # sentinel auth-pass <master-name> <password>
复制代码

拓扑:

网络异常,图片无法展示
|


3.2 启动redis哨兵

按照上面的主从集群环境进行文件的挂载,然后到容器中根据如下命令进行启动:

[root@iZ2ze4m2ri7irkf6h6n8zoZ src]# ./redis-sentinel ../sentinel.conf 
复制代码

3.3 结论

哨兵的作用就是监控Redis系统的运行状况。它的功能包括以下两个。

(1)监控主服务器和从服务器是否正常运行。

(2)主服务器出现故障时自动将从服务器转换为主服务器。

优点:

  • 哨兵模式是基于主从模式的,所有主从的优点,哨兵模式都具有。
  • 主从可以自动切换,系统更健壮,可用性更高。

缺点:

  • Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。

4 集群方式三:Redis-Cluster集群

Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。

网络异常,图片无法展示
|


由于Redis cluster搭建方式和所需资源较为复杂,因此在这里就不做演示,具体的搭建方式读者可根据搜索引擎快速找出,在这里只提供概念层面的讲解。

核心概念(转自:www.cnblogs.com/runnerjack/…

redis的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台redis服务器都存储相同的数据,很浪费内存,所以在redis3.0上加入了cluster模式,实现的redis的分布式存储,也就是说每台redis节点上存储不同的内容。

Redis-Cluster采用无中心结构,它的特点如下:

  • 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
  • 节点的fail是通过集群中超过半数的节点检测失效时才生效。
  • 客户端与redis节点直连,不需要中间代理层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。

工作方式:

在redis的每一个节点上,都有这么两个东西,一个是插槽(slot),它的的取值范围是:0-16383。还有一个就是cluster,可以理解为是一个集群管理的插件。当我们的存取的key到达的时候,redis会根据crc16的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。

为了保证高可用,redis-cluster集群引入了主从模式,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点。当其它主节点ping一个主节点A时,如果半数以上的主节点与A通信超时,那么认为主节点A宕机了。如果主节点A和它的从节点A1都宕机了,那么该集群就无法再提供服务了。

5 总结

本篇内容介绍了Redis集群搭建的三种不同方式和各自的特点,虽然单机的Redis就有着很好的并发吞吐量,但是在大规模的qps下仍然会显得稍有逊色,因此需要分布式集群的方式来使Redis拥有更高的可用性和容错性。

三种方式中主从复制最为简单,但是只适用于小规模应用中,并且容错性较差,其次是哨兵模式,增强了可用性,但是结构复杂,最后是 Redis-Cluster方式,采用无中心的方式,很好的支持了可用性和容错性,并且应用了一致性哈希的经典思想,目前广泛的应用于Redis集群的搭建中。

参考文章:

www.cnblogs.com/pinghengxin…

www.cnblogs.com/runnerjack/…

www.jianshu.com/p/06ab9daf9…

www.cnblogs.com/kevingrace/…


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
存储 缓存 NoSQL
服务搭建篇(五) Redis单机/redis-cluster集群搭建
当客户端向一个错误的节点发出了指令,该节点会发现指令的 key 所在的槽位并不归自己管理,这时它会向客户端发送一个特殊的跳转指令携带目标操作的节点地址,告诉客户端去连这个节点去获取数据。客户端收到指令后除了跳转到正确的节点上去操作,还会同步更新纠正本地的槽位映射表缓存,后续所有 key 将使用新的槽位映射表。下面第21步操作会有演示
272 0
|
负载均衡 NoSQL Redis
【Redis 系列】redis 学习十,Redis 集群搭建和主从复制
【Redis 系列】redis 学习十,Redis 集群搭建和主从复制
100 0
|
7月前
|
NoSQL Linux Redis
Redis 6.X Sentinel 哨兵集群搭建
Redis 6.X Sentinel 哨兵集群搭建
92 5
|
7月前
|
NoSQL Linux 网络安全
Redis集群搭建
Redis集群搭建
|
7月前
|
存储 监控 NoSQL
一文搞懂不同方式Redis集群搭建
一文搞懂不同方式Redis集群搭建
65 0
|
7月前
|
NoSQL Linux Redis
Redis 6.X Cluster 集群搭建
Redis 6.X Cluster 集群搭建
81 0
|
7月前
|
NoSQL Ubuntu Redis
redis主从配置+集群搭建
redis主从配置+集群搭建
72 0
|
7月前
|
NoSQL Redis Ruby
redis高可用集群搭建
redis高可用集群搭建
|
7月前
|
NoSQL 测试技术 Redis
Redis【性能 02】Redis-5.0.14伪集群和Docker集群搭建及延迟和性能测试(均无法提升性能)
Redis【性能 02】Redis-5.0.14伪集群和Docker集群搭建及延迟和性能测试(均无法提升性能)
232 0
|
7月前
|
NoSQL Shell Redis
Docker【应用 02】借助Docker部署Redis集群(Docker网卡创建+6个Redis集群搭建shell脚本)
Docker【应用 02】借助Docker部署Redis集群(Docker网卡创建+6个Redis集群搭建shell脚本)
123 0