上一篇文章从根本上理解了set/get的处理过程,相当于理解了 增、改、查的过程,现在就差一个删了。本篇我们来看一下删除过程。
对于客户端来说,删除操作无需区分何种数据类型,只管进行 del 操作即可。
零、删除命令 del 的定义
主要有两个: del/unlink, 差别是 unlink 速度会更快, 因为其使用了异步删除优化模式, 其定义如下:
一、delCommand
delCommand 的作用就是直接删除某个 key 的数据,释放内存即可。
框架代码一看即明,只是相比于我们普通的删除是多了不少事情。否则也不存在设计了。
二、unlinkCommand
如下,其实和del是一毛一样的,仅是变化了一个 lazy 标识而已。
三、删除数据过程详解
删除数据分同步和异步两种实现方式,道理都差不多,只是一个是后台删一个是前台删。我们分别来看看。
1. 同步删除 dbSyncDelete
同步删除很简单,只要把对应的key删除,val删除就行了,如果有内层引用,则进行递归删除即可。
其实对于有GC收集器的语言来说,根本不用关注内存的释放问题,自有后台工具处理,然而对于 c 语言这种级别语言,则是需要自行关注内存的。这也是本文存在的意义,不然对于一个 hash 表的元素删除操作,如上很难吗?并没有。
下面,我们就来看看 redis 是如何具体释放内存的吧。
额,可以看出,对key的释放自然是简单之极。而对 value 则谨慎许多,首先它表面上只对引用做减操作。只有发只剩下1个引用即只有当前引用的情况下,本次释放就是最后一次释放,所以才会回收内存。
2. 异步删除过程
异步删除按理说会更复杂,更有意思些。只不过我们前面已经把核心的东西撸了个遍,这剩下的也不多了。
从此处redis异步处理过程,我们可以看到,redis并不是每次进入异步时都进行异步操作,而是在必要的时候才会进行。这也提示我们,不要为了异步而异步,而是应该计算利弊。
如此,整个 del/unlink 的过程就完成了。总体来说,删除都是基于hash的简单remove而已,唯一有点难度是对内存的回收问题,这其实就是一个简单的使用引用计数器算法实现的垃圾回收器应该做的事而已。勿须多言。具体过程需依赖于数据的存储结构,主要目的自然是递归释放空间,避免内存泄漏了。
领取专属 10元无门槛券
私享最新 技术干货