使用 Sentinel 实现 Redis 集群高可用部署

2021/7/19 19:11:03

本文主要是介绍使用 Sentinel 实现 Redis 集群高可用部署,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Redis 概述

  • Redis 的出现时间并不长,是 NoSQL 中的一种,基于键-值型的存储,在 2009 年第一次发布 Redis。
  • Redis 全称(Remote Dictionary Server)远程字典服务器,而这个字典服务器从本质上来讲,主要是提供数据结构的远程存储功能的,可以理解为 Redis 是一个高级的 K-V 存储和数据结构存储,因为 Redis除了能够存储 K-V 这种简单的数据之外,还能够存储,列表、字典、hash 表、等对应的数据结构。
  • Redis 支持主从模式,Redis 能够借助于 Sentinel 工具来监控主从节点,当主节点发生故障时,会自
  • 己提升另外一个从节点成为新的主节点。 sentinel [ˈsentɪnl] 哨兵
  • Redis 官网:https://redis.io 

Redis 所支持的数据类型

  • 支持存储的数据类型有、String(字符串,包含整数), List(列表), Hash(关联数组), Sets(集合), Sorted Sets(有序集合), Bitmaps(位图), HyperLoglog
  • Redis 性能评估
  • 100 万较小的键存储字符串,大概消耗 100M 内存
  • 由于 Redis 是单线程,如果服务器主机上有多个 CPU,只有一个能够使用,但并不意味着 CPU 会成为瓶颈,因为 Redis 是一个比较简单的 K-V 数据存储,CPU 通常不会成为性能瓶颈
  • 在常见的 linux 服务器上,500K(50 万)的并发,只需要一秒钟处理,如果主机硬件较好的情况下,每秒钟可以达到上百万的并发
  • Redis 与 Memcache 对比
  • Memcache 只能使用内存来缓存对象,若要持久化,需要第三方插件的支持。而 Redis 除了可以使用内存来缓存对像,还可以周期性的将数据保存到磁盘上,对数据进行永久存储。当服务器突然断电或死机后, redis 基于磁盘中的数据进行恢复。
  • Redis 是单线程服务器,只有一个线程来响应所有的请求。Memcache 是多线程的
  • Redis 支持更多的数据类型

  • 试验环境

  • 系统统一使用   CentOS 7.6   防火墙、iptables以及 SElinux 均为关闭状态
  • 192.168.2.23    c7_2_23_redis1     Master
  • 192.168.2.23    c7_2_24_redis2     Slave1
  • 192.168.2.23    c7_2_25_redis3     Slave2
  • 使用 Remi repository 源安装 redis

  • 扩展:Remi repository 是什么源?
    Remi repository 是包含最新版本 PHP 和 MySQL 包的 Linux 源,由 Remi 提供维护。有了这个源之后,使用 YUM 安装或更新 PHP、MySQL、phpMyAdmin 等服务器相关程序的时候就非常方便了。但与此同时,Remi 源也提供了目前最新版本的 Redis,可以通过该源使用 YUM 安装目前最新版本的 Redis。
  • 在安装 Remi repository 源时,需要依赖 epel 源,因此先安装 epel 源
  • 这里使用 aliyun 的源

  • Remi repository 官网:http://rpms.remirepo.net/enterprise/ 

  • 分别在3台服务器上安装 Remi repository 源

  • yum -y install  http://rpms.remirepo.net/enterprise/remi-release-7.rpm
  • 查看 源文件 
  • yum repolist all
  • 使用 remi repository 源安装 Redis
    yum --enablerepo=remi install -y redis
  • 注:/etc/yum.repos.d/remi.repo 源安装完成后,默认为disabled,使用--enablerepo=remi 选项指定使用 remi repository 源进行安装。
  • 查看 Redis 版本
    redis-cli --version

  • 启动 Redis
  • systemctl enable redis.service --now
  • redis 默认端口为 6379

  • Redis 基本操作

  • Redis 配置文件参数说明
  • Redis 配置文件存放路径:/etc/redis.conf
    vim /etc/redis.conf              #配置文件中主要参数如下
    改:69 bind 127.0.0.1
    为:69 bind 0.0.0.0         #redis 监听的地址,默认监听在 127.0.0.1 地址上,改为 0.0.0.0 地址或192.168.2.23

