首先,並非說redis是內存應用就徹底沒性能問題,用的很差,仍是會出現各類情況,例如RDB頻繁,碎片太多等.mysql
性能分析
linux
info信息:
redis
在redis-cli進入登陸界面後,輸入info all,或者redis-cli -h ${ip} -p ${post} -a "${pass}" -c info all,一般咱們只輸入info就夠了,是簡介模式的意思,info all是詳細模式
sql
以後,就會獲取全部與Redis服務相關的實時性能信息,相似於linux命令top那樣的東西.mongodb
info命令輸出的數據可分爲10個類別,分別是:docker
server數據庫
clients後端
memory數組
persistence緩存
stats
replication
cpu
commandstats
cluster
keyspace
下面展開解析一些重點信息.
server 部分:
redis_version : Redis 服務器版本,不一樣版本會有些功能和命令不一樣
arch_bits : 架構(32 或 64 位),某些狀況,容易被忽略的坑
tcp_port : TCP/IP 監聽端口,確認你操做的對不對
uptime_in_seconds : 自 Redis 服務器啓動以來,通過的秒數,能夠確認有沒有被重啓過
uptime_in_days : 自 Redis 服務器啓動以來,通過的天數,能夠確認有沒有被重啓過
clients 部分:
connected_clients : 已鏈接客戶端的數量(不包括經過從屬服務器鏈接的客戶端)
client_longest_output_list : 當前鏈接的客戶端當中,最長的輸出列表
client_longest_input_buf : 當前鏈接的客戶端當中,最大輸入緩存
blocked_clients : 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客戶端的數量
memory部分:
maxmemory/maxmemory_human: 配置文件redis.conf限制的可分配的最大內存總量,當超過以後,就會觸發LRU刪除舊數據.
used_memory/used_memory_human: 當前redis-server實際使用的內存總量,若是used_memory > maxmemory ,那麼操做系統開始進行內存與swap空間交換,以便騰出新的物理內存給新頁或活動頁(page)使用,那是有多糟糕你們能夠想獲得.
used_memory_rss/used_memory_rss_human: 從操做系統上顯示已經分配的內存總量,也就是這個redis-server佔用的系統物理內存實際值,比used_memory多出來的就多是碎片.
mem_fragmentation_ratio: 內存碎片率,內存碎片率稍大於1是合理的,說明redis沒有發生內存交換,若是內存碎片率超過1.5,那就說明Redis消耗了實際須要物理內存的150%,其中50%是內存碎片率。如果內存碎片率低於1的話,說明Redis內存分配超出了物理內存,操做系統正在進行內存交換。內存交換會引發很是明顯的響應延遲.
下面是計算公式:
當碎片率出現問題,有3種方法解決內存管理變差的問題,提升redis性能:
1. 重啓Redis服務器:若是內存碎片率超過1.5,重啓Redis服務器可讓額外產生的內存碎片失效並從新做爲新內存來使用,使操做系統恢復高效的內存管理。
2.限制內存交換: 若是內存碎片率低於1,Redis實例可能會把部分數據交換到硬盤上。內存交換會嚴重影響Redis的性能,因此應該增長可用物理內存或減小實Redis內存佔用
3.修改內存分配器:
Redis支持glibc’s malloc、jemalloc十一、tcmalloc幾種不一樣的內存分配器,每一個分配器在內存分配和碎片上都有不一樣的實現。不建議普通管理員修改Redis默認內存分配器,由於這須要徹底理解這幾種內存分配器的差別,也要從新編譯Redis。
used_memory_lua: Lua腳本引擎所使用的內存大小。redis默認容許使用lua腳本,不過太多了的話就佔用了可用內存
mem_allocator: 在編譯時指定的Redis使用的內存分配器,能夠是libc、jemalloc、tcmalloc.
persistence 部分:
RDB信息,RDB的操做要用到bgsave命令,是比較耗費資源的持久化操做,並且不是實時的,容易形成宕機數據消失,若是內存容量滿了,不能作bgsave操做的話,隱患會很大.
rdb_changes_since_last_save : 距離最近一次成功建立持久化文件以後,通過了多少秒。持久化是須要佔用資源的,在高負載下須要儘可能避免持久化的影響,下列參數均有參考價值.
rdb_bgsave_in_progress: 當前是否在進行bgsave操做。是爲1
rdb_last_save_time : 最近一次成功建立 RDB 文件的 UNIX 時間戳。
rdb_last_bgsave_time_sec : 記錄了最近一次建立 RDB 文件耗費的秒數。
rdb_last_bgsave_status: 上次保存的狀態
rdb_current_bgsave_time_sec : 若是服務器正在建立 RDB 文件,那麼這個域記錄的就是當前的建立操做已經耗費的秒數。
AOF信息,AOF是持續記錄命令到持久化文件的方法,比較節省資源,可是AOF存儲文件會沒有限制存儲,時間一長,或者操做太頻繁,那就會出現AOF文件過大,撐爆硬盤的事.並且,這個方法仍是會按期bgsave操做.
aof_enabled: AOF文件是否啓用
aof_rewrite_in_progress: 表示當前是否在進行寫入AOF文件操做
aof_last_rewrite_time_sec : 最近一次建立 AOF 文件耗費的時長。
aof_current_rewrite_time_sec : 若是服務器正在建立 AOF 文件,那麼這個域記錄的就是當前的建立操做已經耗費的秒數。
aof_last_bgrewrite_status: 上次寫入狀態
aof_last_write_status: 上次寫入狀態
aof_base_size : 服務器啓動時或者 AOF 重寫最近一次執行以後,AOF 文件的大小。
aof_pending_bio_fsync : 後臺 I/O 隊列裏面,等待執行的 fsync 調用數量。
aof_delayed_fsync : 被延遲的 fsync 調用數量。
stats部分:
total_commands_processed: 顯示了Redis服務處理命令的總數,且值是遞增的.由於Redis是個單線程模型,客戶端過來的命令是按照順序執行的,若是命令隊列裏等待處理的命令數量比較多,命令的響應時間就變慢,甚至於後面的命令徹底被阻塞,致使Redis性能下降.因此這個時候就須要記錄這個參數的值,是否是增加過快,致使了性能下降.
instantaneous_ops_per_sec : 服務器每秒鐘執行的命令數量,同上,若是增加過快就有問題。
expired_keys : 由於過時而被自動刪除的數據庫鍵數量,具備參考意義。
evicted_keys: 顯示由於maxmemory限制致使key被回收刪除的數量.根據配置文件中設置maxmemory-policy值來肯定Redis是使用lru策略仍是過時時間策略.若是是過時回收的,不會被記錄在這裏,一般這個值不爲0,那就要考慮增長內存限制,否則就會形成內存交換,輕則性能變差,重則丟數據.
latest_fork_usec: 最近一次 fork() 操做耗費的微秒數。fork()是很耗費資源的操做,因此要留意一下.
commandstats部分:
cmdstat_XXX: 記錄了各類不一樣類型的命令的執行統計信息,命令包含有讀有寫,分得比較細,其中calls表明命令執行的次數,usec表明命令耗費的 CPU 時間,usec_per_call表明每一個命令耗費的平均 CPU 時間,單位爲微秒.對於排錯有必定用途.
---------------------------------------------------------------------------------------------------
通用術語解析:
1.緩存穿透
緩存一般是經過後端持久化存儲的DB(mysql/mongodb/hbase等)查詢數據,而後加載到內存的概念.從通常代碼層邏輯來講,當在緩存找不到對應的key和value時,就會主動去查詢後端DB,這個時候緩存就不起做用了,壓力都會打在後端的DB上,彷彿就是被穿透了同樣.
緣由多是原本就沒加載到緩存,多是LRU原則被刪了,多是過時時間到了自動刪除了,也多是後端DB的這個數據修改太過於頻繁,沒加載到緩存就又被訪問了.
一般來講,少許的穿透是被容許的,畢竟理論上來講,把後端DB的全部數據加載到內存並不現實.若是出現大量的穿透,那就確定是有問題了,多是代碼的邏輯有問題,也多是DB設計有問題.解決的方案大部分狀況要在代碼層解決,要麼就是加大內存來作緩存.
2.緩存雪崩
當緩存服務器重啓或者大量緩存集中在某一個時間段失效,這樣在失效的時候,也會給後端系統(好比DB)帶來很大壓力,由於可能要把這些數據從新加載到緩存。
解決方案仍是要從代碼層去作,最佳方案是不一樣的key,設置不一樣的過時時間,讓緩存失效的時間點儘可能均勻。
其餘問題的分析方法:
查看redis的網絡延時:
網絡延時對於redis性能影響是巨大的,咱們都知道內存處理數據的速度是很是快的,快到甚至能夠忽略偏差.因此網絡延時0.1毫秒,1毫秒,10毫秒看似相差不大,可是就等因而10倍和100倍的差異.
Redis的延遲數據是沒法從info信息中獲取的。假若想要查看延遲時間,能夠用 Redis-cli工具加--latency參數運行
redis-cli --latency -h 10.1.2.11 -p 6379
他將會持續掃描延遲時間,直到按ctrl+C退出,以毫秒爲單位測量Redis的響應延遲時間,因爲服務器不一樣的運行狀況,延遲時間可能有所偏差,一般1G網卡的延遲時間是0.2毫秒,若延時值遠高於這個參考值,那就有多是有性能問題了。這個時候咱們要考慮檢查一下網絡情況.
注意:網絡延時的問題須要綜合考慮,由於不一樣的網絡狀況不盡相同,例如同交換機,同內網,跨城,集羣化等等.通常來講,同交換機單機redis的網絡延時應該少於0.2毫秒,可是一個codis集羣的網絡延時可能就去到2毫秒,看起來沒差多少,其實也有十倍,加上程序客戶端的網絡延時,相差就可能30倍,因此咱們部署redis應用時,必須把網絡情況也考慮進去.
查看redis的慢查詢:
Slow log 是 Redis 用來記錄查詢執行時間的日誌系統。Redis中的slowlog命令可讓咱們快速定位到那些超出指定執行時間的慢命令,默認狀況下會記錄執行時間超過10ms的記錄到日誌,由參數slowlog-log-slower-than控制.最多記錄128條,由參數slowlog-max-len控制,超過就自動刪除.
一般這個默認參數夠用,也能夠在線CONFIG SET修改參數slowlog-log-slower-than和slowlog-max-len來修改這個時間和限制條數。
一般1gb帶寬的網絡延遲,預期在0.2ms左右,假若一個命令僅執行時間就超過10ms,那比網絡延遲慢了近50倍。能夠經過使用Redis-cli工具,輸入slowlog get命令查看,返回結果的第三個字段以微妙位單位顯示命令的執行時間。假如只須要查看最後3個慢命令,輸入slowlog get 10便可。
127.0.0.1:6379> slowlog get 10 . . . 4) 1) (integer) 215 2) (integer) 1489099695 3) (integer) 11983 4) 1) "SADD" 2) "USER_TOKEN_MAP51193" 3) "qIzwZKBmBJozKprQgoTEI3Qo8QO2Fi!4" 5) 1) (integer) 214 2) (integer) 1489087112 3) (integer) 18002 4) 1) "SADD" 2) "USER_TOKEN_MAP51192" 3) "Z3Hs!iTUNfweqvLLf!ptdchSV2JAOrrH" 6) 1) (integer) 213 2) (integer) 1489069123 3) (integer) 15407 4) 1) "SADD" 2) "USER_TOKEN_MAP51191" 3) "S3rNzOBwUlaI3QfOK9dIITB6Bk7LIGYe"
1=日誌的惟一標識符
2=被記錄命令的執行時間點,以 UNIX 時間戳格式表示
3=查詢執行時間,以微秒爲單位。例子中命令使用11毫秒。
4= 執行的命令,以數組的形式排列。完整命令是拼在一塊兒.
監控客戶端的鏈接:
由於Redis是單線程模型(只能使用單核),來處理全部客戶端的請求, 但因爲客戶端鏈接數的增加,處理請求的線程資源開始下降分配給單個客戶端鏈接的處理時間,這時每一個客戶端須要花費更多的時間去等待Redis共享服務的響應。
#查看客戶端鏈接狀態 127.0.0.1:6379> info clients # Clients connected_clients:11 client_longest_output_list:0 client_biggest_input_buf:0 blocked_clients:0
第一個字段(connected_clients)顯示當前實例客戶端鏈接的總數,Redis默認容許客戶端鏈接的最大數量是10000。如果看到鏈接數超過5000以上,那可能會影響Redis的性能。假若一些或大部分客戶端發送大量的命令過來,這個數字會低的多。
查當前客戶端狀態
#查看全部正在鏈接的客戶端狀態, 127.0.0.1:6379> client list id=821882 addr=10.25.138.2:60990 fd=8 name= age=53838 idle=24 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ping
這個看起來有點繞,由於和歷史數據是混在一塊兒的:
addr:客戶端的地址和端口,包含當前鏈接和歷史鏈接
age:這個客戶端連進來的生命週期,也就是連進來以後的持續時間,單位是秒
idle:這個客戶端的空閒時間,也就是說這個時間內,客戶端沒有操做,單位是秒
db:操做的數據庫,redis默認有db0~db15可用選擇
cmd:客戶端最後一次使用的命令
也就是說,idle越少,那就表明這個客戶端剛剛操做,反則是歷史記錄而已.age越少就表明是剛剛創建的鏈接,越大則是歷史鏈接.而有些時候個別使用者用了scan或keys命令,會對數據量大的redis形成很大的負載壓力,因此須要特別關注.
特大key的統計:
在redis的單線程處理方式下,一些數據量比較大的key的操做明顯是會影響性能,因此必要時,咱們要統計出來,交給開發來優化
#統計生產上比較大的key redis-cli -h* -a* -p* --bigkeys #查看某個key的持續時間 127.0.0.1:6379> OBJECT IDLETIME key名字
--bigkeys信息解析:
1.該命令使用scan方式對key進行統計,因此使用時無需擔憂對redis形成阻塞。
2.輸出大概分爲兩部分,summary之上的部分,只是顯示了掃描的過程。summary部分給出了每種數據結構中最大的Key,因此下面部分更重要些。
3.統計出的最大key只有string類型是以字節長度爲衡量標準的。list,set,zset等都是以元素個數做爲衡量標準,不能說明其佔的內存就必定多,須要另外計算。
得出最大key名字後,就去看看粗略大小,
#查看某個key序列化後的長度 debug object key
輸出的項的說明:
Value at:key的內存地址
refcount:引用次數
encoding:編碼類型
serializedlength:通過壓縮後的序列化長度,單位是 B, 也就是 Byte(字節),由於壓縮效果要看編碼類型,不必定反應內存中的大小,只是有參考價值.
lru_seconds_idle:空閒時間
終上所述,咱們要關注的大key信息正是serializedlength的長度了.
另外還有一個工具[rdbtools],能夠全面分析redis裏面的key信息,可是要額外安裝,對於內網用戶不可謂不麻煩,由於不是系統自帶的功能,這裏不詳細說明,請等待另外一篇文章另外介紹.
數據持久化引起的延遲
Redis的數據持久化工做自己就會帶來延遲,須要根據數據的安全級別和性能要求制定合理的持久化策略:
1.AOF + fsync always的設置雖然可以絕對確保數據安全,但每一個操做都會觸發一次fsync,會對Redis的性能有比較明顯的影響
2.AOF + fsync every second是比較好的折中方案,每秒fsync一次
3.AOF + fsync never會提供AOF持久化方案下的最優性能,使用RDB持久化一般會提供比使用AOF更高的性能,但須要注意RDB的策略配置
4.每一次RDB快照和AOF Rewrite都須要Redis主進程進行fork操做。fork操做自己可能會產生較高的耗時,與CPU和Redis佔用的內存大小有關。根據具體的狀況合理配置RDB快照和AOF Rewrite時機,避免過於頻繁的fork帶來的延遲.
例如:Redis在fork子進程時須要將內存分頁表拷貝至子進程,以佔用了24GB內存的Redis實例爲例,共須要拷貝24GB / 4kB * 8 = 48MB的數據。在使用單Xeon 2.27Ghz的物理機上,這一fork操做耗時216ms。
能夠經過INFO命令返回的latest_fork_usec字段查看上一次fork操做的耗時(微秒)。
Swap引起的延遲
當Linux將Redis所用的內存分頁移至swap空間時,將會阻塞Redis進程,致使Redis出現不正常的延遲。Swap一般在物理內存不足或一些進程在進行大量I/O操做時發生,應儘量避免上述兩種狀況的出現。
在/proc/redis進程號/smaps文件中會保存進程的swap記錄,經過查看這個文件,可以判斷Redis的延遲是否由Swap產生。若是這個文件中記錄了較大的Swap size,則說明延遲頗有多是Swap形成的。
例子以下,能夠看到當前swap的狀態時0KB,也就是沒用到swap,
#/proc/pid/smaps顯示了進程運行時的內存影響,系統的運行時庫(so),堆,棧信息都可在其中看到。 cat /proc/`ps aux |grep redis |grep -v grep |awk '{print $2}'`/smaps 00400000-00531000 r-xp 00000000 fc:02 805438521 /usr/local/bin/redis-server Size: 1220 kB Rss: 924 kB Pss: 924 kB Shared_Clean: 0 kB Shared_Dirty: 0 kB Private_Clean: 924 kB Private_Dirty: 0 kB Referenced: 924 kB Anonymous: 0 kB AnonHugePages: 0 kB Shared_Hugetlb: 0 kB Private_Hugetlb: 0 kB Swap: 0 kB SwapPss: 0 kB KernelPageSize: 4 kB MMUPageSize: 4 kB Locked: 0 kB
內存滿了怎麼辦:
redis內存滿了,那確實是很麻煩的事,可是再麻煩也得處理啊,這就得從redis架構原理提及了.
首先咱們要了解,redis的內存滿,並不表明是用了系統的100%內存,爲何這麼說呢?咱們都知道redis作持久化是save和bgsave,而經常使用的bgsave(也是默認)是fork一個進程,把內存copy一份再壓縮後存到硬盤成*.rdb文件.這裏就涉及一個問題,你內存必須保證有和數據同樣大的空間才能作bgsave,那嚴格來講,只要你的內存超過系統內存的50%,那就能夠被稱爲redis內存滿了.
redis的持久化策略,上面只說了持久化會阻塞操做致使延時,而若是內存滿了,數據量的增長會讓持久化形成的延時會更嚴重,並且持久化失敗後是默認每分鐘重試一遍.
那麼問題就來了,由於內存滿了,持久化失敗,而後一分鐘後再持久化,就形成了惡性循環,redis的性能直線降低.那怎麼辦好呢?
更改持久化策略是個臨時解決方案,
能夠先嚐試關閉持久化失敗致使的終止全部的客戶端write請求的選項,
config set stop-writes-on-bgsave-error no
可是這個方法治標不治本,咱們只是忽略了問題而已,
另外一種解決方案就是直接把rdb持久化關閉掉:
config set save ""
爲何能解決,答案也很明顯,關閉了持久化,那就不會阻塞操做,那你redis的性能仍是保證到了.可是又會引入新問題,沒了持久化,內存數據若是redis-server程序重啓或關閉就沒了,仍是比較危險的.並且內存滿的問題還在,若是內存用到了系統內存100%,甚至觸發了系統的OOM,那就坑大了,由於內存被完全清空,數據也都沒有了.也就是所謂的臨時解決辦法.
因此正確的作法是,在不阻塞操做以後,刪掉能夠刪除的數據,再從新拉起持久化,而後準備擴容的工做.
佔用內存看哪裏,上面已經說了,可是內存滿了的定義,並不必定只是實際內存佔用,碎片也是要包含在內的,例如:
#這種狀況,確定就是內存滿 used_memory_human:4.2G maxmemory_human:4.00G #可是這種狀況,也是內存滿 used_memory_human:792.30M used_memory_rss_human:3.97G used_memory_peak_human:4.10G maxmemory_human:4.00G
由於內存碎片沒有被釋放,那它仍是會佔用內存空間,對於系統來講,碎片也是redis-server佔用的內存,不是空閒的內存,那剩下的內存仍是不足以用來bgsave.那怎麼解決碎片呢?
在redis4.0以前,沒其餘更好辦法,只能重啓redis-server,以後的新版本則新加了一個碎片回收參數,杜絕了這個問題.
而碎片問題其實影響頗大,由於正常狀況下,這些用不了又確實佔着內存的數據,會讓咱們的redis浪費空間之餘,還會額外形成內存滿的風險.因此也正如上面說的那樣,若是碎片率超過1.5以後,是該想一想回收一下.
那確實須要保存內存數據怎麼辦?只能忍痛割愛,把沒必要要的數據刪除掉,讓內存降到能作bgsave以後再重啓來回收碎片.要不,就是升級到4.0以後避免同類問題.
優化建議
系統優化
1.關閉Transparent huge pages
Transparent HugePages會讓內核khugepaged線程在運行時動態分配內存。在大部分linux發行版本中默認是啓用的,缺點是可能會形成內存在運行時的延遲分配,對於大內存應用並不友好,例如:oracle,redis等會佔用大量內存的應用,因此建議關閉。
#關閉Transparent HugePages,默認狀態是[always] echo never > /sys/kernel/mm/transparent_hugepage/enabled
2.修改 vm.overcommit_memory 參數
解析:
0 表示檢查是否有足夠的內存可用,若是是,容許分配;若是內存不夠,拒絕該請求,並返回一個錯誤給應用程序。
1 容許分配超出物理內存加上交換內存的請求
2 內核老是返回 true
在作bgsave時,RDB文件寫的時候會先fork一個子進程,至關於複製了一個內存鏡像.當系統的內存是8G,而redis佔用了近 5G的內存時,因爲剩下的內存不足夠fork一個鏡像空間,所以確定會報內存沒法分配而失敗.默認狀況下,vm.overcommit_memory設置爲 0,在可用內存不足的狀況下, 就沒法分配新的內存。若是vm.overcommit_memory設置爲1。 那麼redis將使用交換分區swap來作fork,雖然速度會慢一些,可是至少是不會失敗了。
#修改內核參數 vi /etc/sysctl #設置,沒有就添加一行 vm.overcommit_memory = 1 #而後執行 sysctl -p
固然了,使用交換內存swap並非一個完美的方案,有些服務器在分配時甚至就沒有swap。因此,最好的辦法是擴大物理內存,或者合理分配合適的內存空間,讓LRU規則來淘汰舊key。
3.在物理機部署redis,這點不用多說了,虛擬機或者是docker的內存都會有必定的延時,沒有必要爲了好管理而浪費這些性能。
4.多用鏈接池,而不是頻繁斷開再鏈接,效果我想不言而喻。
5.客戶端進行的批量數據操做,應使用Pipeline特性在一次交互中完成。
6.當併發和QPS都很是大的狀況下,應該改用redis-cluster或者codis這些高性能redis集羣
行爲優化
1.假如緩存數據小於4GB,能夠選擇使用32位的Redis實例。由於32位實例上的指針大小隻有64位的一半,它的內存空間佔用空間會更少些。Redis的dump文件在32位和64位之間是互相兼容的, 所以假若有減小佔用內存空間的需求,能夠嘗試先使用32位,後面再切換到64位上。
2.儘量的使用Hash數據結構。由於Redis在儲存小於100個字段的Hash結構上,其存儲效率是很是高的。因此在不須要集合(set)操做或list的push/pop操做的時候,儘量的使用Hash結構。Hash結構的操做命令是HSET(key, fields, value)和HGET(key, field),使用它能夠存儲或從Hash中取出指定的字段。
3.儘可能設置key的過時時間。一個減小內存使用率的簡單方法就是,每當存儲對象時確保設置key的過時時間。假若key在明確的時間週期內使用或者舊key不大可能被使用時,就能夠用Redis過時時間命令(expire,expireat, pexpire, pexpireat)去設置過時時間,這樣Redis會在key過時時自動刪除key.用ttl命令能夠查詢過時時間,單位是秒,顯示-2表明key不存在,顯示-1表明沒有設置超時時間(也就是永久的).
4.使用多參數命令:如果客戶端在很短的時間內發送大量的命令過來,會發現響應時間明顯變慢,這因爲後面命令一直在等待隊列中前面大量命令執行完畢。舉例來講,循環使用LSET命令去添加1000個元素到list結構中,是性能比較差的一種方式,更好的作法是在客戶端建立一個1000元素的列表,用單個命令LPUSH或RPUSH,經過多參數構造形式一次性把1000個元素髮送的Redis服務上。
5.管道命令:另外一個減小多命令的方法是使用管道(pipeline),把幾個命令合併一塊兒執行,從而減小因網絡開銷引發的延遲問題。由於10個命令單獨發送到服務端會引發10次網絡延遲開銷,使用管道會一次性把執行結果返回,僅須要一次網絡延遲開銷。Redis自己支持管道命令,大多數客戶端也支持,假若當前實例延遲很明顯,那麼使用管道去下降延遲是很是有效的。
6.避免操做大集合的慢命令:若是命令處理頻率太低致使延遲時間增長,這多是由於使用了高時間複雜度的命令操做致使,這意味着每一個命令從集合中獲取數據的時間增大。 因此減小使用高時間複雜的命令,能顯著的提升的Redis的性能。
7.限制客戶端鏈接數:自Redis2.6之後,容許使用者在配置文件(Redis.conf)maxclients屬性上修改客戶端鏈接的最大數,也能夠經過在Redis-cli工具上輸入config set maxclients 去設置最大鏈接數。根據鏈接數負載的狀況,這個數字應該設置爲預期鏈接數峯值的110%到150之間,如果鏈接數超出這個數字後,Redis會拒絕並馬上關閉新來的鏈接。經過設置最大鏈接數來限制非預期數量的鏈接數增加,是很是重要的。另外,新鏈接嘗試失敗會返回一個錯誤消息,這可讓客戶端知道,Redis此時有非預期數量的鏈接數,以便執行對應的處理措施。 上述二種作法對控制鏈接數的數量和持續保持Redis的性能最優是很是重要的