打不死的redis集群
导读 | 最近遇到部分系统因为redis服务挂掉,导致部分服务不可用。所以希望搭建一个redis集群镜像,把原先散落各处的redis服务器统一管理起来,并且保障高可用和故障自动迁移。 |
最近遇到部分系统因为redis服务挂掉,导致部分服务不可用。所以希望搭建一个redis集群镜像,把原先散落各处的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为例:
首先增加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集群。
打不死的redis集群的更多相关文章
- 就publish/subscribe功能看redis集群模式下的队列技术(一)
Redis 简介 Redis 是完全开源免费的,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中 ...
- linux环境(CentOS-6.7)下redis集群的搭建全过程
linux环境下redis集群的搭建全过程: 使用mount命令将光盘挂载到/mnt/cdrom目录下: [root@hadoop03 ~]# mount -t iso9660 -o ro /dev/ ...
- [个人翻译]Redis 集群教程(下)
[个人翻译]Redis 集群教程(上) [个人翻译]Redis 集群教程(中) 官方原文地址:https://redis.io/topics/cluster-tutorial 水平有限,如果您在阅读过 ...
- redis单点、redis主从、redis哨兵sentinel,redis集群cluster配置搭建与使用
目录 redis单点.redis主从.redis哨兵 sentinel,redis集群cluster配置搭建与使用 1 .redis 安装及配置 1.1 redis 单点 1.1.2 在命令窗口操作r ...
- Redis系列九:redis集群高可用
Redis集群的概念: RedisCluster是redis的分布式解决方案,在3.0版本后推出的方案,有效地解决了Redis分布式的需求,当一个服务挂了可以快速的切换到另外一个服务,当遇到单机内存. ...
- 04: redis集群
1.1 主从同步 1.CPA原理 1. CPA原理是分布式存储理论的基石: C(一致性): A(可用性): P(分区容忍性); 2. 当主从网络无法连通时,修改操作无法同步到节点,所以“一致性” ...
- redis集群管理--sentinel
什么是sentinel? Sentinel(哨兵)是用于监控redis集群中Master状态的工具,是Redis 的高可用性解决方案,sentinel哨兵模式已经被集成在redis2.4之后的版本中. ...
- Redis集群数据没法拆分时的搭建策略
在上一篇文章中,针对服务器单点.单例.单机存在的问题: 单点故障 容量有限 可支持的连接有限(性能不足) 提出了解决的办法:根据AKF原则搭建集群,大意是先X轴拆分,创建单机的镜像,组成主主.主备.主 ...
- Docker-生成镜像、服务搭建(redis集群、kibana、运行项目jar包)、上传镜像至阿里云
目录 生成自己的镜像 1.下载官方tomcat镜像 2.运行镜像后将webapp目录里新增文件(官方镜像是没有页面的 具体操作见) 3.使用docker ps -a 查看刚刚修改后的容器id 4.执行 ...
随机推荐
- Java GC系列
一个国外站点的Java JVM调优系列 下面是国内站点翻译的 http://www.importnew.com/1993.html
- Multiply Strings
Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...
- linux系统top命令查看系统状态
Linux系统可以通过top命令查看系统的CPU.内存.运行时间.交换分区.执行的线程等信息.通过top命令可以有效的发现系统的缺陷出在哪里.是内存不够.CPU处理能力不够.IO读写过高. 使用SSH ...
- [LeetCode] Is Subsequence 是子序列
Given a string s and a string t, check if s is subsequence of t. You may assume that there is only l ...
- TextView字体阴影效果
android:shadowDx="1" android:shadowDy="1" android:shadowColor="#8c8c8c" ...
- Spring test
@Rollback 用于标记在spring test中是否提交事务, 默认为true, 即不提交, 如果需要设置单元测试完成时自动提交事务, 需要设置rollback为false; 可以使用 @Com ...
- django用户认证
利用django自带认证功能实现用户登录认证. views.py # Create your views here. from django.shortcuts import render_to_re ...
- pecl 轻松安装php扩展
PECL 的全称是 The PHP Extension Community Library ,是一个开放的并通过 PEAR(PHP Extension and Application Reposito ...
- Linux and symmetric multiprocessing
没空看,暂时留着 http://www.ibm.com/developerworks/library/l-linux-smp/
- js获取手机验证码倒计时的实现
方案一 <div class="div user-input"> <input type="number" class="code& ...