搜尋
首頁資料庫mysql教程Redis源码解析3

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. 写时复制:变量改变会引发变量分离,导致复制一份新变量

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
MySQL中的存儲過程是什麼?MySQL中的存儲過程是什麼?May 01, 2025 am 12:27 AM

存儲過程是MySQL中的預編譯SQL語句集合,用於提高性能和簡化複雜操作。 1.提高性能:首次編譯後,後續調用無需重新編譯。 2.提高安全性:通過權限控制限制數據表訪問。 3.簡化複雜操作:將多條SQL語句組合,簡化應用層邏輯。

查詢緩存如何在MySQL中工作?查詢緩存如何在MySQL中工作?May 01, 2025 am 12:26 AM

MySQL查詢緩存的工作原理是通過存儲SELECT查詢的結果,當相同查詢再次執行時,直接返回緩存結果。 1)查詢緩存提高數據庫讀取性能,通過哈希值查找緩存結果。 2)配置簡單,在MySQL配置文件中設置query_cache_type和query_cache_size。 3)使用SQL_NO_CACHE關鍵字可以禁用特定查詢的緩存。 4)在高頻更新環境中,查詢緩存可能導致性能瓶頸,需通過監控和調整參數優化使用。

與其他關係數據庫相比,使用MySQL的優點是什麼?與其他關係數據庫相比,使用MySQL的優點是什麼?May 01, 2025 am 12:18 AM

MySQL被廣泛應用於各種項目中的原因包括:1.高性能與可擴展性,支持多種存儲引擎;2.易於使用和維護,配置簡單且工具豐富;3.豐富的生態系統,吸引大量社區和第三方工具支持;4.跨平台支持,適用於多種操作系統。

您如何處理MySQL中的數據庫升級?您如何處理MySQL中的數據庫升級?Apr 30, 2025 am 12:28 AM

MySQL數據庫升級的步驟包括:1.備份數據庫,2.停止當前MySQL服務,3.安裝新版本MySQL,4.啟動新版本MySQL服務,5.恢復數據庫。升級過程需注意兼容性問題,並可使用高級工具如PerconaToolkit進行測試和優化。

您可以使用MySQL的不同備份策略是什麼?您可以使用MySQL的不同備份策略是什麼?Apr 30, 2025 am 12:28 AM

MySQL備份策略包括邏輯備份、物理備份、增量備份、基於復制的備份和雲備份。 1.邏輯備份使用mysqldump導出數據庫結構和數據,適合小型數據庫和版本遷移。 2.物理備份通過複製數據文件,速度快且全面,但需數據庫一致性。 3.增量備份利用二進制日誌記錄變化,適用於大型數據庫。 4.基於復制的備份通過從服務器備份,減少對生產系統的影響。 5.雲備份如AmazonRDS提供自動化解決方案,但成本和控制需考慮。選擇策略時應考慮數據庫大小、停機容忍度、恢復時間和恢復點目標。

什麼是mySQL聚類?什麼是mySQL聚類?Apr 30, 2025 am 12:28 AM

MySQLclusteringenhancesdatabaserobustnessandscalabilitybydistributingdataacrossmultiplenodes.ItusestheNDBenginefordatareplicationandfaulttolerance,ensuringhighavailability.Setupinvolvesconfiguringmanagement,data,andSQLnodes,withcarefulmonitoringandpe

如何優化數據庫架構設計以在MySQL中的性能?如何優化數據庫架構設計以在MySQL中的性能?Apr 30, 2025 am 12:27 AM

在MySQL中優化數據庫模式設計可通過以下步驟提升性能:1.索引優化:在常用查詢列上創建索引,平衡查詢和插入更新的開銷。 2.表結構優化:通過規範化或反規範化減少數據冗餘,提高訪問效率。 3.數據類型選擇:使用合適的數據類型,如INT替代VARCHAR,減少存儲空間。 4.分區和分錶:對於大數據量,使用分區和分錶分散數據,提升查詢和維護效率。

您如何優化MySQL性能?您如何優化MySQL性能?Apr 30, 2025 am 12:26 AM

tooptimizemysqlperformance,lofterTheSeSteps:1)inasemproperIndexingTospeedUpqueries,2)使用ExplaintplaintoAnalyzeandoptimizequeryPerformance,3)ActiveServerConfigurationStersLikeTlikeTlikeTlikeIkeLikeIkeIkeLikeIkeLikeIkeLikeIkeLikeNodb_buffer_pool_sizizeandmax_connections,4)

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具