- 1.事务机制
- 2.持久化机制
- RDB触发条件(自动触发):
- 记忆
save 3600 1 #表示1小时内至少1个键被更改则进行快照。
save 300 100 #表示5分钟(300秒)内至少100个键被更改则进行快照。
save 60 10000 #表示1分钟内至少10000个键被更改则进行快照。 - 进入客户端
bin/redis-cli - 执行save命令(同步执行)
save - 执行bgsave命令(异步子线程执行)
bgsave - RDB优缺点:
- AOF:是基于日志文件进行持久化的,往日志文件里面存之前输入的命令,后面它会依次执行命令来达到持久化
- 设置AOF文件名称
appendfilename appendonly.aof
当开启了AOF机制之后,Redis何时会向aof文件中记录内容呢?
对于AOF的触发方式有三种:always、everysec、no。 默认使用everysec。可以通过redis.conf中appendfsync属性进行配置。
always:每次执行写入命令都会将aof_buf缓冲区文件全部内容写入到AOF文件中,并将AOF文件同步到磁盘。该方式效率最低,安全性最高。
everysec:每次执行写入命令都会将aof_buf缓冲区文件全部内容写入到AOF文件中。 并且每隔一秒会由子线程将AOF文件同步到磁盘。该方式兼备了效率与安全,即使出现宕机重启,也只会丢失不超过两秒的数据。
no:每次执行写入命令都会将aof_buf缓冲区文件全部内容写入到AOF文件中,但并不对AOF文件进行同步磁盘。 同步操作交由操作系统完成(每30秒一次),该方式最快,但最不安全。 - 高可用-主从复制
- 高可扩-分片集群
- key过期删除策略
- 内存淘汰策略
1.事务机制
事务介绍:
Redis事务是基于队列实现的,创建一个事务队列,然后将事务操作都放入队列中,最后依次执行,不支持回滚。
事务执行的步骤:
1.开启事务: multi
2.添加命令:比如:sadd user:1001:follow 1002 sadd user:1002:follow 1001
3.执行事务:exec
4.取消事务:discard
事务处理机制:
语法错误:执行命令的语法不正确
执行错误:命令在运行过程中出现错误
2.持久化机制
Redis提供了两种持久化机制:RDB、AOF。 根据不同的场景,可以选择只使用其中一种或一起使用。
RDB触发条件(自动触发):
在redis.conf文件中配置了一些默认触发机制
save “” # save后面为空的话 表示不使用RDB存储 不能主从
记忆
save 3600 1 #表示1小时内至少1个键被更改则进行快照。
save 300 100 #表示5分钟(300秒)内至少100个键被更改则进行快照。
save 60 10000 #表示1分钟内至少10000个键被更改则进行快照。
RDB触发条件(手动触发):
进入客户端
bin/redis-cli
执行save命令(同步执行)
save
执行bgsave命令(异步子线程执行)
bgsave
save和bgsave的区别:
1.save:同步处理,阻塞Redis服务进程,服务器不会处理任何命令,直到RDB文件保存完毕。
2.bgsave:会fork一个和主线程一致的子线程负责操作RDB文件,不会阻塞Redis服务进程,操作RDB文件的同时仍然可以处理命令。
Redis默认使用的是 bgsave 来保存快照数据。
RDB优缺点:
优点:
1.基于二进制文件完成数据备份,占用空间少,便于文件传输。
2.能够自定义规则,根据Redis繁忙状态进行数据备份。
缺点:
1.无法保证数据完整性,会丢失最后一次快照后的所有数据。
2.bgsave执行每次执行都会阻塞Redis服务进程创建子线程,频繁执行影响系统吞吐率。
AOF:是基于日志文件进行持久化的,往日志文件里面存之前输入的命令,后面它会依次执行命令来达到持久化
基础使用:
AOF方式需要手动开启,修改redis.conf
# 是否开启AOF,默认为no
appendonly yes
设置AOF文件名称
appendfilename appendonly.aof
当开启了AOF机制之后,Redis何时会向aof文件中记录内容呢?
对于AOF的触发方式有三种:always、everysec、no。 默认使用everysec。可以通过redis.conf中appendfsync属性进行配置。
always:每次执行写入命令都会将aof_buf缓冲区文件全部内容写入到AOF文件中,并将AOF文件同步到磁盘。该方式效率最低,安全性最高。
everysec:每次执行写入命令都会将aof_buf缓冲区文件全部内容写入到AOF文件中。 并且每隔一秒会由子线程将AOF文件同步到磁盘。该方式兼备了效率与安全,即使出现宕机重启,也只会丢失不超过两秒的数据。
no:每次执行写入命令都会将aof_buf缓冲区文件全部内容写入到AOF文件中,但并不对AOF文件进行同步磁盘。 同步操作交由操作系统完成(每30秒一次),该方式最快,但最不安全。
执行原理:
AOF功能实现的整个执行过程可以分为三个部分:命令追加、文件写入、文件同步。
AOF重写优化:
AOF会将对Redis操作的所有写命令都记录下来,随着服务器的运行,AOF文件内保存的内容会越来越多。这样就会造成两个比较严重的问题:占用大量存储空间、数据还原花费的时间多。
RDB与AOF对比
1.RDB默认开启,AOF需手动开启
2.RDB性能优于AOF
3.AOF安全性优于RDB
4.AOF优先级高于RDB
5.RDB存储某个时刻的数据快照,AOF存储写命令
6.RDB在配置触发状态会丢失最后一次快照以后更改的所有数据,AOF默认使用everysec,每秒保存一次,最多丢失两秒以内的数据
高可用-主从复制
主从复制的作用:
1.Slave服务启动,主动连接Master,并发送SYNC命令,请求初始化同步
2.Master收到SYNC后,执行BGSAVE命令生成RDB文件,并缓存该时间段内的写命令
3.Master完成RDB文件后,将其发送给所有Slave服务器
4.Slave服务器接收到RDB文件后,删除内存中旧的缓存数据,并装载RDB文件
5.Master在发送完RDB后,即刻向所有Slave服务器发送缓存中的写命令
主从复制的作用:
读写分离:主写从读,提高服务器的读写负载能力
负载均衡:基于主从结构,配合读写分离,由slave分担master负载,并根据需求的变化,改变slave的数量,通过多个从节点分担数据读取负载,大大提高Redis服务器并发量与数据吞吐量
故障恢复:当master出现问题时,由slave提供服务,实现快速的故障恢复
数据冗余:实现数据热备份,是持久化之外的一种数据冗余方式
高可用基石:基于主从复制,构建哨兵模式与集群,实现Redis的高可用方案
哨兵模式:
哨兵模式介绍:
哨兵(sentinel) 是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的master并将所有slave连接到新的master。
注意:
1.哨兵也是一台redis服务器,只是不提供数据服务
2.通常哨兵配置数量为单数
3.如果配置启用单节点哨兵,如果有哨兵实例在运行时发生了故障,主从库无法正常
切换啦,所以我们需要搭建哨兵集群
集群哨兵模式介绍:
1.Redis提供了哨兵的命令,是一个独立的进程
2.原理 哨兵通过发送命令给多个节点,等待Redis服务器响应,从而监控运行的多个Redis实例的运行情况
3.当哨兵监测到master宕机,会自动将slave切换成master,通过通知其他的从服务器,修改配置文件切换主机
Sentinel三大工作任务:
监控:Sentinel 会不断地检查你的主服务器和从服务器是否运作正常
提醒:当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知
自动故障迁移:
1.当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器
2.当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器
客观下线和主观下线:
主观下线:
1.哨兵进程会使用 PING 命令检测它自己和主、从库的网络连接情况,用来判断实例的状态。如果哨兵发现主库或从库对 PING 命令的响应超时了,那么,哨兵就会先把它标记
为“主观下线”
2.一个服务器没有在 down-after-milliseconds 选项所指定的时间内, 对向它发送 PING 命令的 Sentinel 返回一个有效回复(valid reply), 那么 Sentinel 就会将这个服务器标记为主观下线
3.如果检测的是从库,那么,哨兵简单地把它标记为“主观下线”就行了,因为从库的下线影响一般不太大,集群的对外服务不会间断
4.如果检测的是主库,那么,哨兵还不能简单地把它标记为“主观下线”,开启主从
切换。因为很有可能存在这么一个情况:那就是哨兵误判了,其实主库并没有故障。可
是,一旦启动了主从切换,后续的选主和通知操作都会带来额外的计算和通信开销。
我们要知道啥叫误判。很简单,就是主库实际并没有下线,但是哨兵误以为它下线了。误判一般会发生在集群网络压力较大、网络拥塞,或者是主库本身压力较大的情况下。
客观下线:
1.指的是多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断
2.一个 Sentinel 可以通过向另一个 Sentinel 发送 SENTINEL is-master-down-by-addr 命令来询问对方是否认为给定的服务器已下线
3.客观下线条件只适用于主服务器
仲裁 qurum:
1.Sentinel 在给定的时间范围内, 从其他 Sentinel 那里接收到了【足够数量】的主服务器下线报告, 那么 Sentinel 就会将主服务器的状态从主观下线改变为客观下线
2.这个【足够数量】就是配置文件里面的值,一般是Sentinel个数的一半加1,比如3个Sentinel则就设置为2
3.down-after-milliseconds 是一个哨兵在超过规定时间依旧没有得到响应后,会自己认为主机不可用
4.当拥有认为主观下线的哨兵达到sentinel monitor所配置的数量时,就会发起一次投票,进行failover
哨兵日志名词解释:
基于pub/sub的客户端事件通知
- 主库下线事件:
- +sdown:实例进入主观下线状态
- -sdown:实例退出主观下线状态
- +odown:实例进入客观下线状态
- -odown:实例退出客观下线状态
- 从库重新配置事件
- +slave-reconf-sent:哨兵发送SLAVEOF命令重新配置从库
- +slave-reconf-inpprog:从库配置了新主库,但尚未进行同步
- +slave-reconf-done:从库配置了新主库,且和新主库完成同步
- 新主库切换:
- +swith-master:主库地址发送变化
总结:
1.主从集群间可以实现自动切换,可用性更高
2.数据更大限度的防止丢失
3.解决哨兵的集群高可用问题,减少误判率
高可扩-分片集群
分片集群原理:
分片集群允许有多个主节点,这些主节点都可用参与写数据
采用16384个虚拟的哈希槽,来分配给主节点(默认平均分配)
存储数据的时候 都是采用的key-value格式,Redis会根据键值对的 key,按照CRC16 算法算出一个16bit值
再用这个值对16384取模,得到0~16384范围内的一个数,每个数代表一个相应编号的哈希槽
然后根据这个哈希槽来查询这个槽在哪个主节点 就把数据放到哪个主节点
每个主节点都有多个自己的副节点来保存数据 所以当主节点宕机的话 副节点会成为主节点
我们一般设置主节点和副节点的时候 都会设置成单数 因为当主节点宕机的时候 一台机器说的不算 需要半数加一的计器说 主节点宕机了 主节点才算宕机,然后 剩下的主节点机器会投票选举宕机的主节点的其中一个副节点成为主节点,选举机制也是半数加一
注意:Redis集群是可以进行扩容和缩容的!!!
总结:
分片解决了什么问题?
高可用架构总结:
1.主从模式:读写分离,负载均衡,一个Master可以有多个Slaves
2.哨兵sentinel:监控,自动转移,哨兵发现主服务器挂了后,就会从slave中重新选举一个主服务器
3.分片集群: 为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS不受限于单机,提高并发量。
key过期删除策略
定时删除:该策略对内存空间足够友好,但对CPU非常不好,会拉低系统性能,因此不建议使用
惰性删除:惰性删除对CPU足够友好,但是对内存空间非常不友好,会造成大量内存空间的浪费
定期删除:就是每隔一段时间进行一次删除
1.如果删除操作执行次数过多、执行时间过长,就会导致和定时删除同样的问题:占用大量CPU资源去进行删除操作。
2.如果删除操作执行次数过少、执行时间过短,就会导致和惰性删除同样的问题:内存资源被持续占用,得不到释放。
所以key过期删除策略是采用:惰性删除+定期删除的 但是也需要合适的配置:
默认配置为:每秒运行10次会对具有过期时间的key进行一次扫描,但是并不会扫描全部的key,因为这样会大大延长扫描时间。
每次默认只会随机扫描20个key,同时删除这20个key中已经过期的key。
如果这20个key中过期key的比例达超过25%,则继续扫描。
内存淘汰策略
数据驱逐策略:其实所谓的驱逐就是将数据从内存中删除掉
1.lru:Least Recently Used,它是以时间为基准,删除最近最久未被使用的key。
2.lfu:Least Frequently Used,它是以频次为基准,删除最近最少未被使用的key。
对设置了过期时间数据淘汰:
1.volatile-lru:删除设置了过期时间,且最近最久未被使用的key
2.volatile-lfu:删除设置了过期时间,且最近最少未被使用的key
3.volatile-ttl:删除设置了过期时间,且即将过期的key
4.volatile-random:从删除设置了过期时间的key中随机删除
对所有数据淘汰:
1.allkeys-lru:从所有key中,删除最近最久未被使用的key
2.allkeys-lfu:从所有key中,删除最近最少未被使用的key
3.allkeys-random:从所有key中随机删除
不淘汰(默认的):
noevction:不删除,当内存空间不足时,直接返回错误信息报内存溢出错误
不同策略的使用场景:
1.Redis只做缓存,不做DB持久化,使用allkeys。如状态性信息,经常被访问,但数据库不会修改。
2.同时用于缓存和DB持久化,使用volatile。如商品详情页。
3.存在冷热数据区分,则选择LRU或LFU。如热点新闻,热搜话题等。
4.每个key被访问概率基本相同,选择使用random。如企业内部系统,访问量不大,删除谁对数据库也造成太大压力。
5.根据超时时间长久淘汰数据,选择选用ttl。如微信过期好友请求。