管道
客戶端和
redis
使用tcp
協議連線。不論是客戶端向
redis
傳送命令還是
redis
向客戶端返回命令執行的結果,都需要經過網路傳輸,這兩部分的總耗時稱為往返時延。
在執行多條命令時。每條命令都需要等待上一條命令執行完畢(即收到
redis
的返回結果)才能執行,即使命令不需要上一條命令的執行結果。
redis
的底層通訊協議對管道(
pipelining
)提供了支援。通過管道可以一次性傳送多條命令並在執行完後一次性將結果返回,當一組命令中每條命令都不依賴於之前命令的執行結果時就可以將這組命令通過管道一起發出。管道通過減少客戶端與
redis
的通訊次數來實現降低往返時延累計值的目的。
節省空間
減少記憶體占用來控制成本
精簡鍵名和鍵值
內部編碼優化:
redis
為每種資料型別都提供了兩種內部編碼方式,以雜湊型別為例,雜湊型別是通過雜湊表實現的,這樣就可以實現
o(1)
時間複雜度的查詢和賦值操作,然而當鍵中元素很少時,
o(1)
的操作並不會比
o(n)
有明顯的效能提高,所以這種情況下
redis
會採用一種更為緊湊但效能稍差(獲取元素的時間複雜度為
o(n)
)的內部編碼方式。內部編碼方式對於開發者來說是透明的,
redis
會根據實際情況自動調整。如果想檢視乙個鍵的內部編碼方式可以使用
object encoding
命令,如:
redis> set foo bar ok
redis> object encoding foo
"raw"
redis
的每個鍵值都是使用乙個
redisobject
的結構體儲存的,
redisobject
的定義如下:
typedef
struct redisobject robj;
type
字段表示的是鍵值的資料型別,取值如下:
#define redis_string 0
#define redis_list 1
#define redis_set 2
#define redis_zset 3
#define redis_hash 4
encoding
字段表示的就是
redis
鍵值的內部編碼方式,取值:
#define redis_encoding_raw 0 /*raw representation*/
#define redis_encoding_int 1 /*encoded as integer*/
#define redis_encoding_ht 2 /*encoded as hash table*/
#define redis_encoding_zipmap 3 /*encoded as zipmap*/
#define redis_encoding_linkedlist 4 /*encoded as regular linkedlist*/
#define redis_encoding_ziplist 5 /*encoded as ziplist*/
#define redis_encoding_intset 6 /*encoded as intset*/
#define redis_encoding_skiplist 7 /*encoded as skiplist*/
資料型別
內部編碼方式
object
encoding
命令結果
字串型別
redis_encoding_raw
redis_encoding_int
"raw"
"int"
雜湊型別
redis_encoding_ht
redis_encoding_ziplist
"hashtable"
"ziplist"
列表型別
redis_encoding_linkedlist
redis_encoding_ziplist
"linkedlist"
"ziplist"
集合型別
redis_encoding_ht
redis_encoding_intset
"hashtable"
"intset"
有序集合型別
redis_encoding_skiplist
redis_encoding_ziplist
"skiplist"
"ziplist" 1
、字串型別
redis
使用乙個
sdshdr
型別的變數來儲存字串,而
redisobject
的ptr
字段指向的是該變數的位址。
struct sdshdr;
len表示字串的長度,
free
字段表示
buf中的剩餘空間,
buf儲存字串的內容。
當鍵值內容可以用乙個
64位有符號整數表示時,
redis
會將鍵值轉換成
long
型別來儲存。
redis
啟動後會預先建立
10000
個分別儲存從0到
9999
這些數字的
redisobject
型別變數作為共享物件。
當通過配置檔案引數
maxmemory
設定了redis
可用的最大空間大小時,
redis
不會使用共享物件。 2
、雜湊型別
在配置檔案中可以定義使用
redis_encoding_ziplist
方式編碼雜湊型別的時機:
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
當雜湊型別鍵的字段個數少於
hash-max-ziplist-entries
引數值,且每個欄位名和字段值的長度都小於
hash-max-ziplist-value
引數值時,
redis
就會使用
redis_encoding_ziplist
來儲存該鍵,否則使用
redis_encoding_ht。
redis_encoding_ziplist
的編碼結構: z
lbytes
zltail
zllen元素1
元素2
...zlend
其中元素的結構如下:
前乙個元素的大小
當前元素的編碼型別
當前元素的大小
當前元素的型別 使用
redis_encoding_ziplist
編碼儲存雜湊型別的記憶體結構:
zlbytes
zltail
zllen欄位1
字段值1
欄位2字段值2
...zlend 3
、列表型別
在配置檔案中可以定義使用
redis_encoding_ziplist
編碼方式的時機:
list
-max_ziplist-entries512
list-max-ziplist-value 64
4、集合型別
當集合中的所有元素都是整數且元素的個數小於配置檔案中的
set-max-intset-entries
引數指定值(預設
512)時
redis
會使用redis_encoding_intset
編碼儲存該集合,否則使用
redis_encoding_ht
來儲存。
typedef struct intset intset;
5、有序集合型別
配置檔案中可以定義使用
redis_encoding_ziplist
方式編碼的時機:
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
當編碼方式為
redis_encoding_skiplist
時,redis
使用雜湊表和跳躍列表兩種資料結構來儲存有序集合型別鍵值。雜湊表用來儲存元素值與元素分數的對映關係來實現
o(1)
時間複雜度的
zscore
等命令。跳躍列表用來儲存元素的分數及其到元素值的對映以實現排序的功能。 使用
redis_encoding_ziplist
編碼有序集合時按照「元素
1的值,元素
1的分數,元素
2的值,元素
2的分數」的順序排列,並且分數是有序的。
Redis筆記六之管道
redis中乙個操作命令就是客戶端和服務端的一次互動,如果有1000條set命令則意味著客戶端和服務端會有1000次互動,這顯然在效能上不符合我們的期望。redis提供管道機制來解決這一問題,使用管道會將1000條命令一次性發給伺服器然後再一次性全部執行,管道就是執行了乙個批處理操作。下面兩個例子分...
程序間通訊學習筆記一 管道通訊
程序間通訊 ipc 應用場景 資料傳輸 資源共享 通知事件 程序控制 system v at t system v posix portable operating system inte ce 可移植作業系統介面 常用的程序間通訊的方式 管道 pipe 和有名管道 fifo 訊號 signal 訊...
Redis的學習之管道
redis的工作模式 請求響應式 redis是乙個使用客戶端 伺服器模型 也被稱作請求 響應協議 的tcp伺服器。這說明通常來講乙個乙個請求的實現有以下步驟 1.客戶端傳送請求到伺服器,並從socket中以 堵塞的方式 讀取伺服器的響應資料。2.伺服器對發動的命令進行處理並把響應資料發回客戶端。環路...