需求
- 查询redis中ttl=-1的key
- 输出到文档中
代码 (python)
import redis
import argparse
import time
import sys
import os
class ShowProcess:
i = 0
max_steps = 0
max_arrow = 50
def __init__(self, max_steps):
self.max_steps = max_steps
self.i = 0
def show_process(self, i=None):
if i is not None:
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
process_bar = '[' + '>' * num_arrow + ' ' * num_line + ']' \
+ '%.2f' % percent + '%' + '\r'
sys.stdout.write(process_bar)
sys.stdout.flush()
def close(self, words='done'):
print
''
print
words
self.i = 0
def check_ttl(redis_conn, no_ttl_file, dbindex):
start_time = time.time()
no_ttl_num = 0
keys_num = redis_conn.dbsize()
print
"there are {num} keys in db {index} ".format(num=keys_num, index=dbindex)
process_bar = ShowProcess(keys_num)
with open(no_ttl_file, 'a') as f:
for key in redis_conn.scan_iter(count=1000):
process_bar.show_process()
if redis_conn.ttl(key) == -1:
no_ttl_num += 1
if no_ttl_num < 1000:
f.write(key + '\n')
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
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-password', type=str, dest='password', action='store', help='password of redis ')
parser.add_argument('-port', type=int, dest='port', action='store', help='port of redis ')
parser.add_argument('-db', type=str, dest='db_list', action='store', default=0,
help='ex : -d all / -d 1,2,3,4 ')
parser.add_argument('-host', type=str, dest='host', action='store', default='127.0.0.1',
help='host of redis ')
args = parser.parse_args()
port = args.port
password = args.password
host = args.host
path = os.getcwd()
if args.db_list == 'all':
db_list = [i for i in xrange(0, 16)]
else:
db_list = [int(i) for i in args.db_list.split(',')]
for index in db_list:
try:
pool = redis.ConnectionPool(host=host, port=port, password=password, db=index)
r = redis.StrictRedis(connection_pool=pool)
except redis.exceptions.ConnectionError as e:
print
e
else:
no_ttl_keys_file = "{path}/{host}_{port}_{db}_no_ttl_keys.txt".format(path=path, host=host, port=port,
db=index)
check_ttl(r, no_ttl_keys_file, index)
if __name__ == '__main__':
main()
代码(Shell)
db_host={你的redis host}
db_port={你的redis port}
db_pwd={你的redis password}
async_count=200
function checkTTL() {
host=$1
port=$2
pwd=$3
key=$4
ttl_result=$(redis-cli -h $host -p $port -a $pwd TTL $key)
if [[ $ttl_result == -1 ]]; then
echo $key >>./tmp/no_ttl_scan.log
fi
}
function fixTTL() {
host=$1
port=$2
pwd=$3
key=$4
ttl_result=$(redis-cli -h $host -p $port -a $pwd TTL $key)
if [[ $ttl_result == -1 ]]; then
new_ttl=$(($RANDOM + 2592000))
reuslt=$(redis-cli -h $host -p $port -a $pwd EXPIRE $key $new_ttl)
echo "$key | $new_ttl | $reuslt" >>./tmp/no_ttl_fix.log
fi
}
if [ ! -d "./tmp" ]; then
mkdir ./tmp
fi
if [ ! -f ./tmp/KEYSPACE ]; then
redis-cli -h $db_host -p $db_port -a $db_pwd INFO KEYSPACE >./tmp/KEYSPACE
echo "INFO KEYSPACE重新查询"
fi
keys_count=$(cat ./tmp/KEYSPACE | grep 'keys' | awk '{t=$0;gsub( ".*keys=|,expires.*" ,"" ,t );print t}' | awk -FS '{sum+=$1} END {print sum}')
echo "KEY总数[$keys_count]"
if [ -f "./tmp/count_list" ]; then
cat "./tmp/count_list" | awk -FS '{sum+=$1} END {print sum}' >>./tmp/count_total
else
echo "0" >>./tmp/count_total
fi
new_cursor=$(sed -n '1p' ./tmp/scan_tmp)
if [[ -n $new_cursor ]]; then
echo "从历史游标[$new_cursor]开始"
else
echo "从全新游标[0]开始"
new_cursor=0
fi
while :; do
{
if [[ ! "$new_cursor" =~ ^[0-9]+$ ]]; then
echo "当前游标异常[$new_cursor], 退出"
exit
fi
echo "当前游标[$new_cursor], 每次查询[$async_count]个"
redis-cli -h $db_host -p $db_port -a $db_pwd SCAN $new_cursor COUNT $async_count >./tmp/scan_tmp
new_cursor=$(sed -n '1p' ./tmp/scan_tmp)
if [[ $new_cursor == 0 ]]; then
echo "当前游标[$new_cursor], 退出"
break 2
fi
sed -n '2,$p' ./tmp/scan_tmp >./tmp/key_tmp
cat ./tmp/key_tmp | while read line; do
if [[ $1 == "-f" ]]; then
fixTTL $db_host $db_port $db_pwd $line &
else
checkTTL $db_host $db_port $db_pwd $line &
fi
done
wait
echo $async_count >>./tmp/count_list
total=$(($(sed -n '$p' ./tmp/count_total) + $async_count))
echo $total >>./tmp/count_total
echo "当前已经扫描[$total|$keys_count]"
sleep 0.2
}
done