1 redis之列表
'''
1 lpush(name, values)
2 rpush(name, values) 表示从右向左操作
3 lpushx(name, value)
4 rpushx(name, value) 表示从右向左操作
5 llen(name)
6 linsert(name, where, refvalue, value))
7 r.lset(name, index, value)
8 r.lrem(name, value, num)
9 lpop(name)
10 rpop(name) 表示从右向左操作
11 lindex(name, index)
12 lrange(name, start, end)
13 ltrim(name, start, end)
14 rpoplpush(src, dst)
15 blpop(keys, timeout)
16 r.brpop(keys, timeout),从右向左获取数据
17 brpoplpush(src, dst, timeout=0)
'''
import redis
conn = redis.Redis()
1 lpush(name, values) # 从左侧插入
conn.lpush('girls', '迪丽热巴', '刘亦菲') # 刘亦菲在迪丽热巴的左边
conn.lpush('girls', '周淑怡') # 默认插在最左
2 rpush(name, values) 表示从右向左操作
conn.rpush('girls', '小红')
3 lpushx(name, value)
conn.lpushx('boys','小刚') # 库里有boys K值才会创建value对象 这里还没有boys 所以不会创建
conn.lpush('boys','小刚') # 基本创k:V
conn.lpushx('boys','小刚')
#由于这里有boys Key值 所以会创建value=小刚
4 rpush(name, value) # 表示从右向左操作
conn.rpush('boys','吴彦祖','周润发')
5 rpushx(name, value) # 同理 有keys才会对列表进行从右往左的操作
6 llen(name)
res = conn.llen('girls')
# 判断value值的个数长度 里面有刘亦菲 迪丽热巴 周淑怡 输出结果为 3
7 linsert(name, where, refvalue, value)
# 插入 第一个条件 key值 第二个在哪 第三个标杆 最后一个是要插入的值
conn.linsert('girls','before','迪丽热巴','古力娜扎')
# 在girls里 迪丽热巴前面插入 古力娜扎
conn.linsert('girls', 'after', '小黑', '小嘿嘿') # 没有标杆,我的key值里没有小黑 所以小黑黑插入不进去
8 r.lset(name, index, value) # 按照位置修改值
conn.lset('girls',1,'xxx') # 索引也是从0开始
9 r.lrem(name, num, value) # 从左侧开始,删除1个
conn.lrem('girls',-1,'xxx') # 从右侧开始,删除1个xxx
conn.lrem('girls',0,'xxx') # 从左开始,全删除有xxx的value值
10 lpop(name) #从左边开始弹出第一个name对应的value值
res=conn.lpop('girls')
11 rpop(name) # 表示从右向左操作弹出第一个
12 lindex(name, index) # 索引取值
res = str(conn.lindex('girls', 1), encoding='utf-8')
print(res)
13 lrange(name, start, end)
res=conn.lrange('girls',2,4) # 前闭后闭区间 范围取值
res=conn.lrange('girls',0,0) # 取第一个
14 ltrim(name, start, end)
conn.ltrim('girls',2,3)
15 rpoplpush(src, dst)
# 需要两个列表 先弹出 再放入到另外一个
16 blpop(keys, timeout) # 记住,可以左消息队列使用 阻塞式弹出,如果没有。就阻塞
res = conn.blpop('boys')
conn.close()
'''
lpush
lpop
llen
lrange
'''
2 redis之hash
'''
1 hset(name, key, value)
2 hmset(name, mapping)
3 hget(name,key)
4 hmget(name, keys, *args)
5 hgetall(name)
6 hlen(name)
7 hkeys(name)
8 hvals(name)
9 hexists(name, key)
10 hdel(name,*keys)
11 hincrby(name, key, amount=1)
12 hincrbyfloat(name, key, amount=1.0)
13 hscan(name, cursor=0, match=None, count=None)
14 hscan_iter(name, match=None, count=None)
'''
import redis
conn = redis.Redis()
1 hset(name, key, value)
conn.hset('userinfo','name','wei')
conn.hset('userinfo',mapping={'age':19,'hobby':'篮球'}) # 设置多个
2 hmset(name, mapping) # 批量设置,被弃用了,以后都使用hset
# conn.hmset('userinfo2',{'age':19,'hobby':'篮球'})
3 hget(name,key)
res = conn.hget('userinfo','name')
print(res) # wei
4 hmget(name, key, *agrs)
res = conn.hmget('userinfo',['name','age'])
res = conn.hmget('userinfo', 'name', 'age') # 底层也会自动拼成['name','age'] 两者是一样的
print(res) # wei 19
5 hgetall(name) # 慎用
res=conn.hgetall('userinfo') # 一次性取所有 数据量会很大
6 hlen(name) # 判断长度
res = conn.hlen('userinfo')
print(res) # 3 name age hobby
7 hkeys(name) # 拿所有的k值
res = conn.hkeys('userinfo')
print(res) # name age hobby
8 hvals(name) # 拿所有的value对应的值
res = conn.hvals('userinfo')
print(res) # wei 19 篮球
9 hexists(name, key) # 判断是否存在
res = conn.hexists('userinfo', 'name') # True
res = conn.hexists('userinfo', 'name1') # False
10 hdel(name, *keys) # 删除
res = conn.hdel('userinfo','age') # 返回结果是0或者1
print(res)
11 hincrby(name, key, amount=1) # 自增
conn.hincrby('userinfo', 'age', 2) # 自增2 不写就是默认自增1
12 hincrbyfloat(name, key, amount=1.0) # 自增 带小数
13 hgetall 会一次性全部取出,效率低,可以能占内存很多
# 分批获取, hash类型是无序
# 插入一批数据
for i in range(100):
conn.hset('hash_test','id_%s'%i,'鸡蛋_%s号'%i)
res = conn.hgetall('hash_test') # 可以, 但是不好,一次性拿出,可能占很大内存
14 hscan(name, cursor=0, match=None, count=None) # 它不单独使用,拿的数据,不是特别精准
# res = conn.hscan('hash_test', cursor=0, count=5)
# print(len(res[1])) #(数字,拿出来的10条数据) 数字是下一个游标位置
# 咱们用这个 它内部用了hscan, 等同于hgetall 所有数据都拿出来 count的作用是 生成器,每次拿count个个数
15 hscan_iter(name, match=None, count=None)
res=conn.hscan_iter('hash_test',count=10)
print(res) # generator 只要函数中有yielid关键字,这个函数执行的结果就是生成器,生成器就是迭代器,可以被for循环
for i in res:
print(i)
'''
hset
hget
hmget
hlen
hdel
hscan_iter 获取所有值,但是省内存 等同于hgetall
'''
3 redis其他操作
'''通用操作 不指定类型,所有类型都支持
1 delete(*names)
2 exists(name)
3 keys(pattern='*')
4 expire(name ,time)
5 rename(src, dst)
6 move(name, db))
7 randomkey()
8 type(name)
'''
import redis
conn = redis.Redis()
1 delete(*names) # 删除
conn.delete('name','userinfo2') # 可以多个删除
# conn.delete(['name', 'userinfo2']) # 不能用它
conn.delete(*['name', 'userinfo2']) # 可以用它
2 exists(name) # 判断是否存在
res=conn.exist('userinfo')
print(res) # True
3 keys(pattern='*')
res = conn.keys('*') # 取所有的key值
res1 = conn.keys('*b') # 取所有带b的key值
res2=conn.keys('w?e') # ?表示一个字符, * 表示多个字符
print(res) # [b'boys', b'hobby', b'job', b'age']
print(res1) # [b'job']
print(res2) # []
4 expire(name, time) # 过期时间
conn.expire('userinfo',3) # 3秒之后过期
5 rename(src, dst) # 重命名
conn.rename('hobby','hobby111')
6 move(name, db) # 移动库
conn.move('hobby111', 8) # redis默认16库 把hobby111 移动到第八个库
7 randomkey()
res = conn.randomkey() # 随机一个key
8 type(name)
print(conn.type('age')) # b'string'
print(conn.type('boys')) # b'list'
4 redis 管道
# 事务----> 四大特性
-原子性
-一致性
-隔离性
-持久性
# redis支持事务吗 单例才支持所谓的事务,支持事务是基于管道的
-执行命令 一条一条执行
- 张三 金额 -100
conn.decr('zs_money', 100)
# 程序中断
- 李四 金额 +100
conn.incr('ls_money', 100)
-把这两条命令 放到一个管道中,先不执行,执行excute,一次性都执行完成
conn.decr('zs_money', 100) conn.incr('ls_money', 100)
# 如何使用
import redis
conn = redis.Redis()
p = conn.pipeline(transaction=True) # 开启事务
p.multi()
p.decr('zs_money', 100)
# raise Exception('崩了')
p.incr('ls_money', 100)
p.execute()
conn.close()
5 django中使用redis
## 方式一: 自定义包方案(通用的,不针对与框架,所有框架都可以用)
-第一步: 写一个pool.py
import redis
POOL = redis.ConnectionPool(max_connections=100)
# 第二步:以后再使用的地方,直接导入即可
conn = redis.Redis(connection_poo=POOL)
conn.incr('count')
res = conn.get('count')
## 方式二: django 方案
-方案一: django的缓存使用redis 【推荐使用】
-setting.py
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100}
# "PASSWORD": "123",
}
}
}
-再使用redis的地方:
def test_redis(request):
res = cache.get('count')
cache.set('count', res+1)
-pickle序列化后,存入的
-方案二: 第三方: django-redis模块
from django_redis import get_redis_connection
def test_redis(request):
conn=get_redis_connection()
print(conn.get('count'))
return JsonResponse({'count': '今天这个接口被访问的次数为:%s'}, json_dumps_params={'ensure_ascii': False})
5 celery介绍和安装
# Celery 是什么
-翻译过来是 芹菜 但是和芹菜没有什么关系
-框架:服务,python的框架,跟django无关
-能用来做什么
-1 异步任务
-2 定时任务
-3 延时任务
# 理解celery的运行原理
"""
1 可以不依赖任何服务器,通过自身命令,启动服务
2 celery服务为其他项目服务提供异步解决任务需求的
注:会有两个服务同时运行,一个是项目服务,一个是celery服务,项目服务将需要异步处理的任务交给celery服务,celery就会在需要时异步完成项目的需求
人是一个独立运行的服务 | 医院也是一个独立运行的服务
正常情况下,人可以完成所有健康情况的动作,不需要医院的参与;但当人生病时,就会被医院接收,解决人生病问题
人生病的处理方案交给医院来解决,所有人不生病时,医院独立运行,人生病时,医院就来解决人生病的需求
"""
# celery架构(Broker, backend 都用redis)
-1 任务中间件 Broker(中间件), 其他服务提交的异步任务,放在里面排队
-需要借助于第三方 redis rabbitmq
-2 任务执行单元 worker 真正执行异步任务的进程
-celery提供的
-3 结果存储 backend 结果存储,函数的返回结果,存到 backend中
-需要借助于第三方: redis, mysql
# 使用场景
异步执行: 解决耗时任务
延迟执行:解决延迟任务
定时执行: 解决周期(周期)任务
# celery 不支持win 通过eventlet支持在win上运行
6 celery快速使用
# 安装---> 安装完成,会有一个可执行文件 celery
pip install celery
win: pip install eventlet
# 快速使用
###### 第一步: 新建 main.py ####
from celery import Celery
# 提交的异步任务,放在里面
broker = 'redis://127.0.0.1:6379/1'
# 执行完的结果,放在这里
backend = 'redis://127.0.0.1:6379/2'
app = Celery('test', broker=broker, backend=backend)
@app.task
def add(a, b):
import time
time.sleep(3)
print('------',a + b)
return a + b
###### 第二步: 其他程序,提交任务 ######
res = add.delay(5,6) # 原来add的参数,直接放在delay中传入即可
print(res) # 22e149bf-16fa-4e95-bad8-d89182a5ba83
####### 第三步: 启动worker
# 启动worker命令,win需要安装eventlet
win:
-4.0之前版本
celery worker -A main -l info -P eventlet
-4.x之后
celery -A main worker -l info -P eventlet
mac:
celery -A main worker -l info
###### 第四步: worker会执行消息中间件中的任务,把结果存起来#####
### 第五步:咱们要看执行结果,拿到执行的结果 #####
from main import app
from celery.result import AsyncResult
id = '22e149bf-16fa-4e95-bad8-d89182a5ba83'
if __name__ == '__main__':
a = AsyncResult(id=id, app=app)
if a.successful(): # 执行完了
result = a.get() #
print(result)
elif a.failed():
print('任务失败')
elif a.status == 'PENDING':
print('任务等待中被执行')
elif a.status == 'RETRY':
print('任务异常后正在重试')
elif a.status == 'STARTED':
print('任务已经开始被执行')
7 celery包结构
project
├── celery_task # celery包
│ ├── __init__.py # 包文件
│ ├── celery.py # celery连接和配置相关文件,且名字必须交celery.py
│ └── tasks.py # 所有任务函数
├── add_task.py # 添加任务
└── get_result.py # 获取结果
############# 第一步:新建包 celery_task #############
# 在包下新建[必须叫celery]的py文件,celery.py 写代码
from celery import Celery
broker = 'redis://127.0.0.1:6379/1'
backend = 'redis://127.0.0.1:6379/2'
app = Celery('test', broker=broker, backend=backend, include=['celery_task.order_task', 'celery_task.user_task'])
##### 第二步:在包内部,写task,任务异步任务####
# order_task
from .celery import app
import time
@app.task
def add(a, b):
print('-----', a + b)
time.sleep(2)
return a + b
# user_task
from .celery import app
import time
@app.task
def send_sms(phone, code):
print("给%s发送短信成功,验证码为:%s" % (phone, code))
time.sleep(2)
return True
###第四步:其他程序 提交任务,被提交到中间件中,等待worker执行,因为worker启动了,就会被worker执行
# handup.py
from celery_task.user_task import send_sms
from celery_task.order_task import add
'异步调用'
res = send_sms.delay(199999999, '88888')
print(res)
# res = add.delay(19, 3)
# print(res)
####第三步:启动worker ,包所在目录下
celery -A celery_task worker -l info -P eventlet
### 第五步:worker执行完,结果存到backend中
### 第六步:我们查看结构
from celery_task import app
from celery.result import AsyncResult
id = '7d39033c-4cc7-4af2-8d78-e62c277db183'
if __name__ == '__main__':
a = AsyncResult(id=id, app=app)
if a.successful(): # 执行完了
result = a.get() #
print(result)
elif a.failed():
print('任务失败')
elif a.status == 'PENDING':
print('任务等待中被执行')
elif a.status == 'RETRY':
print('任务异常后正在重试')
elif a.status == 'STARTED':
print('任务已经开始被执行')
标签:name,res,redis,celery,路飞,print,conn
From: https://www.cnblogs.com/wei0919/p/17196480.html