简介 本文主要是讲解Redis 6的ACL的实现原理。基本使用详见:Redis 6.0新特性——ACLs,以及Redis启动过程分析。 启动初始化 初始化默认用户 ACL子模块在Redis启动过程中初始化,下面代码主要是初始化ACL的结构: /* * 初始化ACL子系统 * */ void ACLInit(void) { Redis ACL配置信息主要有两种方式: 在redis.conf文件中通过user 配置项配置的ACL信息。 比如:user worker +@list +@connection ~jobs:* on >ffa9203c493aa99 在redis.conf中配置aclfile所配置的文件中。 格式如下图所示: 通过user方式 通过加载redis.conf配置文件中读取user配置项加载ACL信息。
简介 Redis服务器是典型的事件驱动程序,而事件又分为文件事件(socket的可读可写事件)与时间事件(定时任务)两大类。 有多个定时任务,因此理论上应该有多个时间事件,多个时间事件形成链表, timeEventHead即为时间事件链表头节点;Redis服务器需要阻塞等待文件事件的发生,进程阻塞之前会调用beforesleep Redis底层可以使用4种I/O多路复用模型(kqueue、epoll等), apidata是对这4种模型的进一步封装。 文件监听事件 Redis客户端通过TCP socket与服务端交互,文件事件指的就是socket的可读可写事件。socket读写操作有阻塞与非阻塞之分。 Redis创建时间事件节点的函数为aeCreateTimeEvent,内部实现非常简单,只是创建时间事件并添加到时间事件链表。
zipmap redis旧版小hash使用的数据结构,紧密数组存储结构 用1字节存储总节点数(如果1字节满了,代表需要遍历到底才知道有多少节点) 每个节点存储自己占用的内存空间,修改删除后,标记为闲置空间 adlist 环形双端链表,没啥好说的 dict 这里比较特别的是一个字典里会有最多两个hash表同时存在,目的是rehash的时候可以做渐进式hash table的结构是个数组,每个元素是一条链表,redis rehash 不在进行时,值为 -1 int rehashidx; /* rehashing not in progress if rehashidx == -1 */ } dict; scan算法 redis size/2) % size 比如size是8,缩容后就是4,所以对size为8的遍历就是 0->4 1->5 2->6 3->7 基于idx与idx + size/2这个公式得到的bucket 源码里把这用一个数学公式体现
# 源码-调试Redis 在阅读源码的时候,通过debug调试的方式逐行去理解代码的意思,不免是一个好的方式。 第一步: 在src目录下新建一个文件learn.h,在这里面定义入口 #ifndef REDIS_LEARN_H #define REDIS_LEARN_H int learn(); #endif = NULL) redis_check_rdb_main(argc,argv,NULL); else if (strstr(argv[0],"redis-check-aof") /* Check if we need to start in redis-check-rdb/aof mode. = NULL) redis_check_rdb_main(argc,argv,NULL); else if (strstr(argv[0],"redis-check-aof")
而redis的底层实现是十分简单的,核心源码也仅有几万行。本文就带大家来领略,小小的redis是如何实现这些复杂功能的。 *注:本文介绍的源码为redis 5.0.14版本 * 二、字符串 C语言存储字符串的问题: 二进制安全 C语言中表示字符串结尾的符号是'\0',如果字符串本身就具有'\0'字符,就会被截断,即非二进制安全 即多浪费了30%的空间,redis的跳表使用了较低的空间成本,实现了时间复杂度的大减少 3.3.3 插入节点 插入节点总的来说一共四步 查找插入位置 调整高度 插入节点 调整backward 源码如下 源码注解的例子。 工作中我们也常常使用redis进行各种逻辑的处理,而了解其源码可以避免踩很多坑。
bin的目录,里面包括了以下文件: redis-benchmark redis-check-aof redis-check-dump redis-cli redis-server redis-server :Redis服务器的daemon启动程序 redis-cli:Redis命令行操作工具。 redis #将报以下错误: redis服务不支持chkconfig #为此,我们需要更改redis脚本。 /redis/bin/redis-cli #将redis配置文件拷贝到/etc/redis/${REDISPORT}.conf mkdir /etc/redis cp /data/tgz/redis -3.0.7/redis.conf /etc/redis/6379.conf cp /data/tgz/redis-3.0.7/redis.conf /data/apps/redis/bin/redis.conf
entry的数量 ZIPLIST_LENGTH(zl) = 0; // 结束字节 zl[bytes-1] = ZIP_END; return zl; } resize的源码
简介 需要了解Redis命令执行过程,请先了解Redis启动过程和Redis事件监听。 Redis启动过程分析 Redis事件监听 在Redis事件监听中我们了解到在创建文件监听事件的时候 acceptTcpHandler就是的执行函数。 创建Redis连接。 listLength(server.ready_keys)) handleClientsBlockedOnKeys(); } return C_OK; } 命令表详见:《Redis
我们知道,Redis在解析命令行参数时,会将各个参数解析成robj类型,当expire值不为NULL则表示需要设置key的超时时间。 MAXMEMORY_FLAG_NO_SHARED_INTEGERS \ (MAXMEMORY_FLAG_LRU|MAXMEMORY_FLAG_LFU) #define OBJ_SHARED_INTEGERS 10000 第一种情况: 如果Redis Redis key的超时时间实际存储的是当前key的到期毫秒时间戳,所以在指定超时时间单位为秒时,需要将时间值乘以1000来转化为毫秒数,将当前时间加上超时毫秒数的结果就是key的超时毫秒时间戳。 Redis将所有含有超时时间的key存储到redisDb的expire字典内,ttl命令可以快速确定key的超时秒数,就是通过查找这个字典实现的。 通过以上4个步骤已经成功地将一个key-value设置到Redis的数据库中。
链表相关数据结构 在 Redis 的源码中,链表的数据结构和相关的操作都包含在 adlist.h 和 adlist.c 两个文件当中,这两个文件是 Redis 中对底层链表的所有实现。 对于 Redis 的 list(列表) 这种数据类型(这里说的是我们操作 Redis 时的 list 数据类型,此 list 非数据结构的 list,文中混用较多,请根据上下文理解),就是使用 链表 这种数据结构 无环链表 Redis 的链表是无环的双向链表,这点可以通过 Redis 插入头节点和插入尾节点的函数看出,两个函数代码如下: /** * 将值插入到链表的头部 */ list *listAddNodeHead 最后 上面就是关于 Redis 中链表实现的代码了。Redis 的链表会用在包括但不限于 list(列表)的场景,比如发布订阅、慢查询等也会使用列表的数据结构。 喝水不忘打井人,没有黄老师的书籍做我 Redis 学习的指路明灯,恐怕对于学习 Redis 的源码我会艰难万分。再次感谢黄老师写的关于 Redis 的书籍,能够让好的技术遍地开花。
大家都知道redis默认是16个db,但是这些db底层的设计结构是什么样的呢? 我们来简单的看一下源码,重要的字段都有所注释 typedef struct redisDb { dict *dict; /* The keyspace for this defrag_later; /* List of key names to attempt to defrag one by one, gradually. */ } redisDb; redis 中的所有kv都是存放在dict中的,dict类型在redis中非常重要。 防止链表无限增长*/ unsigned long iterators;/* number of iterators currently running 遍历记录的一些字段*/ } dict; redis
数据库已经有了key,它的值为value。当我们发现value值需要追加字符串却又不想直接用set命令覆盖原值时,可以用append命令来实现。
简介 最近在学习Redis源码,主要是目前负责华为产品FusionInsight HD中Redis组件的相关事务,不得不学习Redis源码。 本文主要讲述的是怎么通过vscode查看Redis的源码(Linux平台下面). "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/src/redis-server ", "args": [ "redis.conf" ], "stopAtEntry": true,
一、事务基础1 redis事务介绍 事务能够将多个操作作为一个整体来执行,具备ACID四大特性。原子性:redis主线程对字典空间进行操作,天生是原子的,不需要同步机制。 持久性:redis作为缓存是允许丢失数据的,我觉得不应该对持久性有过多的要求。另外redis也有rdb、aof来持久化数据。 redis事务期间是不能使用监视器的,待会儿源码中就能够看到。 图片1 multi/** * multi命令对应的源码 */void multiCommand(redisClient *c) { // 判断是否嵌套执行multi if(c->flags c->argv = NULL; c->argc = 0; c->argv_len_sum = 0; c->argv_len = 0;}3 exec/** * exec命令对应的源码
下载Redis源码:git clone https://github.com/redis/redis.git切换到指定的版本git checkout 7.0File => New CMake Project ,那就试试重新加载一下3 Redis源码阅读技巧3.1 Redis 的目录结构Redis 的目录:deps: Redis 所依赖的第三方代码库- hdr_histogram:用于生成命令的延迟追踪直方图 - modules:实现 Redis Module 的示例代码。- 其他文件均是源码test:测试代码- cluster,Redis Cluster 功能测试。- sentinel,哨兵集群功能测试。 utils:工具类Makefile:编译文件redis.conf : redis 启动的配置文件sentinel.conf:哨兵配置3.2 Redis 源码阅读顺序网上的源码阅读顺序(引自网上):自底向上 从大方向来说,学习 Redis 会有两种路径:先从数据机构入手,直接手撕数据结构- 好处:学着踏实,知根知底- 坏处:容易从入门到放弃先从启动 Redis 开始,跟着启动顺序读源码,跟着具体的操作读源码
简介 由于本人目前是华为FusionInsight HD 中Redis组件的Owner,所以要对Redis进行深入的了解,这对于C语言水平不咋地的我来讲还是有点难度的,于是我决定先从Redis的启动开始看 配置初始化 Redis服务启动首先做的第一步就是初始化配置。Redis初始化配置主要包括初始化命令表和加载配置两部分。 初始化ACL 权限信息 主要是通过加载redis.conf配置文件里面的配置信息,用于控制登录用户执行命令的权限,仔细详见:Redis 6 ACL源码详解 初始化命令表 在函数populateCommandTable ()/redis_check_aof_main()检查RDB/AOF文件的完整性。 这个设计就是以Redis启动时多消耗一些时间为代价,换取运行的更小的延迟。
文章目录 redis集群概述 客户端重定向 槽位迁移 redis cluster 的运行流程 redis集群概述 哨兵、主从、集群,一串下来。 redis cluster 主要作用如下(虽然是显而易见了): 数据分片,流量分发。 cluster 将不同的数据分发给不同的节点,不过没有使用一致性hash算法,而是引入了Hash槽位的概念。 所以本文的重心也就很明确了:redis集群是如何实现通信及数据分片、流量分发的 关于实操:【redis】闲得无聊,来聊聊当下爆火的 redis集群,顺便搭一个玩玩呗 客户端重定向 如果cluster中的某个节点收到客户端请求 the base case. */ if (error_code) *error_code = CLUSTER_REDIR_NONE; /* Modules can turn off Redis "writing" : "reading")); return; } redis cluster 的运行流程 这个启动过程我就不放代码了,和前面的主从、哨兵有很多相似之处。
与append命令一样,原key在Redis中不存在时,Redis会创建一个robj对象,并将robj先设置到数据库;当key在Redis中存在时,会要求原值必须为string类型,并且由于Redis的限制
我的目标定位,这个项目是资深程序猿阅读和理解redis源码最优质的中文材料。 我这个项目预期做到 源码+中文注释+系列博文 三位一体,全方位帮大家深入理解redis的原理。 另外github上我源码库不是redis的copy,而是直接fork出来的,所以会定期和redis当前源码保持一致,时更时新。 这里放上相关链接,欢迎关注 Redis中文注解版仓库:https://github.com/xindoo/redis Redis源码剖析专栏:https://blog.csdn.net/xindoo 基础 [ ] 初识Redis [ ] redis的日常使用 [ ] 搭建redis源码环境(单步调试) [ ] 了解redis的启动过程 各种数据结构 [ ] SDS(simple dynamic
如图11-1所示,二进制串“abc”在内存中是以011000010110001001100011来表示的,现在字符串第9比特位的值为1,如果想设置此值为0,需要经过以下步骤。