打不死的redis集群

admin2个月前笔记35

搭建一个redis集群镜像,把原先散落各处的redis服务器统一管理起来,并且保障高可用和故障自动迁移。
image.png

一 redis集群分类

大家都知道redis集群有两种,一种是redis sentinel,高可用集群,同时只有一个master,各实例数据保持一致;一种是redis cluster,分布式集群,同时有多个master,数据分片部署在各个master上。基于我们的需求和redis本身技术的成熟度,本次要搭建的是redis sentinel。
Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:

  • 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。

  • 提醒(Notification    : 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。

  • 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

二制作镜像

整个集群可以分为一个master,N个slave,M个sentinel,本次以2个slave和3个sentinel为例:
image.png首先增加redis.conf

##redis.conf
 ##redis-0,默认为master
port $redis_port
 ##授权密码,请各个配置保持一致
 ##暂且禁用指令重命名
 ##rename-command
 ##开启AOF,禁用snapshot
appendonly yes
 #slaveof redis-master $master_port
slave-read-only yes

默认为master,#slaveof注释去掉后变为slave,这里固化了master的域名redis-master。
增加sentinel.conf

 port $sentinel_port
dir  "hljs-string""/tmp"
 ##sentinel监控的redis的名字、IP和端口,最后一个数字是sentinel做决策的时候需要投赞同票的最少的sentinel的数量。
sentinel "hljs-instruction" monitor mymaster redis-master $master_port 2
 ##选项指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步, 这个数字越小, 完成故障转移所需的时间就越长。
sentinel config-epoch mymaster 1
sentinel leader-epoch mymaster 1
sentinel current-epoch 1

增加启动脚本,根据入参判断启动master,slave,sentinel

  cd /data
redis_role= "hljs-variable"$1
echo  "hljs-variable"$redis_role
 if [  "hljs-variable"$redis_role =  "hljs-string""master" ] ;  then
    echo  "hljs-string""master" 
    sed -i  "hljs-string""s/\$redis_port/ "hljs-variable"$redis_port/g" redis.conf
    redis-server /data/redis.conf
 elif [  "hljs-variable"$redis_role =  "hljs-string""slave" ] ;  then   
    echo  "hljs-string""slave" 
    sed -i  "hljs-string""s/\$redis_port/ "hljs-variable"$redis_port/g" redis.conf
    sed -i  "hljs-string""s/#slaveof/slaveof/g" redis.conf
    sed -i  "hljs-string""s/\$master_port/ "hljs-variable"$master_port/g" redis.conf
    redis-server /data/redis.conf
 elif [  "hljs-variable"$redis_role =  "hljs-string""sentinel" ] ;  then 
    echo  "hljs-string""sentinel" 
    sed -i  "hljs-string""s/\$sentinel_port/ "hljs-variable"$sentinel_port/g" sentinel.conf
    sed -i  "hljs-string""s/\$master_port/ "hljs-variable"$master_port/g" sentinel.conf
    redis-sentinel /data/sentinel.conf
 else 
    echo  "hljs-string""unknow role!" 
 fi      #ifend

其中$redis_port和$master_port,$sentinel_port都是取自环境变量,通过Docker启动时候传入。
编写Dockerfile

  FROM redis:3-alpine
MAINTAINER voidman voidman

COPY  "bash"Shanghai /etc/localtime
COPY  "bash"redis.conf /data/redis.conf
COPY  "bash"sentinel.conf /data/sentinel.conf
COPY  "bash"start.sh /data/start.sh
RUN  "bash"chmod +x /data/start.sh
RUN  "bash"chown redis:redis /data/*
ENTRYPOINT  "bash"[ "hljs-string""sh", "hljs-string""/data/start.sh"] 
CMD  "bash"[ "hljs-string""master"]

选取redis-alpine镜像作为基础镜像,因为它非常小,只有9M,修改时区和把一些配置拷贝进去后,变更下权限和用户组,因为基础镜像是redis用户组。ENTRYPOINT和CMD组合,默认以master方式启动。
build完成后,镜像只有15M。

三 启动

采用docker-compose格式:

redis-master-host:
  environment:
    redis_port:  "hljs-string"'16379'
  labels:
    io "hljs-class".rancher "hljs-class".container "hljs-class".pull_image: always
  tty: true
  image: xxx "hljs-class".aliyun "hljs-class".com:5000/aegis-redis-ha:1.0
  stdin_open: true
  net: host
redis-slaves:
  environment:
    master_port:  "hljs-string"'16379'
    redis_port:  "hljs-string"'16380'
  labels:
    io "hljs-class".rancher "hljs-class".scheduler "hljs-class".affinity:container_label_soft_ne: name=slaves
    io "hljs-class".rancher "hljs-class".container "hljs-class".pull_image: always
    name: slaves
  tty: true
  command:
  - slave
  image: xxx "hljs-class".aliyun "hljs-class".com:5000/aegis-redis-cluster:1.0
  stdin_open: true
  net: host
redis-sentinels:
  environment:
    master_port:  "hljs-string"'16379'
    sentinel_port:  "hljs-string"'16381'
  labels:
    io "hljs-class".rancher "hljs-class".container "hljs-class".pull_image: always
    name: sentinels
    io "hljs-class".rancher "hljs-class".scheduler "hljs-class".affinity:container_label_ne: name=sentinels
  tty: true
  command:
  - sentinel
  image: xxx "hljs-class".aliyun "hljs-class".com:5000/aegis-redis-cluster:1.0
  stdin_open: true
  net: host

首先启动master,传入端口16379,host模式,在启动slave,成为16379 master 的slave,并且设置调度策略为尽可能分散的方式,sentinels也类似。

四 总结

总的来说,只要集群中有一台redis实例存活,集群就能对外提供服务,而sentinel只会在master或slave挂掉才会有实际的作用。
这次的镜像大小只有15M,非常小。采用启动时配置角色和端口,包括master,slave,和sentinel3个角色,通过服务编排启动一个redis集群。


相关文章

evasive 模块保护您的网站免受应用层 DOS 攻击

evasive 模块保护您的网站免受应用层 DOS 攻击

有多种可以导致网站下线的攻击方法,比较复杂的方法要涉及数据库和编程方面的技术知识。一个更简单的方法被称为“拒绝服务Denial Of Service”(DOS)攻击。这个攻击方法的名字来源于它的意图:...

使用本地 eclipse 调试服务器代码

使用本地 eclipse 调试服务器代码

设置eclipse首先是启动jar程序的时候,需要设置-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,addr...

网络钓鱼工具及技术

网络钓鱼工具及技术

我们都曾收到这样的邮件,宣布“你中了大奖”或邀请你“参加幸运抽奖免费游迪士尼”。而实际情况与邮件内容大相径庭。多数情况下,这些邮件是钓鱼骗局,只要点击了其中的链接就会进入到以获取个人信息为目的的假冒网...

用过GPT-4 Turbo以后,我们再也回不去了

用过GPT-4 Turbo以后,我们再也回不去了

前阵子,很多人彻夜未眠 —— 全球科技圈都把目光聚焦在了美国旧金山。短短 45 分钟时间里,OpenAI CEO 山姆・奥特曼向我们介绍了迄今为止最强的大模型,和基于它的一系列应用,一切似乎就像当初...

Linux系统清理缓存方法

Linux系统清理缓存方法

在旧版系统中虚拟内存常常设置为物理内存的两倍,但是新版新硬件,内存已经极大提升了容量与速率,再加上固态硬盘,就不需要甚至不用虚拟内存了。但是在HPC中,往往还是得加入虚拟内存,以免系统出现异常卡死的情...

ChatGPT- 进阶篇- 训练自己的ChatGPT

ChatGPT- 进阶篇- 训练自己的ChatGPT

ChatGPT其实是不接受来自互联网的知识的,他的所有内容都是来自于至少3年前各种来源的知识库。但这并不意味着ChatGPT没有能力学习你的回答。首先ChatGPT一般会根据你和他的问答内容进行一定的...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。