찾다

Redis源码解析3

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

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
MySQL은 다른 RDBM에 비해 동시성을 어떻게 처리합니까?MySQL은 다른 RDBM에 비해 동시성을 어떻게 처리합니까?Apr 29, 2025 am 12:44 AM

mysqlhandlesconcurrencyusingamixofrow-reveltable-levellocking, 주로 throughinnodb'srow-levellocking.comparedtootherrdbms, mysql 's trofficefice formanyusecasesbutmayfacechallengeswithdeadlocksandlacksadvancturespostpostgresql'sserializa

MySQL은 다른 관계형 데이터베이스에 비해 트랜잭션을 어떻게 처리합니까?MySQL은 다른 관계형 데이터베이스에 비해 트랜잭션을 어떻게 처리합니까?Apr 29, 2025 am 12:37 AM

mysqlhandlestransactionseffectialthicatied theinnodbengine, support-propertiessimilartopostgresqlandoracle.1) mysqlusesepeatablereadasthedefaultisolationlevel, itpoptormizestperformance와 함께

MySQL에서 사용 가능한 데이터 유형은 무엇입니까?MySQL에서 사용 가능한 데이터 유형은 무엇입니까?Apr 29, 2025 am 12:28 AM

MySQL 데이터 유형은 숫자, 날짜 및 시간, 문자열, 이진 및 공간 유형으로 나뉩니다. 올바른 유형을 선택하면 데이터베이스 성능 및 데이터 스토리지를 최적화 할 수 있습니다.

MySQL에서 효율적인 SQL 쿼리를 작성하기위한 모범 사례는 무엇입니까?MySQL에서 효율적인 SQL 쿼리를 작성하기위한 모범 사례는 무엇입니까?Apr 29, 2025 am 12:24 AM

모범 사례에는 다음이 포함됩니다. 1) 데이터 구조 및 MySQL 처리 방법 이해, 2) 적절한 인덱싱, 3) 선택을 피하십시오*, 4) 적절한 결합 유형 사용, 5)주의와 함께 하위 쿼리 사용, 6) 설명과 함께 쿼리 분석, 7) 서버 리소스에 대한 쿼리의 영향을 고려하십시오. 8) 데이터베이스를 정기적으로 유지하십시오. 이러한 관행은 MySQL 쿼리를 빠르게 만들뿐만 아니라 유지 보수, 확장 성 및 자원 효율성을 만들 수 있습니다.

MySQL은 PostgreSQL과 어떻게 다릅니 까?MySQL은 PostgreSQL과 어떻게 다릅니 까?Apr 29, 2025 am 12:23 AM

mysqlisbetterforspeedandsimplicity, 적절한 위장; postgresqlexcelsincmoMplexDatascenarioswithrobustFeat.MySqlisIdeAlforQuickProjectSandread-Heavytasks, whilepostgresqlisprefferredforapticationstrictaintetaintegritytetegritytetetaintetaintetaintegritytetaintegritytetaintegritytetainte

MySQL은 데이터 복제를 어떻게 처리합니까?MySQL은 데이터 복제를 어떻게 처리합니까?Apr 28, 2025 am 12:25 AM

MySQL은 비동기식, 반 동시성 및 그룹 복제의 세 가지 모드를 통해 데이터 복제를 처리합니다. 1) 비동기 복제 성능은 높지만 데이터가 손실 될 수 있습니다. 2) 반 동기화 복제는 데이터 보안을 향상 시키지만 대기 시간을 증가시킵니다. 3) 그룹 복제는 고 가용성 요구 사항에 적합한 다중 마스터 복제 및 장애 조치를 지원합니다.

설명 명세서를 사용하여 쿼리 성능을 분석 할 수있는 방법은 무엇입니까?설명 명세서를 사용하여 쿼리 성능을 분석 할 수있는 방법은 무엇입니까?Apr 28, 2025 am 12:24 AM

설명 설명은 SQL 쿼리 성능을 분석하고 개선하는 데 사용될 수 있습니다. 1. 쿼리 계획을 보려면 설명 명세서를 실행하십시오. 2. 출력 결과를 분석하고 액세스 유형, 인덱스 사용량 및 조인 순서에주의를 기울이십시오. 3. 분석 결과를 기반으로 인덱스 생성 또는 조정, 조인 작업을 최적화하며 전체 테이블 스캔을 피하여 쿼리 효율성을 향상시킵니다.

MySQL 데이터베이스를 어떻게 백업하고 복원합니까?MySQL 데이터베이스를 어떻게 백업하고 복원합니까?Apr 28, 2025 am 12:23 AM

논리 백업에 mysqldump를 사용하고 핫 백업을 위해 mysqlenterprisebackup을 사용하는 것은 mySQL 데이터베이스를 백업하는 효과적인 방법입니다. 1. MySQLDUMP를 사용하여 데이터베이스를 백업합니다 : MySQLDUMP-UROOT-PMYDATABASE> MYDATABASE_BACKUP.SQL. 2. Hot Backup : MySQLBackup- 사용자 = root-password = password-- backup-dir =/path/to/backupbackup에 mysqlenterprisebackup을 사용하십시오. 회복 할 때 해당 수명을 사용하십시오

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

SublimeText3 영어 버전

SublimeText3 영어 버전

권장 사항: Win 버전, 코드 프롬프트 지원!

SublimeText3 Linux 새 버전

SublimeText3 Linux 새 버전

SublimeText3 Linux 최신 버전

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Atom Editor Mac 버전 다운로드

Atom Editor Mac 버전 다운로드

가장 인기 있는 오픈 소스 편집기