redis高级特性 (性能分析,持久化,主从,哨兵)

慢查询

Redis查询指令过程一般如下:
在这里插入图片描述
在Redis中当执行时间超过阀值,会将发生时间 耗时 命令记录,此时的慢查询指的是第三阶段执行命令时期。关于慢查询的配置记录可参考慢查询设置,
PS:项目部署前对服务器对redis性能测试很有必要,好好利用redis-benchmark

Pipeline

该指令出现的背景:redis客户端执行一条命令分4个过程:
发送命令-〉命令排队-〉命令执行-〉返回结果
这个过程称为Round trip time(简称RTT, 往返时间),mget mset有效节约了RTT,但大部分命令(如hgetall,并没有mhgetall)不支持批量操作,需要消耗N次RTT ,这个时候需要pipeline来解决这个问题
未使用pipeline执行N条指令
在这里插入图片描述
使用了pipeline执行N条命令 jedis.pipeline,此处可以懂了RESP手动实现执行流程就很简单了,
在这里插入图片描述
性能测试结果:
在这里插入图片描述
结论:使用Pipeline执行速度与逐条执行要快,特别是客户端与服务端的
网络延迟越大,性能体能越明显。但是使用pipeline组装的命令个数不能太多,不然数据量过大,增加客户端的等待时间,还可能造成网络阻塞,可以将大量命令的拆分多个小的pipeline命令完成。

mysql数据倒入到Redis

mysql -u用户 -p密码 stress --default-character-set=utf8 
--skip-column-names --raw < order.sql |redis-cli -h IP
-p 端口 -a 密码 --pipe

order.sql

SELECT CONCAT(
 '10\r\n',
 '$',LENGTH(redis_cmd),'\r\n',redis_cmd,'\r\n',
 '$',LENGTH(redis_key),'\r\n',redis_key,'\r\n',
 '$',LENGTH(hkey1),'\r\n',hkey1,'\r\n',
 '$',LENGTH(hval1),'\r\n',hval1,'\r\n',
 '$',LENGTH(hkey2),'\r\n',hkey2,'\r\n',
 '$',LENGTH(hval2),'\r\n',hval2,'\r'
)
FROM(
 SELCET 
 'HSET as redis_cmd,
 CONCAT('order:info',orderid) as redis_key,
 'ordertime' as hkey1,ordertime as hval1,
 'ordermoney' as hkey2,ordermoney as hval2
 from ``order
) as t

弱事务性

在Redis中要记住 Redis中原生批命令是原子性,pipeline是非原子性,
原生批命令是服务端实现,而pipeline需要服务端与客户端共同完成。
Redis简单事务:将一组需要一起执行的命令放到multiexec两个命令之间,其中multi代表事务开始,exec代表事务结束。使用watch后, multi失效,事务失效。
弱事务性测试:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
结论:Redis自带的事务性贼鸡肋,用好Redis必须用好Lua。

发布跟订阅

redis提供了“发布、订阅”模式的消息机制,其中消息订阅者与发布者不直
接通信,发布者向指定的频道(channel)发布消息,订阅该频道的每个客
户端都可以接收到消息。不过比专业的MQ(RabbitMQ RocketMQ ActiveMQ Kafka)相比不值一提,这个功能就别用了。。。
SUBSCRIBE subscribe,

Redis持久化原理剖析

redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到磁盘来保证持久化,持久化可以避免因进程退出而造成数据丢失。

RBD持久化

RDB:把当前进程数据生成快照(.rdb)文件保存到硬盘的过程。
手动触发有save和bgsave两命令

  1. save命令:阻塞当前Redis,直到RDB持久化过程完成为止,若内存实例比较大会造成长时间阻塞,线上环境不建议用它
  2. bgsave命令:redis进程执行fork操作创建子线程,由子线程完成持久化,阻塞时间很短(微秒级),是save的优化,在执行redis-cli shutdown关闭redis服务时,如果没有开启AOF持久化,自动执行bgsave;
    在这里插入图片描述
    自动触发就是在redis配置文件中
save 900 1
save 300 10
save 60 10000

那么只要满足以下三个条件中的任意一个,BGSAVE 命令就会被执行:

  1. 服务器在 900 秒之内,对数据库进行了至少 1 次修改
  2. 服务器在 300 秒之内,对数据库进行了至少 10 次修改
  3. 服务器在 60 秒之内,对数据库进行了至少 10000 次修改

优点:

  1. 压缩后的二进制文,适用于备份、全量复制,用于灾难恢复
  2. 加载RDB恢复数据远快于AOF方式

缺点:

  1. 无法做到实时持久化,每次都要创建子进程,频繁操作成本过高
  2. 保存后的二进制文件,存在老版本不兼容新版本rdb文件的问题

AOF持久化

redis 针对RDB不适合实时持久化,redis提供了AOF持久化方式来解决,底层原理就是将所有涉及到增删到RESP指令全部写到appendonly.aof文件中,恢复到时候将全部指令执行一遍。

开启:redis.conf设置:appendonly yes (默认不开启,为no)
默认文件名:appendfilename “appendonly.aof”

AOF流程:

  1. 所有的写入命令(set hset)会append追加到aof_buf缓冲区中
  2. AOF缓冲区向硬盘做sync同步
  3. 随着AOF文件越来越大,需定期对AOF文件rewrite重写,达到压
  4. 当redis服务重启,可load加载AOF文件进行恢复

