Redis學習筆記之(十一)管道與節省空間

2021-07-07 02:22:57 字數 4561 閱讀 4920

管道

客戶端和

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.伺服器對發動的命令進行處理並把響應資料發回客戶端。環路...