以下内容,保持不变,大家可以了解一下,每个配置的含意:
protected-mode yes    #参数是为了禁止外网访问 redis,如果启用了,则只能够通过 lookback ip(127.0.0.1)访问 Redis。
port 6379                     #默认监听端口:6379。
tcp-backlog 511          #指定 tcp-backlog 的长度。backlog 是一个等待队列。当有大量请求需要redis 处理时,redist 有可能处理不过来,需要等待的请求队列会通过 backlog 来缓存。backlog 的数量决定了可以缓存的队列数。
unixsocket /tmp/redis.sock         #指定使用 sock 文件通信及 sock 文件位置,如果服务端和客户都在同一台主机上,建议打开此项,基于 sock 方式通信可以直接在内存中交换,数据不用再经过 TCP/TP 协议栈进行封装、拆封。
unixsocketperm 700       #定义 sock 文件的访问权限。
timeout 0                        #表示当客户端连接成功后,空闲(非活跃、或没有任何数据交互)多长时间则连接超时,0 表示不启用此功能。
tcp-keepalive 300          #定义是否启用 tcp-keepalive 功能。长链接功能。
daemonize no               #如果需要在后台运行,把该项改为 yes。如果使用 redis 服务脚本启动,即使daemonize 为 no,也会运行为一个守护进程。
supervised no               #定义是 upstart 还是 systemd 接管 redis 进程。默认无监督互动,不需要修改。
loglevel notice               #定义日志级别。
logfile /var/log/redis/redis.log      #定义日志文件。
databases 16                             #定义 redis 默认有多少个 databases,但是在分布式中,只能使用一个。
# masterauth <master-password>     #如果连接主数据库时需要密码验证,在这里指定密码。默认不启用。
# 限制同时连接的客户端数量。超过数量将不再接受新的请求并返回错误信息。
# maxclients 10000          #设置同时连接 redis 客户端的最大数量。  

  • 登录 Redis
  • redis-cli 
  • 选项:
  • -h <hostname> 指定主机 IP -p <port> 指定端口 socket 文件进行通信。
  • redis-cli -h 127.0.0.1                     #连接 redis,默认不启用密码认证。
  • 127.0.0.1:6379> exit                    #退出连接。
  • 或:
  • redis-cli                             #使用 redis-cli 直接连接,默认连接是 127.0.0.1 IP。 
  • Redis 字符串(String)操作
    键的命名规则遵循
    1.可以使用 ASCII 字符
    2.键的长度不要过长,键的长度越长则消耗的空间越多
    3.在同一个库中(名称空间),键的名称不得重复,如果复制键的名称,实际上是修改键中的值
    4.在不同的库中(名称空间),键的多种名称可以重复
    5.键可以实现自动过期
  • 设置键 system 的值为 centos
  • 127.0.0.1:6379> set system centos
    OK
    127.0.0.1:6379> get system
    "centos"

  • 定义一个键 name 值为 zhangsan,并设置过期时间为 60 秒。
    127.0.0.1:6379> set name zhangsan EX 60

  • 开启 redis 用户认证服务
    vim /etc/redis.conf
    改:507 # requirepass foobared   #启用此项,并指定密码即可。
    为:507 requirepass 123456        #指定密码为 123456。

    systemctl restart redis                   #重启服务。
  • edis-cli
    127.0.0.1:6379> get name
    (error) NOAUTH Authentication required.
    127.0.0.1:6379> auth 123456
    OK
    127.0.0.1:6379> get name
    (nil)
    127.0.0.1:6379> get system
    "centos"
    127.0.0.1:6379> 
    redis-cli -a 123456
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    127.0.0.1:6379> get system
    "centos"
    127.0.0.1:6379> 

