Redis 客戶端使用與監控

NO IMAGE
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

 

1、客戶端通訊協議

1)客戶端與服務端之間的同學協議是在TCP協議之上構建的;

2)Redis定製了RESP(Redis Serialization Protocol ,Redis 序列化協議)實現客戶端與服務端的正常互動。正因為這種協議簡單而又容易理解,所以很多程式語言的客戶端就容易實現了,比如 Java的客戶端 Jedis.

 

2、客戶端Jedis的使用

生產環境一般我們不會使用直連的方式(因為連線沒法管理,導致資源不可控),而是使用連線池,使用 Jedis 連線池時主要注意一下幾個方面。

1)maxActive:最大連線數,預設8個,生產環境一般配置16個差不多,(主要是Jedis處理高效)

2)maxIdle:池子裡的最大空閒連線數,預設8個,意思是沒有客戶端來連線時池裡最多閒置 8 個

3)minIdle:池子裡的最小空閒連線數,預設0,意思是沒有客戶端來連線時池裡最少閒置數

4)jmxEnabled:是否開啟jmx監控,預設為 true,可以通過 jconsole 等工具監控連線池

5)minEvictableIdleTimeMillis:連線最小空閒時間,預設30分鐘,達到這個值後空閒連線被移除

6)numTestsPerEvictionRun:做空閒連線檢測時每次取樣數,預設 3

7)TestOnBorrow:向連線池借用連線時是否做連線的有效性檢測(Ping),預設false,如果設定為true,那麼每次借用時都會多一次 ping,不過增強了程式碼的健壯性,其實如果是在Redis服務端配置了 timeout ,那麼這個操作我覺得是很有必要的,因為服務端會把你這邊的連線給移除。

8)testOnReturn:同上,不過這裡是歸還時,預設為false。

9)testWhileIdle:對連線池的連線時是否做空閒檢測,預設為 false

10)timeBetweenEvicationRunsMillis:空閒連線檢測週期,單位為毫秒,預設 -1 ,不做檢測

11)blockWhenExhausted:當連線池用盡後,新的呼叫者是否要等待空閒連線,這個引數和下面的maxWaitMillis 對應的,只有當 blockWhenExhausted = true 時 maxWaitMillis 才會生效。預設為 true。

12)maxWaitMillis:當連線池資源用盡後,新的呼叫者來等待空閒連線時的最大時間,單位毫秒,預設 -1 ,表示永不超時,這個很要命的,一定要改掉。

 

3、客戶端管理

1)檢視客戶端連線情況

>info clients

# Clients

connected_clients:2 // 當前連線數,這個暴增,說明連線池沒有配置得當

client_longest_output_list:0 // 輸出緩衝區列表最大物件數,其實就是最大 oll

client_biggest_input_buf:0 // 最大輸入緩衝區,單位位元組,其實就是最大 qbuf

blocked_clients:0 // 正在阻塞阻塞命令(比如 blpop brpop 等)的客戶端個數

 

2)檢視服務端連線彙總

> info stats

# Stats

total_connections_received:6 // 從啟動到現在連線的總數(並不是當前連線數)

rejected_connections:0 // 從啟動到現在拒絕的連線數

 

3)檢視客戶端連線的詳細資訊

>client list

id=5 addr=127.0.0.1:52821 fd=8 name= age=115 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client

 

id=6 addr=127.0.0.1:52822 fd=9 name= age=91 idle=10 flags=O db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=monitor

 

id:唯一標識

name:客戶端名稱,通過 client setName client1 和 client getName 來設定獲取名稱

addr : 客戶端的地址和埠,當想停止該客戶端時則可以通過這個值 kill 掉

fd : 套接字所使用的檔案描述符,Linux 裡的 socket 控制代碼

age : 以秒計算的已連線時長,表示 client 從連線到現在的時長,所以叫做年齡

idle : 以秒計算的空閒時長,表示當前距離上一次執行命令的空閒時長

flags : 客戶端 flag,標識客戶端的資訊,比如主從服務,事務執行情況等

db : 該客戶端正在使用的資料庫 ID

sub : 已訂閱頻道的數量

psub : 已訂閱模式的數量

multi : 在事務中被執行的命令數量,如果沒有使用事務就是 -1,記住是命令個數,包括讀寫

qbuf : 查詢緩衝區的長度(位元組為單位, 0 表示沒有分配查詢緩衝區)

qbuf-free : 查詢緩衝區剩餘空間的長度(位元組為單位, 0 表示沒有剩餘空間)

obl : 輸出緩衝區的長度(位元組為單位, 0 表示沒有分配輸出緩衝區)

oll : 輸出列表包含的物件數量(當輸出緩衝區沒有剩餘空間時,命令回覆會以字串物件的形式被入隊到這個佇列裡)

omem : 輸出緩衝區和輸出列表佔用的記憶體總量

events : 檔案描述符事件,w 可寫, r 可讀

cmd : 最近一次執行的命令

 

注意:

A:輸入緩衝區 qbuf 和 qbuf-free 以及 client_biggest_input_buf

Redis為每個客戶端分配了輸入緩衝區,它的作用是將客戶端傳送的命令臨時儲存,同時Redis會從輸入緩衝區拉取命令並執行。其中 qbuf 代表這個緩衝區的總容量,qbuf-free 代表剩餘容量。

