redisObject详解
这里写目录标题
- Redis的两层数据结构简介
- Redis数据结构的内部实现
- redisObject结构体
- redisObject的作用
Redis的两层数据结构简介
redis的性能高的原因之一是它每种数据结构都是经过专门设计的,并都有一种或多种数据结构来支持,依赖这些灵活的数据结构,来提升读取和写入的性能。如果要了解redis的数据结构,可以从两个不同的层面来讨论它:
- 第一个层面,是从使用者的角度,这一层面也是Redis暴露给外部的调用接口,比如:string,list,hash,set,sorted set。
- 第二个层面,是从内部实现的角度,属于更底层的实现,比如:dict,sds,ziplist,quicklist,skiplist,intset。
Redis数据结构的内部实现
从Redis的使用者的角度来看,一个Redis节点包含多个database(非cluster模式下默认是16个,cluster模式下只能是1个),而一个database维护了从key space到object space的映射关系。这个映射关系的key是string类型,而value可以是多种数据类型,比如:string, list, hash、set、sorted set等。我们可以看到,key的类型固定是string,而value可能的类型是多个。
而从Redis内部实现的角度来看,database内的这个映射关系是用一个dict来维护的。dict的key固定用一种数据结构来表达就够了,这就是动态字符串sds。而value则比较复杂,为了在同一个dict内能够存储不同类型的value,这就需要一个通用的数据结构,这个通用的数据结构就是robj,全名是redisObject。
举个例子:
- 如果value是一个list,那么它的内部存储结构是一个quicklist。
- 如果value是一个string,那么它的内部存储结构一般情况下是一个sds。但如果string类型的value的值是一个数字,那么Redis内部还会把它转成long型来存储,从而减小内存使用。
所以,一个robj既能表示一个sds,也能表示一个quicklist,甚至还能表示一个long型。
redisObject结构体
redisObject的定义如下:
typedef struct redisObject {unsigned type:4;unsigned encoding:4;unsigned lru:LRU_BITS; /* lru time (relative to server.lruclock) */int refcount;void *ptr;
} robj;
一个robj包含如下5个字段:
- type: 对象的数据类型。占4个bit。可能的取值有5种: OBJ_STRING, OBJ_LIST, OBJ_SET, OBJ_ZSET,
OBJ_HASH,分别对应Redis对外暴露的5种数据结构 - encoding: 对象的内部表示方式(也可以称为编码),占4个bit,可能的取值有10种。
- lru: 做LRU替换算法用,占24个bit。
- refcount: 引用计数。它允许robj对象在某些情况下被共享。
- ptr: 数据指针。指向真正的数据。比如,一个代表string的robj,它的ptr可能指向一个sds结构;一个代表list的robj,它的ptr可能指向一个quicklist。
这里特别需要仔细察看的是encoding字段。对于同一个type,还可能对应不同的encoding,这说明同样的一个数据类型,可能存在不同的内部表示方式。而不同的内部表示,在内存占用和查找性能上会有所不同。
当type = OBJ_STRING的时候,表示这个robj存储的是一个string,这时encoding可以是下面3种中的一种:
- OBJ_ENCODING_RAW: string采用原生的表示方式,即用sds来表示。
- OBJ_ENCODING_INT: string采用数字的表示方式,实际上是一个long型。
- OBJ_ENCODING_EMBSTR: string采用一种特殊的嵌入式的sds来表示。
当type = OBJ_HASH的时候,表示这个robj存储的是一个hash,这时encoding可以是下面2种中的一种:
- OBJ_ENCODING_HT: hash采用一个dict来表示。
- OBJ_ENCODING_ZIPLIST: hash采用一个ziplist来表示。
encoding的十种取值如下:
- OBJ_ENCODING_RAW: 最原生的表示方式。其实只有string类型才会用这个encoding值(表示成sds)。
- OBJ_ENCODING_INT: 表示成数字。实际用long表示。
- OBJ_ENCODING_HT: 表示成dict。
- OBJ_ENCODING_ZIPMAP: 是个旧的表示方式,已不再用。在小于Redis 2.6的版本中才有。
- OBJ_ENCODING_LINKEDLIST: 也是个旧的表示方式,已不再用。
- OBJ_ENCODING_ZIPLIST:表示成ziplist。
- OBJ_ENCODING_INTSET: 表示成intset。用于set数据结构。
- OBJ_ENCODING_SKIPLIST: 表示成skiplist。用于sorted set数据结构。
- OBJ_ENCODING_EMBSTR: 表示成一种特殊的嵌入式的sds。
- OBJ_ENCODING_QUICKLIST: 表示成quicklist。用于list数据结构。
redisObject的作用
redisObject的作用的作用如下:
- redisObjec是联结两个层面的数据结构的桥梁。
- 为多种数据类型提供一种统一的表示方式。
- 允许同一类型的数据采用不同的内部表示,从而在某些情况下尽量节省内存。
- 支持对象共享和引用计数。当对象被共享的时候,只占用一份内存拷贝,进一步节省内存。
redisObject详解相关推荐
- 万字长文的Redis五种数据结构详解(理论+实战),建议收藏。
本文脑图 前言 Redis是基于c语言编写的开源非关系型内存数据库,可以用作数据库.缓存.消息中间件,这么优秀的东西一定要一点一点的吃透它. 关于Redis的文章之前也写过三篇,阅读量和读者的反映都还 ...
- Redis数据类型使用场景及有序集合SortedSet底层实现详解
Redis常用数据类型有字符串String.字典dict.列表List.集合Set.有序集合SortedSet,本文将简单介绍各数据类型及其使用场景,并重点剖析有序集合SortedSet的实现. Li ...
- redis 数据类型详解 以及 redis适用场景场合
redis 数据类型详解 以及 redis适用场景场合 1. MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访 ...
- Redis设计与实现详解二:Redis数据库实现
Redis设计与实现详解一:数据结构与对象 Redis设计与实现详解三:多机功能实现 Redis设计与实现详解四:其他单机功能 数据库 服务器中的数据库 Redis服务器将所有数据库都保存在服务器状态 ...
- 详解 Redis 应用场景及应用实例
Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发工作由VMware主 ...
- Redis内存淘汰策略LRU、LFU详解
Redis内存淘汰原因 Redis是一种内存数据库,redis的容量往往有限,无法存放所有的数据.当内存满了的时候,并且这个时候还需要往Redis中放入新的数据,就需要将Redis中的一部分数据淘汰了 ...
- 40000+字超强总结?阿里P8把Java全栈知识体系详解整理成这份PDF
40000 +字长文总结,已将此文整理成PDF文档了,需要的见文后下载获取方式. 全栈知识体系总览 Java入门与进阶面向对象与Java基础 Java 基础 - 面向对象 Java 基础 - 知识点 ...
- Redis五种基本数据类型底层详解(原理篇)
Redis五种基本数据类型底层详解 详细介绍Redis用到的数据结构 简单动态字符串 SDS和C字符串的区别 总结 链表 字典 哈希表 字典 哈希算法 解决键冲突 rehash(重点) 渐进式reha ...
- 【Redis】数据类型的详解与使用场景【原创】
文章目录 Redis数据类型的详解与使用场景 1-1 NoSQL的概述 1. 概述 2. 为什么需要NoSQL 3. NoSQL产品 4. 分类 5. 特点 2-1 Redis的概述 1. 概述 2. ...
最新文章
- R语言可视化分别使用lattice包和ggplot2包可视化热图(heatmap)并绘制热力图对应的系统树图(dendrogram)实战
- 解决远程登录MYSQL数据库
- python mysql library popular_【过时】MySQLdb:Python 操作 MySQL 数据库
- Windows系统中安装Python模块pip numpy matplotlib
- django的admin界面删除因为外键约束导致失败
- 多思计组原理虚拟实验室_先睹为快!汽院实验室组团来亮相_搜狐汽车
- [HNOI2017]礼物
- JEECG 引领J2EE新开发模式插件式开发 - 公开课2013-12-12
- Pycharm常见问题
- 6年前的Dubbo,2年前的Spring Cloud,都被这个架构干掉了!
- 酷应用,这个小玩意为中国软件业趟出了一条新路
- java digester_Apache Commons Digester
- word文档更新目录为什么更新不了?
- numpy.meshgrid()绘制网格图
- Win32创建异形窗口
- 电容的字母型规格型号标号材料容差总结
- nas与文件服务器对比,NAS网络存储设备为什么能取代文件服务器
- spring关于Aspect、Joinpoint、Advice Pointcut的区别
- 场上比分为米兰1-0当先佩斯卡拉
- 洞若观火,聊聊旧系统升级改造那些事儿
热门文章
- 【紫光同创PGL22G学习】七、千兆以太网(ETH)上手
- 太有才了!创新的街头涂鸦手绘欣赏【中篇】
- ubuntu安装宝塔面板
- Oracle EBS应用产品-外币重估原则
- linux时间老变成市区,Linux(CentOS6.5)修改系统市区被中国标准时间(北京时间)
- 转 精辟,太生动了,太形象了。应用于实践,价值无比!
- 如何使Android应用程序获得root权限
- hbuilderx 小程序分包_HbuilderX微信小程序打包失败
- 前端二(HTML、CSS)
- Qt程序编译成功,执行时报错:程序异常结束.crashed