大家好,我是飛宇。
作為當今廣受歡迎的內存數據庫,Redis以其卓越的性能和廣泛的應用場景著稱。
掌握Redis技術幾乎成為每位開發人員、測試人員和運維人員的看家本領!
微信公眾號「碼哥跳動」(原「碼哥字節」,后改名為「碼哥跳動」)主理人碼哥持續輸出的Redis技術相關文章受到廣大讀者的喜愛,不少小伙伴都從中受益!
在大家的持續催更下,碼哥的這本《Redis高手心法》終于和大家見面了!

作者將復雜的概念與實際案例相結合,以簡潔、詼諧、幽默的方式揭示了Redis的精髓。
本書不僅是學習 Redis 的必備指南,更是駕馭 Redis 強大功能的秘籍。
無論你是初學者還是經驗豐富的開發者,都會在閱讀本書的過程中得到啟發與收獲。
如果你希望站在Redis的頂峰,那么《Redis高手心法》絕對是你不可或缺的利器!
千古無同局,葉底能否藏花,我們未來印證,愿此心法能讓你學有所成!
下面就讓碼哥帶我們一探本書的究竟,提前領略一下其中精彩紛呈的內容吧~~
文/碼哥
Chaya:碼哥,Redis 這么快,你咋就這么慢呢?從戀愛到生娃都沒你這么久。
寫書的難度可比寫公眾號文章大多了。公眾號的文章,可能有一些錯別字,也有可能存在語病。
編寫書的話,要求嚴格多了,語言要精準正確,不能存在錯別字和語病,內容需要循序漸進有層次感,還要經過出版社老師的多次審核、校正,每一段話和文字都是我們精心「雕刻」的成果。
此外,我經過多年對 Redis 的深耕,花了很多時間重新梳理了 Redis 技術架構,加入了 Redis 6.0 ~ 7.0 版本的各種全新特性,從更深層次的角度挖掘底層實現原理,并盡量用風趣幽默的語言和 158 張圖片解釋難懂的技術點。
作為后端開發者的我深刻知道,學習是一件比較難的事情,所以我就想著站在開發者的角度,用擬人化、場景化詼諧幽默的言語,再加撩人心弦又準確圖片讓讀者輕松愉快地學習 Redis 實現原理和開發實戰技巧。
總之一句話,每一個章節都經過反復推敲,只為呈現出最精彩的內容給你們。在我花費了大量精力更系統更全面地規劃,以及出版社老師不斷編排打磨,《Redis 高手心法》紙質書成為了去繁存簡,精益求精的作品,就好像從鋼鐵俠戰甲馬克1 號,進化到成功拿下滅霸一血的馬克 85 戰甲。
Chaya:網絡資料很多,但碎片化嚴重,如何才能成為 Redis 高手,建立完整的知識框架?
本書基于 Redis 7.0 版本的源碼來講解,并建立了一個完整的 Redis 知識框架,從全局視角整理 Redis 知識體系,結合難點給出158 張圖片,希望能讓你們更容易理解。
對于一門技術,如果只接觸了零散的技術點,沒有在腦海里建立?個完整的知識框架和架構體系,沒有系統觀,就會很吃力,而且會出現一看好像會,過后就忘記,?臉懵逼的情況。
我會引導大家從全局出發,帶著問題去尋找答案,嘗試輸出對一個技術點的思考和理解。

