打不死的redis集羣

導讀 最近遇到部分系統由於redis服務掛掉,致使部分服務不可用。因此但願搭建一個redis集羣鏡像,把原先散落各處的redis服務器統一管理起來,而且保障高可用和故障自動遷移。

最近遇到部分系統由於redis服務掛掉,致使部分服務不可用。因此但願搭建一個redis集羣鏡像,把原先散落各處的redis服務器統一管理起來,而且保障高可用和故障自動遷移。
docker-redis1html

一 redis集羣分類

你們都知道redis集羣有兩種,一種是redis sentinel,高可用集羣,同時只有一個master,各實例數據保持一致;一種是redis cluster,分佈式集羣,同時有多個master,數據分片部署在各個master上。基於咱們的需求和redis自己技術的成熟度,本次要搭建的是redis sentinel。
Redis 的 Sentinel 系統用於管理多個 Redis 服務器(instance), 該系統執行如下三個任務:linux

  • 監控(Monitoring): Sentinel 會不斷地檢查你的主服務器和從服務器是否運做正常。
  • 提醒(Notification : 當被監控的某個 Redis 服務器出現問題時, Sentinel 能夠經過 API 向管理員或者其餘應用程序發送通知。
  • 自動故障遷移(Automatic failover): 當一個主服務器不能正常工做時, Sentinel 會開始一次自動故障遷移操做, 它會將失效主服務器的其中一個從服務器升級爲新的主服務器, 並讓失效主服務器的其餘從服務器改成複製新的主服務器; 當客戶端試圖鏈接失效的主服務器時, 集羣也會向客戶端返回新主服務器的地址, 使得集羣可使用新主服務器代替失效服務器。
二製做鏡像

整個集羣能夠分爲一個master,N個slave,M個sentinel,本次以2個slave和3個sentinel爲例:
docker-redis3
首先增長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

 

本文地址: http://www.linuxprobe.com/docker-redis.html

相關文章
相關標籤/搜索