1. 程式人生 > >Python--Redis實戰:第四章:資料安全與效能保障:第8節:關於效能方面的注意事項

Python--Redis實戰:第四章:資料安全與效能保障:第8節:關於效能方面的注意事項

習慣了關係資料庫的使用者在剛開始使用Redis的時候,通常會因為Redis帶來的上百倍的效能提升而感到欣喜若狂,卻沒有認識到Redis效能實際上還可以進一步的提高。雖然上一節介紹的非事務型流水線可以儘可能地減少應用程式和Redis之間的通訊往返次數,但是對於一個已經存在的應用程式,我們應該如何判斷這個程式能否被優化呢?我們又應該如何對它進行優化呢?

要對Redis的效能進行優化,使用者首先需要弄清楚各種型別的Redis命令到底能跑多快,而這一點可以通過呼叫Redis附帶的效能測試程式redis-benchmark來得知,下面清單展示了一個相應的例子。如果有興趣的話,讀者也可以試著用redis-benchmark來了解Redis在自己伺服器上的各種效能特徵:

在裝有英特爾酷睿2雙核2.4GHz處理器的臺式電腦上執行redsi-benchmark

#給定‘-q’選項可以讓程式簡化輸出結果,給定‘-c 1’選項讓程式只使用一個客戶端來進行測試
$ redis-benchmark -c 1 -q
PING (inline):34246.57 requests per second
Pind:34843.32 requests per second
MSET (10 keys):24213 08 request per second
SET: 32467.53 request per second
GET: 33112.59 request per second
INCR: 32679.74 request per second
LPUSH: 33333.33 request per second
LPOP: 33670.04 request per second
SADD: 33222.59 request per second
SPOP: 34482.76 request per second
LPUSH (again, in order to bench LRNAGE):33222.59 request per second
LRANGE (first 100 elements):22988.51 request per second
LRANGE (first 300 elements):13888.89 request per second
LRANGE (first 450 elements):11061.95 request per second
LRANGE (first 600 elements):9041.59 request per second

redis-benchmark的執行結果展示了一些常用Redis命令在1秒內可以執行的此時。如果使用者在不給定任何引數的情況下執行redis-benchmark,那麼redis-benchmark將使用50個客戶端來進行效能測試,但是為了在redis-benchmark和我們自己的客戶端之間進行效能對比,讓redis-benchmark只使用一個客戶端要比使用多個客戶端更方一些。

在考察redis-benchmark的輸出結果時,切記不要將輸出結果看做是用於程式的實際效能,這是因為redis-benchmark不會處理執行命令所獲得的命令回覆,所以它節約了大量用於對命令回覆進行語法分析的時間。在一般情況下,對於只使用單個客戶端的redis-benchmark來說,根據被呼叫命令的複雜度,一個不使用流水線的Python客戶端的效能大概只有redis-benchmark所示效能的50%~60%。

另一方面,如果你發現自己客戶端的效能只有redis-benchmark所示效能的25%~30%,或者客戶端向你返回了”Cannot assign requested address“(無法分配指定的地址)錯誤,那麼你可能是不小心在每次傳送命令時都建立了新的連線。

下表列出了只使用單個客戶端的redis-benchmark與Python客戶端之間的效能對比結果,並介紹了一些常見的造成客戶端效能底下或者出錯的原因:

比較了Redis在通常情況下的效能表現以及redis-benchmark使用單客戶端進行測試時的結果,並說明了一些可能引起效能問題的原因
效能或者錯誤 可能的原因 解決方法
單個客戶端的效能達到redis-benchmark的50%~60% 這是不使用流水線的預期效能無
單個客戶端的效能達到redis-benchmark的25%~30% 對於每個命令或者每組命令都建立了新的連線 重用已有的Redis連線
客戶端返回錯誤:”Cannot assign requested address“(無法分配指定的地址) 對於每個命令或者每組命令都建立了新的連線 重用已有的Redis連線

儘管上表列出的效能問題以及問題的解決方法都非常簡短,但絕大部分常見的效能問題都是由表格中列出的原因引起的(另一個引起效能問題的原因是以不正確的方式使用Redis的資料結構)。如果讀者遇到了難以解決的效能問題,或者遇到上表沒有介紹的效能問題,那麼讀者可以考慮通過1.4節介紹的方法來尋求幫助。

大部分Redis客戶端庫都提供了某種級別的內建連線池。以Python的Redis客戶端為例,對於每個Redis伺服器,使用者只需要建立一個redis.Redis()物件,該物件就會按需建立連線、重用已有的連線並關閉超時的連線(在使用多個數據庫的情況下,即使客戶端只連線了一個Redis伺服器,它也需要為每一個被使用的資料庫建立一個連線),並且Python客戶端的連線池還可以安全地應用於多執行緒環境和多程序環境。