?起搭建?套完整的知識框架, 學會從全局視角整理整個知識體系。
本書的特點是 Redis 化身成人,將復雜的概念與實際案例相結合,以簡潔詼諧幽默的方式,為你揭示 Redis 的精髓。
從 Redis 作為第一人稱視角出發,以擬人故事化的方式和詼諧幽默的語言與各路“神仙”對話,配合 158 張圖片,由淺入深循序漸進地講解 Redis的數據結構實現原理。
現在新書上市,優惠力度特別大,原價 100,現在 5 折優惠,只需要 50 靈石,推薦大家趁著這個機會,趕緊沖一波,拍下《Redis 高手心法》 秘籍,早日修煉天階斗技。
由于篇幅有限,接下來我從書中摘取少量內容,給大家感受下文字和圖片的溫度......
天下武功,無堅不摧,唯快不破!我的名字叫 Redis,全稱是 Remote Dictionary Server。
Chaya:我知道你支持很多種數據類型,對于不同的數據類型,底層應該用了多種數據結構來實現存儲吧?
Chaya 小姐姐很聰明,我給開發者提供了 String(字符串)、Hashes(散列表)、Lists(列表)、Sets(無序集合)、SortedSets(可根據范圍查詢的排序集合)、Bitmap(位圖)、HyperLogLog、Geospatial(地理空間)和 Stream(流)等數據類型。
為了在速度和內存占用之間找到最優解,我設計了多種數據結構。總之為了實現多快好省(支持數據類型多、速度快、好用、節省內存)。

MySQL:“就拿 Sting 類型來舉例吧,C 語言本就有字符串,為嘛還自己搞了一套字符串類型,嚇唬誰呢?!”
格局能不能打開一點兒,我并沒有直接使用 C 語言的字符串,而是自己搞了一個 SDS 的結構體來表示字符串。
為了支持豐富和高性能的字符串操作函數、保存二進制格式數據、節省內存,以及實現“既 要又要還要”的目標。

SDS 中的 len 字段保存了字符串的長度,實現了 O(1) 時間復雜度獲取字符串長度。
SDS 結構有一個 flags 字段,表示的是 SDS 類型。實際上 SDS 一共設計了 5 種類型,分別是 sdshdr5、sdshdr8、sdshdr16、sdshdr32 和 sdshdr64,區別在于數組的len 長度和分配空間長度 alloc 不同。
struct?__attribute__?((__packed__))?sdshdr8?{
???uint8_t?len;
???uint8_t?alloc;
???unsigned?char?flags;
???char?buf[];
};
節省內存
之所以這么設計,是因為使用不同的 SDS 類型保存不同大小的字符串可以節省內存。
二進制格式數據安全
SDS 不僅可以存儲字符串類型數據,還能存儲二進制格式數據。SDS 并不是通過“\0” 來判斷字符串結束的,而是采用 len 標志結束,所以可以直接存儲二進制格式數據。
編碼格式
我還對字符串類型的數據采用了三種編碼格式來存儲,分別是 int、embstr 和 raw,你可使 用 OBJECT encoding key來查找對象所使用的編碼類型。
空間預分配
當對 SDS 進行縮短操作時,程序并不會回收多余的內存空間,如果后面需要 append 追 加操作,則直接使用 buf 數組 alloc -len 中未使用的空間。
通過惰性空間釋放策略,避免了減小字符串所需的內存重新分配操作。
篇幅有限,更多的底層數據結構實現原理詳見《Redis 高手心法》,不再一一列舉......
Chaya:Redis 數據保存在內存,如果沒有持久化,一旦斷電或者宕機,保存在內存中的數據將全部丟失,咋辦呢?
我有兩大撒手锏,可以實現數據持久化,做到宕機快速恢復,“不丟數據穩如山”,無須從數據庫中慢慢恢復數據。它們就是 RDB 快照和 AOF(Append Only File)。
MySQL:“在實際生產環境中,程序員通常會給你配置 6GB 的內存,將這么大的內存數據生成 RDB 快照文件落到磁盤的過程會持續比較長的時間。你如何做到在繼續處理寫命令請求的同時保證 RDB 與內存中的數據一致呢?”
作為唯快不破的 NoSQL 數據庫扛把子,我在對內存數據做快照時,并不會暫停寫操作(讀操作不會造成數據的不一致)。
我使用了操作系統的多進程寫時復制技術(Copy On Write ,COW)來實現快照持久化。

Chaya:“隨著寫入操作持續執行,AOF 日志過大怎么辦?文件越大,數據恢復就越慢。”
為了解決 AOF 文件體積膨脹的問題,創造我的 Antirez 老哥設計了 AOF 重寫機制(AOF Rewrite),對文件進行瘦身。
每次 AOF 重寫時,Redis 都會先執行內存復制操作,讓 bgrewriteaof 子進程擁有此時的 Redis 內存快照,子進程遍歷Redis 內存快照中的全部 field-value pairs,生成重寫記錄。

