Redis持久化

1、reids持久化

一、持久化的取舍和选择
(1)持久化的做用

redis全部数据保持在内存中,对数据的更新将异步地保存到磁盘上。node

(2)持久化方式 RDB快照

RDB文件(二进制)
Redis建立RDB文件,启动时自带载入RDB文件
触发机制-主要三种方式
save(同步) 建立RDB 阻塞 文件策略:如存在老的RDB文件,新替换老 复杂度:O(n)
bgsave(异步) 一、basave 二、fork子进程 三、create RDB 四、bgsave successfully(异步响应客户端在fork以后)
自动 配置 secondes 900 changes 1 seconds 300 changes 10 seconds 60 changes 10000 知足任一条件
最佳配置
dbfilename dump-{$port}.rdb
dir /bigdiskpath
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yesios

  • RDB是Redis内存到硬盘的快照,用于持久化
  • save一般会阻塞Redis
  • bgsave不会阻塞Redis,可是会fork新进程
  • save自动配置知足任一就会被执行
(3)持久化方式 AOF 写日志

RDB的现存问题:耗时耗性能
三种策略:
always 写命令刷新的缓冲区 每条命令 fsync到硬盘 优势 不丢数据 缺点 IO开销大
everysec 写命令刷新缓冲区,每秒把缓冲区 fsync到硬盘 优势 IO开销可控 缺点 丢失一秒数据
no 写命令到缓冲区 OS决定fsync到硬盘 优势 不用管 缺点 不可空
推荐 everysec
AOF重写:redis

  • 减小硬盘占用量
  • 加速恢复速度

AOF 重写实现的两种方式 bgrewriteof AOF重写配置
重写配置 auto-aof-rewrite-min-size AOF文件重写须要的尺寸 auto-aof-rewrite-percentage AOF文件增加率
aof_current_size AOF当前尺寸 aof_base_size AOF上次启动和重写的尺寸
同时知足 自动出发机制
aof_current_size > auto-aof-rewrite-min-size
aof_current_size - aof_base_size/aof_base_size > auto-aof-rewrite-percentage
推荐配置缓存

appendonly yes
appendfilename "appendonly-${port}.aof"
appendfsync everysec
dir /bigdiskpath
no-appendfsync-on-rewrite yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
(4)RDB和AOF的抉择

RDB 启动优先级安全

命令 RDB AOF
启动优先级
体积
恢复速度
数据安全性 丢数据 根据策略决定
轻重
  • RDB最佳策略

关 集中管理 主关从开
AOF最佳策略
开:缓存和存储 AOF重写集中管理 everysec
最佳策略
小分片 缓存或者存储 监控(硬盘、内存、负载、网络) 足够的内存ruby

二、fork子进程的开销和优化
(1)fork操做

fork特性网络

  • 同步操做
  • 与内存量息息相关:内存越大,耗时越长
  • info: latestt_fork_usec

改善fork数据结构

  • 有限使用物理机或者搞笑支持fork操做的虚拟化计数
  • 控制redis实例最大可用内存:maxmemory
  • 合理配置Linux内存分配策略:vm.overcommit_memory=1
  • 下降fork频率
(2)子进程开销和优化

CPU
开销:RDB和AOF文件生成,属于CPU密集型
优化:不作CPU绑定,不和CPU密集型部署
内存
开销:fork内存开销,copy-on-write
优化:echo never > /sys/kernel/mm/transparent_hugepage/enable
硬盘
开销:AOF和RDB文件写入,能够结合iostat,iotop分析
优化:不要和高硬盘负载服务部署一块儿:存储服务,队列服务等 no-appendfsync-on-rewrite=yes
根据写入量决定磁盘类型 单机多实例持久化目录能够考虑分盘架构

(3)AOF追加阻塞

阻塞定位:Redis日志 info Persistence并发

2、Redis的主从复制原理
一、redis的复制

单机的问题:机器故障 容量瓶颈 QPS瓶颈
主从复制的做用:数据副本 扩展读性能

  • 一个master能够有多个slave
  • 一个slave只能有一个master
  • 数据流向是单向的,master到slave

实现方式:slaveof命令 配置