配置 Redis 持久化

  • redis 持久化概述
  • Redis 工作时所有数据集都是存储于内存中的,如果 Redis 崩溃或断电导致所有数据丢失,所以 Redis提供了持久化功能来保证数据的可靠性
  • Redis 持久化有两种实现方法:RDB 和 AOF
  • RDB: 存储为二进制格式的数据文件,是默认启动的持久化机制;按事先定制的策略,周期性地将数据保存至磁盘。
  • AOF:Append Only File 类似于 MySQL 的二进制日志,记录每一次 redis 的写操作命令,以顺序 IO 方式附加在指定文件的尾部,是使用追加方式实现的,这也叫做一种附加日志类型的持久化机制。
  • 由于每一次的操作都记录,则会随着时间长而增大文件的容量,并且有些记录的命令是多余的。但是 redis 进程能够自动的去扫描这个对应的 AOF 文件,把其中一些冗余的操作给合并一个,以实现将来一次性把数据恢复。
  • 总结:AOF 记录操作命令,RDB 是直接保存数据集的本身。
  • 配置文件中的与 RDB 相关的参数

  • vim /etc/redis.conf            #默认参数就够用了。
  • stop-writes-on-bgsave-error yes    #在进行快照备份时,一旦发生错误的话是否停止。
  • rdbcompression yes    #RDB 文件是否使用压缩,压缩会消耗 CPU。
  • rdbchecksum yes       #是否对 RDB文件做校验码检测,此项定义在 redis 启动时加载 RDB文件是否对文件检查校验码,在 redis 生成 RDB 文件是会生成校验信息,在 redis 再次启动或装载 RDB 文件时,是否检测校验信息。如果检测的情况下会消耗时间,会导致 redis 启动时慢,但是能够判断 RDB 文件是否产生错误。
  • dbfilename dump.rdb   #定义 RDB 文件的名称。
  • dir /var/lib/redis            #定义 RDB 文件存放的目录路径。
  • 注意:持久化本身不能取代备份;还应该制定备份策略,对 redis 数据库定期进行备份。

  • vim /var/lib/redis/dump.rdb         #可查看到数据已经保存在磁盘上


  • 搭建 Redis 主从复制架构 

  • 主从复制的工作过程
    Redis 的主从复制是自动进行的,并不需要用户的介入,slave 端会自动连接 master 并进行数据同步。如果同步连接时 slave 端短暂的与 master 端断开了连接,那连接恢复后 slave 端会与 master 端进行一次同步。从而保证数据一致。
  • Redis 主从同步数据流程如下图: 

  • master 不需要特别配置保证能正常运行即可
  • 只需要在 slave1 和 2 上配置
  • vim /etc/redis.conf
    replicaof 192.168.2.23 6379     master  的 IP 以及端口
    masterauth 123456                   master  密码,如果没有密码可以不设置
    requirepass 123456

  • 登录   master   2.23  查看主从复制状态
  •  info replication

  • redis-cli -a 123456
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    127.0.0.1:6379> info replication
    # Replication
    role:master                          角色 master
    connected_slaves:2            slave 数量 2 个
    slave0:ip=192.168.2.24,port=6379,state=online,offset=0,lag=0        slave  1   信息
    slave1:ip=192.168.2.25,port=6379,state=online,offset=0,lag=0        slave  2   信息

    master_failover_state:no-failover
    master_replid:9f270ccf6277aa3b5652f0216d1953f4dcd0ec47
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:0
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:0
    127.0.0.1:6379>

  • redis-cli -a 123456
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    127.0.0.1:6379> info replication
    # Replication
    role:slave                                角色 slave 
    master_host:192.168.2.23     mster IP地址
    master_port:6379                   master 端口
    master_link_status:up           状态 UP 为已经同步
    master_last_io_seconds_ago:2
    master_sync_in_progress:0
    slave_repl_offset:406
    slave_priority:100
    slave_read_only:1                  成为从服务以后,1 表示该服务器为只读。
    replica_announced:1
    connected_slaves:0
    master_failover_state:no-failover
    master_replid:ac49e447d70bee8f57428b1d35391150e0dfba74
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:406
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:407
    repl_backlog_histlen:0
    127.0.0.1:6379> 

  •  测试

  • 在 master 端 创建一个 user 键

  • 在 slave 端 查看

  • 可以查看到键值,说明主从数据同步成功。 
  • 查看 redis 从服务器上有关主从复制的高级配置参数

  • /etc/redis.conf                          #保持默认参数就可以,不需要修改
    #### SNAPSHOTTING #### #定义快照存储的策略,定义存到硬盘的持久化策略。
    save <seconds> <changes>    #使用 save 指令,并指定每隔多少秒,如果发生多大变化,进行存储。
    save 900 1                    #表示在 900 秒(15 分钟内),如果至少有 1 个键发生改变,则做一次快照(持久化)
    save 300 10                 #表示在 300 秒(5 分钟内),如果至少有 10 个键发生改变,则做一次快照(持久化)
    save 60 10000             #表示在 60 秒(1 分钟内),如果至少有 10000 个键发生改变,则做一次快照(持久化)。
    replica-serve-stale-data yes      #当 slave 端在主从复制的过程中与 master 端断开了连接,此时有 2 种处理方法:一种是继续提供服务即使数据可能不是最新的,另一种是对请求返回一个错误信息,默认配置是继续提供服务。replica [ˈreplɪkə] 复制品 ; stale [steɪl] 不新鲜的
    replica-read-only yes                #redis 从只读。自 redis 2.6 版本开始,slave 端默认为 readonly
    repl-diskless-sync no                #默认不使用 diskless 同步方式 。
    扩展:主从同步支持两种策略,即 disk 和 socket 方式(socket 方式尚不完善,还处于实验阶段)。
    新的 slave 端和重连的 salve 端不允许去继续同步进程,这被称之为“完全同步”。
  • 一个 RDB 文件从 master 端传到 slave 端,分为两种情况:
  • 支持 disk:master 端将 RDB file 写到 disk,稍后再传送到 slave 端;
  • 无磁盘 diskless:master 端直接将 RDB file 传到 slave socket,不需要与 disk 磁盘进行交互。
  • 无磁盘 diskless 方式适合磁盘读写速度慢但网络带宽非常高的环境。

