Redis常见数据类型,Redis为什么快,Redis持久化机制,主从复制原理

[原文链接 - Redis之AOF重写及其实现原理]
[原文链接 - Redis到底是多线程还是单线程]
[原文链接 - Redis持久化原理(RDB)]
[原文链接 - Redis6的多线程设计]

1、常见数据类型:String、Hash、List、Set、zset(有序集合)
2、redis快:纯内存操作、单线程(避免锁的上下文切换,redis6后支持多线程,但也是主线程执行,其他线程进行IO读写和解析但不执行内存操作)、IO多路复用
3、redis支持事务操作,支持消息订阅和发布机制(这个机制是redission的锁的实现)
4、redis持久化支持RDB、AOF:

一、RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程(CopyOnWriter),先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。RDB的启动效率高,但是持久化过程中宕机会丢数据,还有数据大会卡顿。
1) Redis父进程首先判断:当前是否在执行save,或bgsave/bgrewriteaof(后面会详细介绍该命令)的子进程,如果在执行则bgsave命令直接返回。bgsave/bgrewriteaof 的子进程不能同时执行,主要是基于性能方面的考虑:两个并发的子进程同时执行大量的磁盘写操作,可能引起严重的性能问题。
2) 父进程执行fork操作创建子进程,这个过程中父进程是阻塞的,Redis不能执行来自客户端的任何命令
3) 父进程fork后,bgsave命令返回”Background saving started”信息并不再阻塞父进程,并可以响应其他命令
4) 子进程创建RDB文件,根据父进程内存快照生成临时快照文件,完成后对原有文件进行原子替换
5) 子进程发送信号给父进程表示完成,父进程更新统计信息

二、AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。缺点:启动慢,最近的redis会优化重写(也是fork一个子进程重写的,不影响性能),如果选择同步落盘性能会慢些(每个1秒落盘,极端下会丢最后1秒数据)
在Redis的配置文件中存在三种同步方式,它们分别是:
appendfsync always     #每次有数据修改发生时都会写入AOF文件。
appendfsync everysec  #每秒钟同步一次,该策略为AOF的缺省策略。
appendfsync no          #从不同步。高效但是数据不会被持久化。(根据操作系统调度写入)

5、AOF重写的触发条件

AOF重写可以由用户通过调用BGREWRITEAOF手动触发。
服务器在AOF功能开启的情况下,会维持以下三个变量:

记录当前AOF文件大小的变量aof_current_size。
记录最后一次AOF重写之后,AOF文件大小的变量aof_rewrite_base_size。
增长百分比变量aof_rewrite_perc。
每次当serverCron(服务器周期性操作函数)函数执行时,它会检查以下条件是否全部满足,如果全部满足的话,就触发自动的AOF重写操作:

没有BGSAVE命令(RDB持久化)/AOF持久化在执行;
没有BGREWRITEAOF在进行;
当前AOF文件大小要大于server.aof_rewrite_min_size(默认为1MB),或者在redis.conf配置了auto-aof-rewrite-min-size大小;
当前AOF文件大小和最后一次重写后的大小之间的比率等于或者等于指定的增长百分比(在配置文件设置了auto-aof-rewrite-percentage参数,不设置默认为100%)
如果前面三个条件都满足,并且当前AOF文件大小比最后一次AOF重写时的大小要大于指定的百分比,那么触发自动AOF重写。

6、redis的过期策略和内存淘汰策略
[原文链接 - Redis的缓存淘汰策略LRU与LFU]

定期删除
redis 会将每个设置了过期时间的 key 放入到一个独立的字典中,以后会定期遍历这个字典来删除到期的 key。

Redis 默认会每秒进行十次过期扫描(100ms一次),过期扫描不会遍历过期字典中所有的 key,而是采用了一种简单的贪心策略。

1.从过期字典中随机 20 个 key;

2.删除这 20 个 key 中已经过期的 key;

3.如果过期的 key 比率超过 1/4,那就重复步骤 1;

redis默认是每隔 100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意这里是随机抽取的。为什么要随机呢?你想一想假如 redis 存了几十万个 key ,每隔100ms就遍历所有的设置过期时间的 key 的话,就会给 CPU 带来很大的负载。

优点:通过限制删除操作的时长和频率,来减少删除操作对CPU时间的占用--处理"定时删除"的缺点
定期删除过期key--处理"惰性删除"的缺点。

缺点:在内存友好方面,不如"定时删除",因为是随机遍历一些key,因此存在部分key过期,但遍历key时,没有被遍历到,过期的key仍在内存中。在CPU时间友好方面,不如"惰性删除",定期删除也会暂用CPU性能消耗。

惰性删除
所谓惰性策略就是在客户端访问这个key的时候,redis对key的过期时间进行检查,如果过期了就立即删除,不会给你返回任何东西。

定期删除可能会导致很多过期key到了时间并没有被删除掉。所以就有了惰性删除。假如你的过期 key,靠定期删除没有被删除掉,还停留在内存里,除非你的系统去查一下那个 key,才会被redis给删除掉。这就是所谓的惰性删除,即当你主动去查过期的key时,如果发现key过期了,就立即进行删除,不返回任何东西.

总结:定期删除是集中处理,惰性删除是零散处理。
当某个key被设置了过期时间之后,客户端每次对该key的访问(读写)都会事先检测该key是否过期,如果过期就直接删除;但有一些键只访问一次,因此需要主动删除,默认情况下redis每秒检测10次,检测的对象是所有设置了过期时间的键集合,每次从这个集合中随机检测20个键查看他们是否过期,如果过期就直接删除,如果删除后还有超过25%的集合中的键已经过期,那么继续检测过期集合中的20个随机键进行删除。这样可以保证过期键最大只占所有设置了过期时间键的25%。
内存淘汰策略:
volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。
allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(这个是最常用的)。
volatile-lfu:当内存不足以容纳新写入数据时,在过期密集的键中,使用LFU算法进行删除key。
allkeys-lfu:当内存不足以容纳新写入数据时,使用LFU算法移除所有的key。
volatile-random:当内存不足以容纳新写入数据时,在设置了过期的键中,随机删除一个key。
allkeys-random:当内存不足以容纳新写入数据时,随机删除一个或者多个key。
volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。
noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。

这八种大体上可以分为4中,lru、lfu、random、ttl。
LRU实现:淘汰最老的key。每个key对象内部同样维护了一个24位的时钟,比较系统和key的差值。redis选择key是随机选择N个(这里key的范围也可以配置的)
LFU实现:使用少的被淘汰。LFU把原来的key对象的内部时钟的24位分成两部分,前16位还代表时钟,后8位代表一个计数器counter(默认5)。这样当时间越长没有使用counter就会下降,使用counter会上升。但是新增的key使用量一般为0,为了防止淘汰初始化counter是5。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值