导读 | 最近遇到部分系统由于redis服务挂掉,致使部分服务不可用。因此但愿搭建一个redis集群镜像,把原先散落各处的redis服务器统一管理起来,而且保障高可用和故障自动迁移。 |
最近遇到部分系统由于redis服务挂掉,致使部分服务不可用。因此但愿搭建一个redis集群镜像,把原先散落各处的redis服务器统一管理起来,而且保障高可用和故障自动迁移。
html
你们都知道redis集群有两种,一种是redis sentinel,高可用集群,同时只有一个master,各实例数据保持一致;一种是redis cluster,分布式集群,同时有多个master,数据分片部署在各个master上。基于咱们的需求和redis自己技术的成熟度,本次要搭建的是redis sentinel。
Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行如下三个任务:linux
整个集群能够分为一个master,N个slave,M个sentinel,本次以2个slave和3个sentinel为例:
首先增长redis.confredis
##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.confdocker
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,sentinelbash
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。app
采用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也相似。ui
总的来讲,只要集群中有一台redis实例存活,集群就能对外提供服务,而sentinel只会在master或slave挂掉才会有实际的做用。
此次的镜像大小只有15M,很是小。采用启动时配置角色和端口,包括master,slave,和sentinel3个角色,经过服务编排启动一个redis集群。server