redis高可用集群介绍

    xiaoxiao2021-03-26  3

    一、redis的高可用管理工具sentinel介绍

    sentinel是一个管理redis实例的工具,它可以实现对redis的监控、通知、自动故障转移。sentinel不断的检测redis实例是否可以正常工作,通过API向其他程序报告redis的状态,

    如果redis master不能工作,则会自动启动故障转移进程,将其中的一个slave提升(通过选举)为master,其他的slave重新设置新的master服务器。而故障的master再次启动后会被sentinel自动降级为slave服务器加入到集群中。

    redis主从的特点:

    1、redis使用异步复制,从服务器会以每秒一次的频率向主服务器报告复制流的处理进度

    2、一个主服务器可以有多个从服务器,从服务器也可以有自己的从服务器(级联复制)

    3、复制功能不会阻塞主服务器,即使一个或多个从服务器正在进行初次同步,主服务器也可以继续处理命令请求

    4、复制功能可以用于数据冗余,也可以通过让多个从服务器处理只读命令请求来提升扩展性

    5、Redis从节点默认为只读,无须手动配置

    redis的主从集群可以实现分担压力的效果,但是无法做到高可用,如果master宕掉,服务就不可用了,所以使用redis的sentinel可以实现HA的功能:

    sentinel作用如下:

    1、监控:sentinel会不断的检查你的主服务器和从服务器是否运行正常

    2、当被监控的某个redis服务器出现问题时,sentinel可以通过API向管理员或者其他应用程序发送通知

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

    二、部署说明

    redis-server 192.168.248.131

    redis-slave 192.168.248.132

    redis-slave 192.168.248.133

    先进行的主从的配置

    安装redis

    redis可以根据自己的需求去redist官网去下载https://redis.io/download

    tar –zxvf redis-3.0.7.tar.gz

    cd redis-3.0.7

    make

    mkdir –pv /data/redis

    之后将redis的命令文件拷贝到/usr/local/sbin下面去

    cd /usr/local/src/redis-3.0.7/src

    cp redis-benchmark  redis-check-aof redis-check-dump redis-cliredis-server  redis-sentinel  /usr/local/sbin

    redis-server的redis.conf配置文件

    cat > /etc/redis/redis.conf <<EOF

    maxmemory 256mb

    daemonize yes

    pidfile"/data/redis/redis-6379.pid"

    port 6379

    bind 0.0.0.0

    tcp-backlog 511

    timeout 0

    tcp-keepalive 0

    loglevel notice

    logfile "/data/redis/redis.log"

    databases 16

    save 900 1

    save 300 10

    save 60 10000

    stop-writes-on-bgsave-error yes

    rdbcompression yes

    rdbchecksum yes

    dbfilename "dumpredis-6379.rdb"

    dir "/data/redis"

    slave-serve-stale-data yes

    slave-read-only yes

    repl-diskless-sync no

    repl-diskless-sync-delay 5

    # repl-ping-slave-period 10

    # repl-timeout 60

    repl-disable-tcp-nodelay no

    # repl-backlog-size 1mb

    # repl-backlog-ttl 3600

    slave-priority 100

    # min-slaves-to-write 3

    # min-slaves-max-lag 10

    appendonly no

    appendfilename "appendonly.aof"

    appendfsync everysec

    no-appendfsync-on-rewrite no

    auto-aof-rewrite-percentage 100

    auto-aof-rewrite-min-size 64mb

    aof-load-truncated yes

    lua-time-limit 5000

    slowlog-log-slower-than 10000

    slowlog-max-len 128

    latency-monitor-threshold 0

    notify-keyspace-events ""

    hash-max-ziplist-entries 512

    hash-max-ziplist-value 64

    list-max-ziplist-entries 512

    list-max-ziplist-value 64

    set-max-intset-entries 512

    zset-max-ziplist-entries 128

    zset-max-ziplist-value 64

    hll-sparse-max-bytes 3000

    activerehashing yes

    client-output-buffer-limit normal 0 0 0

    client-output-buffer-limit slave 256mb 64mb60

    client-output-buffer-limit pubsub 32mb 8mb60

    hz 10

    aof-rewrite-incremental-fsync yes

    EOF

    slave的redis.conf

    cat >/etc/redis/redis.conf <<EOF

    slaveof 192.168.248.131  6379

    maxmemory 256mb

    daemonize yes

    pidfile"/data/redis/redis-6379.pid"

    port 6379

    bind 0.0.0.0

    tcp-backlog 511

    timeout 0

     

    tcp-keepalive 0

    loglevel notice

    logfile "/data/redis/redis.log"

    databases 16

    save 900 1

    save 300 10

    save 60 10000

    stop-writes-on-bgsave-error yes

    rdbcompression yes

    rdbchecksum yes

    dbfilename "dumpredis-6379.rdb"

    dir "/data/redis"

    slave-serve-stale-data yes

    slave-read-only yes

    repl-diskless-sync no

    repl-diskless-sync-delay 5

    # repl-ping-slave-period 10

    # repl-timeout 60

    repl-disable-tcp-nodelay no

    # repl-backlog-size 1mb

    # repl-backlog-ttl 3600

    slave-priority 100

    # min-slaves-to-write 3

    # min-slaves-max-lag 10

     

    appendonly no

    appendfilename "appendonly.aof"

    appendfsync everysec

    no-appendfsync-on-rewrite no

    auto-aof-rewrite-percentage 100

    auto-aof-rewrite-min-size 64mb

    aof-load-truncated yes

    lua-time-limit 5000

    slowlog-log-slower-than 10000

    slowlog-max-len 128

    latency-monitor-threshold 0

    notify-keyspace-events ""

    hash-max-ziplist-entries 512

    hash-max-ziplist-value 64

    list-max-ziplist-entries 512

    list-max-ziplist-value 64

    set-max-intset-entries 512

    zset-max-ziplist-entries 128

    zset-max-ziplist-value 64

    hll-sparse-max-bytes 3000

    activerehashing yes

    client-output-buffer-limit normal 0 0 0

    client-output-buffer-limit slave 256mb 64mb60

    client-output-buffer-limit pubsub 32mb 8mb60

    hz 10

    aof-rewrite-incremental-fsync yes

    EOF

    在slave的配置文件中需要指明的是slaveof  masterip  port

    之后就组成了redis的集群,但是这样同样会存在问题,如果我们的master出现问题之后,slave就会找不到master同步数据,另外client端也会发生找不到master从而不能写的请求被拒绝的情况。

    所以下面为redis添加sentinel添加哨兵,哨兵的作用就是当redis的master发生改变的时候,会在其余的slave中重新选举一个新的master,如果原来的master的redis服务恢复之后,他不会重新的抢回master的角色,而是会被降级为slave。

    redis-sentinel.conf

    cat>/etc/redis/sentinel.conf <<EOF

    dir /tmp     

    sentinel monitor mymaster 192.168.248.131 6379 2     

    sentinel down-after-milliseconds mymaster 30000     

    sentinel parallel-syncs mymaster 1     

    sentinel failover-timeout mymaster 180000 

    EOF

    三个节点的sentinel.conf配置文件是一样的。

    之后启动redis-server和redis-sentinel服务

    redis-server  /etc/redis/redis.conf &

    redis-sentinel  /etc/redis/sentinel.conf &

    表示两个服务全部从在后台启动。

    redis配置文件解析

    maxmemory 256mb

    redis可以使用的最大的内存大小,redis访问速度非常快的原因是他把数据全部的加载到内存中去,然后在持久化到磁盘中。但是如果内存满了的话,那么redis就会清除一些key,这些key是设置了超时时间的key,虽然超时时间还没有到,但是仍然有可能被删除。如果删除了这些key之后,仍然没有办法多余空间的话,那么redis就会返回错误给连接的客户端。

    daemonize yes

    是不是以守护进程的方式运行,如果此处是yes的话,在启动redis的时候,我们就不需要使用&,让服务去后台运行。

    pidfile"/data/redis/redis-6379.pid"

    redis的pid文件所在的位置

    port 6379

    redis监听的端口

    bind 0.0.0.0

    监听的地址,如果为了保证安全的话在此处可以进行限制为自己需要的内网地址

    tcp-backlog 511

    为了避免redis客户端连接的慢,需要调节的redis客户端的最大的数量,这个值会默认的设置为/proc/sys/net/core/somaxconn下面的数量,所以如果想要修改的话,记住两处都要修改

    timeout 0

    客户端连接的超时时间,如果是0的话表示的话,不超时,不管这个连接

    tcp-keepalive 0

    是不是启用长连接,0表示不启用

    loglevel notice

    日志的级别,日志级别有四种debug  notice  info warning

    logfile "/data/redis/redis.log"

    日志文件的位置

    databases 16

    启用的数据库

    save 900 1

    save 300 10

    save 60 10000

    在相应的时间内有多少个key发生了变化,就将数据持久化到磁盘中去

    stop-writes-on-bgsave-error yes

    当后台保存失败,持久化失败的是,是不是停止进行写操作

    rdbcompression yes

    数据是否压缩

    rdbchecksum yes

    是否对数据进行校验

    dbfilename "dumpredis-6379.rdb"

    持久化数据的名称

    dir "/data/redis"

    数据的保存路径

    slave-serve-stale-data yes

    当slave和master数去联系或者是在进行数据复制的时候,是不是仍然提供给客户端服务

    slave-read-only yes

    slave是不是只是只读的

    repl-diskless-sync no

    复制集同步策略:磁盘或者socket

    新slave连接或者老slave重新连接时候不能只接收不同,得做一个全同步。需要一个新的RDB文件dump出来,然后从master传到slave。可以有两种情况:

    1)基于硬盘(disk-backed):master创建一个新进程dump RDB,完事儿之后由父进程(即主进程)增量传给slaves。

    2)基于socket(diskless):master创建一个新进程直接dumpRDB到slave的socket,不经过主进程,不经过硬盘。

    基于硬盘的话,RDB文件创建后,一旦创建完毕,可以同时服务更多的slave。基于socket的话,新slave来了后,得排队(如果超出了repl-diskless-sync-delay还没来),完事儿一个再进行下一个。

    当用diskless的时候,master等待一个repl-diskless-sync-delay的秒数,如果没slave来的话,就直接传,后来的得排队等了。否则就可以一起传。

    disk较慢,并且网络较快的时候,可以用diskless。(默认用disk-based)

    repl-diskless-sync-delay 5

    同步延迟时间

    # repl-ping-slave-period 10

    # repl-timeout 60

    repl-disable-tcp-nodelay no

    # repl-backlog-size 1mb

    # repl-backlog-ttl 3600

    slave-priority 100

    slave的优先级(和竞选master有关系)

    # min-slaves-to-write 3

    # min-slaves-max-lag 10

    appendonly no

    redis异步的dump数据到disk,如果是断电了那么就会有比部分数据丢失,aof则提供了更好的方式,保证了如果发生错误那么丢失的仅仅是上一秒的数据或者是上一次写操作的数据。当aof文件过大的话就会重新再生成另外的一个aof文件

    appendfilename "appendonly.aof"

    aof文件的名称

    appendfsync everysec

    文件的同步的方式,有单重  no always  everysec ,第一种的话由操作系统自己决定,这样子会跟快,第二种的话是每次写操作更新速度慢但是最安全,第三种是每秒进行一次 两种的折中办法

    no-appendfsync-on-rewrite no

    当fsync为always或者everysec,当一个bgsave或者AOF rewrite线程正在耗费大量I/0,redis可能会在fsync上阻塞很久。发生之后就无法fix,即使是另一个线程跑fsync,也会阻塞我们同步的write方法。

    如下方法可以解决这个问题:当bgsave()或bgrewriteaof()在跑,主进程的fsync()就无法调用。也就是当子进程在save,那段时光相当于redis是appendaof no的。也就是有可能会丢失最多30s的log。

    所以如果你有lag问题,把下边改成yes,否则就用no。yes意思是暂停aof,拒绝主进程的这次fsync。no是redis是排队的,不会被prevent了,但主进程是阻塞的。

    auto-aof-rewrite-percentage 100

    auto-aof-rewrite-min-size 64mb

    自动重写AOF

    当AOF文件大小到一定比例,就自动隐式调用BGREWRITEAOF

    过程:redis记住最后一次rewrite时aof文件大小(重启后没rewrite的话,就是启动时AOF文件的大小),如果现在AOF大小和上次的比例达到特定值就重写。也要指定最小AOF大小,防止到2倍:1M的时候也重写。

    aof-load-truncated yes

    aof文件在尾部是不完整的,那redis重启的时候load进内存的时候就会出现问题,如果aof-load-truncated 为yes的时候就会尽量多的将数据load进内存中,如果是no的话就必须手动的修复数据,利用redis-check-aof就行数据的修复

    lua-time-limit 5000

    lua时间时间为毫秒

    slowlog-log-slower-than 10000

    慢日志的时间为微秒

    slowlog-max-len 128

    latency-monitor-threshold 0

    notify-keyspace-events ""

    hash-max-ziplist-entries 512

    hash-max-ziplist-value 64

    list-max-ziplist-entries 512

    list-max-ziplist-value 64

    set-max-intset-entries 512

    zset-max-ziplist-entries 128

    zset-max-ziplist-value 64

    hll-sparse-max-bytes 3000

    activerehashing yes

    client-output-buffer-limit normal 0 0 0

    client-output-buffer-limit slave 256mb 64mb60

    client-output-buffer-limit pubsub 32mb 8mb60

    hz 10

    aof-rewrite-incremental-fsync yes

    当child进程在rewrite AOF文件,如果这个选项是yes,那么这个file每32MB会写fsync()。这个是保证增量写硬盘而防止写硬盘时I/O突增

    当redis-server启动之后可以使用redis-cli info来查看redis的信息

    redis-sentinel介绍

    redis-sentinel实现的是对redis服务进行监控,是想一下加入我们的redis集群中有三台机器,mater角色实现的是write以及read的功能。并且slave一般都是read-only的。当master出现意外的情况下,这时候客户端的write请求就会被拒绝掉,这个显然是不合理的。所以需要有新的slave重新升级为master。

    master的sentinel.conf文件内容

    cat >/etc/redis/sentinel.conf<<EOF

    port 26379    

    dir /tmp    

    sentinel monitor mymaster 192.168.248.131  6379 2    

    sentinel down-after-milliseconds mymaster30000    

    sentinel parallel-syncs mymaster 1    

    sentinel failover-timeout mymaster 180000

    EOF

    redis-sentinel配置详解

    port 26379     监听的端口

    dir /tmp     存放的目录

    sentinel monitor mymaster 192.168.1.2416379 2   

    监听的master的名称(随意起名字)地址端口号 后面的是2表示的是在集群中至少有两个slave同时判断master失效,master才算失效(object_down)

    sentinel down-after-milliseconds mymaster30000   

    经过多长时间之后如果还不能和master联系上之后,就认定master已经down掉,默认的时间是30s

    sentinel parallel-syncs mymaster 1    

    指定在故障转移的过程中,多少个slave和新的master进行数据的同步如果在,这个数值越小,所需的同步时间越长(一共有n个slave,每次只进行一个的同步当时需要的时间会比较长)当客户端执行slaveof并进行同步时,会中断和客户端的请求,所以如果后面的数字越大,那么会给客户端的访问带来一定的问题

    sentinel failover-timeout mymaster180000 

    故障切换的过程中slave和新的master同步的超时时间,如果在超时时间内没有完成,则认为失败。默认时间为3minutes

    note:在进行redis的故障转移过程中,redis配置文件会被rewrite为新的slaveof,也就是redis的配置文件会被重写

    在此redis 主从加上sentinel就已经搭建好了。现在还存在一个问题,如果程序中写死了写缓存的地址,就是192.168.248.254,但是当masterdown掉之后新的master的地址可能是发生变化的,所以此时我们需要keepalived来实现地址的漂移。

    redis-server + redis-sentinel + keepalived

    keepalived下载的官网地址为http://www.keepalived.org/download.html,可以根据自己的需求来进行下载

    安装之前先解决掉依赖

    yum –y install  openssl-devel

    tar –zxvf keepalived-1.2.20.tar.gz

    cd keepalived-1.2.20

    ./configure –prefix=/usr/local/keepalived

    make

    make install

    mkdir /etc/keepalived

    cd /usr/local/keepalived

    cp etc/keepalived/keepalived.conf/etc/keepalived

    cp rc.d/init.d/keepalived /etc/init.d

    cp sysconfig/keepalived  /etc/sysconfig/

    cp sbin/keepalived /usr/sbin/

    默认keepalived的日志会存放到/var/log/message中,在此处可以进行自定义

    修改/etc/sysconfig/keepalived

    KEEPALIVED_OPTIONS="-D -d -S 0"

    修改/etc/rsyslog.conf  追加下面的配置

    local0.*   /var/log/keepalived.log  

    cat>/etc/keepalived/keepalived.conf<< EOF                                       

    ! Configuration File for keepalived

     

    global_defs {

      notification_email {

        acassen@firewall.loc

        failover@firewall.loc

        sysadmin@firewall.loc

       }

      notification_email_from Alexandre.Cassen@firewall.loc

      smtp_server  127.0.0.1

      smtp_connect_timeout 30

      router_id LVS_DEVEL

      vrrp_skip_check_adv_addr

      vrrp_strict chk_redis {

          script "redis-cli info | grep role:master &>/dev/null2>&1"

          weight -10

          interval 1

          timeout 2

          rise 1

          fall 2

    }

    }

     

    vrrp_instance VI_1 {

       state  BACKUP

       interface eth1

       virtual_router_id 51

       priority 100

       advert_int 1

       authentication {

           auth_type PASS

           auth_pass 1111

        }

       virtual_ipaddress {

           192.168.248.254

        }

       tack_script {

           chk_redis

    }

    }

    EOF

    其余的slave节点的配置是相同的,但是需要注意的是通信的接口是不是都是eth0。

    至此,我们就配置好了,当keepalived或者是redis出现问题的时候,就会自动的进行IP地址的漂移。

    二、redis+keepalived+twemproxy实现redis高可用

    twemproxy是Twitter推出的redis集群的解决方案

    twemproxy特点:

    1、        对外暴露一个访问节点

    2、        请求分片

    3、        分片要合理(分片均匀,相同的请求分配到同样的redis节点)

    对于和sentinel不同的是,sentinel组成是redis的主从集群,也就是说当master节点出现问题之后,会有一个新的原来的slave成为master节点,然后slave在向master同步数据。所有的主从节点的数据是一致的。但是twemproxy实现的是一个代理的作用,只对外暴露一个节点地址,client端通过这个地址来进行访问,代理节点将client的请求分发到后面的redis节点。如果一个节点出现问题,这个节点上面的数据会受到影响。

    下面简单的介绍实现方法

    首先下载twemproxy

    git clone https://github.com/twitter/twemproxy.git

    之后执行autoreconf,这时候有可能会包autoconf的版本比较低,需要更高版本的autoconf,这时候需要去下载更高版本的autoconf,http://ftp.gnu.org/gnu/autoconf/可以到这个站点去下载,安装之后

    CFLAGS="-ggdb3 -O0" autoreconf -fvi && ./configure --prefix=/usr/local/twemproxy --enable-debug=log

    进行安装,如果报错的话解决掉相应的依赖即可。

    make && makeinstall

    安装好之后

    cd /usr/local/twemproxy

    mkdir conf

    此时编辑配置文件,不过同样可以从原来下载的源码包将配置文件的样例复制过来,文件为原来twemproxy的conf目录下,名字叫做nutcracker.yml,复制到安装目录的conf目录下,过来进行如下的编辑

    redis:

      listen: 0.0.0.0:6379

      hash: fnv1a_64

      distribution: ketama

      auto_eject_hosts: true

      redis: true

      timeout: 400

      server_retry_timeout: 2000

      server_failure_limit: 1

      servers:

       - 192.168.248.135:6380:1

       - 192.168.248.136:6380:1

    创建好之后就可以启动了

    /usr/local/twemproxy/sbin/nutcracker-d -c /usr/local/twemproxy/nutcracker.yml

    在此处,我们想集群中添加了两个redis,并且监听的端口号为6380,权重全部为1,后面权重代表的是前端对后面两个分配任务的额度。

    为了实现高可用下面搭建keepalived

    ! Configuration File for keepalived

     

    global_defs {

      notification_email {

        #sysadmin@firewall.loc

      }

      #notification_email_from Alexandre.Cassen@firewall.loc

     # smtp_server 192.168.200.1

     # smtp_connect_timeout 30

      router_id LVS_DEVEL

    }

     

    vrrp_script chk_nutcracker {

           script "killall -0 nutcracker"

           interval 2

           weight -4

    }

     

    vrrp_instance VI_85 {

       state BACKUP

       interface eth1

       virtual_router_id 85

       priority 100

       virtual_ro

       advert_int 1

       authentication {

           auth_type PASS

           auth_pass 8888

       }

       virtual_ipaddress {

           192.168.248.254

       }

       track_script {

           chk_haproxy

       }

    }

     

    vrrp_instance VI_86 {

       state MASTER

       interface eth1

       virtual_router_id 86

       priority 101

       virtual_ro

       advert_int 1

       authentication {

           auth_type PASS

           auth_pass 5555

       }

       virtual_ipaddress {

           192.168.248.253

       }

       track_script {

           chk_nutcracker

       }

    }

    两台主机分别互相做主从,另外一台主机做相对应的配置就行。当然如果我们想对keepalived的log进行设置的话,只需要设置/etc/sysconfig/keepalived和/etc/rsyslog.conf就可以了。设置好了之后我们就可以使用VIP来进行redis的处理了。

    转载请注明原文地址: https://ju.6miu.com/read-500405.html

    最新回复(0)