Redis不同数据类型的的数据结构实现
我们知道Redis支持五种数据类型,
分别是字符串、哈希表(map)、列表(list)、集合(set)和有序集合,和Java的集合框架类似,不同数据类型的数据结构实也是不一样的。
1.Redis中的redisObject对象
Redis是使用C编写的,内部实现了一个struct结构体redisObject对象,
通过结构体来模仿面向对象编程的“多态”,作为一个底层的数据支持,redisObject代码:
/*
* Redis 对象
*/
typedef struct redisObject {
// 类型
unsigned type:4;
// 对齐位
unsigned notused:2;
// 编码方式
unsigned encoding:4;
// LRU 时间(相对于 server.lruclock)
unsigned lru:22;
// 引用计数
int refcount;
// 指向对象的值
void *ptr;
} robj;
其中type、encoding、ptr3个属性分别表示:
type:redisObject的类型,字符串、列表、集合、有序集、哈希表
encoding:底层实现结构,字符串、整数、跳跃表、压缩列表等
ptr:实际指向保存值的数据结构
如果一个 redisObject 的 type 属性为 REDIS_LIST , encoding 属性为 REDIS_ENCODING_LINKEDLIST ,
那么这个对象就是一个 Redis 列表,它的值保存在一个双端链表内,而 ptr 指针就指向这个双端链表;
如果一个 redisObject 的 type 属性为 REDIS_HASH , encoding 属性为 REDIS_ENCODING_ZIPMAP ,
那么这个对象就是一个 Redis 哈希表,它的值保存在一个 zipmap 里,而 ptr 指针就指向这个 zipmap 。
下面这张图片中的REDIS_STRING/REDIS_LIST/REDIS_ZSET/REDIS_HASH/REDIS_SET针对的是redisObject中的type,
后面指向的REDIS_ENCODING_LINKEDLIST等针对的是encoding字段。

