前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《Redis设计与实现》读书笔记(十) ——Redis对象相关其他设计与实现

《Redis设计与实现》读书笔记(十) ——Redis对象相关其他设计与实现

作者头像
用户1327360
发布2018-03-07 15:53:11
8160
发布2018-03-07 15:53:11
举报

《Redis设计与实现》读书笔记(十) ——Redis对象相关其他设计与实现

(原创内容,转载请注明来源,谢谢)

一、类型检查与命令多态

redis对键操作的命令分为两种,一种是可以对任意键进行操作的命令,如del、expire、rename、type、object等;另一种是只能对特定类型的键进行操作,redis的五种数据类型都有各自特定的键操作命令。

1、类型检查

redis的类型检查,是通过检查redisObject结构的type属性进行的。在执行一个特定命令之前,redis会先检查键对应的值对象的type属性,是否可以执行所需的命令:如果可以执行则执行;否则服务器将拒绝执行,并返回一个类型错误。

2、命令多态

redis每种数据类型,至少都有两种编码方式,命令多态就是指通过一个命令,可以执行不同的编码方式所提供的api。因此,redis的几乎每种操作命令都是多态的。对于同一个类型,操作不同的编码方式,称为基于编码的多态。

另外,还有上述提到的del、expire等,对于任意类型都可以操作,也是多态。这个是基于类型的多态。

二、内存回收

由于实现redis的C语言,不具备垃圾回收功能,因此redis构建了一套内存回收机制,是基于引用计数技术实现的内存回收。通过这一机制,程序可以通过追踪对象的引用计数信息,在适当的时候自动释放对象,并进行内存回收。

引用计数信息是redisObject结构中的refcount属性进行记录。

typedef structredisObject{
int refcount;
}robj;

上面的结构中省略结构中的其他信息。对象引用计数的信息,会随着对象使用状态的变化而改变,如下:

1)创建一个新对象时,refcount值是1。

2)对象被一个新程序使用,refcount值加1。

3)对象不再被某个程序使用,refcount值减1。

4)对象引用计数变成0时,对象所占的内存会被释放。

修改引用计数的api如下:

在对象的整个生命周期,可以分为创建对象、操作对象、释放对象。

三、对象共享

对象的引用计数属性,除了用于内存回收,还可以用于对象的共享。当多个键保存同一个值的时候,且值是整数类型的字符串对象时,redis会使用对象共享,让键指向同一个值。过程如下:

1)将数据库键的值指针指向一个现有的值对象。

2)将被共享的值对象的引用计数增1。

两个对象公用一个值的情况如下图:

对象共享机制对于节约内存有很大的帮助。redis初始化服务器的时候,会创建一万个字符串对象,是从0~9999的整数值,当服务器要用到这些值的时候,会使用共享对象。

共享对象的默认数量,可以通过修改文件redis.h中的常量REDIS_SHARED_INTEGERS进行修改。

因此,当如果创建了两个对象,值都是100,实际上就有三个对象引用,包括两个客户端创建的,和一个服务端持有的,如下图:

除了单独的字符串对象类型,在其他对象类型中,嵌套的字符串对象,也是会共享的。

另外,redis只共享整数类型的字符串对象,不共享字符串类型的字符串对象,是因为共享的对象如果是字符串,则比较字符串是否相同的过程比较耗时;同理,不把字符串对象以外的其他四种对象共享,也是为了避免对比带来的耗时。

四、对象空转时长

redisObject的最后一个属性——lru属性,是用于记录对象的最后一次被访问的时间。

typedef structredisObject{
unsigned lru:22;
}robj;

object idletime命令,可以打印出给定键的空转时长,这一时长是通过当前时间减去lru属性的值确定的。同时,该命令也具有特殊性。其他命令操作键,都会修改键的lru,而object idletime命令仅仅通过查询键的lru计算空转时长,并不修改lru。

如果配置中开启了maxmemory,并且服务器的回收算法设置为volatile-lru或者allkeys-lru,当服务器的内存超过了maxmemory所设定的上限,空转时长较高的键会被优先释放,从而回收内存。

五、redis对象总结

1、redis数据库的每个键和值都是一个redisObject对象。

2、redis有字符串、哈希、列表、集合、有序集合五种对象类型,每种对象类型至少2中编码方式(其中字符串对象有3中编码方式),不同的编码方式在不同的场景中具有高效的特定。

3、服务器执行某些命令之前,会先进行类型检查,对键进行类型检查,是检查键对应的值的类型。

4、redis具有对象的引用回收机制,当对象没有被使用,内存将被回收。

5、redis会共享0~9999共1万个整数值的字符串对象,这个数目可以通过配置文件修改。

6、redis会记录对象的最后访问时间,可以用来计算对象的空转时间。

——written by linhxx 2017.09.02

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-09-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 决胜机器学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档