阿裏雲redis大key搜索工具
Redis提供了list、hash、zset等複雜類型的數據結構,業務在使用的時候可能由於key設計不合理導致某個key過大,由於redis簡單的單線程模型,業務在獲取或者刪除大key的時候都會有一定的影響,另外在集群模式下由於大key的產生還很容易導致某個子節點的內存滿,綜上所述我們需要提供大key的搜索工具。
初始化環境
安裝python客戶端
下載python客戶端
wget “https://pypi.python.org/packages/68/44/5efe9e98ad83ef5b742ce62a15bea609ed5a0d1caf35b79257ddb324031a/redis-2.10.5.tar.gz#md5=3b26c2b9703b4b56b30a1ad508e31083”
解壓安裝
tar -xvf redis-2.10.5.tar.gz
cd redis-2.10.5
sudo python setup.py install
掃描腳本
遍曆key
對於Redis主從版本可以通過scan命令進行掃描,對於集群版本提供了ISCAN命令進行掃描,命令規則如下, 其中節點個數node可以通過info命令來獲取到
ISCAN idx cursor [MATCH pattern] [COUNT count](idx為節點的id,從0開始,16到64gb的集群實例為8個節點故idx為0到7,128g 256gb的為16個節點)
掃描腳本
import sys
import redis
def check_big_key(r, k,node):
bigKey = False
length = 0
try:
type = r.type(k)
if type == "string":
length = r.strlen(k)
elif type == "hash":
length = r.hlen(k)
elif type == "list":
length = r.llen(k)
elif type == "set":
length = r.scard(k)
elif type == "zset":
length = r.zcard(k)
except:
return
if length > 10240:
bigKey = True
if bigKey :
print db,k,type,length,node
def find_big_key_normal(db_host, db_port, db_password, db_num):
r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, db=db_num)
for k in r.scan_iter(count=1000):
check_big_key(r, k,0)
def find_big_key_sharding(db_host, db_port, db_password, db_num, nodecount):
r = redis.StrictRedis(host=db_host, port=db_port, password=db_password, db=db_num)
cursor = 0
for node in range(0, nodecount) :
while True:
iscan = r.execute_command("iscan",str(node), str(cursor), "count", "1000")
for k in iscan[1]:
check_big_key(r, k,node)
cursor = iscan[0]
if cursor == "0":
break;
if __name__ == '__main__':
if len(sys.argv) != 4:
print 'Usage: python ', sys.argv[0], ' host port password '
exit(1)
db_host = sys.argv[1]
db_port = sys.argv[2]
db_password = sys.argv[3]
r = redis.StrictRedis(host=db_host, port=int(db_port), password=db_password)
nodecount = r.info()['nodecount']
keyspace_info = r.info("keyspace")
for db in keyspace_info:
print 'check ', db, ' ', keyspace_info[db]
if nodecount > 1:
find_big_key_sharding(db_host, db_port, db_password, db.replace("db",""), nodecount)
else:
find_big_key_normal(db_host, db_port, db_password, db.replace("db", ""))
可以通過python find_bigkey host 6379 password來執行,支持阿裏雲Redis的主從版本和集群版本的大key查找,默認大key的閾值為10240,也就是對於string類型的value大於10240的認為是大key,對於list的話如果list長度大於10240認為是大key,對於hash的話如果field的數目大於10240認為是大key。另外默認該腳本每次搜索1000個key,對業務的影響比較低,不過最好在業務低峰期進行操作,避免scan命令對業務的影響。腳本輸出內容個數如下,最後一列為集群裏麵所在節點的序號。
check db0 {'keys': 79648, 'expires': 0, 'avg_ttl': 0}
db0 mylist list 59819 2
最後更新:2017-07-04 17:02:26