📚?前言
🌟🌟🌟精彩導讀
本次我們將全面剖析Redis的核心技術要點,包括其豐富的數據類型體系、高效的編碼方式以及秒級響應的性能奧秘。對于渴望深入理解Redis底層機制的技術愛好者,這是一次難得的學習機會!
🔍 推薦擴展閱讀
想了解更多數據庫技術干貨?歡迎訪問小編的CSDN技術博客: 👉?GGBondlctrl-CSDN博客主頁?👈 (持續更新分布式系統、中間件等深度技術文章)
💖 讀者互動
您的每一個👍點贊、?收藏和??評論,都是我們持續輸出優質技術內容的強大動力!期待在評論區看到您的見解~
目錄
📚?前言
📚?1. 數據結構
📚?2.內部的編碼方式
🚀2.1String類型
🚀2.2hash類型
?🚀2.3list類型
🚀?2.4set類型
🚀2.5zset類型
📚?3.redis的工作過程
🚀3.1單線程模型
🚀3.2redis效率
📚?4.總結
📚?1. 數據結構
可以發現,這里的數據結構即我們之前學習的數據結構,但是redis在底層上實現上述的數據結構時候,會進行特定的優化,達到節省空間時間的效果;
所以在內部的具體的實現的數據結構(編碼方式)就會存在變化
在hash表中,redis在進行插入,查詢時間復雜度就是1,但是背后的實現不一定就是哈希表(使用別的數據結構實現),但是保證時間復雜度為O(1)
📚?2.內部的編碼方式
?具體的編碼方式如下圖所示:
數據結構 | 內部編碼 |
---|---|
??string?? | raw |
int | |
embstr | |
??hash?? | hashtable |
ziplist | |
??list?? | linkedlist |
ziplist | |
??set?? | hashtable |
intset | |
??zset?? | skiplist |
ziplist |
再附一張文本格式的表格;
此設計體現了 Redis ??空間與時間的平衡藝術??:通過編碼自動升級機制,在數據量增長時無縫切換數據結構,兼顧內存效率與操作性能。
🚀2.1String類型
這里涉及:raw,embstr,int
raw:最基本的字符串,長字符串的原始編碼,在大于39字節的字符串,使用raw
embstr:小于等于39字節的字符串,適用比較短的字符串,針對短字符進行的特殊的優化
int:8個字節的長整型,類似與java的long
?這里我們可以舉個例子:
set key 1
object encoding key
可以發現此時我們的value雖然是string類型,但是它的內部編碼的方式就是int
其他兩個編碼方式如下所示:
這里注意了,當我們的整數過長,那么編碼方式就會變成我們的raw的編碼格式
當我們的字符串長度不是很長的情況下,就是embstr的編碼方式~~~~
🚀2.2hash類型
這里涉及:hashtable,ziplist
hashtable:最基本的哈希表(reds內部的哈希表的實現)
ziplist:壓縮列表,在特定情況下節省空間(在哈希表里的元素比較少的時候,優化成ziplist)
設置哈希表命令:
HSET zhangsan field 11 lisi field 12 wangwu field 13注意:key field value的形式
Redis 7.0 用 ??listpack
?? 全面替代?ziplist
?作為緊湊型數據結構,圖中哈希鍵?zhangsan
?滿足壓縮條件,因此展示為?listpack
?而非?ziplist
?或?hashtable
。?
特性 | ziplist (舊版) | listpack (Redis 7.0+) |
---|---|---|
??數據更新?? | 可能觸發級聯內存重分配 | 獨立節點更新,無連鎖反應 |
??查詢效率?? | O(n) 遍歷 | O(n) 但常數項更低 |
??內存布局?? | 前項指針導致反向遍歷困難 | 自包含節點(含本節點長度) |
??最大元素數?? | hash-max-ziplist-entries=512 | hash-max-listpack-entries=512 |
??單元素最大長度?? | hash-max-ziplist-value=64 | hash-max-listpack-value=64 |
??安全性?? | 級聯更新可能引發性能波動 | 無級聯風險 |
如果此時key特別多,hash對應也特別多,那么每個hash不大的情況下,盡量去壓縮后,讓整體的占用的內存更小;
為啥不用hashtable?
數據量過小(僅3個字段),使用?hashtable
?會造成:
- ??內存浪費??:哈希表需預分配桶空間 + 指針開銷
- ??CPU效率低??:計算哈希值的時間遠高于直接遍歷小數據集
?🚀2.3list類型
涉及的類型所示:linkedlist,ziplist
linkedlist:鏈表,占用空間大,執行效率高
ziplist:壓縮列表,在特定情況下節省空間(在哈希表里的元素比較少的時候,優化成ziplist)
但是從redis中3.2開始,應投入了新的實現方式,quicklist兼顧了linkedList與ziplist
quicklist就是一個鏈表,每個元素又是一個ziplist把空間和效率都兼顧到
lpush key4 1 2 3 4object encoding key4
執行結果如下圖所示:?
?
🚀?2.4set類型
涉及的類型:hashtable,intset
hashtable:最基本的哈希表(reds內部的哈希表的實現)
intset:如果集合中都是整數,優化為intset
🚀2.5zset類型
涉及的編碼類型:skiplist,ziplist
skiplist:跳表也是鏈表,每個節點上有很多個指針域,巧妙的搭配這些指針域的指向,可以做到從跳表上查詢元素的時間復雜度是O(logN)
ziplist:壓縮列表,在特定情況下節省空間(在哈希表里的元素比較少的時候,優化成ziplist)
📚?3.redis的工作過程
🚀3.1單線程模型
redis只使用一個線程來處理所有的命令請求;但是不是說redis服務器進程內部只有一個線程,當然還包括多線線程來處理我們的網絡IO(redis是一個客戶端服務器結構的程序)
注意:在多個請求同時到達我們的redis服務器,也是在隊列中進行排隊,等待redis從隊列中一個一個取出來再執行,redis是串行來執行這些命令的
為什么redis可以使用單線程模型???
redis能夠使用單線程模型,很好工作;主要原因是redis是核心業務邏輯,短平快;不消耗CPU資源,不吃多核!!!
弊端:某個時間操作占用過長,就會阻塞其他命令
🚀3.2redis效率
注意:這里的快,是在明確的對比上來說的;
1.redis是訪問內存的,數據庫訪問硬盤
2.redis核心功能,比數據庫的核心功能更簡單
3.單線程模型,避免了一些不必要的線程競爭開銷
4.處理網絡IO時候,使用了epoll這樣的IO多路復用機制(一個線程,可以管理多個socket)針對TCP來說,服務器每次要服務一個客戶端,都需要給這個客戶端安排一個socket進行通信
但是,這些socket都在無時無刻都在傳輸數據嗎?
當然不是的,?很多情況下,每個客戶端和服務器之間的通信沒有那么頻繁此時大多數socket大部分時間都是靜默的,沒有數據進行傳輸
注意:epoll的IO多路復用機制的前提是交互不頻繁,大部分時間都在等待?
📚?4.總結
Redis核心技術解析:本文深入剖析Redis的高效實現機制。首先介紹Redis如何優化基礎數據結構,通過靈活編碼(如string類型采用raw/embstr/int編碼)實現時空平衡;其次詳解各數據類型(hash/list/set/zset)的底層實現,如ziplist/listpack等壓縮結構在小數據量時的空間優化;然后解析Redis單線程模型的工作機制及其高效原因(內存操作、IO多路復用);最后指出Redis在核心業務上的"短平快"特性是其高性能關鍵。文章通過具體命令示例和編碼轉換條件,展現了Redis精巧的內部設計哲學。
🌅🌅🌅~~~~最后希望與諸君共勉,共同進步!!!
💪💪💪以上就是本期內容了, 感興趣的話,就關注小編吧。
? ? ?? 😊😊??期待你的關注~~~