学习目标
- 掌握redis-py的连接池
- 掌握redis-py模板的CURD操作
- 掌握redis-py模块管理事务
- 完成具体的Redis案例
redis-py常用的操作指令
创建连接池
# -*- encoding: utf-8 -*-
"""
@File : redis_db.py
@Time : 2021-08-23 15:52
@Author : XD
@Email : gudianpai@qq.com
@Software: PyCharm
"""
import redis
try:
pool = redis.ConnectionPool(
host = "localhost",
port = 6379,
db = 0,
max_connections = 20
)
except Exception as e:
print(e)
字符串类型
# -*- encoding: utf-8 -*-
"""
@File : example_1.py
@Time : 2021-08-23 15:51
@Author : XD
@Email : gudianpai@qq.com
@Software: PyCharm
"""
from redis_db import pool
import redis
con = redis.Redis(
connection_pool = pool
)
con.set("country", "英国")
con.set("city", "伦敦")
city = con.get("city").decode("utf-8")
con.expire("city", 5) #过期时间五秒钟
print(city)
del con
# -*- encoding: utf-8 -*-
"""
@File : example_2.py
@Time : 2021-08-23 16:28
@Author : XD
@Email : gudianpai@qq.com
@Software: PyCharm
"""
from redis_db import pool
import redis
#获得一个连接
con = redis.Redis(
connection_pool = pool
)
try:
con.delete("country", "city")
con.mset({"country":"德国","city":"柏林"})
result = con.mget("country","city")
for one in result:
print(one.decode("utf-8"))
except Exception as e:
print(e)
finally:
del con
列表类型
# -*- encoding: utf-8 -*-
"""
@File : example_3.py
@Time : 2021-08-23 19:19
@Author : XD
@Email : gudianpai@qq.com
@Software: PyCharm
"""
from redis_db import pool
import redis
con = redis.Redis(
connection_pool = pool
)
try:
con.rpush("dname","董事会","秘书处","财务部","技术部")
con.lpop("dname")
result = con.lrange("dname", 0, -1)
for one in result:
print(one.decode("utf-8"))
except Exception as e:
print(e)
finally:
del con
集合类型
# -*- encoding: utf-8 -*-
"""
@File : example_4.py
@Time : 2021-08-23 20:14
@Author : XD
@Email : gudianpai@qq.com
@Software: PyCharm
"""
from redis_db import pool
import redis
con = redis.Redis(
connection_pool = pool
)
try:
con.sadd("employee",8001,8002,8003)
con.srem("employee",8002)
result = con.smembers("employee")
for one in result:
print(one.decode("utf-8"))
con.zadd("keyword",{"马云":0,"张朝阳":0,"丁磊":0})
con.zincrby("keyword",10,"马云")
result = con.zrevrange("keyword",0,-1)
for one in result:
print(one.decode("utf-8"))
except Exception as e:
print(e)
finally:
del con
8001
8003
马云
张朝阳
丁磊
哈希类型
# -*- encoding: utf-8 -*-
"""
@File : example_5.py
@Time : 2021-08-23 20:49
@Author : XD
@Email : gudianpai@qq.com
@Software: PyCharm
"""
from redis_db import pool
import redis
con = redis.Redis(
connection_pool = pool
)
try:
con.hmset("9527",{"name:":"scott","sex":"male","age":35})
con.hset("9527","city","纽约")
con.hdel("9527","age")
result = con.hexists("9527","sex")
print(result)
result = con.hgetall("9527")
# for one in result:
# print(one.decode("utf-8"), result[one].decode("utf-8"))
for k, v in result.items():
print(k.decode("utf-8"), v.decode("utf-8"))
except Exception as e:
print(e)
finally:
del con
True
name: scott
sex male
city 纽约
利用redis缓存学生成绩
# -*- encoding: utf-8 -*-
"""
@File : example_8.py
@Time : 2021-08-24 13:49
@Author : XD
@Email : gudianpai@qq.com
@Software: PyCharm
"""
#练习1,从txt文档中解析学生的信息,把考试语数外成绩超过85分的同学信息缓存到哈希表中
from redis_db import pool
import redis
con = redis.Redis(
connection_pool = pool
)
try:
file = open(file = "chengji.txt",mode = "r", encoding = "utf-8")
data = file.read().splitlines()#元组
for one in data:
temp = one.split(",")
sid = temp[0]
name = temp[1]
classno = temp[2]
score_1 = int(temp[3])
score_2 = int(temp[4])
score_3 = int(temp[5])
if score_1 >= 85 and score_2 >= 85 and score_3 >= 85:
con.hmset(sid, {"name":name,
"classno":classno,
"score_1":score_1,
"score_2":score_2,
"score_3":score_3})
except Exception as e:
print(e)
finally:
if "file" in dir():
file.close()
del con
redis事务机制
- redis事务机制为了什么?为了在并发执行时,被别的客户端的命令插队。事务机制就为了解决这个插队执行的问题。
2.为了实现数据的一致性 在开启事务之前务必需要用watch命令监视要操作的记录,如果数据被别的客户端修改了则该事务关闭。满足了数据的一致性。
# -*- encoding: utf-8 -*-
"""
@File : example_7.py
@Time : 2021-08-24 11:35
@Author : XD
@Email : gudianpai@qq.com
@Software: PyCharm
"""
#redis用pipline(管道)的方式向redis服务器传递批处理命令和执行事务
from redis_db import pool
import redis
con = redis.Redis(
connection_pool = pool
)
try:
pipline = con.pipeline()
pipline.watch("9527")
pipline.multi()
pipline.hset("9527","name","jack")
pipline.hset("9527","age",23)
pipline.execute()
except Exception as e:
print(e)
finally:
if "pipline" in dir():
pipline.reset()
del con
缓存观众投票数据信息案例
# -*- encoding: utf-8 -*-
"""
@File : example_6.py
@Time : 2021-08-23 21:05
@Author : XD
@Email : gudianpai@qq.com
@Software: PyCharm
"""
#用python程序模拟300位观众,为5位嘉宾随机投票,最后按照降序排列结果
from redis_db import pool
import redis
import random
con = redis.Redis(
connection_pool = pool
)
try:
con.delete("ballot")
con.zadd("ballot",{"马云":0,"丁磊":0,"张朝阳":0,"马化腾":0,"李彦宏":0})
names = ["马云","丁磊","张朝阳","马化腾","李彦宏"]
for i in range(0, 300):
num = random.randint(0,4)
name = names[num]
con.zincrby("ballot", 1 , name)
result = con.zrevrange("ballot",0, -1, "WITHSCORES")#希望得到元组值和分数值要加上"WITHSCORES"
for one in result:
print(one[0].decode("utf-8"), int(one[1]))
except Exception as e:
print(e)
finally:
del con
丁磊 71
李彦宏 60
张朝阳 60
马化腾 57
马云 52
线程池简单案例
# -*- encoding: utf-8 -*-
"""
@File : example_9.py
@Time : 2021-08-24 16:33
@Author : XD
@Email : gudianpai@qq.com
@Software: PyCharm
"""
from concurrent.futures import ThreadPoolExecutor
def say_hello():
print("hello")
excutor = ThreadPoolExecutor(50)
for i in range(0, 10):
excutor.submit(say_hello)
hello
hello
hello
hello
hello
hello
hello
hello
hello
hello
模拟秒杀
redis事务机制为了什么?为了在并发执行时,被别的客户端的命令插队。事务机制就为了解决这个插队执行的问题。为了实现数据的一致性 在开启事务之前务必需要用watch命令监视要操作的记录,如果数据被别的客户端修改了则该事务关闭。满足了数据的一致性。
# -*- encoding: utf-8 -*-
"""
@File : example_10.py
@Time : 2021-08-24 18:14
@Author : XD
@Email : gudianpai@qq.com
@Software: PyCharm
"""
#利用python多线程模拟商品秒杀活动,不可以出现超买和超卖的情况,假设A商品有50件参与秒杀活动,10分钟秒杀自动结束
import redis
from redis_db import pool
import random
from concurrent.futures import ThreadPoolExecutor
#生成用户ID
id = set()
while True:
if len(id) == 1000:
break
num = random.randint(10000,100000)
id.add(num)
con = redis.Redis(
connection_pool = pool
)
try:
con.delete("kill_total", "kill_num", "kill_flag", "kill_user")
con.set("kill_total", 50)
con.set("kill_num", 0)
con.set("kill_flag", 1)
con.expire("kill_flag", 10)
except Exception as e:
print(e)
finally:
del con
#线程池
executor = ThreadPoolExecutor(200)
def buy():
connection = redis.Redis(
connection_pool = pool
)
pipline = connection.pipeline()
try:
if connection.exists("kill_flag") == 1:
pipline.watch("kill_num", "kill_user",)
total = int(pipline.get("kill_total").decode("utf-8"))
num = int(pipline.get("kill_num").decode("utf-8"))
if num < total:
pipline.multi()
pipline.incr("kill_num")
user_id = id.pop()
pipline.rpush("kill_user", user_id)
pipline.execute()
except Exception as e:
print(e)
finally:
if "pipline" in dir():
pipline.reset()
del connection
for i in range(0, 1000):
executor.submit(buy)
print("秒杀已经结束")
Watched variable changed.
Watched variable changed.
Watched variable changed.
Watched variable changed.
Watched variable changed.
Watched variable changed.
Watched variable changed.
Watched variable changed.
Watched variable changed.
Watched variable changed.
Watched variable changed.
秒杀已经结束
Too many connections
Too many connections
Too many connections
Too many connections
Too many connections