repl-diskless-sync-delay 5      #无磁盘 diskless 方式在进行数据传递之前会有一个时间的延迟,以便 slave 端能够进行到待传送的目标队列中,这个时间默认是 5 秒 。
repl-ping-replica-period 10      #slave 端向 server 端发送 pings 的时间区间设置,默认为10 秒
repl-timeout 60                    #设置超时时间

repl-disable-tcp-nodelay no     #是否启用 TCP_NODELAY,如果启用则会使用少量的 TCP包和带宽去进行数据传输到 slave 端,当然速度会比较慢;如果不启用则传输速度比较快,但是会占用比较多的带宽。
repl-backlog-size 1mb      #设置 backlog 的大小,backlog 是一个缓冲区,在 slave 端失连时存放要同步到 slave 的数据,因此当一个 slave 要重连时,经常是不需要完全同步的,执行局部同步就足够了。backlog 设置的越大,slave 可以失连的时间就越长。
repl-backlog-ttl 3600    #如果一段时间后没有 slave 连接到 master,则 backlog size 的内存将会被释放。如果值为 0 则表示永远不释放这部份内存。 默认是 3600 秒
replica-priority 100      #slave 端的优先级设置,值是一个整数,数字越小表示优先级越高。当master 故障时将会按照优先级来选择 slave 端进行恢复,如果值设置为 0,则表示该 slave 永远不会被选择。
min-replicas-to-write 3
min-replicas-max-lag 10     #这两行的意思是,设置当一个 master 端的可用 slave 少于 N个,延迟时间大于 M 秒时,不接收写操作。

