當前位置:
首頁 > 最新 > 獲取沒有設置TTL的key

獲取沒有設置TTL的key

一 前言

在運維Redis的時候,總會遇到使用不規範的業務設計,比如沒有對key設置ttl,進而導致內存空間吃緊,通常的解決方法是在slave上dump 出來所有的key ,然後對文件進行遍歷再分析。遇到幾十G的Redis實例,dump + 分析 會是一個比較耗時的操作,為此,我開發了一個小腳本直接連接Redis 進行scan 遍歷所有的key,然後在檢查key的ttl,將沒有ttl的key輸出到指定的文件裡面。


# encoding: utf-8

"""

author: yangyi@youzan.com

time: 2018/4/26 下午4:34

func: 獲取資料庫中沒有設置ttl的 key

"""

importredis

importargparse

importtime

importsys

classShowProcess:

"""

顯示處理進度的類

調用該類相關函數即可實現處理進度的顯示

"""

i =# 當前的處理進度

max_steps =# 總共需要處理的次數

max_arrow =50# 進度條的長度

# 初始化函數,需要知道總共的處理次數

def__init__(self,max_steps):

self.max_steps = max_steps

self.i =

# 顯示函數,根據當前的處理進度i顯示進度

# 效果為[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]100.00%

defshow_process(self,i =None):

ifiis notNone:

self.i = i

else:

self.i +=1

num_arrow =int(self.i *self.max_arrow /self.max_steps)# 計算顯示多少個">"

num_line =self.max_arrow - num_arrow# 計算顯示多少個"-"

percent =self.i *100.0/self.max_steps# 計算完成進度,格式為xx.xx%

process_bar ="["+">"* num_arrow +" "* num_line +"]"

+"%.2f"% percent +"%"+"
"# 帶輸出的字元串,"
"表示不換行回到最左邊

sys.stdout.write(process_bar)# 這兩句列印字元到終端

sys.stdout.flush()

defclose(self,words="done"):

print""

printwords

self.i =

defcheck_ttl(redis_conn,no_ttl_file,dbindex):

start_time = time.time()

no_ttl_num =

keys_num = redis_conn.dbsize()

print"there are keys in db ".format(num=keys_num,index=dbindex)

process_bar = ShowProcess(keys_num)

withopen(no_ttl_file,"a")asf:

forkeyinredis_conn.scan_iter(count=1000):

process_bar.show_process()

ifredis_conn.ttl(key) == -1:

no_ttl_num +=1

ifno_ttl_num

f.write(key+"
")

else:

continue

process_bar.close()

print"cost time(s):",time.time() - start_time

print"no ttl keys number:",no_ttl_num

print"we write keys with no ttl to the file: %s"% no_ttl_file

defmain():

parser = argparse.ArgumentParser()

parser.add_argument("-p",type=int,dest="port",action="store",help="port of redis ")

parser.add_argument("-d",type=str,dest="db_list",action="store",default=,

help="ex : -d all / -d 1,2,3,4 ")

args = parser.parse_args()

port = args.port

ifargs.db_list =="all":

db_list = [iforiinxrange(,16)]

else:

db_list = [int(i)foriinargs.db_list.split(",")]

forindexindb_list:

try:

pool = redis.ConnectionPool(host="127.0.0.1",port=port,db=index)

r = redis.StrictRedis(connection_pool=pool)

exceptredis.exceptions.ConnectionErrorase:

printe

else:

no_ttl_keys_file ="/tmp/__no_ttl_keys.txt".format(port=port,db=index)

check_ttl(r,no_ttl_keys_file,index)

if__name__ =="__main__":

main()

注意:

代碼裡面對沒有ttl的key的輸出做了限制,大家使用的時候可以調整閾值 或者去掉 全部輸出到指定的文件裡面。歡迎大家使用,並給出功能或者演算法上的改進措施。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 大千世界 的精彩文章:

真正的仁慈是近乎冷漠的
《水形物語》被誤解的人魚戀

TAG:大千世界 |