查看Redis的性能狀態不得不提到info。
官方文檔http://redis.io/commands/info
下面簡單的介紹一下info的信息:
info主要有一下幾項,因版本不同可能略有差別
- server
- clients
- memory
- persistence
- stats
- replication
- cpu
- keyspace
server段一般是配置以及系統項不用特別的關注。
client段:
\# Clients
connected_clients:2053 #當前客戶端連接數
client_longest_output_list:0 #當前連接的客戶端當中,最長的輸出列表
client_biggest_input_buf:0 # 當前連接的客戶端當中,最大輸入緩存
blocked_clients:0 #被阻塞的客戶端數
因為Redis是單線程模型(只能使用單核),來處理所有客戶端的請求, 但由於客戶端連接數的增長,處理請求的線程資源開始降低分配給單個客戶端連接的處理時間,這時每個客戶端需要花費更多的時間去等待Redis共享服務的響應。
因為Redis是單線程模型(只能使用單核),來處理所有客戶端的請求,且Redis默認允許客戶端連接的最大數量是10000。若是看到連接數超過5000以上,那可能會影響Redis的性能。因此監控客戶端連接數是非常重要的,因為客戶端創建連接數的數量可能超出預期的數量,也可能是客戶端端沒有有效的釋放連接。
相關配置項:
maxclients 10000
tcp-backlog 10240 #TCP 監聽的最大容納數量 默認511
memory段:
# Memory
used_memory:65256464 #使用內存,以字節(byte)為單位
used_memory_human:62.23M #以人類可讀的格式返回 Redis 分配的內存總量
used_memory_rss:54554624 #系統給redis分配的內存即常駐內存,和top 、 ps 等命令的輸出一致。
used_memory_peak:2857386920 #內存使用的峰值大小
used_memory_peak_human:2.66G #以人類可讀的格式返回 Redis 的內存峰值
used_memory_lua:33792 #lua引擎使用的內存
mem_fragmentation_ratio:0.84 #redis 內存碎片率
mem_allocator:jemalloc-3.6.0 #內存分配器
在使用redis經常會因為memory引發一些列的問題。像因為內存交換產生的性能問題以及延遲問題等。
我們可以通過一下幾種方式來減少redis內存交換的發生
- 使用Hash Redis在儲存小於100個字段的Hash結構上,其存儲效率是非常高的。官方也建議我們盡可能多的使用Hash存儲。Hash的操作命令是HSET(key, fields, value)和HGET。
- 設置key的過期時間
- 回收key 設置要maxmemory,切redis實例啟用了rdb功能就需要將maxmemory設置為系統可使用內存的45%,因為快照時需要一倍的內存來復制整個數據集,也就是說如果當前已使用45%,在快照期間會變成95%(45%+45%+5%),其中5%是預留給其他的開銷。如果沒開啟快照功能,maxmemory最高能設置為系統可用內存的95%。
當內存使用達到設置的最大閥值時,需要選擇一種key的回收策略,即配置文件中的maxmemory-policy字段設置
若是Redis數據集中的key都設置了過期時間,那么volatile-ttl策略是比較好的選擇。但如果key在達到最大內存限制時沒能夠迅速過期,或者根本沒有設置過期時間。那么設置為allkeys-lru值比較合適,它允許Redis從整個數據集中挑選最近最少使用的key進行刪除(LRU淘汰算法)。
Redis還提供了一些其他淘汰策略,如下:
- volatile-lru:使用LRU算法從已設置過期時間的數據集合中淘汰數據。
- volatile-ttl:從已設置過期時間的數據集合中挑選即將過期的數據淘汰。
- volatile-random:從已設置過期時間的數據集合中隨機挑選數據淘汰。
- allkeys-lru:使用LRU算法從所有數據集合中淘汰數據。
- allkeys-random:從數據集合中任意選擇數據淘汰。
- no-enviction:禁止淘汰數據。
通過設置maxmemory為系統可用內存的45%或95%(取決於持久化策略)和設置maxmemory-policy為volatile-ttl或allkeys-lru(取決於過期設置),可以比較准確的限制Redis最大內存使用率,在絕大多數場景下使用這2種方式可確保Redis不會進行內存交換。倘若你擔心由於限制了內存使用率導致丟失數據的話,可以設置noneviction值禁止淘汰數據。
另外一定要配置/proc/sys/vm/min_free_kbytes 讓系統及時回收內存
echo 102400 > /proc/sys/vm/min_free_kbytes 設置100m開始回收內存
persistence 段
# Persistence
loading:0
rdb_changes_since_last_save:1866 #自上次dump后rdb的改動
rdb_bgsave_in_progress:0 #標識rdb save是否進行中
rdb_last_save_time:1452048771 #上次save的時間戳
rdb_last_bgsave_status:ok #上次的save操作狀態
rdb_last_bgsave_time_sec:0 #上次rdb save操作使用的時間(單位s)
rdb_current_bgsave_time_sec:-1 #如果rdb save操作正在進行,則是所使用的時間
aof_enabled:1 #是否開啟aof,默認沒開啟(已開啟)
aof_rewrite_in_progress:0 #標識aof的rewrite操作是否在進行中
aof_rewrite_scheduled:0 #標識是否將要在rdb save操作結束后執行
aof_last_rewrite_time_sec:0 #上次rewrite操作使用的時間(單位s)
aof_current_rewrite_time_sec:-1 #如果rewrite操作正在進行,則記錄所使用的時間
aof_last_bgrewrite_status:ok #上次rewrite操作的狀態
aof_last_write_status:ok #上次write操作的狀態
aof_current_size:42820373 #aof當前大小,以字節(byte)為單位
aof_base_size:16223723 #aof上次啟動或rewrite的大小
aof_pending_rewrite:0 #同上面的aof_rewrite_scheduled
aof_buffer_length:0 #aof buffer的大小
aof_rewrite_buffer_length:0 #aof rewrite buffer的大小
aof_pending_bio_fsync:0 #后台IO隊列中等待fsync任務的個數
aof_delayed_fsync:41394 #延遲的fsync計數器 TODO
stats段
# Stats
total_connections_received:61264941 #自啟動起連接過的總數
total_commands_processed:951647408 #自啟動起運行命令的總數
instantaneous_ops_per_sec:13 #每秒執行的命令個數
rejected_connections:0 #因為最大客戶端連接書限制,而導致被拒絕連接的個數
sync_full:23
sync_partial_ok:0
sync_partial_err:0
expired_keys:40225836 #自啟動起過期的key的總數
evicted_keys:0 #因為內存大小限制,而被驅逐出去的鍵的個數
keyspace_hits:54841673 #自啟動起命中key的個數
keyspace_misses:344507 #自啟動起未命中key的個數
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:8775 #上次的fork操作使用的時間(單位ms)
因為Redis是個單線程模型,客戶端過來的命令是按照順序執行的。因此網絡問題、慢命令會造成阻塞導致redis性能下降。
如果發生命令阻塞就可以看到每秒命令處理數在明顯下降。要分析解決這個性能問題,需要跟蹤命令處理數的數量和延遲時間。
降低延遲的幾個技巧:
- 使用多參數命令 若是客戶端在很短的時間內發送大量的命令過來,會發現響應時間明顯變慢,這由於后面命令一直在等待隊列中前面大量命令執行完畢。因此我們可以使用單命令多參數的方式,來減少操作。例如mset mget hmset hmget等。
- 管道拼接,降低網絡延遲
- 避免操作大集合的慢命令
產看redis延遲時間
[root@13 ~]# /usr/local/redis6379/bin/redis-cli -c -h 192.168.11.13 -p 6380 --latency
min: 0, max: 3, avg: 0.16 (9746 samples)
本機的延遲是160μs
查詢慢日志:
redis-cli -h 127.0.0.1 -p 6379 slowlog get
1) 1) (integer) 11
2) (integer) 1451987715
3) (integer) 14387
4) 1) "CONFIG"
2) "GET"
3) "*
1)日志的唯一標識符
2)被記錄命令的執行時間點,以 UNIX 時間戳格式表示
3)查詢執行時間,以微秒為單位。例子中命令使用14毫秒。
4)執行的命令,以數組的形式排列。完整命令是config get *
replication段
# Replication
role:master #角色(主從)
connected_slaves:1 #從庫數量
slave0:ip=10.15.x.x,port=6379,state=online,offset=2230297606,lag=2 #從庫信息
master_repl_offset:2230300129
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2229251554
repl_backlog_histlen:1048576
cpu段
# CPU
used_cpu_sys:23111.87 #cpu在內核態所消耗的cpu的時間
used_cpu_user:17763.81 #cpu在用戶態所消耗的cpu的時間
used_cpu_sys_children:7909.22
used_cpu_user_children:62767.11
key段
# Keyspace
db0:keys=85904,expires=81390,avg_ttl=47463342