安装redis-py模块 :
pip3 install redis -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
1. 创建连接
创建连接对象与线程池对象,最后封装连接池:
python
import redis
try:
pool = redis.ConnectionPool(
host='localhost',
port=6379,
#password='123456',
db=0,
max_connections=2000
)
except Exception as e:
print(e)
2.基本键值对管理
从连接池中获取连接、设置键值对、获取键值、设置键的过期时间以及删除键。
python
from redis_db import pool
import redis
#从连接池中获取一根连接,赋值跟conn
conn = redis.Redis(connection_pool=pool)
conn.set("country","中国")
conn.set("city","沈阳")
conn.set("s.country","日本")
country = conn.get("s.country").decode("utf-8")
# 30秒后销毁日本
conn.expire("s.country",30)
print(country)
#删除数据
conn.delete("city")
#删除连接
del conn
3.操作五种数据类型
初始化Redis连接:
python
from redis_db import pool
import redis
conn = redis.Redis(connection_pool=pool)
3.1 操作字符串
python
#多个字符串操作
#mset必须传入字典类型的数据
conn.mset({
"country":"中国",
"city":"沈阳",
})
result = conn.mget("country","city")
for one in result:
print(one.decode("utf-8"))
del conn
3.2 操作列表
python
#列表
conn.lpush(
"dname","董会","秘处","财部","技部"
)
result = conn.lrange("dname",0,-1)
# 随机删除
# conn.lpop("dname")
for one in result:
print(one.decode("utf-8"))
del conn
3.3 操作集合
python
#集合
conn.sadd("employee",8001,8002,8003)
conn.srem("employee",8002)
result = conn.smembers("employee")
for one in result:
print(one.decode("utf-8"))
del conn
3.4 操作有序集合
python
conn.zadd("keyword",{"Adela":0,"Hela":0,"Zoya":0})
conn.zincrby("keyword",10,"Adela")
result = conn.zrevrange("keyword",0,-1)
for one in result:
print(one.decode("utf-8"))
del conn
3.5 操作哈希表
python
#哈希
conn.hset("9527","ciy","北京")
result = conn.hexists("9527","name")
print(result)
result = conn.hgetall("9527")
for one in result:
print(one.decode("utf-8"),result[one].decode("utf-8"))
del conn
4.事务函数
redis-py模块用pipeline(管道)的方式向Redis服务器传递批处理命令和执行事务
python
# 事务控制
from redis_db import pool
import redis
conn = redis.Redis(connection_pool=pool)
try:
pipline = conn.pipeline() # 通过管道模块实现事务控制
pipline.watch("9527")
pipline.multi() # 启动事务控制
pipline.hset("9527","name1","tom")
pipline.hset("9527","age1","33")
pipline.execute() # 提交事务
except Exception as e:
print(e)
pipline.reset() #回滚
finally:
if "pipline" in dir():
pipline.close()
5.观众投票数据信息案例
用Python程序模拟300位观众,为5位嘉宾(马云、马明哲、张朝阳、马化腾、李彦宏)随机投票,
最后,按照降序排列结果。
python
import random
from redis_db import pool
import redis
conn = redis.Redis(connection_pool=pool)
conn.delete("ballot")
conn.zadd("ballot", {"马云":0,"马明哲":0,"张朝阳":0,"马化腾":0,"李彦宏":0})
names =["马云","马明哲","张朝阳","马化腾","李彦宏"]
for i in range(0,300):
num = random.randint(0,4)
name = names[num]
conn.zincrby("ballot",1,name)
result = conn.zrevrange("ballot",0,-1,"WITHSCORES")
for one in result:
print(one[0].decode("utf-8"),int(one[1]))
6.使用线程池并发执行函数
这段代码将创建一个包含 20 个线程的线程池,
并提交 10 个 say_hello
函数的执行任务到线程池中。
由于线程池的大小是 20,所以这 10 个任务将并发执行,但任何时刻最多只有 20 个线程在运行。
如果 say_hello
函数执行的时间非常短,你可能会看到 "Hello World!" 被快速打印多次,具体打印顺序取决于线程的调度。
python
from concurrent.futures.thread import ThreadPoolExecutor
def say_hello():
print("Hello World!")
executor = ThreadPoolExecutor(20)
for i in range(0,10):
executor.submit(say_hello)
7.模拟商品秒杀活动案例
利用Python多线程模拟商品秒杀过程,不可以出现超买和超卖的情况。假设A商品有50件参与秒杀活 动,10分钟秒杀自动结束。
python
from concurrent.futures.thread import ThreadPoolExecutor
import random
from redis_db import pool
import redis
import threading
lock = threading.Lock()
# 1000个人的id值
s = set()
while True:
if len(s) == 1000:
break
num = random.randint(1000, 10000)
s.add(num)
# 初始化数据
try:
conn = redis.Redis(connection_pool=pool)
conn.delete("kill_total","kill_num","kill_flag","kill_user")
conn.set("kill_total",50)
conn.set("kill_num",0)
conn.set("kill_flag",1)
#秒杀活动,过去时长
conn.expire("kill_flag",600)
except Exception as e:
print(e)
finally:
del conn
#线程池
executor = ThreadPoolExecutor(200)
#秒杀过程
def buy():
conn = redis.Redis(connection_pool=pool)
pipline = conn.pipeline()
try:
if conn.exists("kill_flag") == 1:
#秒杀数量与用户数量满足一致性
lock.acquire()
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")#秒杀数量+1
user_id = s.pop()# 随机删除用户id并返回删除的值
pipline.rpush("kill_user",user_id)#用户id追加至redis的kill_user中
pipline.execute()
lock.release()
except Exception as e:
print(e)
pipline.reset()
finally:
del conn
#开启秒杀
for i in range(0,1000):
executor.submit(buy)
print("秒杀活动结束")