需求
现在有一个文件列表,如果直接在文本里面做查询,效率很低也很慢,现在想导入到redis里面,然后再供后面的使用,那么这个操作怎么处理
功能需求
需要实现下面几个功能
- 导入
- 遍历
- 删除
查询的话,直接get key就可以了,所以这里是遍历的功能
导入功能的实现
使用单进程的导入
单进程的导入就是一行行的读取文本,然后塞入到数据库里面,我们看下实现这个时间是多少
文件条目数量
[root@lab102 ssd]# cat /root/chuli/file.list|wc -l
983040
[root@lab102 ssd]# time python3 filetoredis-rclone.py /root/chuli/file.list
0
开始时间为 : Thu Nov 25 11:31:10 2021
结束时间为 : Thu Nov 25 11:33:31 2021
real 2m20.554s
user 1m25.535s
sys 0m31.026s
代码如下:
#! /usr/bin/env python3
# -*- coding:utf-8 -*-
import sys
import redis
import time
starttime = time.asctime( time.localtime(time.time()) )
inputfile=sys.argv[1]
r=redis.StrictRedis(host='localhost',port=6379,db=0)
def filekeytoredis(inputfile):
for line in open(inputfile):
r.set(line.strip('\n'),0)
filekeytoredis(inputfile)
endtime = time.asctime( time.localtime(time.time()) )
print ("开始时间为 :", starttime)
print ("结束时间为 :", endtime)
98万文件的操作,使用了2分20秒完成导入
我们看下多进程的实现
使用多进程的导入
[root@lab102 pget]# time python3 filetoredis.py /root/chuli/file.list
开始时间为 : Thu Nov 25 11:43:24 2021
结束时间为 : Thu Nov 25 11:43:51 2021
real 0m27.962s
user 2m18.184s
sys 0m52.835s
98万文件的操作,使用了27秒完成导入,快了不少
filetoredis.py脚本内容如下:
#! /usr/bin/env python3
# -*- coding:utf-8 -*-
import sys
import redis
import time
import multiprocessing
starttime = time.asctime( time.localtime(time.time()) )
inputfile=sys.argv[1]
def initialize():
global r
r=redis.StrictRedis(host='localhost',port=6379,db=0)
linekeys=[]
def redisset(key):
r.set(key,0)
def filekeytoredis(inputfile):
count=len(open(inputfile).readlines())
for line in open(inputfile):
line=line.strip('\n')
linekeys.append(line)
count=count-1
if count < 20000:
if count==0:
pool = multiprocessing.Pool(20,initialize)
pool.map(redisset, linekeys)
pool.close()
pool.join()
else:
pass
else:
if len(linekeys) == 20000:
pool = multiprocessing.Pool(20,initialize)
pool.map(redisset, linekeys)
pool.close()
pool.join()
#print(linekeys)
linekeys.clear()
else:
pass
filekeytoredis(inputfile)
endtime = time.asctime( time.localtime(time.time()) )
print ("开始时间为 :", starttime)
print ("结束时间为 :", endtime)
上面的多进程的是读取文件列表,然后把文件列表分配给多个进程进行相关的处理
遍历功能的实现
单进程的遍历
[root@lab102 pget]# time python3 checkredis.py 0
real 0m6.825s
user 0m5.334s
sys 0m0.135s
脚本实现如下:
#! /usr/bin/env python3
# -*- coding:utf-8 -*-
# 本脚本是清理查询数据库,后面接db的编号
import sys
import redis
import time
starttime = time.asctime( time.localtime(time.time()) )
dbnumber=sys.argv[1]
r=redis.StrictRedis(host='localhost',port=6379,db=dbnumber)
cursor=0
while True:
cursor,keys = r.scan(cursor,match="*",count=20000)
for key in keys:
#print(key)
pass
if cursor == 0:
break
上面的6秒就完成了对98万key的遍历
这个地方还不清楚怎么多进程的实现,主要的时间本身就在拿cursor上面了
删除功能的实现
单进程的删除
[root@lab102 pget]# time python3 cleanredis.py 0
real 2m14.760s
user 1m21.221s
sys 0m30.077s
cleanredis.py删除脚本如下:
#! /usr/bin/env python3
# -*- coding:utf-8 -*-
# 本脚本是清理redis数据库,后面接db的编号
import sys
import redis
import time
starttime = time.asctime( time.localtime(time.time()) )
dbnumber=sys.argv[1]
r=redis.StrictRedis(host='localhost',port=6379,db=dbnumber)
cursor=0
while True:
cursor,keys = r.scan(cursor,match="*",count=10000)
for key in keys:
r.delete(key)
if cursor == 0:
break
单进程的删除98万要2分14秒
多进程的删除
[root@lab102 rclone]# time python3 cleanredis.py 0
real 0m38.574s
user 1m39.278s
sys 0m37.553s
脚本的内容如下
#! /usr/bin/env python3
# -*- coding:utf-8 -*-
# 本脚本是清理redis数据库,后面接db的编号
import sys
import redis
import time
import multiprocessing
starttime = time.asctime( time.localtime(time.time()) )
dbnumber=sys.argv[1]
r=redis.StrictRedis(host='localhost',port=6379,db=dbnumber)
def keydelete(key):
global r
r.delete(key)
cursor=0
while True:
cursor,keys = r.scan(cursor,match="*",count=10000)
pool = multiprocessing.Pool(10)
pool.map(keydelete, keys)
pool.close()
pool.join()
if cursor == 0:
break
98万条目,多进程的删除38秒
总结
通过redis存储一些数据确实是非常的快,这里只是导入遍历删除等操作,查询的话,直接进行get,一般是key val,如果是查key就是get,查val的就需要遍历里面去实现了,这里只是把最基本的一些操作记录下来
本篇里面通过单进程和多进程进行了实现,可以看到多进程的还是能够提升不小的速度的