[转帖]一文搞懂不同方式Redis集群搭建

一文,搞懂,不同,方式,redis,集群,搭建 · 浏览次数 : 0

小编点评

## Redis 集群搭建三种方式概述 **1. 单机 Redis 模式** * 只适用于小型应用。 * 存储所有数据在本地服务器。 * 存储数据时,每个 key 都会存储在一个独立的插槽中。 * 每个 key 对应一个唯一的插槽位置。 **2. 哨兵模式** * 与单机模式相比,哨兵模式增加了监控功能。 * 当主服务器出现故障时,会自动将从服务器转换为为主服务器。 * 哨兵模式结构简单,但容错性较差。 **3. Redis-Cluster 模式** * 采用无中心结构,每个节点保存数据和整个集群状态。 * 每个节点都和其他所有节点连接,实现高可用性和容错性。 * 每个 key 对应一个唯一的集群槽。 * 每个节点上都会维护多个插槽,以提高读取性能。 **总结:** * 主从复制适用于小规模应用,但容错性较差。 * 哨兵模式增强了可用性,但结构复杂。 * Redis-Cluster 模式提供更高的可用性和容错性,但应用范围受限制。

正文

https://bbs.huaweicloud.com/blogs/380521

 

 

【摘要】 1 实验环境准备 1.1 构建Redis的Docker镜像[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker pull redis[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker imagesREPOSITORY TAG IMAGE ID CREATED...

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

核心概念(转自:https://www.cnblogs.com/runnerjack/p/10269277.html):

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集群的搭建中。

参考文章:

https://www.cnblogs.com/pinghengxing/p/11139997.html

https://www.cnblogs.com/runnerjack/p/10269277.html

https://www.jianshu.com/p/06ab9daf921d

https://www.cnblogs.com/kevingrace/p/9004460.html

与[转帖]一文搞懂不同方式Redis集群搭建相似的内容:

[转帖]一文搞懂不同方式Redis集群搭建

https://bbs.huaweicloud.com/blogs/380521 【摘要】 1 实验环境准备 1.1 构建Redis的Docker镜像[root@iZ2ze4m2ri7irkf6h6n8zoZ redis]# docker pull redis[root@iZ2ze4m2ri7irk

[转帖]java性能分析之火焰图

http://t.zoukankan.com/lemon-le-p-13820204.html 原由 最近因为kafka、zookeeper、ES和相关的Java应用的内存问题搞的头大,做运维将近4年,对Java调优、性能方面的知识了解的少之又少,是时候下定决心来对他多一个学习了。不能一口吃成一个胖

[转帖]图文结合带你搞懂 MySQL 日志之 Slow Query Log(慢查询日志)

https://my.oschina.net/GreatSQL/blog/5719211 GreatSQL 社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。 GreatSQL 是 MySQL 的国产分支版本,使用上与 MySQL 一致。 作者:KAiTO 文章来源:GreatSQL 社区

[转帖] 传参base64时的+号变空格问题

https://www.cnblogs.com/codelogs/p/17255425.html 原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明。 问题发生# 上上周,看到一位老哥找我们组同事联调接口,不知道是什么问题,两人坐一起搞了快1个小时,看起来好像有点复

[转帖]Nginx 反向代理解决跨域问题

https://juejin.cn/post/6995374680114741279 编写代码两分钟,解决跨域两小时,我吐了。 如果对跨域还不了解的朋友,可以看这篇:【基础】HTTP、TCP/IP 协议的原理及应用 最近一段时间,在搞一个 SDK 的项目,使用的 TS + rollup。rollup

[转帖]必看!PostgreSQL参数优化

https://www.modb.pro/db/48129 前不久,一个朋友所在的公司,业务人员整天都喊慢。 朋友是搞开发的,不是很懂DB,他说他们应用的其实没什么问题,但是就是每天一到高峰期就办理特别的慢啊,各种堵塞,一堆请求无法完成。他们没有专门的DBA,想找我帮忙看看。 我下班后打开他们的数据

[转帖]必看!PostgreSQL参数优化

https://zhuanlan.zhihu.com/p/333201734 前不久,一个朋友所在的公司,业务人员整天都喊慢。 朋友是搞开发的,不是很懂DB,他说他们应用的其实没什么问题,但是就是每天一到高峰期就办理特别的慢啊,各种堵塞,一堆请求无法完成。他们没有专门的DBA,想找我帮忙看看。 我下

[转帖][搞点翻译]系统设计基础: 缓存(Caching)

https://zhuanlan.zhihu.com/p/569553681 最近在看一些系统设计相关的知识, 按我自己的理解做些翻译和整理, 和原文不一样, 有问题欢迎指出, 细节以原文为主: https://www.educative.io/courses/grokking-the-system

[转帖]性能优化 YYDS - Brendan Gregg 与 Intel.com 的故事

https://www.modb.pro/db/421309 译者序 金庸笔下的《鹿鼎记》有: !! 平生不识陈近南,便称英雄也枉然 现代的认真搞技术的后端程序员,应该也有一句: !! 平生不识 Brendan Gregg,便呆 BAT 也 SoSo 从 2016 年开始,做一个 JVM 调优开始,

[转帖]一文搞懂各种数据库SQL执行计划:MySQL、Oracle等

https://zhuanlan.zhihu.com/p/99331255 MySQL 执行计划 Oracle 执行计划 SQL Server 执行计划 PostgreSQL 执行计划 执行计划(execution plan,也叫查询计划或者解释计划)是数据库执行 SQL 语句的具体步骤,例如通过索