Redis(三):redis集群——主从复制、哨兵、集群

主从复制

概述

单机redis的风险及问题

  1. 机器故障:硬盘故障,系统崩溃,数据丢失,很可能对业务造成灾难性打击
  2. 容量瓶颈:随着数据越来越多,内存不足,内存需要无限升级
    解决
    为了避免单点Redis服务器故障,准备多台服务器,互相连通。将数据复制多个副本保存在不同的服务器上,连接在一起,并保证数据是同步的,即使其中一台服务器宕机,其他服务器仍然可以继续提供服务,实现Redis的高可用,同时实现数据的冗余备份
    Redis(三):redis集群——主从复制、哨兵、集群_第1张图片
    主从复制就是将master数据即使、有效的同步(复制)到slave的过程;一个master可以有多个slave,但一个slave只对应一个master

主从复制的作用

  1. 读写分离:master写,slave读,提高服务器的读写负载能力
  2. 负载均衡:基于主从结构,配合读写分离,由slave分担master负载,并根据需求的变化,改变slave的数量,通过多个节点分担数据读取负载,大大提高Redis服务器并发量于数据吞吐量
  3. 故障恢复:当master出现问题时,由slave提供服务,实现快速的故障恢复
  4. 数据冗余:实现数据热备份,是持久化之外的一种数据冗余方式
  5. 高可用基石:基于主从复制,构建哨兵模式和集群,实现Redis的高可用方案

主从复制工作流程

主从复制过程大体可以分为三个阶段:建立连接阶段(即准备阶段)、数据同步阶段、命令传播阶段

建立连接阶段

Redis(三):redis集群——主从复制、哨兵、集群_第2张图片

  1. 设置master的地址和端口,保存master信息
  2. 建立socket连接
  3. 发送ping指令(定时器任务,周期性检测连接正常)
  4. 身份验证
  5. 发送slave端口信息

状态

  • slave保存了master的地址和端口
  • master保存了slave的端口
  • slave与master之间创建了连接的socket

数据同步阶段

Redis(三):redis集群——主从复制、哨兵、集群_第3张图片

  1. slave请求同步数据
  2. master创建rdb同步数据
  3. slave恢复rdb同步数据
  4. slave请求部分同步数据
  5. master响应部分数据命令信息
  6. slave恢复部分数据

状态

  • slave具有master端全部数据,包含RDB过程接收的数据
  • master保存slave当前数据同步的位置
  • 主从之间完成了数据克隆

复制缓冲区

  • 复制缓冲区又名复制积压缓冲区,是一个先进先出的队列,用于存储服务器执行过的命令,每次传播命令,master都会将传播的命令记下来,并存储在复制缓冲区
  • 复制缓冲区默认数据存储空间大小时1M,由于存储空间大小是固定的,当入队元素的数量大于队列长度时,最先入队的元素会被弹出,而新元素会被放入队列
  • 每台服务器启动时,如果开启有AOF或被链接称为master时,即创建复制缓冲区
  • 用于保存master收到的所有指令(仅影响数据变更命令,例如set、select)

复制偏移量

  • 一个数字,描述复制缓冲去中的指令字节位置
  • master复制偏移量:记录发送给所有slave的指令字节对应的位置(多个),发送一次记录一次
  • slave复制偏移量:记录slave接收master发送过来的指令字节对应的位置(一个),接受一次记录一次
  • 用于同步信息,比对master与slave的差异,当slave断线后,恢复数据使用
  • 第一次建立连接时,直接发送psync2 ? -1,进行全量复制

命令传播阶段

  • 当master数据库状态被修改之后,导致主从服务器数据库状态不一致,此时需要让主从数据同步到一致的状态,同步动作称为命令传播
  • master将接收到的数据变更命令发送给slave,slave接受命令后执行

心跳机制

  • 进入命令传播阶段,master与slave期间需要进行信息交换,使用心跳机制进行保护,实习双方连接保持在线
  • master心跳
    指令:ping
    周期:由repl-ping-slave-period决定,默认10秒
    作用:判断slave是否在线
    查询:INFO replication
  • slave心跳:
    指令:REPLCONF ACK [offset]
    周期:1秒
    作用:汇报slave自己的复制偏移量,获取最新的数据变更指令;判断master是否在线
    Redis(三):redis集群——主从复制、哨兵、集群_第4张图片

