全書主要分為三部分介紹Redis。第壹部分介紹Redis5中使用的數據結構,包括動態(tài)字符串、跳躍表、壓縮列表、字典、整數集合和快速鏈表,詳細介紹其基本結構及常見操作。第二部分為本書核心篇章,首先介紹了Redis5的啟動流程,命令解析流程,之后對Redis5中的命令實現進行了全面的介紹,包括鍵命令、字符串命令、哈希表命令、列表命令、集合及有序集合命令、地理位置相關的GEO命令、統計相關的HyperLogLog命令。第三部分,主要介紹了Redis5的一些特性及使用,包括事務、持久化、主從復制以及集群等。
多名專家聯袂推薦,資深專家聯合撰寫,深入理解Redis 5設計精髓
系統講解Redis 5設計、數據結構、底層命令實現,以及持久化、主從復制、集群
為什么要寫這本書
2年前,我們團隊建立了學習圈,團隊成員可以自愿參加,每天8∶50~10∶30到公司充電100分鐘,深入剖析工作中的技術棧,同時2017~2018年編寫出版了《PHP 7底層設計與源碼實現》一書,接著我們又深入研讀了Redis的源碼。2018年年初開始,我們開始了Redis源碼一書的編寫,起初是研讀Redis 4.0版本的源碼,2018年下半年5.0版本發(fā)布,增加了很多的新特性,下半年我們又在之前的基礎上結合Redis 5的源碼,編寫了此書。
Redis是一款高性能的開源key-value型數據庫,難能可貴的是代碼寫得非常優(yōu)雅,非常適合剛入門C語言的讀者閱讀。本書前半部分詳細介紹了Redis中的各種數據結構,適合讀者學習和掌握基本的數據結構;后半部分介紹了Redis命令執(zhí)行的生命周期,以及各類命令的源碼實現,希望使用Redis的讀者不止會使用Redis,并且能掌握它的原理和細節(jié),提升對Redis的掌控能力。
決定編寫Redis源碼一書后,學習圈里方波、黃桃、李樂、施洪寶、熊浩含、閆昌、張仕華、周生政和我一起編寫了這本書。大家在工作之外,每天寫到深夜,周末一起探討,經過一年的編寫和校對,終于完成了這本書。希望能給使用Redis的讀者一些啟發(fā),幫助更多的人理解Redis的實現。
讀者對象
使用Redis的工程師、架構師
對Redis源碼感興趣的讀者
有一定C語言基礎的讀者
如何閱讀本書
本書內容邏輯上分為三篇,共計22章內容。
第一篇:第1章簡單介紹了Redis,以及Redis的編譯安裝和研讀的方式;第2~8章重點講解了SDS、跳躍表、壓縮列表、字典、整數集合、quicklist和Stream數據結構的實現。
第二篇:第9章講解了Redis的生命周期,命令執(zhí)行的過程,需要重點閱讀;第10~19章,分別講解了鍵、字符串、散列表、鏈表、集合、有序集合、GEO、HyperLog和數據流相關命令的實現。
第三篇:第20~22章簡單講解了持久化、主從復制和集群的實現,沒有詳細展開,希望能帶讀者入門。
如果讀者是有一定經驗的資深開發(fā)人員,本書可能會是一本不錯的案頭書。當然,如果讀者是一名初學者,請在開始本書閱讀之前,建議先掌握一些C語言和網絡編程等基礎理論知識。
勘誤和支持
由于筆者的水平有限,編寫時間倉促,書中難免會出現一些錯誤或者不準確的地方,懇請讀者批評指正。如果您有更多的寶貴意見,歡迎訪問https://segmentfault.com/u/php7internal進行專題討論,我們會盡量在線上為讀者提供解答。同時,您也可以通過微博@PHP7內核,或者郵箱cltf@163.com聯系到我們,期待能夠得到您的反饋,在技術之路上互勉共進。
致謝
感謝張國輝、盧紅波兩位工作導師的支持,前者是我現在的領導,也是我在技術和管理方面的導師,后者是我在滴滴的領導,在技術和管理上給了我很多的指引與幫助。
感謝黑夜路人(謝華亮)兄弟的指導和支持,在技術上給了非常多的指點。
感謝黃健宏、黃鵬程、付磊、錢文品、張晉濤和吳建超兄弟的指導與建議,他們都是在Redis方面有很深研究的人。
感謝方波、黃桃、李樂、施洪寶、熊浩含、閆昌、張仕華和周生政8位兄弟在學習和研究過程中的陪伴與合作,本書是幾位兄弟共同合作的結晶。特別是黃桃,已經跟我一起編寫了兩本書。
特別致謝
最后,我要特別感謝我的太太夢云、兒子和女兒,我為寫作這本書,犧牲了很多陪伴她們的時間,但也正因為有了她們的付出與支持,我才能堅持寫下去。同時,感謝我的父母、岳父岳母,不遺余力地幫助我們照顧兒女,有了你們的幫助和支持,我才有時間和精力去完成寫作工作。
另外要特別感謝我團隊的兄弟們,感謝大家的堅持,為大家的成長點贊!重點感謝一下兄弟們背后的太太團,是她們的大力支持,作者們才有時間來編寫本書。
最后要重點感謝高婧雅編輯,這是第二次跟她合作,她依然非常負責;她耐心審稿,給出很多寶貴建議,才有了這本書的完成。
謹以此書獻給我最親愛的家人和團隊的兄弟們,以及眾多熱愛Redis的朋友們!
陳 雷
陳雷,好未來學而思網校增長研發(fā)負責人,清華與北京郵電大學碩士,曾在百度、騰訊和滴滴等公司工作,12年后端架構經驗。合著有《PHP7底層設計與源碼實現》。
方波,資深工程師,先后就職于360、百度、滴滴,設計并開發(fā)360消息系統Qbus、Nginx接入層、電商網站架構等分布式高并發(fā)系統。
黃桃,好未來學而思網校架構師,從事互聯網服務端研發(fā)與架構工作多年,熟悉PHP、Nginx、Redis等源碼實現,樂于學習與分享。合著有《PHP 7底層設計與源碼實現》。
李樂,好未來PHP工程師,西安電子科技大學碩士,樂于鉆研技術與源碼研究,對Redis和Nginx有較深理解。
施洪寶, 好未來后端研發(fā)工程師,東南大學碩士,對Redis、Nginx等開源軟件有較深的理解,熟悉C/C 開發(fā),對高并發(fā)、分布式有濃厚興趣,曾發(fā)表EI論文2篇,。
熊浩含,百度研發(fā)工程師、PHP開發(fā)者,對Redis等開源軟件有較深的研究。樂于鉆研技術難點,喜歡折騰,在學習思路上有很好的方法論。
閆昌,好未來后端軟件開發(fā)工程師,深耕信息安全領域多年,對Linux下服務端開發(fā)有較深見解,擅長高并發(fā)業(yè)務的實現。
張仕華,滴滴資深軟件開發(fā)工程師,熱衷于研究高并發(fā)場景下的架構設計及實現,熟悉Redis、Nginx和LevelDB等源碼,熱衷于探究技術本質。
周生政,滴滴后端高級工程師,多年LNMP技術棧開發(fā)經驗,曾任北京環(huán)球購物電商后端技術負責人。熱衷于Linux平臺效率工具, 熟悉Bash、Docker等自動化工具。
本書贊譽
序
前言
第1章 引言1
1.1 Redis簡介1
1.2 Redis 5.0的新特性2
1.3 Redis源碼概述3
1.4 Redis安裝與調試4
1.5 本章小結6
第2章 簡單動態(tài)字符串7
2.1 數據結構7
2.2 基本操作11
2.2.1 創(chuàng)建字符串11
2.2.2 釋放字符串12
2.2.3 拼接字符串12
2.2.4 其余API15
2.3 本章小結15
第3章 跳躍表17
3.1 簡介17
3.2 跳躍表節(jié)點與結構19
3.2.1 跳躍表節(jié)點19
3.2.2 跳躍表結構20
3.3 基本操作20
3.3.1 創(chuàng)建跳躍表21
3.3.2 插入節(jié)點22
3.3.3 刪除節(jié)點28
3.3.4 刪除跳躍表30
3.4 跳躍表的應用31
3.5 本章小結32
第4章 壓縮列表33
4.1 壓縮列表的存儲結構33
4.2 結構體35
4.3 基本操作37
4.3.1 創(chuàng)建壓縮列表37
4.3.2 插入元素38
4.3.3 刪除元素42
4.3.4 遍歷壓縮列表44
4.4 連鎖更新44
4.5 本章小結45
第5章 字典47
5.1 基本概念47
5.1.1 數組48
5.1.2 Hash函數49
5.1.3 Hash沖突51
5.2 Redis字典的實現52
5.3 基本操作55
5.3.1 字典初始化55
5.3.2 添加元素56
5.3.3 查找元素60
5.3.4 修改元素61
5.3.5 刪除元素61
5.4 字典的遍歷62
5.4.1 迭代器遍歷62
5.4.2 間斷遍歷65
5.5 API列表70
5.6 本章小結71
第6章 整數集合72
6.1 數據存儲72
6.2 基本操作75
6.2.1 查詢元素75
6.2.2 添加元素78
6.2.3 刪除元素82
6.2.4 常用API83
6.3 本章小結85
第7章 quicklist的實現86
7.1 quicklist簡介86
7.2 數據存儲87
7.3 數據壓縮91
7.3.1 壓縮92
7.3.2 解壓縮93
7.4 基本操作94
7.4.1 初始化94
7.4.2 添加元素95
7.4.3 刪除元素96
7.4.4 更改元素98
7.4.5 查找元素99
7.4.6 常用API100
7.5 本章小結101
第8章 Stream102
8.1 Stream簡介102
8.1.1 Stream底層結構listpack103
8.1.2 Stream底層結構Rax簡介104
8.1.3 Stream結構108
8.2 Stream底層結構listpack的實現112
8.2.1 初始化112
8.2.2 增刪改操作112
8.2.3 遍歷操作113
8.2.4 讀取元素113
8.3 Stream底層結構Rax的實現114
8.3.1 初始化114
8.3.2 查找元素114
8.3.3 添加元素116
8.3.4 刪除元素118
8.3.5 遍歷元素120
8.4 Stream結構的實現123
8.4.1 初始化124
8.4.2 添加元素124
8.4.3 刪除元素125
8.4.4 查找元素128
8.4.5 遍歷129
8.5 本章小結131
第9章 命令處理生命周期132
9.1 基本知識132
9.1.1 對象結構體robj132
9.1.2 客戶端結構體client136
9.1.3 服務端結構體redisServer138
9.1.4 命令結構體redisCommand139
9.1.5 事件處理141
9.2 server啟動過程149
9.2.1 server初始化149
9.2.2 啟動監(jiān)聽152
9.3 命令處理過程155
9.3.1 命令解析156
9.3.2 命令調用159
9.3.3 返回結果161
9.4 本章小結163
第10章 鍵相關命令的實現164
10.1 對象結構體和數據庫結構體回顧164
10.1.1 對象結構體redisObject164
10.1.2 數據庫結構體redisDb166
10.2 查看鍵信息166
10.2.1 查看鍵屬性166
10.2.2 查看鍵類型169
10.2.3 查看鍵過期時間170
10.3 設置鍵信息171
10.3.1 設置鍵過期時間171
10.3.2 刪除鍵過期時間172
10.3.3 重命名鍵173
10.3.4 修改鍵最后訪問173
10.4 查找鍵174
10.4.1 判斷鍵是否存在174
10.4.2 查找符合模式的鍵175
10.4.3 遍歷鍵176
10.4.4 隨機取鍵177
10.5 操作鍵178
10.5.1 刪除鍵178
10.5.2 序列化/反序列化鍵182
10.5.3 移動鍵183
10.5.4 鍵排序185
10.6 本章小結187
第11章 字符串相關命令的實現188
11.1 相關命令介紹188
11.2 設置字符串189
11.2.1 set命令189
11.2.2 mset命令195
11.3 修改字符串196
11.3.1 append命令196
11.3.2 setrange命令197
11.3.3 計數器命令197
11.4 字符串獲取199
11.4.1 get命令199
11.4.2 getset命令199
11.4.3 getrange命令199
11.4.4 strlen命令200
11.4.5 mget命令201
11.5 字符串位操作201
11.5.1 setbit命令201
11.5.2 getbit命令203
11.5.3 bitpos命令203
11.5.4 bitcount命令205
11.5.5 bitop命令208
11.5.6 bitfield命令209
11.6 本章小結212
第12章 散列表相關命令的實現213
12.1 簡介213
12.1.1 底層存儲213
12.1.2 底層存儲轉換215
12.1.3 接口說明215
12.2 設置命令216
12.3 讀取命令217
12.3.1 hexists命令218
12.3.2 hget/hmget命令218
12.3.3 hkeys/hvals/hgetall命令219
12.3.4 hlen命令220
12.3.5 hscan命令220
12.4 刪除命令221
12.5 自增命令222
12.6 本章小結224
第13章 列表相關命令的實現225
13.1 相關命令介紹225
13.1.1 命令列表225
13.1.2 棧和隊列命令列表226
13.2 push/pop相關命令228
13.2.1 push類命令的實現228
13.2.2 pop類命令的實現229
13.2.3 阻塞push/pop類命令的實現230
13.3 獲取列表數據234
13.3.1 獲取單個元素234
13.3.2 獲取多個元素235
13.3.3 獲取列表長度236
13.4 操作列表236
13.4.1 設置元素237
13.4.2 插入元素237
13.4.3 刪除元素238
13.4.4 裁剪列表239
13.5 本章小結240
第14章 集合相關命令的實現241
14.1 相關命令介紹241
14.2 集合運算254
14.2.1 交集254
14.2.2 并集258
14.2.3 差集260
14.3 本章小結263
第15章 有序集合相關命令的實現264
15.1 相關命令介紹264
15.2 基本操作272
15.2.1 添加成員272
15.2.2 刪除成員275
15.2.3 基數統計276
15.2.4 數量計算277
15.2.5 計數器279
15.2.6 獲取排名279
15.2.7 獲取分值279
15.2.8 遍歷280
15.3 批量操作280
15.3.1 范圍查找280
15.3.2 范圍刪除283
15.4 集合運算284
15.5 本章小結284
第16章 GEO相關命令285
16.1 基礎知識285
16.2 命令實現288
16.2.1 使用geoadd添加坐標288
16.2.2 計算坐標的geohash291
16.2.3 使用geopos查詢位置經緯度292
16.2.4 使用geodist計算兩點距離295
16.2.5 使用georadius/georadius-bymembe查詢范圍內元素295
16.3 本章小結297
第17章 HyperLogLog相關命令的實現298
17.1 基本原理298
17.1.1 算法演進299
17.1.2 線性計數算法299
17.1.3 對數計數算法300
17.1.4 自適應計數算法302
17.1.5 超對數計數算法302
17.2 HLL Redis實現302
17.2.1 HLL頭對象303
17.2.2 稀疏編碼304
17.2.3 密集編碼306
17.2.4 內部編碼308
17.2.5 編碼轉換309
17.3 命令實現310
17.3.1 添加基數310
17.3.2 近似基數311
17.3.3 合并基數313
17.4 本章小結314
第18章 數據流相關命令的實現315
18.1 相關命令介紹315
18.2 基本操作命令原理分析323
18.2.1 添加消息323
18.2.2 刪除消息325
18.2.3 范圍查找326
18.2.4 獲取隊列信息327
18.2.5 長度統計327
18.2.6 剪切消息328
18.3 分組命令原理分析328
18.3.1 分組管理328
18.3.2 消費消息330
18.3.3 響應消息331
18.3.4 獲取未響應消息列表331
18.3.5 修改指定未響應消息歸屬331
18.4 本章小結332
第19章 其他命令333
19.1 事務333
19.1.1 事務簡介333
19.1.2 事務命令實現334
19.2 發(fā)布-訂閱命令實現339
19.3 Lua腳本345
19.3.1 初始化Lua環(huán)境345
19.3.2 在Lua中調用Redis命令347
19.3.3 Redis和Lua數據類型轉換349
19.3.4 命令實現351
19.4 本章小結356
第20章 持久化357
20.1 RDB358
20.1.1 RDB執(zhí)行流程358
20.1.2 RDB文件結構359
20.2 AOF367
20.2.1 AOF執(zhí)行流程368
20.2.2 AOF重寫369
20.3 RDB與AOF相關配置指令372
20.4 本章小結374
第21章 主從復制375
21.1 主從復制功能實現375
21.2 主從復制源碼基礎378
21.3 slaver源碼分析382
21.4 master源碼分析388
21.5 本章小結391
第22章 哨兵和集群392
22.1 哨兵392
22.1.1 哨兵簡介393
22.1.2 代碼流程394
22.1.3 主從切換396
22.1.4 常用命令399
22.2 集群400
22.2.1 集群簡介401
22.2.2 代碼流程402
22.2.3 主從切換404
22.2.4 副本漂移406
22.2.5 分片遷移407
22.2.6 通信數據包類型409
22.3 本章小結415