問題:
線上有部分的redis key需要清理。
?
一、
由于Keys模糊匹配,請大家在實際運用的時候忽略掉。因為Keys會引發Redis鎖,并且增加Redis的CPU占用,情況是很惡劣的,
官網說明如下:
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.
?
?
二、方案一
如果有這種需求的話可以自己對鍵值做索引,
比如把各種鍵值存到不同的set里面,分類建立索引,這樣就可以很快的得到數據,
但是這樣也存在一個明顯的缺點,就是浪費寶貴的空間,要知道這可是內存空間啊,所以還是要合理考慮,當然也可以想辦法,比如對于有規律的鍵值,可以存儲他們的始末值等等。?
?
三、方案二
從redis的官方文檔上看,2.8版本之后SCAN命令已經可用,允許使用游標從keyspace中檢索鍵。
對比KEYS命令,雖然SCAN無法一次性返回所有匹配結果,但是卻規避了阻塞系統這個高風險,從而也讓一些操作可以放在主節點上執行。
?
需要注意的是,SCAN 命令是一個基于游標的迭代器。
SCAN 命令每次被調用之后, 都會向用戶返回一個新的游標,用戶在下次迭代時需要使用這個新游標作為 SCAN 命令的游標參數, 以此來延續之前的迭代過程。同時,使用SCAN,用戶還可以使用keyname模式和count選項對命令進行調整。SCAN相關命令還包括SSCAN 命令、HSCAN 命令和 ZSCAN 命令,分別用于集合、哈希鍵及有續集等。
?
四、代碼示例
?
# -*- coding: utf-8 -*-
import sys
from sys import argv
from rediscluster import RedisCluster# 生產環境
product_redis_nodes_str = "*"def get_redis():redis_nodes_str = product_redis_nodes_strprint redis_nodes_strstartup_nodes = []for hp in redis_nodes_str.split(','):host, port = hp.split(':')port = int(port)startup_nodes.append({"host": host, "port": port})rc = RedisCluster(startup_nodes=startup_nodes, max_connections=16, decode_responses=False)print "get_redis success"return rcdef test_keys():rc = get_redis()key_list = []for key in rc.scan_iter(match='rc.rs.smallvideo*', count=1000):key_list.append(key)if(len(key_list)>=100000):break;for key in key_list:rc.delete(key)if __name__ == "__main__":Usage = "python %s" % __file__if len(argv) != 1:print Usagesys.exit(1)test_keys()
?
?
參考:
1、http://www.redis.cn/commands/scan.html