12.redis 之阅读大佬文章随笔

1.熟悉redis备份持久化机制(RDB和AOF机制)
RDB:
-- RDB:将当前进程数据生成快照保存起来
-- 自动触发和手动触发
-- save和bgsave(手动触发): save会阻塞当前redis服务器,知道rdb过程完成为止。对于内存比较大的实例会造成长时间阻塞
线上环境不建议使用。且save命令已经废弃。
bgsave:redis会fork一个子进程,rdb的过程会有子进程负责,阻塞一般只会发生在fork阶段。时间较短

-- 自动触发:
1.可以在配置文件配置,例如 save m n :表示在m秒内数据集发生n次变化,会自动触发bgsave
2.如果从节点执行全量复制,主节点会自动执行bgsave生成RDB文件并且发送给从节点,
3.执行debug reload 命令时重新加载redis时,也会自动触发save操作
4.默认情况下,执行shutdown时,如果没有开启AOF持久化功能则会自动执行bgsave

--RDB文件处理:
config set dir xxxxx:rdb文件保存目录
config set dbfilename xxxx :rdb文件名称
-->注意以上的配置只能是在临时配置,如果想要永久的使用该配置,应该将上面的配置写到redis.conf文件中。

--RDB的优点
1.它是一个紧凑的二进制文件,代表Redis在某个时间点上的数据快照,非常适合备份 、全量复制等场景,比如每6个小时执行bgsave备份,并且把rdb文件拷贝到远程机器或者文件系统(如hdfs),用于灾难恢复。
2.Redis加载RDB恢复数据远远快于AOF方式

--RDB缺点:
不能实时、因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作、频繁执行成本过高。
老版本的redis服务器无法兼容新版本的RDB格式

AOF
--主要作用是解决数据持久化的实时性,目前已经是Redis持久化的主流方式。
--功能开启:appendonly yes 默认是不开启
--执行过程
1.所有命令都写入到aof_buf缓冲中
2.aof缓冲以对应的刷盘策略向磁盘写入
3.随着aof文件越大,需要对其进行重写,到达压缩目的
4.redis重启,加载AOF文件
--刷盘策略
有appendfsync控制
1 always:命令写入aof_buf后调用系统fsync操作同步到AOF文件,fsync完成后线程返回
2.everysec: 命令写入aof_buf后调用系统write操作,write完成后线程返回,fsync同步文件操作有专门线程每秒调用一次
3.no:命令写入aof_buf后调用系统write操作,不对AOF文件做fsync同步,同步硬盘操作有操作系统完成,通常同步周期为30s
--->
第一种是最安全的一种方法,但是会损失部分redis性能
第二种选项是默认的配置。能够兼顾性能和数据安全。
第三种该选项下redis的性能可以保证,但是数据安全性不足

2.熟悉redis的主从复制技术
--从库上执行
slaveof host port -->host:代表主库ip地址 port:代表主库的端口号

--断开复制
slaveof no one -->从库从主库上断开复制连接


--数据一致性
除此之外,我们可以设置slave-read-only=yes来配置从节点为只读模式,防止从节点人为写入数据,导致主从数据不一致。


--复制原理--
1.保存主节点的master值
2.主从建立socket连接
从节点内部会通过每秒运行的定时任务维护复制的相关逻辑,当定时任务发现存在新的主节点之后,会尝试与该节点建立网络连接
从节点会建立一个socket套接字,专门用于接收主节点发送的复制命令。如果此时从节点无法建立连接,定时任务会进行无数次的重试知道连接成功或者执行slaveof no one取消复制。
3.发送ping命令
4.权限验证
5.同步数据集
6.命令持续复制

3.Redis的阻塞,一般来讲,是由以下原因构成的:
不合理的使用API或者数据结构、CPU饱和、持久化阻塞等内在原因;
CPU竞争、内存交换、网络问题等外在原因
下面我们分别分析这些原因

4.Redis内存优化
从内存消耗、管理内存的原理与方法、内存优化技巧三个方面讲述如何高效高效实现内存的存储

缩减键值对象:降低redis内存最直接的方式就是缩减key和value的长度

共享对象池:redis在内存中维护了一个[0-9999]的整数对象池,用于节约内存,除了整数值对象,其它类型,如list/hash/set/zset中元素也可以使用整数对象池、

5.redis sentinel(哨兵)
我们知道Redis主从模式下,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点的地址。然后在很多场景下这种故障处理的方式是无法接受的,应用程序需要实时感知当前的可用节点。为了解决这个问题,Redis sentinel就来了,也被称为’哨兵‘。

主从复制问题:
1.一旦主节点发生故障,从节点晋升为主节点的过程和应用调整新主节点的过程,都需要认为干预
2.主节点的存储能力容易受到单机的限制
一种常见的方法就是使用脚本来触发主从节点的角色切换,例如在一个一主两从的结构中,假设主节点master,从节点slave1.slave2,我们来看看故障发生时架构的状态
2.1 主节点master故障,客户端连接失败,两个从节点复制失败
2.2 选择一个主节点slave1,对其执行slaveof no one命令使其成为主节点master2
2.3 更新应用程序连接的节点为slave1的ip地址
2.4 slave2以slave1为新的主节点,复制slave1上的命令
2.5 待原来的master恢复之后,让它成为slave1的从节点
上述过程可以做成自动化的过程,但是需要考虑三点:a、要确保判断节点不可达的机制健全、否则容易出现误判情况,b.如果有多个从节点,如果保证只有一个从节点被晋升为主节点是个关键的问题,c.通知客户端新的主节点的机制是否足够健壮。