主从服务器搭建

主从连接

  1. 创建链接
    方式一:客户端发送指令slaveof
    方式二:启动服务器参数redis-server -slaveof
    方式三:服务器配置slaveof
  2. 断开连接:slaveof no one
  3. 授权访问
    master配置文件设置密码:requirepass
    master客户端发送命令设置密码:config set requirepass config get requirepass
    slave客户端发送命令设置密码:auth
    slave配置文件设置密码:masterauth
    启动客户端设置密码:redis-cli -a

配置

  1. 复制缓冲区大小配置:repl-backlog-size
  2. 关闭slave对外写的服务:slave-serve-stale-data yes|no
  3. 心跳相关配置
    min-slaves-to-write :配置当前存活的slave的最小数量,当小于该值时停止同步
    min-slaves-max-lag time:配置slave延迟的最大值,当所有slave的延迟大于该值时,停止同步

哨兵

概述

哨兵(sentinel)是一个分布式系统,用于对主从结构中每台服务器进行监控,当出现故障时通过投票机制选择新的master并将所有slave连接到新的master
哨兵也是一台redis服务器,但他通常不提供数据服务,通常配置单数个哨兵
作用

  1. 监控:不断的检查master和slave是否正常运行,master存活检测,master与slave运行情况检测
  2. 通知:当被监控的服务器存在问题时,向其他哨兵、客户端发送通知
  3. 自动故障转移:断开master与slave的连接,选取一个slave作为master,将其他slave连接到新的master,并告知客户端新的服务器地址

配置

启动哨兵:redis-sentinel sentinel.conf

工作原理

监控

sentinel会从master和slave通过cmd连接获取信息,并且在sentinel中快速散发;即一个哨兵节点会监控master、slave、其他sentinel的信息

通知

sentinel内部会推出一个sentinel节点将信息发送给master和slave

故障转移

  1. 发现故障
    某一个sentinel发送到master的信息无响应,该sentinel会将消息发布给其他sentinel,其他sentinel会去ping该master,超过半数的 sentinel认为该master挂了,才会采取故障转移的措施
  2. 选出处理故障的sentinel
    sentinel内部会进行投票,每个sentinel都会向其他sentinel发送信息,并将自己的票投给自己收到的第一个信息发送方sentinel,最后得票最高的sentinel来处理故障
  3. 从slave中挑选新的master
    挑选原则:依次淘汰不在线的、响应慢的、与原master断开时间久的;再通过优先级高的、偏移量小的、runid小的选出slave
  4. 向新的master发送slaveof no one,并向其他slave发送信息让他们连接这个新的master

集群

概述

集群就是使用网络将若干台计算机连通起来,并提供统一的管理方式,使其对外呈现单机的服务效果

作用

  • 分散单台服务器的访问压力,实现负载均衡
  • 分散单台服务器的存储压力,实现可扩展性
  • 降低单台服务器宕机带来的业务灾难

数据存储设计

  • 通过算法设计,计算出key应该保存的位置
  • 将所有的存储空间计划切割成16384份,每台主机保存一部分,每一份代表一个存储空间
  • 将key按照计算出的结果放到对应的存储空间
    Redis(三):redis集群——主从复制、哨兵、集群_第5张图片

搭建集群

  1. 配置
    1.cluster-enabled yes:声明该服务器为集群中的节点
    2.cluster-config-file 文件名:节点的配置文件,由集群自动维护
    3.cluster-node-timeout time:指定节点超时时间,用于判定该节点是否下线或切换为从节点
    4.cluster-migration-barrier :master连接的slave最小数量
  2. 集群配置指令:redis-cli create masterip slaveip number --cluster,number表示一个master对应几个slave
  3. 客户端启动指令:redis-cli -c -p port,使用-c可以自动重定向,如果不用-c则只有对应端口的客户端才能获取对应服务器的数据

主从下线与切换

如果从机下线,主机标记其不可用;如果主机下线,哨兵选出一台从机来替代主机,当主机重新连接时原主机变成从机

企业级方案