在这里插入图片描述
重要指令详解

  • appendonly yes //启用aof持久化方式
  • appendfsync always //每收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
  • appendfsync everysec //每秒强制写入磁盘一次,性能和持久化方面做了折中,推荐
  • appendfsync no //完全依赖os,性能最好,持久化没保证(操作系统自身的同步)
  • no-appendfsync-on-rewrite yes //正在导出rdb快照的过程中,要不要停止同步aof
  • auto-aof-rewrite-percentage 100 //aof文件大小比起上次重写时的大小,增长率100%时,重写
  • auto-aof-rewrite-min-size 64mb //aof文件,至少超过64M时,重写

优点:

AOF持久化方式相比于RDB来说,可读性高(保存的是代码,可读性好),适合保存增量数据,数据不易丢失。
ps:为什么数据不容易丢失?因为数据被保存在内存中的AOF缓冲区中,数据不易丢失。

缺点:

保存基本上所有redis除读之外的代码,保存的文件大,恢复数据需要重写执行所有的代码,恢复的时间长

RDB和AOF恢复顺序

redis重启恢复数据时流程如下:

  1. 当AOF和RDB文件同时存在时,优先加载AOF
  2. 若关闭了AOF,加载RDB文件
  3. 加载AOF/RDB成功,redis重启成功
  4. AOF/RDB存在错误,启动失败打印错误信息
    在这里插入图片描述

主从复制

和Mysql主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或者级联结构,Redis主从复制可以根据是否是全量分为全量同步和增量同步,一般主节点负责数据,从节点负责数据。
整体图如下:
在这里插入图片描述
注意传输延迟性,主从一般部署在不同机器上,复制时存在网络延时问题,redis提供repl-disable-tcp-nodelay参数决定是否关闭TCP_NODELAY,默认为关闭

  1. 参数关闭时:无论大小都会及时发布到从节点,占带宽,适用于主从网络好的场景,
  2. 参数启用时:主节点合并所有数据成TCP包节省带宽,默认为40毫秒发一次,取决于内核,主从的同步延迟40毫秒,适用于网络环境复杂或带宽紧张,如跨机房

一主一从:

用于主节点故障转移从节点,当主节点的且需要持久化写命令并发高,可以只在从节点开启AOF(主节点不需要)
在这里插入图片描述

一主多从:

针对读较多的场景,“读”由多个从节点来分担,但节点越多,主节点同步到多节点的次数也越多,影响带宽,也加重主节点的稳定。
在这里插入图片描述

树状主从:

一主多从的缺点(主节点推送次数多压力大)可用些方案解决,主节点只推送一次数据到从节点B,再由从节点B推送到D和E,减轻主节点推送的压力
在这里插入图片描述

复制原理

先启动master然后启动若干slave,可以用info replication 查看主从及同步信息。
redis 2.8版本以上使用psync命令完成同步,过程分“全量”与“部分”复制
全量复制
一般用于初次复制场景(第一次建立SLAVE后全量)
部分复制
网络出现问题,从节点再次连主时,主节点补发缺少的数据,每次数据增加同步
心跳
主从有长连接心跳,主节点默认每10S向从节点发ping命令,repl-ping-slave-period控制发送频率
后台同步原理:

  1. 保存主节点信息
  2. 主从建立socket连接
  3. 发送ping命令
  4. 权限验证
  5. 同步数据集
  6. 命令持续复制

哨兵机制

前面的主从复用配置文件启动很简单,问题是如何实现高可用,master 停止后可自动切换到slave节点。
在这里插入图片描述

Redis Sentinel

高可用:当主节点出现故障时,由Redis Sentinel自动完成故障发现和转移,并通知应用方,实现高可用性。
在这里插入图片描述
哨兵有三个定时监控任务完成对各节点的发现和监控,主要是循环性到监控master跟slave
在这里插入图片描述
下线的时候分为主观下线和客观下线。
主观下线:单独一个哨兵发现master故障了。
客观下线:多个哨兵进行抉择发现达到quorum数时候开始进行切换。

哨兵选举规则

大部分情况下都是那个哨兵发现master了就会成为领导者负责节点切换工作。
在这里插入图片描述

故障转移流程

故障转移流程A

sentinel会向master发送心跳PING来确认master是否存活,如果master在“一定时间范围”内不回应PONG 或者是回复了一个错误消息,那么这个sentinel会主观地(单方面地)认为这个master已经不可用了。

在这里插入图片描述

故障转移流程B

当主节点出现故障,此时假设3个Sentinel节点共同选举了Sentinel3节点为领导者sentinel,负载处理主节点的故障转移。
在这里插入图片描述

故障转移流程C

由Sentinel3领导者节点执行故障转移,过程和主从复制一样,但是自动执行。
在这里插入图片描述

故障转移后的拓扑结构图D

在这里插入图片描述

故障转移大致流程

在这里插入图片描述

部署建议
  1. sentinel节点应部署在多台物理机(线上环境)
  2. 至少三个且奇数个sentinel节点
  3. 三个sentinel可同时监控一个主节点或多个主节点,当监听N个主节点较多时,如果sentinel出现异常,会对多个主节点有影响,同时还会造成sentinel节点产生过多的网络连接,一般线上建议还是, 3个sentinel监听一个主节点

最后客户端通过JedisSentinelPool 来操作即可啦。。。

参考

rdb持久化
主从笔记
主从,持久化,哨兵
java客户端Jedis操作Redis Sentinel 连接池

发布了371 篇原创文章 · 获赞 1788 · 访问量 153万+

猜你喜欢

转载自blog.csdn.net/qq_31821675/article/details/104583781