redis之字符串命令源码解析(一)
redis之字符串命令源码解析(二)
前面已经将set get命令的原理与过程作了详细的解析,下面对一些常用的命令做一些简单讲解,前提是前面的已经明白。
1、append方法解析
t_string.c中的appendCommand方法:
void appendCommand(redisClient *c) { size_t totlen; robj *o, *append; // 取出键相应的值对象 o = lookupKeyWrite(c->db,c->argv[1]); // 如果键值对不存在 if (o == NULL) { // 键值对不存在,创建一个新的 c->argv[2] = tryObjectEncoding(c->argv[2]); dbAdd(c->db,c->argv[1],c->argv[2]); incrRefCount(c->argv[2]); //获取字符串对象中字符串值的长度 totlen = stringObjectLen(c->argv[2]); } else { // 键值对存在。。。 /* Key exists, check type */ // 检查类型 if (checkType(c,o,REDIS_STRING)) return; /* "append" is an argument, so always an sds */ // 检查追加操作之后,字符串的长度是否符合 Redis 的限制 append = c->argv[2]; totlen = stringObjectLen(o)+sdslen(append->ptr); //检查给定字符串长度 len 是否超过限制值 512 MB if (checkStringLength(c,totlen) != REDIS_OK) return; //解除key的共享,之后就可以进行修改操作(采用的方法是新建一个robj对象,覆盖掉原有的) o = dbUnshareStringValue(c->db,c->argv[1],o); //执行追加操作 o->ptr = sdscatlen(o->ptr,append->ptr,sdslen(append->ptr)); totlen = sdslen(o->ptr); } // 向数据库发送键被修改的信号 signalModifiedKey(c->db,c->argv[1]); // 发送事件通知 notifyKeyspaceEvent(REDIS_NOTIFY_STRING,"append",c->argv[1],c->db->id); // 将服务器设为脏 server.dirty++; // 发送回复(字符的长度) addReplyLongLong(c,totlen); }
大致可图解为:
2、incrby方法解析
void incrbyCommand(redisClient *c) { long long incr; //将第二个参数转化成long long类型,指向incr if (getLongLongFromObjectOrReply(c, c->argv[2], &incr, NULL) != REDIS_OK) return; incrDecrCommand(c,incr); }
void incrDecrCommand(redisClient *c, long long incr) { long long value, oldvalue; robj *o, *new; // 取出值对象 o = lookupKeyWrite(c->db,c->argv[1]); // 检查对象是否存在,以及类型是否正确 if (o != NULL && checkType(c,o,REDIS_STRING)) return; // 取出对象的整数值,并保存到 value 参数中 if (getLongLongFromObjectOrReply(c,o,&value,NULL) != REDIS_OK) return; // 检查加法操作执行之后值释放会溢出 // 如果是的话,就向客户端发送一个出错回复,并放弃设置操作 oldvalue = value; if ((incr < 0 && oldvalue < 0 && incr < (LLONG_MIN-oldvalue)) || (incr > 0 && oldvalue > 0 && incr > (LLONG_MAX-oldvalue))) { addReplyError(c,"increment or decrement would overflow"); return; } // 进行加法计算,并将值保存到新的值对象中 // 然后用新的值对象替换原来的值对象 value += incr; new = createStringObjectFromLongLong(value); if (o) dbOverwrite(c->db,c->argv[1],new); else dbAdd(c->db,c->argv[1],new); // 向数据库发送键被修改的信号 signalModifiedKey(c->db,c->argv[1]); // 发送事件通知 notifyKeyspaceEvent(REDIS_NOTIFY_STRING,"incrby",c->argv[1],c->db->id); // 将服务器设为脏 server.dirty++; // 返回回复 addReply(c,shared.colon); addReply(c,new); addReply(c,shared.crlf); }
大致可图解为:
这里说下“addReply(c,shared.colon);”这行代码,shared.colon是什么?
Redis 在内部使用了一个Flyweight 模式:通过预分配一些常见的值对象,并在多个数据结构之间共享这些对象,程序避免了重复分配的麻烦,也节约了一些CPU时间。redis.c的createSharedObjects创建了shared
shared.colon = createObject(REDIS_STRING,sdsnew(":"));由可见如果运行incrby test 3,如果test不存在,那么服务器返回的应该是":3\r\n",可以用telnet连接试试。
总体来看,Redis的结构设计得有许多巧妙之处,为实现字符串各种需求打下了很好的基础,后序还将剖析Redis相比memcache比较特殊的结构。
相关推荐
源码解析有助于深入理解其工作原理,提高在实际应用中的优化能力。本篇文章将聚焦Redis的源码,探讨其核心组件、数据结构以及内部运行机制。 1. **Redis的数据结构** Redis的核心数据结构包括字符串(String)、...
2. **丰富的数据结构**:Redis提供了多种数据结构,如字符串、哈希、列表、集合、有序集合,这些数据结构在处理各种复杂应用场景时非常实用。例如,哈希可用于存储对象,列表可以实现消息队列,有序集合则适用于排行...
Redis支持多种数据结构,如字符串、哈希表、列表、集合和有序集合。这些数据结构的实现是Redis高效性的关键。例如,链表、跳跃表(用于有序集合的快速查找)和压缩表(用于节省内存)等都是Redis内部的重要组件。 ...
Redis源码解析是一项深入学习数据库系统、内存管理以及并发控制等核心计算机科学概念的宝贵资源。 首先,我们来看Redis中的核心数据结构。Redis支持多种数据类型,包括字符串(String)、哈希表(Hash)、列表...
这通常涉及解析响应的类型(简单字符串、错误、整数、多条批量数据等)。例如,获取键的值: ```pascal var Response: string; begin RedisClient.SendCommand('GET', ['mykey']); if RedisClient.GetResponse...
它主要包含三种数据类型:简单的字符串(Simple Strings)、错误(Errors)、整数(Integers)、大整数(Bulk Strings)和多条数据(Multi-Bulk)。在易语言源码中,你会看到如何将这些数据类型转化为易语言的数据...
Redis使用多种自定义的数据结构来存储和操作数据,如字符串(String)、哈希表(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。这些数据结构在源码中都有对应的实现,例如` SDS (Simple Dynamic ...
1. 数据结构:Redis的核心在于其高效的数据结构,如字符串、哈希表、链表、集合和有序集合等,这些都是C++实现的。 2. 异步I/O:Redis采用单线程模型处理所有客户端请求,通过事件驱动的非阻塞I/O(epoll、kqueue等...
1. 键值对(Key-Value):Redis的核心存储结构,键是唯一的标识,值可以是多种类型,如字符串、哈希、列表、集合和有序集合。 2. 数据类型: - 字符串(String):最基础的类型,可存储整数、浮点数或任意文本。 ...
1. **数据结构**:Redis 的核心在于其高效的数据结构实现,如字符串(String)、哈希表(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。这些数据结构的实现通常采用内存优化的方式,如 SDS(Simple ...
源码的阅读可以帮助我们深入理解Redis如何处理数据结构(如字符串、哈希表、列表、集合、有序集合等)、命令执行、持久化机制(RDB和AOF)、网络I/O模型(基于epoll的事件驱动)以及复制和集群功能。 首先,Redis的...
同时,通过精心设计的数据结构(如哈希表、链表、跳跃表等)和编码方式(如SDS代替C字符串)来减少内存占用。 3. **命令执行原子性**:Redis的所有操作都是原子性的,即每个命令的执行不会被其他命令打断,保证了...
LabVIEW程序需要正确构建这些命令的字符串格式并发送到Redis服务器。 3. **数据序列化与反序列化**:由于LabVIEW是基于图形的,而Redis处理的是字符串,所以数据在两者之间传输时,需要进行序列化和反序列化。例如...
1. **Redis的数据结构**:Redis支持多种数据结构,如字符串(Strings)、哈希表(Hashes)、列表(Lists)、集合(Sets)和有序集合(Sorted Sets)。这些数据结构的设计使得Redis在处理复杂数据操作时非常高效。 2...
本文将深入探讨 Redis 的基础知识,包括其核心概念、数据类型、命令操作以及源码解析。 ### 1. Redis 核心概念 Redis 作为内存数据库,所有数据存储在内存中,通过持久化策略将数据保存到磁盘以防止数据丢失。其...
- **字符串(Strings)**:简单动态字符串(SDS)是Redis内部实现的字符串,提供预分配空间、长度计算等功能,比C语言的原始字符串更高效。 - **列表(Lists)**:可以使用quicklist或linked list实现,前者是优化...
Redis支持多种数据结构,如字符串(String)、哈希表(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。这些数据结构在源码中由不同的C结构体实现,例如`sds`用于表示字符串,`dict`表示哈希表,`list`...
- 源码中包含了Redis服务器的核心实现,如命令解析、数据结构操作、持久化、网络通信等。 - `redis.c`是主程序,负责初始化和事件循环。 - `server.h`和`server.c`定义了服务器状态和主要功能。 - `networking.c...
1. 字符串:Redis的基础数据类型,使用`sds`(Simple Dynamic Strings)实现,具备预分配空间和O(1)的修改操作。 2. 哈希表:用于存储键值对,采用开放寻址法解决冲突,源码在`dict.c`中。 3. 列表:支持双向链表,...