Redis並沒有提供相應的配置來規定每個緩衝區的大小,輸入緩衝區會根據輸入的內容大小的不同動態調整,只是要求每個客戶端緩衝區的大小不能超過1G,超過後客戶端將被關閉;另外如果沒有達到 1 G,但是和當前Redis的空間加起來已經超過 MaxMemory 時,也可能出現 OOM,這個時候命令可能會被丟失。

其實生產環境很少有因為輸入緩衝區導致的阻塞,主要還是因為命令過多積累在執行佇列中,因此我們可以通過 qbuf 預測出這個連線有多少命令被髮送,如果真的 qbuf 非常大,那麼命令太多,可能會導致阻塞,比如管道、事務命令等。當然也有可能服務端發生阻塞導致客戶端的命令一直被積壓,也有可能客戶端執行了大物件。

 

B:輸出緩衝區 obl 和 oll 以及 client_longest_output_list

Redis為每個客戶端分配了輸出緩衝區,它的作用是儲存命令執行的結果返回給客戶端,其實就是為命令返回結果提供臨時緩衝區。

與輸入緩衝區不同的是,輸出緩衝區的大小可以通過 client-output-buffer-limit 來進行設定。

輸出緩衝區有兩部分組成,固定緩衝區(obl)和動態緩衝區(oll),固定緩衝區只有 16KB,也就是返回值大於 16KB時,就會動用固定緩衝區,兩種計算方式不一樣哦,固定緩衝區是用位元組單位,動態緩衝區使用 物件個數。另外 omem 是指動態緩衝區 固定緩衝區的總位元組數。

生產環境遇到的問題在輸出緩衝區還是比較多的,比如大物件的獲取,就會造成 oll 佔用過大,從而導致阻塞,所以最好是限制住 client-output-buffer-limit ,然後報警提示。

 

 

4)設定最大連線數 maxClients

> config get maxClients

1) “maxclients”

2) “10000”

> config set maxClients 500

OK

// 最大連線數 10000,然而 Jedis的連線數預設是 8 ,對比一下差距好大啊,不知道這裡如何設定的,是不是考慮到叢集等因素。

 

5)設定檢測客戶空閒時間

> config get timeout

1) “timeout”

2) “30”

> config get timeout

1) “timeout”

2) “45”

// 如果client的idle得到了45,那麼這個連線就會被kill掉,所以使用連線池時最好對連線進行可用性檢測,同時也要避免客戶端在一個連線內消耗大量的時間。

 

6)client setName | getName

> client setName client1

OK

> client getName

“client1”

// 給客戶端指定一個自定義名字,方便查詢。 我們可以在 client list 找到。

或者執行 > redis-cli client list | grep client1

 

7)client kill addr

>client kill 127.0.0.1:52875

>OK

 

8)client pause timeout(毫秒)

>client pause 1000

// 阻塞客戶端 1000 毫秒,要知道Redis是單執行緒的,如果這個客戶端阻塞,那麼其他客戶端全部都要等待他執行完成,所以一切客戶端導致的延遲阻塞,都會是服務端的延遲阻塞。

 

 

9)monitor 監控其他客戶端的命令執行

> monitor

OK

1503724607.774500 [0 127.0.0.1:52880] “get” “str”

1503724610.339557 [0 127.0.0.1:52880] “set” “str” “hll”

// 在尋找問題時這個命令很管用,但是高併發下,這個命令很致命的,因為大量輸出導致該客戶端的輸出緩衝區被佔滿,從阻塞輸出。所以用過後儘早關閉。

第一個是執行命令的時間戳,可以使用 new Date(1503724607.774*1000)

第二個時資料庫索引 0

第三個是執行的命令以及命令的引數 “get” “str”

 

 

10)客戶端的其他配置

1)timeout :指Redis的連線如果空閒時間超過timeout則斷開,可以通過 client list 檢視連線

2)maxClients:這個和下面的 tcp 連線數不是一碼事,這個指的是客戶端數。

3)tcp-keepalive:檢測TCP連線的活性週期,預設為 0 ,不檢測。這個最好是配置一個 60 秒,因為大量的死連線會佔用服務端的TCP資源。

4)tcp-backlog:TCP 三次握手成功後,會把這個連線放入佇列中,這個佇列的最大長度就是 tcp-backlog 的配置,預設是 511 , 通常這個引數不用調整。但是有些Linux系統的這個值配置時 128,則需要對應調整為 511.

如下檢視和設定

> cat /proc/sys/net/core/somaxconn

128

> echo 511 > /proc/sys/net/core/somaxconn

> cat /proc/sys/net/core/somaxconn

511

 


(adsbygoogle = window.adsbygoogle || []).push({});

function googleAdJSAtOnload() {
var element = document.createElement(“script”);
element.src = “//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js”;
element.async = true;
document.body.appendChild(element);
}
if (window.addEventListener) {
window.addEventListener(“load”, googleAdJSAtOnload, false);
} else if (window.attachEvent) {
window.attachEvent(“onload”, googleAdJSAtOnload);
} else {
window.onload = googleAdJSAtOnload;
}

資料庫 最新文章