MySQL:在 AOF Rewrite 過程中,主進程除了把寫命令寫入 AOF 緩沖區,還要把寫命令寫入 AOF 重寫緩沖區。一份數據要寫入兩個緩沖區,還要寫入兩個 AOF 文件,產生兩次磁盤 I/O,太浪費了。
上述的 AOF Rewrite 操作是 Redis 7.0 之前的邏輯,俗話說得好,“只要思想不滑坡,辦法總比困難多”。為了解決性能問題,7.0 版本開始引入 Multi-Part AOF 機制。
篇幅有限,Multi-Part AOF 具體實現原理詳見《Redis 高手心法》,這里不在一一列舉。
Chaya:“有了 RDB 快照和 AOF 再也不怕宕機丟失數據了,但是 Redis 實例宕機了怎么辦?如何實現高可用呢?”
Chaya 愣了一會兒,又趕緊補充道:“依然記得那晚我和我的戀人鴛語輕傳,香風急促,走在成都的街頭約會。可是這時候 Redis 忽然宕機了,無法對外提供服務,電話連環 call,豈不是折煞人也“。
莫怕,為了你們的幸福。我提供了主從模式,通過主從復制,將一份冗余數據復制到其他 Redis 服務器,實現高可用。你們放心地說溫存,說風月。
Chaya:“master 和 slave 的同步是如何完成的呢?master 的數據是一次性傳給 slave,還是分批同步?主從正常運行期間又怎么同步呢?要是 master 和 slave 間的網絡斷連了,重新連接后數據還能保持一致嗎?”
你問題怎么這么多?不要急。我知道你想安心地與戀人相會,不受 Redis 宕機導致的服務報警的干擾。主從數據同步分為 4 種情況。
◎ master 和 slave 第一次全量同步。
◎ master 和 slave 正常運行期間的數據同步。
◎ master 和 slave 網絡斷開重連同步。
主從庫第一次復制過程大體可以分為 3 個階段:建立連接階段(準備階段)、同步數據階段、發送同步期間接收的新寫命令到 slave 階段。

主從復制架構面臨一個嚴峻問題:master 宕機,無法執行寫操作,無法自動選擇一個 slave 切換為 master,也就是無法實現故障自動切換。
Chaya 的戀人:“眼前是橡樹的綠葉,白色的竹籬笆。好想告訴我的她,這里像幅畫。一起手牽手么么噠(此處省略 10000 字)Redis 忽然宕機,我總不能把 Chaya 推開,停止甜蜜,然后打開電腦手工進行主從切換,再通知其他程序員把地址改成新master 的信息上線?”。
如此一折騰恐,想必你心里的雨傾盆地下,萬萬使不得。所以必須有一個高可用的方案,為此,我提供一個高可用方案——哨兵(sentinel)。
哨兵是 Redis 的一種運行模式,它專注于對 Redis 實例(master、slave)運行狀態的監控,并能夠在 master 發生故障時通過一系列的機制實現選主及主從切換,實現自動故障切換,確保整個Redis 系統的可用性。
你就可以安心地與你的戀人 Chaya 在歡樂港灣約會,盡情享受甜蜜,哪怕是吵架都那么醉人,不再需要擔心 Redis 忽然宕機帶來的煩惱。
我們先從全局看哨兵,簡要地了解它的整個運作流程,接著針對每個任務詳細分析,Redis 哨兵的主要職責如下。

Chaya:“來說下實現原理吧。”
篇幅有限,我就不繼續細說實現原理的細節了,現在新書上市,優惠力度很大,原價 100,現在 5 折優惠,各位道友只需拿出 50 靈石,購買查看完整版的《Redis 高手心法》進行修煉。
限時五折優惠,快快搶購吧!
感興趣的小伙伴可以點擊上面鏈接購買
贈書活動
點擊下方公眾號,回復 抽獎 二字即可參與抽獎,注意不是本號哈
如下所示
歡迎?在看丨留言丨分享至朋友圈?三連