Redis實現了不定長壓縮前綴的radix tree,用在集羣模式下存儲slot對應的的全部key信息。本文將詳述在Redis中如何實現radix tree。數據庫
raxNode是radix tree的核心數據結構,其結構體以下代碼所示:性能優化
typedef struct raxNode { uint32_t iskey:1; uint32_t isnull:1; uint32_t iscompr:1; uint32_t size:29; unsigned char data[]; } raxNode;
iskey:表示這個節點是否包含key數據結構
data:存儲子節點的信息架構
[header strlen=0][abc][a-ptr][b-ptr][c-ptr](value-ptr?)
,有size個字符,緊跟着是size個指針,指向每一個字符對應的下一個節點。size個字符之間互相沒有路徑聯繫。[header strlen=3][xyz][z-ptr](value-ptr?)
,只有一個指針,指向下一個節點。size個字符是壓縮字符片斷如下用幾個示例來詳解rax tree插入的流程。假設j是遍歷已有節點的遊標,i是遍歷新增節點的遊標。分佈式
z-ptr指向的葉子節點iskey=1,使用了壓縮前綴。性能
從abcd父節點的每一個壓縮前綴字符比較,遍歷完全部abcd節點後指向了其空子節點,j = 0, i < len(abcded)。
查找到abcd的空子節點,直接將ef賦值到子節點上,成爲abcd的子節點。ef節點被標記爲iskey=1,用來標識abcd這個key。ef節點下再建立一個空子節點,iskey=1來表示abcdef這個key。優化
ab在abcd能找到前兩位的前綴,也就是i=len(ab),j < len(abcd)。
將abcd分割成ab和cd兩個子節點,cd也是一個壓縮前綴節點,cd同時被標記爲iskey=1,來表示ab這個key。
cd下掛着一個空子節點,來標記abcd這個key。ui
abcABC在abcd中只找到了ab這個前綴,即i < len(abcABC),j < len(abcd)。這個步驟有點複雜,分解一下:spa
abcd和Aabc沒有前綴匹配,i = 0,j = 0。
將abcd拆分紅a、bcd兩個節點,a節點是一個非壓縮前綴節點。
將Aabc拆分紅A、abc兩個節點,A節點也是一個非壓縮前綴節點。
將A節點掛在和a相同的父節點上。
同上,在bcd和abc這兩個節點下掛空子節點來分別表示兩個key。3d
刪除一個key的流程比較簡單,找到iskey的節點後,向上遍歷父節點刪除非iskey的節點。若是是非壓縮的父節點而且size > 1,表示還有其餘非相關的路徑存在,則須要按刪除子節點的模式去處理這個父節點,主要是作memove和realloc。
刪除一個key以後須要嘗試作一些合併,以收斂樹的高度。
合併的條件是:
雲數據庫Redis版(ApsaraDB for Redis)是一種穩定可靠、性能卓越、可彈性伸縮的數據庫服務。基於飛天分佈式系統和全SSD盤高性能存儲,支持主備版和集羣版兩套高可用架構。提供了全套的容災切換、故障遷移、在線擴容、性能優化的數據庫解決方案。歡迎各位購買使用:雲數據庫 Redis 版
原文連接 本文爲雲棲社區原創內容,未經容許不得轉載。