命令实现:slaveof 127.0.0.1 6379 复制 slaveof no one 取消复制
修改配置:

slaveof ip port 
slave-read-only yes

比较

方式 命令 配置
优势 不须要重启 统一配置
缺点 不便于管理 须要重启

info replaction 查看主从复制的信息

二、redis的全量复制和部分复制

run_id:redis每次启动的时候都会有一个随机的id来保障redis的标识,重启后消失
复制偏移量:master_repl_offset 记录写入了多少字节
全量复制:psync -> fullresync -> save masterInfo -> bgsave -> send RDB -> send buffer -> flush old data -> load RDB
全量复制的开销:bgsave的时间 RDB文件网络传输时间 从节点清空数据时间 从节点加载RDB时间 可能AOF重写时间
部分复制:connection lost -> master -> connection to master -> psync -> continue

三、redis的故障处理

主从结构故障转移:slave宕掉 客户端从新链接另外一个slave master宕掉 使用sentinel自动故障转移
开发运维中的问题:

  • 读写分离:流量分摊到从节点

    可能遇到的问题: 复制数据延迟 读到过时数据 从节点故障

  • 主从配置不一致:

    例如maxmemory不一致,丢失数据;例如数据结构优化参数,内存不一致

  • 规避全量复制

第一次全量复制,不可避免 小主节点,低峰
节点运行ID不匹配 主节点重启 故障转移,例如哨兵或集群
复制积压缓冲区不足 网络中断,部分复制没法知足 增大复制缓冲区配置rel_backlog_size,网络增长

  • 规避复制风暴

单节点复制风暴 主节点重启,多从节点复制 更换复制拓补
单机器复制风暴 机器宕机后,大量全量复制 主节点分散多机器

2、Redis的高可用sentinel
一、redis sentinel的架构

主从复制的问题:手动故障转移 写能力和存储能力受限

  • 客户端从sentinel获取redis信息
  • redis sentinel故障转移
  • 多个sentinel发现并确认master有问题
  • 选举出一个sentinel做为领导
  • 选出一个slave做为master
  • 通知其他slave做为新的master的slave
  • 通知客户端主从变化
  • 等待心动额master复活成为新的master的slave
二、redis sentinel的安装和配置
  • 配置并开启主从节点
  • 配置并开启sentinel监控主节点。(sentinel是特殊的redis)
  • 多机器
  • 详细配置节点

主节点

port 7000
daemonize yes
pidfile /var/run/redis-7000.pid
logfile "7000.log"
dir "/opt/soft/redis/data/"

从节点

port 7001
daemonize yes
pidfile /var/run/redis-7000.pid
logfile "7000.log"
dir "/opt/soft/redis/data/"
slaveof 127.0.0.1 7000

sentinel主要配置

port ${port}
daemonize yes
dir "/opt/soft/redis/data/"
logfile "${port}.log"
sentinel monitor mymaster 127.0.0.1 7000 2
sentinel down-after-milliseconds mymaster 300000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

客户端接入流程
Sentinel地址集合 =》 mastername =》 不是代理模式

三、redis 高可用实现

客户端高可用观察
服务端日志分析:数据节点和Sentinel节点
三个定时任务

(1)、每10秒每一个sentinel对master和slave执行info

  • 发现每一个slave节点
  • 确认主从关系

(2)、每2秒每一个sentinel经过master节点的channel交换信息(pub/sub)

  • 经过__sentinel__:hello频道交互
  • 交互节点的见解和自身信息

(3)、每1秒每一个sentinel对其余sentinel和redis执行ping

  • 心跳检测,失败断定依据
a、主观下线和客观下线

主观下线:每一个sentinel节点对Redis节点失败的偏见
客观下线:全部sentinel节点对Redis节点失败达成共识

b、领导者选举

缘由:只要一个sentinel节点完成故障转移
选举:经过sentinel is-master-down-by-addr命令都但愿成为领导者

  • 每一个主观下线的sentinel节点向其余sentinel节点发送命令,要求将它设置成为领导者
  • 收到命令的sentinel节点若是没有赞成经过其余Sentinel节点发送的命令,那么就将赞成该请求,不然拒绝
  • 若是该sentinel节点发现本身的票数已经超过sentinel集合半数,而且超过quorum,那么它将成为领导者
  • 若是过程当中有多个sentinel节点成为了领导者,那么将等待一段时间从新进行选举
