定义 adlist.h typedef struct listNode{ struct listNode *prev; struct listNode *next; void *value; } 可以看出,redis的链表是一个双向链表,拥有前驱和后继,数据域为void型指针,意味着数据域可以指向需要的类型。 管理链表 adlist.h typedef struct list{ listNode *head; listNode *tail; unsigned long len; //节点复制函数 void *(*dup)(void *ptr); //节点释放函数 void (*free)(void *ptr); //节点比较函数 int (*match)(void *ptr,void *key); } 容易看出,为了管理链表,redis定义了一个结构体,会去存储链表头、尾、和长度。这样的好处在于求链表长度时间复杂度为O(1),而且便于 继续阅读 >>


李余通 17/12/24 20:31:44
源码分析章节,我尽量使用原生的redis源码,不去看黄建宏的注释,提高自己阅读源码的能力,此外,redis版本还是3.0 源码下载,大家可以到这 http://download.redis.io/releases/ sdsnew typedef char *sds; sds sdsnewlen(const void *init, size_t initlen) { struct sdshdr *sh; //分配内存 if (init) { sh = zmalloc(sizeof(struct sdshdr)+initlen+1); } else { sh = zcalloc(sizeof(struct sdshdr)+initlen+1); } //分配失败返回NULL if (sh == NULL) return NULL; sh->len = initlen; sh->free = 0;//这里可以看到sds初始是 继续阅读 >>


李余通 17/12/19 22:48:51
本系列所有文章基于《Redis设计与实现》学习而做的随笔,以后不再赘述 c语言的字符串 首先,我们都知道,Redis是用c语言实现的,而c语言,有个很大的弊端,那就是没有原生的字符串,字符串,是使用字符数组实现的。 基于这个原因,我们可以分析一下c字符串的缺点。 1. 字符串的拼接需要提前判断空间是否足够,否则可能造成缓冲区溢出。此外还必须进行malloc分配内存占用大量系统资源。 2. 字符串缩短时需要释放空间,否则可能造成内存泄漏。 那么,Redis的第一个要解决的就是实现一个高效的字符串 Redis的SDS 简单动态字符串(simple dynamic string,SDS)的定义如下: struct sdshdr{ int len; //记录buf中字符串的长度(strlen) int free; //记录buf中未使用的空间大小; char buf[]; //保存字符串的数组 } 举个例子: buf 申请了10个sizeof(char)的空间,保存的内容是"Redis" 那么 继续阅读 >>


李余通 17/12/18 22:56:14
背景 最近在学习restful api的开发,遇到这样的问题,书上使用itsdangerous生成token,但是同一个用户可以短时间内生成多个token,而这些token在有效期内都是可以使用的。现在就是要实现的需求是仅最新的token有效。老的token失效。 说明 假设一共开发了三种客户端:WEB,ANDROID,IOS,同一种客户端的token只保存最新的一份。 思路 使用数据库保存token,每次生成token时仅需更新token,验证时候先验证token是否有效,再去数据库查找是否是最新的token。 设计 数据库使用redis,提高查询速率。 现在需要确定使用hash还是k-v更好一些。 存法: hash: token:uid{ WEB:tokenweb, ANDROID:tokenandroid, IPHONE:tokeniphone, } k-v: token:uid:WEB:tokenweb token:uid:ANDROID:tokenandroid token:uid:IPHONE:toke 继续阅读 >>


李余通 17/12/04 17:03:36
源码版本:4.0.1 源码位置: intset.h:数据结构的定义 intset.c:创建、增删等操作实现 1. 整数集合简介 intset是Redis内存数据结构之一,和之前的 sds、 skiplist、dict、adlist 等通用数据相比,它是Redis特有的,用来实现Redis的Set结构(当元素较小且为数字类型时),它的特点有: 元素类型只能为数字。 元素有三种类型:int16_t、int32_t、int64_t。 元素有序,不可重复。 intset和sds一样,内存连续,就像数组一样。 2. 数据结构定义 typedef struct intset { uint32_t encoding; // 编码类型 int16_t、int32_t、int64_t uint32_t length; // 长度 最大长度:2^32 int8_t contents[]; // 柔性数组 } intset; 3. 创建、插入(扩缩容)、查找(二分查找)、删除 以下面这个例子来看下ints 继续阅读 >>


杨博东 17/11/30 00:52:45
1. 什么是守护进程 守护进程daemon,是指没有控制终端,运行在后台的进程,通常伴随着系统启动产生,系统关机结束。可以使用命令ps -axj查看系统的守护进程,输出如下所示: 父ID PID 组ID 会话ID 终端 状态 用户ID 命令 PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 0 1 1 1 ? -1 Ss 0 0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 21 0 2 0 0 ? -1 S 0 0:00 [kthreadd] 2 3 0 0 ? -1 S 0 0:00 [ksoftirqd/0] 说明: 1 继续阅读 >>


杨博东 17/11/28 01:12:09
1 调研目的 主要的目的是想调研各大云平台有关Redis监控功能的实现,但是最后我发现各大云平台提供的监控功能都比较基础,比如我想看诸如访问频率较高的HotKey、占用内存较大的Bigkey等指标,它们都没有提供,一部分Redis监控的开源工具实现了这样的功能,但是实现方法实用性不大,见后文汇总。 2 调研情况 2.1 常见公有云平台监控 我所调研的阿里云、腾讯云、青云这三个平台给用户提供的监控信息均是采用Redis Info命令获取的,他们中有的再次对Redis Info的信息做了一些处理,比如阿里云对INFO Commandstats做了排序,提供了TOP Command的信息,但是他们并没有对服务端做改造或者通过其他的方式获取监控信息,因此也没有提供诸如访问频率较高的HotKey、占用内存较大的Bigkey的指标。 阿里云的监控页面: 腾讯云的监控页面: 青云的监控页面: 2.2 开源的Redis监控工具 有一些开源工具提供了类似的监控指标,汇总如下: RedisLive:提供了Top 继续阅读 >>


杨博东 17/11/15 22:12:22
一、介绍相关 说Redis : 介绍Redis特性,使用场景,使用Jedis操作Redis等。 二、源码分析 1. 数据结构 Redis源码分析(sds):Redis自己封装的C语言字符串类型。 Redis源码分析(dict):字典的实现,Hash表。 Redis源码分析(adlist):Redis中的双向链表。 Redis源码分析(skiplist) :Redis 中的跳跃表,平均O(log n)的查询效率。 2. 内存编码数据结构 3. 数据类型实现 4. 数据库实现相关 5. 客户端和服务器的相关代码 Redis网络库源码分析(1)之介绍篇 : Redis自己实现的单线程IO多路复用网络库分析(1) Redis网络库源码分析(2)之启动服务器: Redis自己实现的单线程IO多路复用网络库分析(2) Redis网络库源码分析(3)之ae.c: Redis自己实现的单线程IO多路复用网络库分析(3) 三、其他 Redis INFO CPU 信息详解:关于INFO CPU显示的CPU信息解释。 Sha 继续阅读 >>


杨博东 17/11/14 13:08:51
源码版本: redis-4.0.1 源码位置: server.h :zskiplistNode和zskiplist的数据结构定义。 t_zset.c: 以zsl开头的函数是SkipList相关的操作函数。 一、跳跃表简介 跳跃表(SkipList),其实也是解决查找问题的一种数据结构,但是它既不属于平衡树结构,也不属于Hash结构,它的特点是元素是有序的。有关于跳跃表的更多解释,大家可以参考 张铁蕾老师 - Redis内部数据结构详解(6)——skiplist 中有关跳跃表的描述部分,我接下来主要分析有关于Redis跳跃表本身的代码部分,Redis作者antirez提到Redis中的实现的跳跃表与一般跳跃表相比具有以下三个特点: a) this implementation allows for repeated scores. // 允许分值重复 b) the comparison is not just by key (our ‘score’) but by satellite data. //对比的时候不仅比较分值还比较对象 继续阅读 >>


杨博东 17/11/13 19:47:20
引子 人在桌前坐,bug天上来。昨天早上到了小组,正准备总结一下爬山之旅,东哥就给我发了一个bug,让我也帮忙瞅瞅。。。 bug描述 是一个使用Redis跳跃表的demo,可以参照 东哥在RedisDB上的求助贴 东哥在StackOverFlow上的提问 这个关于Redis的demo如下 zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank) { zskiplistNode *x; unsigned long traversed = 0; int i; x = zsl->header; for (i = zsl->level-1; i >= 0; i--) { while (x->level[i].forward && (traversed + x->level[i].span) <= rank) { travers 继续阅读 >>


康艺杰 17/11/13 12:01:53