以下是學習筆記
- 出現cpu過高的原因有:
1、連接數過多,通過info clients
查看
2、慢查詢,因為redis是單線程,如果有慢查詢的話,會阻塞住之后的操作,通過redis日志查 待補充
3、value值過大?比如value幾十兆,當然這種情況比較少,其實也可以看做是慢查詢的一種
4、aof重寫/rdb fork發生?瞬間會堵一下Redis服務器
# 修改慢查詢時間與隊列長度
# 方式一
修改配置文件
# The following time is expressed in microseconds, so 1000000 is equivalent
# to one second. Note that a negative number disables the slow log, while
# a value of zero forces the logging of every command.
# 這里默認是10ms 10毫秒
slowlog-log-slower-than 10000
# There is no limit to this length. Just be aware that it will consume memory.
# You can reclaim memory used by the slow log with SLOWLOG RESET.
# 慢日志隊列長度
slowlog-max-len 128
# 方式二
config set slowlog-log-slower-than 20000
config set slowlog-max-len 1000
config rewrite
# 查看命令
# 顯示隊列長度
127.0.0.1:6379> SLOWLOG LEN
128
# 默認顯示隊列尾部的10個
127.0.0.1:6379> SLOWLOG GET
# 默認顯示隊列尾部的最后一個
127.0.0.1:6379> slowlog get 1
71057 // slowlog唯一編號id
1574822285 // 查詢的時間戳
10184 // 查詢的耗時(微秒),如表示本條命令查詢耗時47微秒
KEYS // 查詢命令,完整命令為 KEYS history_1_*,slowlog最多保存前面的31個key和128字符
history_1_*
對應解決方案:
1、連接數過多解決:
1.1 關閉僵尸連接
采用redi-cli登錄,采用client kill ip:port(redis遠程連接的ip和端口)。
需要采用腳本批量刪除多個連接
1.2 修改redis timeout參數
采用redis-cli登錄,采用config set timeout xx 設置redis的keepalive時間
1.3 修改redis進程的文件數限制
echo -n "Max open files 3000:3000" > /proc/PID/limits
1.4 修改系統參數的最大文件數限制
/etc/security/limits.conf
2、對慢查詢進行持久化,比如定時存放到mysql之類。(redis的慢查詢只是一個list,超過list設置的最大值,會清除掉之前的數據,也就是看不到歷史)
3、限制key的長度和value的大小使用redis的注意事項:
1、Master最好不要做任何持久化工作,包括內存快照和AOF日志文件,特別是不要啟用內存快照做持久化。
2、如果數據比較關鍵,某個Slave開啟AOF備份數據,策略為每秒同步一次。
3、為了主從復制的速度和連接的穩定性,Slave和Master最好在同一個局域網內。
4、盡量避免在壓力較大的主庫上增加從庫
5、為了Master的穩定性,主從復制不要用圖狀結構,用單向鏈表結構更穩定,即主從關系為:Master<--Slave1<--Slave2<--Slave3.......,這樣的結構也方便解決單點故障問題,實現Slave對Master的替換,也即,如果Master掛了,可以立馬啟用Slave1做Master,其他不變
6、使用Redis負載監控工具:redis-monitor,它是一個Web可視化的 redis 監控程序
針對keys*的解決方案
方案一:初步方案采用scan,一個基于游標的迭代器,進行處理
// jedis.jar的版本為3.1.0
ScanParams scanParams = new ScanParams();
scanParams.match(patternKey);
scanParams.count(1000);
ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
Redis的SCAN操作由于其整體的數據設計,無法提供特別準的scan操作,僅僅是一個“can't guarantee,just do my best”的實現:
- 提供鍵空間的遍歷操作,支持游標,復雜度O(1), 整體遍歷一遍只需要O(N);
提供結果模式匹配; - 支持一次返回的數據條數設置,但僅僅是個hints,有時候返回的會多;
- 弱狀態,所有狀態只需要客戶端需要維護一個游標;
- 無法提供完整的快照遍歷,也就是中間如果有數據修改,可能有些涉及改動的數據遍歷不到;
- 每次返回的數據條數不一定,極度依賴內部實現;
- 返回的數據可能有重復,應用層必須能夠處理重入邏輯;上面的示例代碼中, redisTemplate.execute方法是個Set,相當于已經對于返回的key去重
- count是每次掃描的key個數,并不是結果集個數。count要根據掃描數據量大小而定,Scan雖然無鎖,但是也不能保證在超過百萬數據量級別搜索效率;count不能太小,網絡交互會變多,count要盡可能的大。在搜索結果集1萬以內,建議直接設置為與所搜集大小相同。
方案二:主從集群,進行分離 待補充……
方案三:在放入之前想策略 待補充……
Redis 如何高效安全刪除大 Hash Key
Redis刪除大的集合鍵的耗時, 測試估算,可參考;和硬件環境、Redis版本和負載等因素有關
Key類型 | Item數量 | 耗時 |
---|---|---|
Hash | ~100萬 | ~1000ms |
List | ~100萬 | ~1000ms |
Set | ~100萬 | ~1000ms |
Sorted Set | ~100萬 | ~1000ms |