• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase
您的位置:首页 > 数据库 >Mysql > Redis源码解析3

Redis源码解析3

作者:匿名 字体:[增加 减小] 来源:互联网 时间:2018-12-05

匿名通过本文主要向大家介绍了Redis,源码,解析等相关知识,希望本文的分享对您有所帮助

Everything is Object 数据结构 在Redis中,用 robj 结构表示一切数据对象,可以把它看作一种元数据(MetaData) 各种不同的结构化数据,通过该对象进行封装、传递、变换、编码,而该对象本身却十分简单 其类型定义如下: 1 typedef struct redisObject { un

Everything is Object

数据结构

在Redis中,用 robj 结构表示一切数据对象,可以把它看作一种元数据(MetaData)
各种不同的结构化数据,通过该对象进行封装、传递、变换、编码,而该对象本身却十分简单

其类型定义如下:

1 typedef struct redisObject { unsigned storage:unsigned encoding:unsigned lru:refcount; } robj;

type字段表示数据类型,有以下几种定义:
REDIS_STRING // 字符串
REDIS_LIST // 链表
REDIS_SET // 集合
REDIS_ZSET // 有序集合
REDIS_HASH // HASH结构(注意,此处不同于传统意义上的哈希表(如stl::hash_map),这里的hash仅有字段散列的语义)
REDIS_VMPOINTER // VM指针(表示数据处于VM管理之下)

encoding字段表示数据编码方式,有以下几种定义:
REDIS_ENCODING_RAW // 原始编码,就是一个原始字符串
REDIS_ENCODING_INT // INT型编码,会将数字类型的字符串编码成该格式
REDIS_ENCODING_HT // 哈希表编码,源代码中以dict结构来管理
REDIS_ENCODING_ZIPMAP // 精简编码的hash结构,更省内存
REDIS_ENCODING_LINKEDLIST // 双向链表
REDIS_ENCODING_ZIPLIST // 精简编码的链表,更省内存
REDIS_ENCODING_INTSET // 精简编码的集合,更省内存
REDIS_ENCODING_SKIPLIST //

refcount字段是对象引用计数,每多一次引用,该计数加1;每减少一次引用,该计数减1,若减至0,则释放该对象内存

操作流程

Redis源代码中,有大量的robj指针在函数间传递
下面,以redis处理“set”命令为例,对 robj的操作进行讲解

1. 在 ProcessInlineBuffer、ProcessMultiBulkBUffer中,对命令缓存进行解析
通常是以空格为分隔符进行分离,每一个字符块都编码为一个独立的robj对象
对象存储在redisClient结构中的argc数组中,提供给后续函数使用
InlineBuffer:对应于Redis单行命令
MultiBulkBuffer:对应于多行命令

2. ProcessCommand对命令进行解析,然后进行函数分发
处理流程进入具体的命令处理函数

3. setCommand是对应于“set”命令的处理函数
该函数非常简单,网站空间,主要起到一个命令接入作用
它会对obj-val进行一次尝试性的编码转换,在本例中,会尝试将val对象转换为一个INT型的对象
转换完成后,进入内部共享函数setGenericCommand处理流程

4. setGenericCommand进行实际的“set”操作逻辑处理,即:
将kv键值对,加入到该连接对应的命名空间中(即一个dict结构)
对应于该dict结构,插入操作的具体语义由一个全局性的 dictType 进行定义:

1 dictType commandTableDictType = { NULL, NULL, dictSdsKeyCompare, dictSdsDestructor, dictRedisObjectDestructor };

根据这个操作定义,执行完比后
obj-key会复制一份原始字符串,将指针加入dict中(复制操作在dbAdd函数中实现)
obj-val直接将指针加入dict中,同时将该对象的refcount加1(加引用操作在setKey函数中实现)

5. 整个处理流程结束后,释放redisClient中的argc对象数组
在本例中,导致的结果是:
obj-key引用计数减1,最终值为0,导致对象删除
obj-val引用计数减1,最终值为1,该对象继续存在于全局key的dict表中

继续上一条“set”命令,针对更进一步的命令,对redis的对象编码转换作个初步了解
在下图中,主要注意 appendCommand中,由于该命令需要改变 obj-val对象的值,从而导致obj-val从INT编码状态解码到RAW编码状态。

解码时生成了临时对象 obj-decoded
临时对象与obj-append合并,将合并后的值赋给obj-val

引用计数 php中的变量

通过引用计数管理对象的生存期,是个好主意。通过上面两张图,也可以初步看出,redis如何通过引用计数来管理对象的生死
在很多动态类型的语言中,也有类似的做法
比如在PHP中,用以下结构表示变量:

1 struct _zval_struct { zend_uint refcount; zend_uchar type; zend_uchar is_ref; }; 7 typedef struct _zval_struct zval;

其中,value是一个 “zvalue_value” 类型的指针
zvalue_value是一个union类型的结构,将不同类型的数据整合进了同一个结构里

1 typedef union _zvalue_value { dval; { 5 char *val; 6 int len; HashTable *ht; zend_object_value obj; } zvalue_value;

可以看到,PHP中的变量有两种引用计数

1. refcount:直接引用计数,赋值时计数增加
2. is_ref:间接引用计数,赋引用时计数增加

之所以有这两个值,是因为PHP中的变量有引用的概念,香港虚拟主机,并且涉及到几个重要原则:

1. 赋值零拷贝:变量赋值时,不会复制一份新的变量,而是直接对zval结构加引用,且引用计数加在refcount变量上
但是,自定义类对象的赋值,和普通变量不同,默认是赋引用,导致计数加在is_ref上
我认为这是PHP语言设计上很混乱的一个地方

2. 写时复制:变量改变会引发变量分离,导致复制一份新变量

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 解析mysql 缓存如何使用内存
  • 基于MySQL Master Slave同步配置的操作详解
  • mysql中使用UDF自动同步memcached效率笔记
  • Redis是什么?有哪些应用场景?
  • Redis的事务操作的命令与执行操作(代码)
  • Redis与Memcached有何区别 ?redis和Memcached的区别比较
  • Redis中keys的通用操作(代码)
  • Redis中整数小集合
  • 黑马云课堂NoSQL之Redis技术视频源码课件分享
  • 燕十八redis视频资料下载(课件、源码)

相关文章

  • 2018-12-05MySQL和SQLServer的比较
  • 2017-05-11mysql外键(Foreign Key)介绍和创建外键的方法
  • 2018-12-05myeclipse连接MySQL数据库详细步骤
  • 2017-05-11MySQL数据库开启、关闭、查看函数功能的方法
  • 2017-05-11基于SQL中SET与SELECT赋值的区别详解
  • 2018-12-05sql 修改表的所有者
  • 2018-12-05SQLSERVER 中datetime 和 smalldatetime类型分析说明
  • 2017-05-11查看 MySQL 已经运行多长时间的方法
  • 2018-12-05memcached 和 mysql 主从环境下php开发代码详解
  • 2018-12-05SQL语句去掉重复记录,获取重复记录实例代码

文章分类

  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase

最近更新的内容

    • mysql5.7.17安装教程附MySQL服务无法启动的解决方法(图文)
    • 分享五个著名的SQL注入漏洞扫描工具
    • MySQL安装图文详解
    • Centos下Mysql安装图文教程_MySQL
    • Mysql如何避免全表扫描的方法
    • mysql自动增量备份的实例方法(本地备份与远程备份)
    • 详细介绍mysql5.7.17 winx64安装配置教程(图)
    • SQL中关于distinct关键字的四种用法
    • 将数据插入到MySQL表中的详细教程
    • 用Oracle9ias开发无线应用程序开发者网络Oracle

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有