Skip to Content
Common Redis IssuesPrimary-secondary Redis search for bigkey

Search for Large Keys in master-replica Redis

Background Information

Redis provides complex data structures such as lists, hashes, and sorted sets (zsets). When using these structures, there may be cases where a key is excessively large due to suboptimal key design. Therefore, we need search tools to identify these large keys.

Operation Steps

1、Create the following scan script scan_big_key.py

#!/usr/bin/python2 import sys import os import redis import time import datetime BigNum=10000 string_keys=[] hash_keys=[] list_keys=[] set_keys=[] zset_keys=[] def scan_hash(source): #print "Begin Import Hash Type" keys_count = len(hash_keys) #print "Hash Key Count is:",keys_count for key in hash_keys: hlen=source.hlen(key) if hlen > BigNum : print "Hash key:%s, size:%d" % (key, hlen) def scan_set(source): #print "Begin Import Set Type" keys_count = len(set_keys) #print "Set Key Count is:",keys_count for key in set_keys: slen=source.scard(key) if slen > BigNum : print "Set key:%s, size:%d" % (key, slen) def scan_zset(source): #print "Begin Import ZSet Type" keys_count = len(zset_keys) #print "ZSet Key Count is:",keys_count for key in zset_keys: zlen = source.zcard(key) if zlen > BigNum : print "ZSet key:%s, size:%d" % (key, zlen) def scan_list(source): #print "Begin Import List Type" keys_count = len(list_keys) #print "List Key Count is:",keys_count for key in list_keys: llen= source.llen(key) if llen > BigNum : print "Hash key:%s, size:%d" % (key, llen) def scan_string(source): #print "Begin Import List Type" keys_count = len(string_keys) #print "List Key Count is:",keys_count for key in string_keys: slen= source.strlen(key) if slen > BigNum : print "String key:%s, size:%d" % (key, slen) def read_type_keys(source, ScanIndex): ScanIndex, keys = source.execute_command('scan', ScanIndex, "count",200000) keys_count = len(keys) #print "Key Count is:",keys_count pipe = source.pipeline(transaction=False) #for key in keys: index=0 pipe_size=5000 while index < keys_count: old_index=index num=0 while (index < keys_count) and (num < pipe_size): pipe.type(keys[index]) index +=1 num +=1 results=pipe.execute() for type in results: if type == "string": string_keys.append(keys[old_index]) elif type == "list": list_keys.append(keys[old_index]) elif type == "hash": hash_keys.append(keys[old_index]) elif type == "set": set_keys.append(keys[old_index]) elif type == "zset": zset_keys.append(keys[old_index]) else : print "no key" #print keys[old_index]," is not find when TYPE" old_index +=1 return ScanIndex if __name__=='__main__': argc = len(sys.argv) if argc < 3: print "usage: %s sourceIP sourcePort [password]" % (sys.argv[0]) exit(1) SrcIP = sys.argv[1] SrcPort = int(sys.argv[2]) Password = "" if argc == 4: Password = sys.argv[3] start=datetime.datetime.now() source=redis.Redis(host=SrcIP,port=SrcPort,password=Password) index=0 times=1 strNum=0 setNum=0 zsetNum=0 listNum=0 hashNum=0 print "begin scan key" while index != '0' or times == 1: first = False print "Times: ", times times += 1 index=read_type_keys(source, index) strNum += len(string_keys) setNum += len(set_keys) zsetNum += len(zset_keys) listNum += len(list_keys) hashNum += len(hash_keys) scan_hash(source) scan_list(source) scan_set(source) scan_zset(source) scan_string(source) string_keys=[] hash_keys=[] list_keys=[] set_keys=[] zset_keys=[] print "String Key Count is: ", strNum print "Set Key Count is : ", setNum print "ZSet Key Count is: ", zsetNum print "List Key Count is: ",listNum print "Hash Key Count is: ",hashNum stop=datetime.datetime.now() diff=stop-start print "Finish, token time:",str(diff)

2、Execute the script

./scan_big_key.py sourceIP sourcePort [password]