1. 程式人生 > 實用技巧 >《Redis設計與實現》筆記

《Redis設計與實現》筆記

本書介紹了以下內容:

字串(string)、雜湊(hash)、列表(list)、集合(set)和有序集合(sorted set)這五種型別的鍵的底層實現資料結構。
Redis 的物件處理機制以及資料庫的實現原理。
事務實現原理。
訂閱與釋出實現原理。
Lua 指令碼功能的實現原理。
SORT 命令的實現原理。
BITOP 、 BITCOUNT 等二進位制位處理命令的實現原理。
慢查詢日誌的實現原理。
RDB 持久化和 AOF 持久化的實現原理。
Redis 事件處理器的實現原理。
Redis 伺服器和客戶端的實現原理。
複製(replication)、Sentinel 和叢集(cluster)這三個多機功能的實現原理。

簡單動態字串

字串(String)使用了一種稱為簡單動態字串(Simple Dynamic String)的抽象資料型別,以空字元結尾,len + free + 1 = buf.length。

'''
struct sdshdr {

// buf 中已佔用空間的長度
int len;

// buf 中剩餘可用空間的長度
int free;

// 資料空間
char buf[];

};
'''

與C語言字串的區別:

  • O(1) 時間複雜度獲取字串長度
  • 避免緩衝區溢位:拼接前進行長度檢查
  • 減少記憶體分配次數
    • 空間預分配:newlen = (len+addlen); newlen = newlen + min(newlen, SDS_MAX_PREALLOC);
    • 惰性空間釋放
  • 二進位制安全:C語言字串中不能包含空字串(因此不能儲存像圖片、音訊、視訊、壓縮檔案這樣的二進位制資料),否則被判為結尾,而SDS用len判定
  • 相容部分C語言字串函式

連結串列

列表鍵的底層實現結構之一是雙向連結串列(也可能是壓縮列表)。當列表鍵包含了許多元素,或者元素是比較長的字串的時候,就會用到連結串列作為列表鍵的底層實現。

字典

字典,鍵值對,Redis資料庫的儲存就是用的hash索引,也是hash鍵的底層實現之一。

字典有2個雜湊表,雜湊表有一個dictEntry陣列,dictEntry 雜湊節點包含鍵、值、next。

  • 雜湊演算法:index = hashFunc(key) & sizemask,採用高速的murmurhash2演算法
  • 鍵衝突解決:採用鏈地址法,插到頭部(O(1))
  • rehash:
    • 裝載因子=鍵值對/雜湊表大小,0.1、1、5時
    • 申請空間:擴容——2*x的最小2的n次方;收縮——x的最小2的n次方
    • 漸進式rehash到 ht[1]上,對字典進行增刪改查的時候進行一步rehash、將ht[0] rehashidx位置的資料遷移到ht[1]上,直到完成

跳錶

平均O(logN),最壞O(N),支援順序遍歷查詢。有序集合元素較多或是元素成員是比較長的字串時就會使用跳錶。

分值可以相同,成員物件必須唯一,跨度用來計算排位。

整數集合(intset)

保持升序、不重複的一個整數陣列。當一個集合只包含整數值元素,並且這個集合的元素數量不多時,Redis就會使用整數集合作為集合鍵的底層實現。

升級:int32—>int64,重新分配陣列空間。不支援降級。

壓縮列表(ziplist)

list(元素少,小整數或短字串時) 和 hash 的底層實現之一。

連鎖更新:插入、刪除最壞情況下N次空間重分配,每次最壞O(N),總共O(N^2)。但這個條件較苛刻,平均O(N)。

物件

字串(string)、雜湊(hash)、列表(list)、集合(set)和有序集合(sorted set),Redis使用物件來表示資料庫中的鍵和值,實現了基於引用計數的記憶體回收機制。

物件的型別(5種)和編碼(底層實現)。

9.資料庫