Redis中String数据类型原理实现
时间:2022-07-26
本文章向大家介绍Redis中String数据类型原理实现,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
微信公众号:Java患者 专注Java领域技术分享
String 数据模型
首先Redis是KV数据结构,跟JDK中的Map是一样的,Redis是通过hashtable实现的,我们把这个叫做外层的哈希,那么每一个KY就是一个entry,在Redis的源码中,是定义为一个dictEntry。
typedef struct dictEntry {
void *key;
union {
void *val;
uint64_t u64;
int64_t s64;
double d;
} v;
struct dictEntry *next;
} dictEntry;
通过源码 定义了dictEntry对象,对象中存储了一个key,跟一个value,并且还有一个指向了下一个键值对节点的对象。
接着了解key-value的原理,key是一个字符串,在C语言中(Redis是用C语言开发的),是没有字符串这个数据类型的,只有字符类型,而key并没有直接使用了C语言中的字符数组char[]来实现,而是存储在了一个自定义的数据类型-SDS。
value并没有存在SDS中,也不是作为字符串存储,而是存储中一个redisObject中,事实上,redis的五大数据类型的value都是存储在redisObject中。、
SDS
什么是SDS?Redis中字符串的实现,SDS有多种结构:sdshdr5、sdshdr8、sdshdr16、sdshdr32、sdshdr64,用于存储不同长度的字符串,分别代表的是2^5byte、2^8byte、2^16byte、2^32byte、2^64byte。
typedef char *sds;
......
struct __attribute__ ((__packed__)) sdshdr8 {
uint8_t len; /* 当前字符数据的长度 */
uint8_t alloc; /* 当前字符数组总共配的内存大小 */
unsigned char flags; /* 当前字符数据的属性 (sdshdr5、sdshdr8、sdshdr16、......) */
char buf[]; /* 字符串真正的值 */
};
......
为什么要使用SDS来实现字符串呢?
- 首先C语言中并没有字符串类型,要实现的话只能使用char[]来实现,但是使用字符数组必须先给变量分配足够的空间,否则会溢出,分配多了又可能造成浪费
- 如果要获取字符串的长度,就需要遍历字符数组,时间复杂度高O(n)
- 字符串的长度更改会对字符数组的内存进行重新分配
- C语言的 是字符串的标志结束位,如果存储图片音频等多媒体文件的时候,存在二进制安全问题
SDS的特点
- 无需担心内存溢出的问题,如果需要就对SDS进行扩容
- 定义了len属性,获取字符串长度时间复杂度O(1)
- 通过“空间预分配” 和“惰性空间释放”,防止多次重分配内存
- 判断字符串是否结束是len属性
redisObject
typedef struct redisObject {
unsigned type:4; /* 对象的数据类型 (OBJ_STRING、OBJ_LIST、OBJ_HASH、OBJ_SET、OBJ_ZSET)*/
unsigned encoding:4; /* 具体的数据结构 */
unsigned lru:LRU_BITS; /* 对象最后一次被命令访问的时间 与内存回收有关 */
int refcount; /* 引用计数 当该变量值为0时,表示该对象不被任何其他对象引用,可以进行垃圾回收了 */
void *ptr; /* 指针指向对象实际的数据结构 */
} robj;
数据模型图
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Hive建表异常
- Spring全家桶之SpringData——Spring 整合Hibernate与Hibernate Jpa
- MyCat练手项目以及简单分页功能实现
- Redis在分布式项目中的应用
- 常见的Form表单提交方式
- 基于RPC实现服务的注册、发布和消费
- HttpClient技术
- JsonP------实现跨域请求
- ActiveMQ—基于Java的消息传递服务器
- SpringMVC知识体系搭建
- 你分得清MySQL普通索引和唯一索引了吗?
- 基于Dubbo的CRUD案例
- 在javaEE中,实现用户登陆功能的实现
- JavaEE中,实现登录时进行校验验证码的功能
- JavaEE中为删除数据操作与退出操作添加确认提示框