1 概述

Redis为什么能支持每秒钟十万级的高并发?

  • 基于内存的存取方式
  • 高效的数据结构
  • 单线程,使用多路I/O复用模型,非阻塞IO

其中一个重要的原因,就是Redis中高效的数据结构,因此我们就专门的来研究下Redis的核心数据结构,Go!

2 五大基本数据结构

分别是String、List、Set、ZSet、Map

  • String类型:一个String类型的value最大可以存储512M

  • List类型:list的元素个数最多为2^32-1个,也就是4294967295个。

  • Set类型:元素个数最多为2^32-1个,也就是4294967295个。

  • Hash类型:键值对个数最多为2^32-1个,也就是4294967295个。

  • Sorted set类型:跟Sets类型相似,但是有序。

2.1 String

(1)使用

127.0.0.1:6379> set str hello
OK
127.0.0.1:6379> get str
"hello"

(2)原理


(3)源码

typedef char *sds;/* Sdshdr5从未被使用过,我们只是直接访问标记字节,在这里是为了记录类型5 SDS字符串的布局。*/
struct __attribute__ ((__packed__)) sdshdr5 {unsigned char flags; /* 3LSB的类型,5MSB的字符串长度   */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {uint8_t len; uint8_t alloc; /* 排除头和空结束符 */unsigned char flags; char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {uint16_t len; uint16_t alloc; unsigned char flags; char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {uint32_t len; uint32_t alloc; unsigned char flags; char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {uint64_t len;uint64_t alloc;unsigned char flags; char buf[];
};

2.2 List

(1)使用

127.0.0.1:6379> lpush items a b c
(integer) 3
127.0.0.1:6379> lrange items 1 10
1) "b"
2) "a"
127.0.0.1:6379> lrange items 0 10
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> lpush items d
(integer) 4
127.0.0.1:6379> lrange items 0 10
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379> lpop items
"d"
127.0.0.1:6379> lrange items 0 10
1) "c"
2) "b"
3) "a"

(2)原理

(3)源码

typedef struct listNode {struct listNode *prev; //头指针struct listNode *next; //尾指针void *value; //节点的值
} listNode;typedef struct listIter {listNode *next; int direction;
} listIter;typedef struct list {listNode *head;listNode *tail;void *(*dup)(void *ptr);void (*free)(void *ptr);int (*match)(void *ptr, void *key);unsigned long len;
} list;

2.3 Set

(1)使用

127.0.0.1:6379> sadd set_items a b c c d d
(integer) 4
127.0.0.1:6379> smembers set_items
1) "c"
2) "b"
3) "d"
4) "a"
127.0.0.1:6379> sadd set_items e
(integer) 1
127.0.0.1:6379> smembers set_items
1) "d"
2) "a"
3) "e"
4) "b"
5) "c"
127.0.0.1:6379>

(2)原理


(3)源码

typedef struct intset {uint32_t encoding;uint32_t length;int8_t contents[];
} intset;

2.4 ZSet

(1)使用

127.0.0.1:6379> zadd zset_items 1 a 2 c 3 b
(integer) 3
127.0.0.1:6379> zrange zset_items 0 10
1) "a"
2) "c"
3) "b"
127.0.0.1:6379> add 2 d
(error) ERR unknown command 'add'
127.0.0.1:6379> zadd zset_items 2 d
(integer) 1
127.0.0.1:6379> zrange zset_items 0 10
1) "a"
2) "c"
3) "d"
4) "b"

(2)原理

(3)源码

/* ZSET使用特殊版本的跳表 */
typedef struct zskiplistNode {sds ele;double score; struct zskiplistNode *backward;struct zskiplistLevel { // 跳表的层数struct zskiplistNode *forward;unsigned long span;} level[];
} zskiplistNode;typedef struct zskiplist {struct zskiplistNode *header, *tail; //头指针和尾指针unsigned long length;int level;
} zskiplist;typedef struct zset {dict *dict; //哈希表zskiplist *zsl; //跳表
} zset;

2.5 Map

(1)使用

127.0.0.1:6379> hmset map name zs age 12
OK
127.0.0.1:6379> hgetall map
1) "name"
2) "zs"
3) "age"
4) "12"
127.0.0.1:6379> hget map name
"zs"
127.0.0.1:6379> hmset map school zz
OK
127.0.0.1:6379> hgetall map
1) "name"
2) "zs"
3) "age"
4) "12"
5) "school"
6) "zz"
127.0.0.1:6379> hdel map age
(integer) 1
127.0.0.1:6379> hgetall map
1) "name"
2) "zs"
3) "school"
4) "zz"
127.0.0.1:6379>

(2)原理

(3)源码

typedef struct dictEntry {void *key;union {void *val;uint64_t u64;int64_t s64;double d;} v;struct dictEntry *next;
} dictEntry;typedef struct dictType {uint64_t (*hashFunction)(const void *key);void *(*keyDup)(void *privdata, const void *key);void *(*valDup)(void *privdata, const void *obj);int (*keyCompare)(void *privdata, const void *key1, const void *key2);void (*keyDestructor)(void *privdata, void *key);void (*valDestructor)(void *privdata, void *obj);
} dictType;/* 这是哈希表结构。 当我们实现增量重哈希时,每个字典都有两个这样的表,从旧表到新表。 */
typedef struct dictht {dictEntry **table;unsigned long size;unsigned long sizemask;unsigned long used;
} dictht;typedef struct dict {dictType *type;void *privdata;dictht ht[2];long rehashidx; unsigned long iterators; /* 当前运行的迭代器数量 */
} dict;