Redis Sentinel的高可用机制
Sentinel 能够自动完成故障发现和故障转移,并及时通知应用方,这个是它的核心价值所在。
Redis Sentinel是一个分布式架构,其中包含若干个Sentinel和若干个Redis数据节点, 每个Sentinel节点会对数据节点和其余sentinel节点进行监控,当它发现节点不可达时,会对节点做下线表示。如果被标识的是主节点,它还会和其他的sentinel进行协商,当大多数sentinel节点都认为主节点不可达时,它们会选举出来一个sentinel节点来实现故障自动转移,同时会将这个变化通知给Redis应用方,整个过程是自动的,不需要人工介入。Redis Sentinel与Redis主从复制模式只是多了若干个sentinel节点,并没有对redis节点做特殊处理,


sentinel monitor


6.redis sentinel 实现原理
sentinel的实现原理主要分为三个定时任务、主观下线和可观下线、sentinel领导者选举以及故障转移4个部分

1.三个定时任务
redis sentinel通过三个定时监控任务完成对各个节点的发现和监控
任务一:每隔10s,每个sentinel节点向主节点和从节点发送info命令,获取最新的拓扑结构
sentinel通过对info节点的结果解析,就能找到响应的从节点,这个info的定时任务,它的具体作用有如下有个三个方面:
a.通过向主节点执行info命令,获取从节点的信息
b.当有新的从节点加入时,都可以立即感应出来
c.节点不可达或者故障转移之后,可以通过info命令实时更新节点的拓扑信息

任务二:每隔2s.每个sentinel节点会向redis数据节点的_sentinel_:hello频道上发送该sentinel节点对于主节点的判断以及当前sentinel节点的信息。同时每个sentinel节点也会订阅频道,来了解其他sentinel节点以及他们对主节点的判断,所以这个定时任务可以在sentinel节点之间交换主节点的状态,作为后面可观下线以及领导者选举的依据。

任务三:每隔1s,每个sentinel节点会向主节点,从节点,其余sentinel节点发送一条ping 命令做一次心跳检测,来确认这些节点当前是否可达,实现对每个节点的监控,这个定时任务是节点失败的重要依据

2.主观下线和客观下线
主观下线:监控过程中的第3个定时任务ping,如果在down-after-milliseconds没有收到有效的回复,sentinel节点就会对该节点做失败判断,这个行为叫做主观下线,主观下线是sentinel做出的判断,存在误判的可能

客观下线:当sentinel主观下线的节点是主节点时,该sentinel节点会通过sentinel is-master-down-by-addr命令向其他sentinel节点询问对主节点的判断,当超过<quorum>个数的sentinel节点认为主节点确实有问题,这时sentinel节点会做出客观下线的决定,也就是说,当大部分sentinel节点都对主节点的下线做了同意的判定,那么这个判定就是客观的。

这里的is-master-down-by-addr命令: sentinel is-master-down-by-addr ip port current_epoch runid
其中:
ip指的是主节点ip,port指的是主节点端口
current_epoch只当前配置纪元

7.Redis事务
1 Redis事务就是一次性,顺序性、排他性的执行一个队列中的一系列命令,分为三个过程:开始事务、命令入队、执行事务
2.Redis提供了简单的事务,使用multi、exec 、discard这三个命令来控制
3.exec命令之前,所有原子操作都被放到了队列中缓存,并不会真正执行
4.Redis事务不存在隔离级别的概念
5.事务中的单条命令是原子执行的,但是事务本身不保证原子性,没有回滚机制


8.redis大key问题
在redis中,大key指的是key对应的value值所占的内存空间比较大,例如一个字符串类型的value最大可以存储512M的内容,一个列表类型的value最多可以存储2的32次方-1个元素,
一般情况下,我们认为字符串类型的key的value的值超过10kb,就算大key


大key的危害
1.内存空间不均匀
2.操作耗时,存在阻塞风险
3.网络阻塞,每次获取大key产生的网络流量较大
4.如果一个key的大小为1MB,每秒访问量为1000,那么每秒产生1000MB的流量。这对于普通千兆网卡的服务器来说是灾难性的。

如果发现大key
1.redis-cli --bigkeys命令可以统计bigkey的分布情况
2.使用debug object key 命令,从命令结果中serializedlength的值来判断当前key的字节数
3.使用strlen命令来判断当前key的长度


9.redis-cluster
Redis-Cluster是redis的分布式解决方案,有效解决了Redis分布式方面的需求。当遇到单机内存、并发、流量等瓶颈时,可以采用cluster架构方案达到负载均衡的目的。

之前,Redis分布式方案一般有两种:
1.客户端分区方案,优点是分区逻辑可控,缺点是需要自己处理数据路由、高可用、故障转移等问题
2.代理方案,优点是简化客户端分布式逻辑和升级维护便利,缺点是加重架构部署复杂度和性能损耗。

官方提供了专有的集群方案:Redis Cluster

原文地址:https://www.cnblogs.com/zmc60/p/15057875.html