redis通过前面几篇的数据结构构键了一个对象系统,这个对象系统包含了字符串对象,列表对象,哈希对象,集合对象,有序集合对象

每一个对象都是一个redisobject

typedef struct redisObject {

    // 类型
unsigned type:; // 编码
unsigned encoding:; // 指向底层实现数据结构的指针
void *ptr; // ... } robj;

type表示类型,有5种,就是

REDIS_STRING,REDIS_LIST,REDIS_HASH,REDIS_SET,REDIS_ZSET

编码表示的就是底层的实现,因为每一种对象都至少有两种以上的实现方式。ptr指向的就是底层实现的数据结构

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

int针对的是整数

如果字符串的长度小于39,那么使用embram,否则使用raw

embstr和raw的区别

(1)embstr是连续的,object和sds是一块连续的内存,这样的话分配内存和释放内存都不是两次,而是一次

(2)充分利用缓存的优势

double类型其实也是字符串类型的

当时用的时候会从字符串类型转换为double类型

int和embstr在满足条件的时候都会转换为raw编码,比如一个整数10085 appending一个字符串的话就不在是一个整数了

另外embsr不可以修改的,他是只读的,如果要修改的话,他会自动转换为raw之后再进行修改

列表对象:

列表对象的编码可以使压缩列表和双端链表,如果其中有字符串的话,字符串是字符串对象的表示,说明字符串对象可以被其他的对象嵌套

编码转换

(1)每一个元素得长度都小于64,

(2)数量小于512,

满足上面两个条件的话就是用压缩列表,否则的话使用双端链表

哈希对象

哈希对象的编码可以是压缩列表和字典

如下图所示

至于编码的转换,和上面的是一样的,如果两个都满足,就使用压缩列表,否则使用字典

ps:注意这两个限制条件在redis.conf的配置文件中是可以修改的

集合对象:

集合对象的编码可以是整数集合和hashtable

看下面:

编码的转换条件

(1)都是整数

(2)元素数量不超过512个

满足以上条件使用整数集合,否则的话使用hashtable

有序集合对象:

编码可以是压缩列表和跳跃表

压缩列表实现的话,使按照分值排序,并且存储的话对象在前,分值在后

zset中基于跳跃表实现的话,就是讲分值从小到大排序,建立一个跳跃表,但是额外还需要一个字典,记录对象和分值的映射,这样的话对于ZSCORE命令,我们可以在O(1)的时间复杂度就可以获得到指定对象的分值

两者结合,无论是有序遍历还是获得指定元素,都会择优选择,降低时间复杂度

编码转换

(1)长度都小于64

(2)数量不超过128个

这两个都满足就是用压缩列表,否者就是用skiplist作为编码

额外对于对象还有很多优化和处理

(1)多态:很多命令都是具有多态的性质,就是可以处理多种命令

在执行一个命令的时候,我们首先会根据值对象的类型去判断这个命令能否执行,如果可以的话,我们还会根据值对象的编码方式选择正确的API去执行

比如上面,我们就可以认为LLEN是多态的,多态可以包括基于类型的多态,和基于编码的多态

(2)内存管理:

对于redisobject我们基于引用计数原值,定义在redisobject结构里面的refcount int,当对象引用计数降低为0的时候,释放对象。这个有点类似windows线程回收机制,采用计数原值,关闭handle减一,线程函数退出减一,为0的时候自动回收线程资源

(3)对象共享:

redis中多个键的值一样的话,会使值指针只想一块内存,引用计数增加,redis服务器初始化的时候会默认创建0-9999字符串,所以他们的引用计数在还没使用的时候就是1了

(4)空转时长:

redisobject中有个lru,表示最后访问的时候

通过idletime可以求出多久没有被访问了,就是当前时间和lru时间差(空转时长)

但是ps(这个命令不会修改lru属性)

如果服务器设置了maxmemory选项,那么当内存达到上线了,服务器会优先空转时间长的进行释放

redis 对象的更多相关文章

  1. 【redis源码阅读】redis对象

    结构定义 在redis中,对象的数据结构定义如下: ​typedef struct redisObject { ​unsigned type:4; ​unsgined encoding:4; ​uns ...

  2. Redis对象类型

    Redis对象类型 Redis基于基础的数据结构创建的对象: 字符串对象. 列表对象. 哈希对象. 集合对象 有序集合对象. 对象回收:Redis对象系统实现了基于引用计数技术的内存回收机制,当程序不 ...

  3. Redis底层探秘(五):Redis对象

    前面几篇文章,我们一起学习了redis用到的所有主要数据结构,比如简单动态字符串(sds).双端链表.字典.压缩列表.整数集合等等. redis并没有直接使用这些数据结构来实现键值对数据库,而是基于这 ...

  4. Redis对象的设计与实现

    一.Redis对象结构Redis中的每个对象都由一个redisObject结构表示: typedef struct redisObject { unsigned type;//类型 unsigned ...

  5. 面试官:你了解过Redis对象底层实现吗

    上一章我们讲了Redis的底层数据结构,不了解的人可能会有疑问:这个和平时用的五大对象有啥关系呢?这一章我们就主要解释他们所建立的联系. 看这个文件之前,如果对ziplist.skiplist.int ...

  6. Redis之对象篇——Redis对象系统简介

    Redis之对象篇--Redis对象系统简介 前言     之前几篇文章,简单介绍 Redis用到的所有主要数据结构,简单动态字符串(SDS).双端链表.字典.压缩列表.整数集合.跳跃表. 图解Red ...

  7. Redis对象——字符串

    文章导航-readme 前言     上一篇文章Redis之对象篇--Redis对象系统简介简单介绍了Redis的对象系统.Redis使用对象来表示数据库中的键和值每个对象都由一个redisObjec ...

  8. Redis对象

    概述 Redis并没有使用基础数据结构去实现键值数据库,而是基于数据结构封装了一个个对象. 类型和编码 由于Redis是键值数据库,所以每次存储数据时,至少包含两个对象,即K.V对应的对象.其数据结构 ...

  9. Redis对象占用内存分析

    当你往Redis中插入了一系统对象,如何分析这些对象的占用情况? 1.我们可以在Redis的控制台使用info命令来查看各项指标,其中有一项是Memory,可以通过存储前后的used_memory差异 ...

随机推荐

  1. springboot(十一):Spring boot中mongodb的使用

    mongodb是最早热门非关系数据库的之一,使用也比较普遍,一般会用做离线数据分析来使用,放到内网的居多.由于很多公司使用了云服务,服务器默认都开放了外网地址,导致前一阵子大批 MongoDB 因配置 ...

  2. Docker - 终端交互

    进入容器交互终端 使用docker attach命令进入容器交互终端. 注意:如果多个窗口同时attach到同一个容器,那么所有窗口都会同步显示.如果某个窗口因命令阻塞时,那么其他窗口将无法执行操作. ...

  3. js快速去除数组重复项

    function unique1(arr) { var tmp = new Array(); tmp.push(arr[0]); for(var i=0;i<arr.length;i++) { ...

  4. vue视频学习笔记06

    video 6 vue动画vue路由--------------------------------------transition 之前 属性<p transition="fade& ...

  5. ssm框架整合+maven项目创建

    在引入外部maven插件后就可以创建一个maven项目了,这篇文章主要介绍ssm框架的整合和如何创建一个maven项目 1.在开发工具的项目空白区单击右键,依次选择New.Other,会出现如下界面, ...

  6. ShadowBroker释放的NSA工具中Esteemaudit漏洞复现过程

    没有时间测试呢,朋友们都成功复现,放上网盘地址:https://github.com/x0rz/EQGRP 近日臭名昭著的方程式组织工具包再次被公开,TheShadowBrokers在steemit. ...

  7. MySQL · 引擎特性 · InnoDB Buffer Pool

    前言 用户对数据库的最基本要求就是能高效的读取和存储数据,但是读写数据都涉及到与低速的设备交互,为了弥补两者之间的速度差异,所有数据库都有缓存池,用来管理相应的数据页,提高数据库的效率,当然也因为引入 ...

  8. VHDL乘除法及转换

    首先鄙视一下这个不智能的语言 1.要进行乘法与除法,数据类型必须是signed 2.两个16位的数相乘,结果必须是32位的 3.乘以2的n次幂的数可以直接乘,之后截位也比较方便,(其实直接移位就可以) ...

  9. 前端设计技巧——用 Promise 处理交互和异步

    本文仅表达前端的一些设计技巧,如果您在查阅js技术,请忽略此文! 前端开发经常会遇到这样的场景: 当满足一定条件时,需要弹出一个模态框,以便接收用户的输入.然后根据不同的输入,进行不用的操作. (ps ...

  10. 你对SpringMvc是如何理解的?

    SpringMVC工作原理 SpringMvc是基于过滤器对servlet进行了封装的一个框架,我们使用的时候就是在web.xml文件中配置DispatcherServlet类:SpringMvc工作 ...