3 重点讲下跳表(SkipList)这个数据结构

3.1 图解

3.2 查找过程

深入Redis数据结构和底层原理相关推荐

  1. Redis的数据结构及底层原理

    一.Redis的两层数据结构简介 redis的性能高的原因之一是它每种数据结构都是经过专门设计的,并都有一种或多种数据结构来支持,依赖这些灵活的数据结构,来提升读取和写入的性能. 如果要了解redis ...

  2. 浅谈Redis五种数据结构的底层原理

    概念 Redis作为一个开源的用C编写的非关系型数据库,基于优秀的CRUD效率,常用于软件系统的缓存,其本身提供了以下五种数据格式: string:字符串 list:列表 hash:散列表 set:无 ...

  3. 广义表头尾链表存储结构_详解Redis五种数据结构的底层原理

    1,redis有五种基本数据结构:string.hash.set.zset.list:底层redis是通过c语言来实现这w五种结构的,具体是如何实现的,我们具体看一下. 2,SDS "sim ...

  4. Redis 数据结构的底层实现 (二) dict skiplist intset

    一.REDIS_INCODING_HT (dict字典,hashtable) dict是一个用于维护key和value映射关系的数据结构.redis的一个database中所有的key到value的映 ...

  5. redis scan 命令底层原理(为什么会重复扫描?)

    文章目录 前言 一.迭代器 1. 全遍历 2. 间断遍历 二.scan 扫描原理 1. 扫描算法: 2. 减少重复扫描? 2.1 扩容 2.2 缩容 3. 迭代过程中正在进行rehash 4. 完整的 ...

  6. long 转为string_面试必问 Redis数据结构底层原理String、List篇

    点击关注上方"Java大厂面试官",第一时间送达技术干货. 阅读文本大概需要 8 分钟. 前言 今天来整理学习下Redis有哪些常用数据结构,都是怎么使用的呢?首先看下全局存储结构 ...

  7. 面试精讲之面试考点及大厂真题 - 分布式专栏 08 Redis中有哪些数据结构及底层实现原理

    08 Redis中有哪些数据结构及底层实现原理 不经一翻彻骨寒,怎得梅花扑鼻香. --宋帆 引言 07小节面完了负载均衡,正向代理,反向代理,终于松了一口气,然后话题转向了缓存Redis,为什么是这个 ...

  8. Redis底层原理和数据结构-总结篇

    本文数据结构部分内容转自:SmartKeyerror 先了解数据结构,后看具体应用部分,本文着重应用部分的优缺点进行总结!数据结构部分仅仅做初步了解介绍,源码实现具体请参考如下目录自行学习,本文以6. ...

  9. Redis中五大数据结构的底层实现

    来自:DBAplus社群 作者介绍 田兆壮,新炬网络开发工程师.具备扎实的Java.Scala开发经验,熟练使用Python和Shell等脚本语言:具备前后端开发能力,熟练使用关系型数据库和非关系型数 ...

最新文章

  1. Dapps-是一个跨平台的应用服务商店
  2. ActivityManager
  3. static unsigned short,int ,char
  4. Linux用户和组管理,查看软件缓存,通过命令查看硬件信息(cpu,版本,序列号,内存,主板,内核等)
  5. 婚纱照嘴巴有点凸好p吗_丑拒80寸奢华大片挂床头,压箱底的婚纱照还能这样摆?...
  6. ios 按钮图片充满按钮_iOS有一些非常危险的按钮-UX评论
  7. Mybatis的批量更新 bug
  8. Allegro 导入ASC file的步骤
  9. python中int input_关于python:如何接受int和float类型的输入?
  10. Centos下磁盘管理
  11. SQL Server中删除重复数据的几个方法
  12. C++基础教程之函数重载,什么是C++函数重载?
  13. 几种Id生成策略方法
  14. 布谷鸟哈希函数的参数_布谷鸟算法详细讲解
  15. mac测试电池软件,BattMan(Mac电池监测软件) V1.6 Mac版
  16. 比较拼音的相似度,汉字纠错使用
  17. be 动词 、 一般动词的过去式
  18. Linux基础入门(详细教程)
  19. javacpp-opencv图像处理系列:国内车辆牌照检测识别系统(万份测试准确率79.7%以上)...
  20. 让老板虎躯一震的前端技术,KPI杀手

热门文章

  1. 背景图片与图片对盒子的影响
  2. 数学建模_国2000A——DNA序列问题中的数据处理
  3. oracle gbk ebcdic,文件编码 ANSI、GBK、GB2312、MS936、MS932、SJIS、Windows-31 、EUC-JP 、EBCDIC 等等之间的区别与联系...
  4. 常用又有趣的网站大合集
  5. 课堂在线录屏:EV录屏软件配置设置
  6. 推特开发者账号 获取推文的视频链接
  7. CountDownTimer 一步实现最简单的倒计时控件
  8. day2(sdasdasdasdasd)
  9. Delphi Web前端开发教程(9):基于TMS WEB Core框架
  10. 情商决定了工作方面的成就