0%

python+redis

创建连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import redis

#创建连接
r = redis.Redis(
host="localhost",
port=6379,
db=0 #逻辑库号数,只能和一个数据库绑定在一起,无法中途改变
)

#创建连接池
try:
pool = redis.ConnectionPool(
host="localhost",
port=6379,
db=0,
max_connections=20
)
except Exception as e:
logging.error(e)
else:
#从连接池中获取连接,不必关闭,垃圾回收时,连接会自动被归还到连接池
r = redis.Redis(
connection_pool=pool
)
del r#此时连接已被归还到连接池

字符串操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
r.set("country","Singapore")
r.set("city","Singapore")
r.expire("city",3)
time.sleep(3)
try :
city = r.get("city").decode("utf-8")#若key不存在,则会报错
except AttributeError:
pass
else:
print(city)
r.delete("country","city") #当key已不存在时,不会报错
dict_ = {"country":"德国","city":"柏林"}
r.mset(dict_)
result = r.mget("country","city")#返回元组类型
for one in result:
print(one.decode("utf-8"))

列表操作

1
2
3
4
5
6
7
8
try:    
r.rpush("dname","d1","d2","d3")
r.lpop("dname")
result=r.lrange("dname",0,-1)#返回元组类型
for one in result:
print(one.decode("urf-8"))
except Exception as e:
pass

集合操作

1
2
3
4
5
6
7
8
9
r.sadd("employee",8001,8002,8003)
r.srem("employee",8001)
result = r.members("employ")#元组

#有序集合
dict_ = {"QAQ":0,"QWQ":0,"QVQ":0}#前面为词条,后面为分数值
r.zadd("keyword",dict_)
r.zincrby("keyword","10","QAQ")#为QAQ词条加十分
result = r.zrevrange("keyword",0,-1)#元组类型

哈希表

1
2
3
4
5
r.hmset("she",{"name":"Lily","age":19}) #redis4.0开始弃用hmset,推荐使用hset
r.hset("she","dream","flower and star")
r.hdel("she","dream")
print(r.hexists("she","name"))#返回True
result = r.hgetall("she")#元组

事务函数

1
2
3
4
5
6
pipline = r.pipline() #创建pipline对象
pipline.watch("she") #监视记录
pipline.multi() #开启事务
#各种操作用pipline完成而不是r
pipline.execute() #递交事务
pipline.reset() #关闭pipline,格外注意

线程池

为什么要创建线程池?

  • 若在程序中经常需要用到线程,线程的频繁创建和销毁会浪费很多硬件资源,所以需要分离线程和任务,线程可以反复利用,省去重复创建的麻烦。

    我们可以把每个任务写成函数,把其交给线程池,而线程池会选择一个空闲的线程去执行这个任务,这和数据库的连接池原理十分相似。

用模拟商品秒杀活动:利用pythonmo’ni商品秒杀的过程,Redis采用单线程机制,不会存在超买和超卖的情况。

1
2
3
4
5
6
7
8
9
10
11
12
from concurrent.futures import ThreadPoolExecutor

#定义线程任务
def say_hello():
print("hello")

if __name__ == "__main__":
#将线程池保存到变量中
executor = ThreadPoolExecutor(20)
for i in range(0,10):
#submit用于向线程池提交任务
executor.submit(say_hello)

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import logging
import random
from concurrent.futures import ThreadPoolExecutor
import redis
from models import redis_db

def buy(user_id):
try:
con_for_buy = redis.Redis(
connection_pool=redis_db.pool
)
pipline = con_for_buy.pipeline()
if con_for_buy.exists("kill_flag"):
total_num = int(con_for_buy.get("kill_total").decode("utf-8"))
num = int(con_for_buy.get("kill_num").decode("utf-8"))
pipline.watch("kill_num", "kill_user") # watch()里放即将要修改的key
if num < total_num:
pipline.incr("kill_num")
pipline.lpush("kill_user", user_id)
pipline.execute()
pipline.reset()
except Exception as e:
logging.error(e)
finally:
del con_for_buy

def is_param_exist():
try:
con = redis.Redis(
connection_pool=redis_db.pool
)
if con.exists("kill_total", "kill_flag", "kill_num"):
return True
else:
return False
except Exception as e:
logging.error(e)
return False
finally:
del con

def create_param():
try:
con = redis.Redis(
connection_pool=redis_db.pool
)
con.set("kill_total", 20)
con.set("kill_num", 0)
con.set("kill_flag", 1)
con.expire("kill_flag",600)
return True
except Exception as e:
logging.error(e)
return False
finally:
del con

def delete_param():
try:
con = redis.Redis(
connection_pool=redis_db.pool
)
con.delete("kill_total","kill_num","kill_flag","kill_user")
return True
except Exception as e:
logging.error(e)
return False
finally:
del con

if __name__ == "__main__":
s = set()
while True:
if len(s) == 1000:
break
s.add(random.randint(10000,100000))


if delete_param() is not True:
exit()
if create_param() is not True:
exit()
if is_param_exist() is not True:
exit()

try:
executor_ = ThreadPoolExecutor(50)
for i in range(0,1000):
user_id = s.pop()
executor_.submit(buy,user_id)
con = redis.Redis(
connection_pool=redis_db.pool
)
except Exception as e:
logging.error(e)
finally:
del executor_,con