5.redis对象介绍(一)

        redis里面用到了主要数据结构,比如简单动态字符串,双端链表,字典,压缩列表,整数集合等,但redis里面并没有直接使用这些数据结构,而是基于这些数据结构建立了一个对象系统,这个对象系统包括字符串对象,列表对象,哈希对象,集合对象和有序集合对象。

        使用对象的好处:

  1. 执行命令前,根据对象的类型判断一个对象是否可以执行给定的命令;
  2. 可以针对不同的场景,为对象设置多种不同的数据结构实现,从而优化对象在不同场景次啊的使用效率;
  3. redis对象系统实现了基于引用计数技术的内存回收机制,当程序不再使用某个对象的时候,这个对象占用的内存就会被自动释放;另外,redis还通过引用计数技术实现了对象共享机制,这一机制可以在适当的条件下,通过让多个数据库键共享同一个对象来节约内存;
  4. redis的对象带有访问时间信息,该信息可以用于计算键的空转时长,在服务器启用了maxmemory功能的情况下,空转时长较大的那些键会优先被服务器删除;

1. 对象的类型与编码

        每当我们在redis的数据库中创建一个键值对时,至少会创建两个对象,一个对象用作键值对的键(键对象),一个用作键值对的值(值对象)。

        redis中的每个对象都由一个redisObject结构表示,该结构中和保存数据有关的三个属性分别是type,encoding和ptr:

1.1 类型

        记录对象的类型,这个属性的值可以是REDIS_STRING(字符串),REDIS_LIST(列表对象),REDIS_HASH(哈希对象),REDIS_SET(集合对象),REDIS_ZSET(有序集合对象)。

        对于redis数据库保存的键值对来说,键总是一个字符串对象,而值则可以是五种对象中的其中一种。当我们执行type命令时,返回的是值对象的类型。

redis> set msg "hello world"
OK

redis> TYPE msg
string
1.2 编码和底层实现

对象的ptr指针指向对象的底层实现数据结构,这些数据结构由对像encoding属性决定。

encoding的值可以是以下几种:

  • REDIS_ENCODING_INT:long类型的整数;
  • REDIS_ENCODING_EMBSTR:embstr编码的简单动态字符串;
  • REDIS_ENCODING_RAW:简单动态字符串;
  • REDIS_ENCODING_HT:字段;
  • REDIS_ENCODING_LINKEDLIST:双端链表;
  • REDIS_ENCODING_ZIPLIST:压缩列表;
  • REDIS_ENCODING_INTSET:整数集合;
  • REDIS_ENCODING_SKIPLIST:跳跃表和字典;

每种类型的对象都至少使用了两种不同的编码,下表列出了每种类型的对象可以使用的编码:

使用OBJECT ENCODING命令可以查看数据库键的值对象的编码:

        redis通过属性encoding属性来设定对象所使用的编码,而不是为特定类型的对象关联一种固定的编码,极大的提升了redis的灵活性和效率。

2. 字符串对象

        字符串对象的编码可以是int,raw,embstr;

        如果字符串对象保存的是一个字符串值,并且这个值的长度大于32字节,那么字符串对象会使用简单动态字符串来保存,对象的编码为raw;如果一个字符串值的长度小于等于32字节,那么字符串对象将使用embstr编码保存这个值。

        raw编码和embstr编码的区别:raw会调用两次内存分配函数来分别创建redisObject结构和sdshdr结构,而embstr编码则通过调用一次内存分配函数来分配一块连续的空间,空间中以及包含redisObject和sdshdr两个结构;

raw编码示例:

embstr编码示例:

        另外,如果我们保存的是一个浮点数,程序会先将这个浮点数转换成字符串值,再保存字符串值;如果执行命令对这个字符串进行增减,也是会把字符串取出来,转成浮点数,做完运算,再转成字符串存进去。

2.1 编码的转换

        对于int编码的字符串对象,如果我们向对象执行命令,使得这个对象保存的不再是整数,而是一个字符串值,那么字符串对象的编码将从int变为raw;

        redis没有为embstr编码的字符串对象编写任何的修改程序,也就是说embstr编码的字符串是只读的,当对embstr编码的对象执行修改命令时,程序会先将对象的编码从embstr转换成raw,因此,embstr编码的字符串对象在执行修改命令之后,都会变成一个raw编码的字符串对象。

2.2 字符串命令的实现

3. 列表对象

列表对象的编码可以是ziplist或者linkedlist,下图分别展示了ziplist和linkedlist编码的列表对象:

3.1 编码转换

当列表对象可以同时满足以下两个条件时,列表对象使用ziplist编码:

  • 保存的所有字符串元素的长度都小于64字节;
  • 列表对象保存的元素数量小于512个;

不能满足这两个条件则使用linkedlist编码;

        需要注意,上面两个条件的上限值是可以修改的,具体可以看配置文件中关于list-max-ziplist-value选项和list-max-ziplist-entries选项的说明;

3.2 常用命令

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值