Redis的底层数据结构有以下几种:
简单动态字符串sds(Simple Dynamic String)
双端链表(LinkedList)
字典(Map)
跳跃表(SkipList)
下面针对五种数据类型,学习相关的底层数据结构。
2.String
如果一个String类型的value能够保存为整数,则将对应redisObject 对象的encoding修改为REDIS_ENCODING_INT,将对应robj对象的ptr值改为对应的数值。
如果不能转为整数,保持原有encoding为REDIS_ENCODING_RAW。
因此String类型的数据可能使用原始的字符串存储(实际为sds - Simple Dynamic Strings,对应encoding为REDIS_ENCODING_RAW)或者整数存储。
Redis可以直接查看对象的ENCODING值:
redis:6379> set strtest 1
OK
redis:6379> OBJECT ENCODING strtest
"int"
redis:6379> set strtest blog
OK
redis:6379> OBJECT ENCODING strtest
"raw"
3.List
列表的底层实现有2种:
REDIS_ENCODING_ZIPLIST
REDIS_ENCODING_LINKEDLIST
ZIPLIST相比LINKEDLIST可以节省内存,
当创建新的列表时,默认是使用压缩列表作为底层数据结构的。
Redis内部会对相关操作做判断,
当list的elem数小于配置值: hash-max-ziplist-entries 或者elem_value字符串的长度小于 hash-max-ziplist-value, 可以编码成 REDIS_ENCODING_ZIPLIST 类型存储,以节约内存;
但由于在zip list添加和删除元素会涉及到数据移动,
因此当list内容较多时,使用双向链表。
4.Hash
创建新的Hash类型时,默认也使用ziplist存储value,保存数据过多时,使用hast table。
5.Set
集合的底层实现也有两种:
REDIS_ENCODING_INTSET
REDIS_ENCODING_HT(字典)
创建Set类型的key-value时,如果value能够表示为整数,则使用intset类型保存value。
数据量大时,切换为使用hash table保存各个value。
6.Sorted Set
有序集合的底层实现也是2种:
REDIS_ENCODING_ZIPLIST
REDIS_ENCODING_SKIPLIST
关于Redis中的跳跃表,查看这篇文章:跳跃表
跳跃表在 Redis中的使用,就是实现有序集合数据类型。
应用版本Redis 2.6,
了解更多:Redis 数据类型
Redis不同数据类型的的数据结构实现的更多相关文章
- redis常用数据类型对应的数据结构
redis的数据类型都是通过多种数据结构来实现,主要是出于时间和空间的考虑,当数据量小的时候通过数组下标访问最快,占用内存最小[压缩列表是数组的变种,允许存储的数据大小不同] 因为数组需要占用连续的内 ...
- Redis基础(一)数据结构与数据类型
Redis数据结构 Redis一共有六种数据结构,分别是简单动态字符串.链表.字典.跳表.整数集合.压缩列表. 简单动态字符串(SDS) Redis只会使用C字符串作为字面量,在大多数情况下,Redi ...
- redis基本数据类型和对应的底层数据结构
Redis的数据类型包含string,list,hash,set,sorted set. Redis中定义了一个对象的结构体: /* * Redis 对象 */ typedef struct redi ...
- 说一下redis中5种数据类型的底层数据结构
前言: 阅读 redis设计与实现 一书的记录.未完待续... redis我们都知道有5种数据类型,分别是string,list,hash,set,zset,那么你知道它们的底层数据结构实现吗? ...
- Redis常用数据类型介绍、使用场景及其操作命令
Redis常用数据类型介绍.使用场景及其操作命令 本文章同时也在cpper.info发布. Redis目前支持5种数据类型,分别是: 1.String(字符串) 2.List(列表) 3.Hash(字 ...
- Redis笔记(三)Redis的数据类型
前面说过,Redis的一大特性是支持丰富的数据类型, 这为更多的应用场景提供了可能. Redis有五种数据类型,包括string,list,set,sorted set和hash,注意,Redis的数 ...
- Redis常用数据类型
Redis常用数据类型 转载自:http://blog.sina.com.cn/s/blog_7f37ddde0101021q.html Redis最为常用的数据类型主要有以下五种: ●Str ...
- Redis常用数据类型和事物以及并发
Redis数据类型 基本类型(String int): 如 set key value .get key 等 所有命令都是按照 key value keys * 可以将全部数据列出,其中后面的 &qu ...
- Redis系列(二):Redis的数据类型及命令操作
原文链接(转载请注明出处):Redis系列(二):Redis的数据类型及命令操作 Redis 中常用命令 Redis 官方的文档是英文版的,当然网上也有大量的中文翻译版,例如:Redis 命令参考.这 ...
随机推荐
- All Kind Of Conference(随时更新...)
收集一些前端开发的各种会议,里面有视频或者PPT,随时查看都还是很有收获的.还有要向这些演讲的前辈看齐- AC 2015:http://ac.alloyteam.com/2015/ AC 2016:h ...
- 项目:DoubleFaceCamera
代码在github: https://github.com/Viyu/DoubleFacedCamera 这个app的想法是:用手机的前置和后置摄像头同时拍摄画面合成输出一张图,把拍摄者和被拍摄者的画 ...
- python 类修饰器
1. 修改类函数. 场景: 如果要给一个类的所有方法加上计时,并打印出来.demo如下: # -*- coding:utf-8 -*- import time def time_it(fn): &qu ...
- Python核心编程这本书的一些错误
<Python核心编程第二版>这本书比<Python基础教程第二版修订版>详细很多,丰富了很多细节,虽然它是一本经典的入门书,但我发现还是存在一些明显的错误.在面向对象编程这一 ...
- Function接口 – Java8中java.util.function包下的函数式接口
Introduction to Functional Interfaces – A concept recreated in Java 8 Any java developer around the ...
- Oracle开发之窗口函数 rows between unbounded preceding and current row
目录=========================================1.窗口函数简介2.窗口函数示例-全统计3.窗口函数进阶-滚动统计(累积/均值)4.窗口函数进阶-根据时间范围统计 ...
- jQuery获取循环中的选中单选按钮radio的值
1.<input type="radio" name="testradio" value="jquery获取radio的值" /> ...
- 不知道数据库中表的列类型的前提下,使用JDBC正确的取出数据
概要: 使用jdbc 如果在不知道表结构的情况下,如何读出表信息? 使用ResultSetMetaData; 然后使用getColumnType 获取column 类型 使用getColumnName ...
- MySQL Got fatal error 1236原因和解决方法【转】
本文来自:http://blog.itpub.net/22664653/viewspace-1714269/ 一 前言 MySQL 的主从复制作为一项高可用特性,用于将主库的数据同步到从库,在维护主 ...
- JS 判断图片尺寸大小,以便页面resize时,动态调整页面元素位置
){ clearInterval(global_timename4pool); } } //由于无法判断图片显示完整的时机,只好用定时器来做,计算完成后再关掉定时器. global_timename4 ...