轉:
關於redis的keys命令的性能問題
KEYS pattern
查找所有符合給定模式 pattern
的 key
。
KEYS *
匹配數據庫中所有
key
。
KEYS h?llo
匹配
hello
,
hallo
和
hxllo
等。
KEYS h*llo
匹配
hllo
和
heeeeello
等。
KEYS h[ae]llo
匹配
hello
和
hallo
,但不匹配
hillo
。
特殊符號用 \
隔開
NOTICE:
KEYS 的速度非常快,但在一個大的數據庫中使用它仍然可能造成性能問題,如果你需要從一個數據集中查找特定的 key ,你最好還是用 Redis 的集合結構(set)來代替。
Keys模糊匹配,請大家在實際運用的時候忽略掉。因為Keys會引發Redis鎖,並且增加Redis的CPU占用,情況是很惡劣的
實際應用中有時候會出現需要遍歷redis中的所有鍵值的需求,比如清理沒用的鍵等等。但是keys這個命令性能真的很差,redis官方文檔是這么說的:
Warning: consider KEYS as a command that should only be used in production environments with extreme care. It may ruin performance when it is executed against large databases. This command is intended for debugging and special operations, such as changing your keyspace layout. Don’t use KEYS in your regular application code. If you’re looking for a way to find keys in a subset of your keyspace, consider using SCAN or sets.
由於執行keys命令,redis會鎖定,如果數據龐大的話可能需要幾秒或更長,對於生產服務器上鎖定幾秒這絕對是災難了
如果有這種需求的話可以自己對鍵值做索引,比如把各種鍵值存到不同的set里面,分類建立索引,這樣就可以很快的得到數據,但是這樣也存在一個明顯的缺點,就是浪費寶貴的空間,要知道這可是內存空間啊,所以還是要合理考慮,當然也可以想辦法,比如對於有規律的鍵值,可以存儲他們的始末值等等。
使用redis的時候要注意很多細節,當時的leader說過一句話很受啟發,雖然redis只提供了五種類型,但是用起來不一定就只有五種,比如string類型,你可以存儲任何你自己定義的類型,所以思想不能局限,靈活的設定數據結構。還有就是雖然redis存取很快,但是正常生產環境,redis服務器肯定和web服務器不是在一起,有時候甚至是在不同的地區,所以網絡通信延遲就很重要了,所以要減少存取次數,一次存取完成更多的工作,否則你會發現做同樣的事redis還沒有關系型數據庫快,所以redis存的時候一定要有技巧,盡可能減少存取次數。
從redis的官方文檔上看,2.8版本之后SCAN命令已經可用,允許使用游標從keyspace中檢索鍵。對比KEYS命令,雖然SCAN無法一次性返回所有匹配結果,但是卻規避了阻塞系統這個高風險,從而也讓一些操作可以放在主節點上執行。
需要注意的是,SCAN 命令是一個基於游標的迭代器。SCAN 命令每次被調用之后, 都會向用戶返回一個新的游標,用戶在下次迭代時需要使用這個新游標作為 SCAN 命令的游標參數, 以此來延續之前的迭代過程。同時,使用SCAN,用戶還可以使用keyname模式和count選項對命令進行調整。SCAN相關命令還包括SSCAN 命令、HSCAN 命令和 ZSCAN 命令,分別用於集合、哈希鍵及有續集等。
另一方面,使用redis的時候一定要注意控制key,對於key的命令要制定一個完善的方案,這樣才能對redis里面的數據可控,避免出現沒用數據長時間占據數據庫這種情況,也可以避免上面說的這種查詢鍵值的操作。