Redis后台线程之非阻塞删除

在这里插入图片描述

当Redis执行删除命令的时候,如果被删除的对象是列表、集合、散列类型,因为这些数据类型包含的元素存放在不同的内存块中,redis需要遍历所有元素来释放其对应的内存块空间,这个耗时操作可能导致redis阻塞,redis4提供的UNLINK命令可以实现非阻塞删除(Redis4引入了后台线程)。

UNLINK删除命令流程:
  1. 首先检查过期字典中是否包含该健,有则先从过期字典中删除
  2. 将该健在从过期字典中删除的返回键值对,这时并没有删除键值对对象
  3. 计算该键值对的值对象占用的字节数
  4. 若该值对象的字节数大于LAZYFREE_THRESHOLD(64字节),且该值对象只被当前一处引用则执行如下操作,实现非阻塞删除:
    1. 创建一个后台任务负责删除值对象(后台线程处理)
    2. 将该键值对的值对象引用设置为NULL,保证主线程访问不到
  5. 删除值对象,并释放其内存空间

非阻塞删除的场景下,后台线程负责删除值对象,主进程负责处理用户请求,后台线程后续删除值对象时并不需要进行线程同步操作(引用为null,主进程访问不到)。

后台线程的实现
  1. Redis有3类后台任务:文件关闭、磁盘同步和非阻塞删除:
    1. 磁盘同步策略若是每秒执行一次,则是后台线程负责
    2. AOF重写时,会用后台线程关闭临时文件
  2. 设置线程栈大小(避免有些线程栈太小无法处理任务)
  3. 创建后台线程,指定该线程负责的任务类型
    1. 线程创建以后抢占该任务的互斥量,再将该任务添加到对应的任务队列中
      1. 首先抢占该任务类型的互斥量
      2. 检查任务队列待处理任务是否为空,若为空,则阻塞当前线程
      3. 若队列中存在待处理的任务,获取一个任务,并释放互斥量
      4. 根据任务类型执行对应的处理逻辑,执行任务
      5. 重新抢占互斥量,并删除任务
    2. 处理任务,最后释放互斥量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑笑布丁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值