缓存预热

系统上线后,提前将相关的缓存数据直接加到缓存系统,避免在用户请求的时候,由于缓存中没有任何数据,而并发全部访问数据库

缓存雪崩

问题出现

  1. 在一个较短的时间内,缓存中较多的key过期
  2. 短时间内很多请求访问过期的key而未命中,从而找到数据库
  3. 数据库面临大量请求,无法及时处理,数据库崩溃
  4. redis得不到数据库的响应,无法释放连接,redis崩溃
  5. 应用服务器无法即使得到redis的响应,同时请求不断,应用服务器崩溃
  6. 同时重启应用服务、redis服务、数据库服务,重启之后,面对海量请求,redis缓存是空的,继续崩溃

解决方案

  1. 对key的过期时间进行分类错峰:均匀分布key的过期时间,避免大量key在较短时间内集中过期
  2. 超热key永不过期
  3. 使用mq消峰,让呼啸而至的请求排队(用户体验不好)
  4. 构建多级缓存架构,nginx+redis+ehcache
  5. 避免mysql慢查询
  6. 灾难预警机制:监控redis服务性能指标(CPU占用、CPU使用率、内存容量、查询平均响应时间、线程数)
  7. 限流、降级:短时间内牺牲一些客户体验,限制一部分请求访问,降低应用服务器压力,待服务器回复时间再逐步恢复正常功能

缓存击穿

问题

  1. Redis某个key过期,同时该key的访问量巨大
  2. 多个数据请求从服务器直接压到redis后,均无法命中
  3. 短时间内数据库面临大量请求

解决方案

  1. 预先设定过期时间,如特殊节日前对特定热点信息设定时间
  2. 现场调整,监控访问量,对自然流量激增的数据延长时间
  3. 后台刷新数据,启动定时任务,高峰期来临之前,刷新数据有效期,确保不丢失
  4. 二级缓存,设置不同的失效时间,保障不会被同时淘汰
  5. 加分布式锁,防止被击穿,但是也是性能瓶颈,慎用

缓存穿透

问题

  1. 出现请求大面积不命中
  2. 非正常url访问,redis无法识别从数据库找,数据库仍然找不到就不会在redis进行缓存

解决方案

  1. 缓存null,对查询为null的数据进行缓存(如果要长期使用要定期清理)
  2. 白名单策略,提前预热数据对应的bitmaps,正常数据放行,异常拦截,效率低或使用布隆过滤器(不是100%拦截)
  3. 实施布控,实时监控redis命中率,根据命中率波动来进行防控
  4. 加密key,问题出现启动防灾业务key,使用加密的方式对不满足加密规则的key驳回

性能指标监控

  1. 性能指标:Performance
    latency:redis响应一个请求的时间
    instancetaneous_ops_per_sec:平均每秒处理的请求总数
    hit rate (calculated):缓存命中率
  2. 内存指标:Memory
    used_memory:已使用内存
    mem_fragmentation_radio:内存碎片率
    evicted_keys:由于最大内存限制被移除的key的数量
    blocked_clients:由于BLPOP、BRPOP、BRPOPLPUSH而被阻塞的客户端
  3. 基本活动指标:Basic activity
    connected_clients:客户端连接数
    connected_slaves:slave数量
    master_last_io_seconds_ago:最近一次主从交互之后的秒数
    keyspace:数据库中key值总数
  4. 持久性指标:Persistence
    rdb_last_save_time:最后一次持久化保存到磁盘的时间戳
    rdb_changes_since_last_save:自最后一次持久化以来数据库的更改数
  5. 错误指标:Error
    rejected_connections:由于达到maxclient限制而被拒绝的连接数
    keyspace_misses:key值查找失败次数
    master_link_down_since_seconds:主从断开持续时间

监控命令

  1. redis-benchmark
    Redis(三):redis集群——主从复制、哨兵、集群_第6张图片
  2. monitor
  3. slowlog:慢查询日志
    get:获取
    len:获取日志条目数
    reset:重置慢查询日志
    相关配置:slowlog-log-slower-than设置慢查询时间下线,单位微秒;slow-max-len设置慢查询命令对应日志显示长度

你可能感兴趣的:(笔记,redis)