c、故障转移
  • 从slave节点中选出一个合适的节点做为新的master节点
  • 从上面的slave节点执行slaveof no one 命令让其成为master节点
  • 向剩余的slave节点发送命令,让他们成为新的master节点的slave节点,复制规则和parallel-syncs参数有关
  • 更新对原来的master节点配置为slave,并保持着对其关注,当其恢复后命令让他取复制新的master节点
选择合适的slave节点
选择slave-pripority最高的slave节点,若是存在则返回,不存在则继续
选择复制偏移量将达的slave节点,若是存在则返回,不存在则继续
选择runId最小的节点
四、redis 高可用实战
(1)、节点运维

机器下线:例如过保等状况
机器性能不足:例如CPU、内存、硬盘、网络等
节点自身故障:例如服务不稳定
从节点:临时下线仍是永久下线,例如是否作一些清理工做,可是要考虑读写分离的状况
主节点:sentinel failover进行替换

(2)、高可用读写分离

从节点的做用
副本:高可用的基础
扩展:读能力

Redis Sentinel是Redis的高可用实现方案

  • 故障发现、故障自动转移、配置中心、客户端通知
  • Redis Sentinel从Redis2.8才开始正式生成可用
  • 尽量在不一样物理机上部署Redis Sentinel的节点
  • RedisSentinel中的Sentinel节点个数应该大于等于3,且最好为奇数
  • Redis Sentinel中的数据节点与普通数据节点没有区别
  • 客户端初始化时链接的时Sentinel节点集合,再也不是具体的Redis节点,但Sentinel只是配置中心不是代理
  • Redis Sentinel经过三个定时任务实现了Sentinel节点对于主节点、从节点、其他Sentinel节点的监控
  • Redis Sentinel在对节点作失败断定时分为主观下线和客观下线
  • 看懂Redis Sentinel故障转移日志对于Redis Sentinel以及问题排查很是有帮助
  • Redis Sentinel实现读写分离高可用能够依赖Sentinel节点的消息通知,获取Redis数据节点的状态变化
3、Redis的高可用 Cluster
一、呼唤集群

并发量超过10万QPS,数据量超过单机内存
解决方法:分布式(简单的认为加机器)
顺序分区:1-100 =》 1-33,34-66,67-100
哈希分区:1-100 =》 hash(key)%3 0,1,2
哈希分布分为 节点取余分区,一致性哈希分区,虚拟槽分区

(1)节点取余分区,添加一个节点 迁移率80%,多倍扩容迁移率50%
客户端分片:哈希+取余
节点伸缩:数据节点关系变化,致使数据迁移
迁移数量和添加节点数量有关:建议翻倍扩容
(2)一致性哈希
客户端分片:哈希+顺时针(优化取余)
节点伸缩:只影响临近节点,可是仍是有数据迁移
翻倍伸缩:保证最小数据迁移和负载均衡
(3)虚拟槽分区

预设虚拟槽:每一个槽映射一个数据子集,通常比节点数大
良好的哈希函数:CRC16
服务端管理节点:槽,数据

二、基本架构

Redis Cluster架构: 节点 meet 指派槽 复制 高可用 分片

(1)安装配置

配置开启节点 =》 meet =》 指派槽 =》 主从

port ${port}
daemonize yes
dir "/opt/redis/redis/data"
dbfilename "dump-${port}.rdb"
logfile "${port}.file"
cluster-enabled yes
cluster-config-file nodes-${port}.conf
cluster-require-full-coverage no

cluster meet ip port

Cluster节点主要配置

cluster-enabled yes
cluster-node-timeout 15000
cluster-config-file "nodes.conf"
cluster-require-full-coverage yes

分配槽: cluster addslots slot
设置主从:cluster replicate node-id

(2)redis-trib安装

下载编译安装Ruby => 安装rubygem redis => 安装redis-trib.rb配置开启Redis一键开启:./redis-trib.rb create --replicas 1 127.0.0.1:8000 127.0.0.1:8001...

相关文章
相关标签/搜索