当 master 可用的从服务器少于 3 个或网络延迟时间大于 10 秒时,master 将拒绝接收用户的写请求


  • 使用 Sentinel 实现 Redis 集群高可用部署

  • redist 主从架构中,如果主服务器离线,那么所有写操作操作则无法执行。为了避免此情况发生,redis 引入了 sentinel(哨兵)机制,当 redis 主挂了,redis 从可以主动变成主。
  • Sentinel 概述和工作过程
    Sentinel 作用:检测 Master 状态,如果 Master 异常,则会进行 Master-Slave 切换,将其中一个 Slave 作为 Master,将之前的 Master 作为 Slave 。当 Master-Slave 切换后,master-redis.conf、slave-redis.conf 和 sentinel.conf 的内容都会发生改变,即 master-redis.conf 中会多一行 slaveof 的配置,sentinel.conf 的监控目标会随之调换
  • Sentinel 工作方式
    Sentinel 是 Redis 官方提供的一种高可用方案(除了 Sentinel,Redis Cluster 是另一种方案),它可以自动监控 Redis master/slave 的运行状态,如果发现 master 无法访问了,就会启动 failover 把其中一台可以访问的 slave 切换为 master。
  • 支持 Sentinel 的 Redis 客户端(例如 Java 的 Jedis)会在连接 Redis 服务器的时候向 Sentinel 询问 master 的 ip,并且会在收到 master 切换的 pub/sub 事件后自动重新连接到新的 master。对调用Redis 客户端的业务系统来说,这些都是完全透明的。
  • 下图是 redis sentinel 的部署和运行机制 : 

  • 扩展:redis 主观下线和客观下线
    主观下线:Subjectively Down,简称 SDOWN,指的是当前 Sentinel 实例对某个 redis 服务器做出的下线判断。 Subjectively [səb'dʒektɪvlɪ] 主观地
    客观下线:Objectively Down, 简称 ODOWN,指的是多个 Sentinel 实例在对 Master Server做出 SDOWN 判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server 下线判断,然后开启 failover。 Objectively [əb'dʒektɪvlɪ] 客观地
  • 使用 Sentinel 实现 Redis 集群高可用部署 

  • 修改 /etc/redis.conf
  • 首先在  192.168.2.23  master 端
  • 取消 密码认证
  • protected-mode no      #关闭 protected-mode,允许外网访问 redis 服务器。
  • /etc/redis.conf
    bind 0.0.0.0
    protected-mode no
    #requirepass 123456
  • 完整的配置文件内容
  • cat /etc/redis.conf
    bind 0.0.0.0
    protected-mode no
    port 6379
    tcp-backlog 511
    timeout 0
    tcp-keepalive 300
    daemonize no
    pidfile "/var/run/redis_6379.pid"
    loglevel notice
    logfile "/var/log/redis/redis.log"
    databases 16
    always-show-logo no
    set-proc-title yes
    proc-title-template "{title} {listen-addr} {server-mode}"
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename "dump.rdb"
    rdb-del-sync-files no
    dir "/var/lib/redis"
    replica-serve-stale-data yes
    replica-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-diskless-load disabled
    repl-disable-tcp-nodelay no
    replica-priority 100
    acllog-max-len 128
    maxclients 10000
    lazyfree-lazy-eviction no
    lazyfree-lazy-expire no
    lazyfree-lazy-server-del no
    replica-lazy-flush no
    lazyfree-lazy-user-del no
    lazyfree-lazy-user-flush no
    oom-score-adj no
    oom-score-adj-values 0 200 800
    disable-thp yes
    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
    aof-use-rdb-preamble 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-size -2
    list-compress-depth 0
    set-max-intset-entries 512
    zset-max-ziplist-entries 128
    zset-max-ziplist-value 64
    hll-sparse-max-bytes 3000
    stream-node-max-bytes 4kb
    stream-node-max-entries 100
    activerehashing yes
    client-output-buffer-limit normal 0 0 0
    client-output-buffer-limit replica 256mb 64mb 60
    client-output-buffer-limit pubsub 32mb 8mb 60
    hz 10
    dynamic-hz yes
    aof-rewrite-incremental-fsync yes
    rdb-save-incremental-fsync yes
    jemalloc-bg-thread yes
    supervised systemd
    save 3600 1
    save 300 100
    save 60 10000
    user default on nopass ~* &* +@all 

  • 接着配置 sentinel1
    vim /etc/redis-sentinel.conf

改: # protected-mode no
为: protected-mode no
port 26379 #默认,保持不变
改:daemonize no
为:daemonize yes
改:sentinel monitor mymaster 127.0.0.1 6379 2
为:sentinel monitor mymaster 192.168.2.23 6379 2
注:# sentinel monitor <master-name> <ip> <redis-port> <quorum> 每项含意如下:
<master-name>为集群名称,可以自定义,如果同时监控有多组 redis 集群时,<master-name>不能一样。
<ip> 主节点的 IP 地址,<redis-port>主节点的端口号。
<quorum>主节点对应的 quorum 法定数量,用于定义 Sentinel 的数量,是一个大于值尽量使用奇数,如果 Sentinel 有 3 个,则指定为 2 即可,如果有 4 个,不能够指定为 2,避免导致集群分裂。最后的数字 2 指定的值,表明如果有 2 个 sentinels 无法连接 master,才认为 master 挂了。quorum [ˈ kwɔ :rə m] 法定人数 
改:# sentinel down-after-milliseconds <master-name> <milliseconds> 
为:sentinel down-after-milliseconds mymaster 10000    #默认单位是毫秒,配成 10 秒
sentinel parallel-syncs mymaster 1 #保存默认parallel [ˈ pærəlel] 平行
改:sentinel failover-timeout mymaster 180000 
为:sentinel failover-timeout mymaster 60000 

  • 把 redis-sentinel.conf 发给 另外2台 slave 

  • 登录 redis 查看 同步状态 信息

  •  测试插入数据

  • 模拟故障 停止  2.23 的 redis

  • 查看日志

  • 恢复 2.23

  • 主 redis 还是 2.24,并不会因为 2.23 恢复成功后,就主动让出权限。 这样可以避免再次回切时,发生服务中断

  • 查看 Sentinel 信息
     
  • redis-cli -h 192.168.2.23 -p 26379
    192.168.2.23:26379> info sentinel
    # Sentinel
    sentinel_masters:1
    sentinel_tilt:0
    sentinel_running_scripts:0
    sentinel_scripts_queue_length:0
    sentinel_simulate_failure_flags:0
    master0:name=mymaster,status=ok,address=192.168.2.24:6379,slaves=2,sentinels=4
    192.168.2.23:26379>

  • 注意:将来客户端应连接 Sentinel,向 Sentinel 发请求去寻址,并根据 Sentinel 的反馈,进行连接新的 Redis 主节点,这一点需要使用 Redis 专用客户端来实现。Redis 客户端会根据 Sentinel 返回的新节点 IP 进行连接。这一块是开发人员的事情了。如果 java 中的 JedisClient 就提供了使用 Sentinel的功能。 

 



这篇关于使用 Sentinel 实现 Redis 集群高可用部署的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程