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