Redis如何判断命令类型的?及 Redis是如何做内存回收的?

Redis中用于操作键的命令基本上可以分为两种类型。

其中一种命令可以对任何类型的键执行,比如说DEL命令、EXPIRE命令、RENAME命令、TYPE命令、OBJECT命令等。

举个例子,以下代码就展示了使用DEL命令来删除三种不同类型的键:

在这里插入图片描述而另一种命令只能对特定类型的键执行,比如说:

  • SET、GET、APPEND、STRLEN等命令只能对字符串键执行;
  • HDEL、HSET、HGET、HLEN等命令只能对哈希键执行;
  • RPUSH、LPOP、LINSERT、LLEN等命令只能对列表键执行;
  • SADD、SPOP、SINTER、SCARD等命令只能对集合键执行;

ZADD、ZCARD、ZRANK、ZSCORE等命令只能对有序集合键执行;

举个例子,我们可以用SET命令创建一个字符串键,然后用GET命令和APPEND命令操作这个键,但如果我们试图对这个字符串键执行只有列表键才能执行的LLEN命令,那么Redis将向我们返回一个类型错误:

在这里插入图片描述

Redis如何判断命令类型的?

从上面发生类型错误的代码示例可以看出,为了确保只有指定类型的键可以执行某些特定的命令,在执行一个类型特定的命令之前,Redis会先检查输入键的类型是否正确,然后再决定是否执行给定的命令。

类型特定命令所进行的类型检查是通过redisobject结构的type属性来实现的:

  • 在执行一个类型特定命令之前,服务器会先检查输入数据库键的值对象是否为执行命令所需的类型,如果是的话,服务器就对键执行指定的命令;
  • 否则,服务器将拒绝执行命令,并向客户端返回一个类型错误。

举个例子,对于LLEN命令来说:

  • 在执行LLEN命令之前,服务器会先检查,输入数据库键的值对象是否为列表类型,也即是,检查值对象redisobject结构type属性的值是否为REDIS_LIsT,如果是的话,服务器就对键执行LLEN命令;
  • 否则的话,服务器就拒绝执行命令并向客举个例子,对于LLEN命令来说:在执行LLEN命令之前,服务器会先检查输入数据库键的值对象是否为列表类型,也即是,检查值对象redisobject结构type属性的值是否为REDIS_LIsT,如果是的话,服务器就对键执行LLEN命令;
  • 否则的话,服务器就拒绝执行命令并向客户端返回一个类型错误;下图展示了这一类型检查过程。
    在这里插入图片描述

Redis是如何做内存回收的?

因为C语言并不具备自动内存回收功能,所以Redis在自己的对象系统中构建了一个引用计数( reference counting)技术实现的内存回收机制,通过这一机制,程序可以通过跟踪对象的引用计数信息,在适当的时候自动释放对象并进行内存回收。

每个对象的引用计数信息由redisobject结构的refcount属性记录:
在这里插入图片描述
对象的引用计数信息会随着对象的使用状态而不断变化:

  • 在创建一个新对象时,引用计数的值会被初始化为1;
  • 当对象被一个新程序使用时,它的引用计数值会被增一;
  • 当对象不再被一个程序使用时,它的引用计数值会被减一;
  • 当对象的引用计数值变为0时,对象所占用的内存会被释放。

下图列出了修改对象引用计数的API,这些API分别用于增加、减少、重置对象的引用计数。
在这里插入图片描述
对象的整个生命周期可以划分为创建对象、操作对象、释放对象三个阶段。作为例子,以下代码展示了一个字符串对象从创建到释放的整个过程:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44533129/article/details/112676463