前段時間,我司內網環境發生了一件有關Redis
阻塞的事情。由於公司業務規模較大,很多數據保存在Redis
中,測試人員壓測時,壓測結果總是不盡人意,出現大批量的timeout
的情況,查看服務器時發現CPU
飆升,導致請求處理緩慢。經過一番努力,終於找到了事情的源頭,新來的開發在本地調試RedisTemplate
,這不是重點,重點在於他執行的是keys
的模糊匹配,導致Redis
阻塞,從而影響壓測,好在這僅僅是在內網環境,如果在外網環境使用模糊匹配等耗時的命令,後果不堪設想。
Redis是單線程的,這個特性再重點標記一下,單線程意味着任何一條命令的執行都是串行的,也就是按順序一條一條的執行。那麼當你執行的命令耗時就會導致後續的Redis
訪問都會阻塞。
對於Redis
的keys * 、flushdb、flushall
等耗時命令,我們應當慎用,或者禁止使用,這類命令我們可以配置redis.conf
禁用這些命令
對於時間複雜度爲O(n)
的數據操作命令,也應該根據自己的數據量使用,命令如下:
List: lindex、lset、linsert
Hash: hgetall、hkeys、hvals
Set: smembers、sunion、sunionstore、sinter、sinterstore、sdiff、sdiffstore
Sorted Set: zrange、zrevrange、zrangebyscore、zrevrangebyscore、zremrangebyrank、zremrangebyscore
使用scan替代keys命令
scan
命令用來分批次掃描Redis
記錄,保證Redis
不會因爲耗時導致服務不可用。
語法:
scan cursor [MATCH pattern] [COUNT count]
案例:
scan 0 match report:* count 10
1) "3932160"
2) 1) "report:12360412"
2) "report:12749274"
scan 第一個參數是遊標,表示從遊標開始
返回的第一行是遊標,第二行是匹配到的數據,
如果第一行返回0,表示沒有更多數據,否則下次使用scan時,就要用第一行返回的值作爲scan的遊標