这里写目录标题
一.昨日回顾
1 redis:内存数据库,key-value方式存储,有5大数据类型,存取速度快,通常用来做缓存数据库
-缓存数据库:放在mysql中的数据,在redis中存一份
-计数(网站访问量,文章阅读量...)
-分布式
-游戏,歌曲,排行榜..
-redis和memche比较:都是内存数据库,redis支持持久化,redis数据类型丰富
-redis为什么这么快? 10w qbs (每秒查询率)--->6w作用
-纯内存
-io多路复用(epoll),非阻塞式io
-单线程,避免了线程间切换(6.x以后,已经多线程了)
2 安装(开源软件,源代码开源,C语言写的),在不同平台编译--->可执行文件-->执行
-官网下载都是源码包--->make,make install --->可执行文件
-网上找专门的Windows安装包(官方不提供),一路下一步即可
-是一个c/s架构的软件
-启动服务端:redis-server.exe 配置文件路径(默认情况下做成了服务)
-客户端连接:redis-cli -h 地址 -p 端口
-图形化界面客户端:RedisDesktopManager
-使用不同语言的客户端连接:python,go,java
3 python操作redis
-pip3 install redis
4 普通连接和连接池
-连一次,操作完,关闭
-最开始造出很多连接,每次从池中取一个连接使用
5 reids之字符串操作
# set:超时时间,nx,xx
# get
# mset
# mget
# incr
# decr
# getrange
# setrange
# append
6 redis之hash操作
hset
hget
hmset
hmget
hincrby
hdel
hexists
hscan_iter/hgetall 区分
二.今日内容
2.1redis之列表操作
import redis
#
# class MyRedis():
# def __enter__(self):
# self.conn = redis.Redis()
# return self.conn
#
# def __exit__(self, exc_type, exc_val, exc_tb):
# self.conn.close()
#
#
# with MyRedis() as conn:
# 列表操作
# 1 lpush(name,values)
# conn.lpush('l1',1,2,3,4,5,'lqz')
# 2 rpush
# conn.rpush('l1','egon')
# 3 lpushx(name,value)
# 在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边
# conn.lpushx('l2',9)
# conn.lpushx('l1',9)
# llen(name)
# res=conn.llen('l1')
# print(res)
# linsert(name, where, refvalue, value)) 在某个位置插入值
# where :BEFORE或AFTER,大小写都行
# refvalue: lqz 表示以lqz为标准(不是下标索引)
# conn.linsert('l1','after','lqz','刘亦菲')
# conn.linsert('l1','before','lqz','baby')
# lset
# conn.lset('l1',0,'黄晓明')
# conn.lset('l1',5,'老伙计')
# lrem
# 第二个参数count:
# count = 0,删除列表中所有的指定值;
# count=2,从前到后,删除2个;
# count=-2,从后向前,删除2个
# conn.lrem('l1',0,'lqz') # 把所有lqz都删除
# conn.lrem('l1',2,'lqz') # 从前往后,删除2个lqz
# conn.lrem('l1',-1,'lqz') # 从前往后,删除2个lqz
# lpop
# res=conn.lpop('l1')
# res=conn.rpop('l1')
# print(res)
# lindex(不删除)
# res=conn.lindex('l1',0)
# print(res)
# lrange # 前闭后闭区间
# res = conn.lrange('l1', 0, 0)
# print(res)
# ltrim
# res=conn.ltrim('l1',3,5)
# print(res)
# rpoplpush 需要两个列表
# conn.lpush('l2','lqz','egon')
# conn.rpoplpush('l1','l1')
# blpop # block:阻塞 左边弹出
# res=conn.blpop('l1')
# print(res)
'''
lpush
llen
linsert
lset
lrem
lpop
lrange # 使用它,自定义增量迭代
blpop
'''
### redis类库中没有提供对列表元素的增量迭代,借助lrange
import redis
conn = redis.Redis()
# res=conn.lrange('l2',0,9999) # 全部取出来
# res=conn.lrange('l2',0,conn.llen('l2')) # 从0取到列表长度
# 类似于字典的hgetall,一次性全取出来,存在的问题是,因为不知道列表有多大,很有可能撑爆内存
# 我们实现一个增量迭代
# print(res)
# for i in range(10000):
# conn.lpush('l_test','test_%s'%i)
# res=conn.lrange('l2',0,conn.llen('l2'))
# print(res)
# res = conn.lrange('l_test', 0, 9)
# print(res)
# def lscan_iter(name, conn, count=10):
# cursor = 0
# lenght = conn.llen(name) # 计算列表总长度
# while cursor < lenght:
# data = conn.lrange(name, cursor, (cursor+count) - 1)
# cursor += count
#
# for item in data:
# yield item
def lscan_iter(name, conn, count=10):
cursor = 0
while True:
data = conn.lrange(name, cursor, (cursor+count) - 1)
if data:
cursor += count
for item in data:
yield item
else:
break
for i in lscan_iter('l_test',conn,20):
print(i)
2.2 redis之其他操作
import redis
## 公共操作
# 搭建哨兵。用了集群,这个模块就不够用了
# conn=redis.Redis()
# delete
# res=conn.delete('l2','name')
#exists
# res=conn.exists('l1','l_test','l2')
# res=conn.exists('l_test')
# expire
# res=conn.expire('l_test',5)
# rename
# conn.lpush('l1',1,2,3)
# res=conn.rename('l1','l2')
#
# res=conn.move('l2',3)
## redis的库是隔离的
conn = redis.Redis()
# res=conn.lpop('l2')
# 随机出一个key值
# res=conn.randomkey()
# conn.sadd('choujiang',9)
# conn.sadd('choujiang',90)
# conn.sadd('choujiang',99)
# print(res)
# res=conn.spop('choujiang')
# print(res)
# type----查看类型
# res=conn.type('choujiang')
# res=conn.type('ss')
res=conn.type('zzz')
print(res)
conn.close()
2.3 redis之管道
### redis是数据库,非关系型数据库,不支持事务
## redis提供了管道,通过管道,实现事务
import redis
conn=redis.Redis()
# 开启一个管道
pi=conn.pipeline(transaction=True)
pi.multi()
# 只要人的年龄加了1,工资加1w
pi.incr('age')
raise Exception('出异常了')
pi.incr('salary',10000)
# 向管道中发送了两个命令,并没有真正的执行
pi.execute() #表示一次性执行管道中的命令
## 原来操作
# conn.incr('age')
# raise Exception('出错误了')
# conn.incr('salary',1000)
conn.close()
2.4 django中使用redis
2.4.1通用方案
redis_pool.py
import redis
POOL=redis.ConnectionPool(host='127.0.0.1',port=6379,max_connections=100)
views.py
from utils.redis_pool import POOL
import redis
def test_redis(request):
conn=redis.Redis(connection_pool=POOL)
age=str(conn.get('age'),encoding='utf-8')
return HttpResponse('人的年龄,从redis中取出来了是:%s'%age)
2.4.2django提供的方案
pip3 install django-redis
配置文件
# redis的配置
#以后django的缓存,用的就是redis,很方便使用redis的连接
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",
}
}
}
views.py
from django_redis import get_redis_connection
def test_django_redis(request):
# 从连接池中拿到连接
conn=get_redis_connection()
age = str(conn.get('age'), encoding='utf-8')
from django.core.cache import cache
cache.set('name','lqz',4) # 往缓存中放key和value,其实放到了redis中了
cache.set('xxx',test_redis)
return HttpResponse('人的年龄是:%s' % age)
2.5.celery简介,架构
1 celery:芹菜(跟芹菜没有任何关系)
2 python中的一个分布式异步任务框架
-执行异步任务---(对立:同步任务):解决耗时任务,将耗时操作任务提交给Celery去异步执行,比如发送短信/邮件、消息推送、音视频处理等等
-执行延时任务(5分钟后干一件事):解决延迟任务
-执行定时任务:每天,隔几分钟,干什么事:解决周期(周期)任务,比如每天数据统计
3 解释
Celery is a project with minimal funding, so we don’t support Microsoft Windows. Please don’t open any issues related to that platform.
4 celery特点(了解)
1)可以不依赖任何服务器,通过自身命令,启动服务(内部支持socket)
2)celery服务为为其他项目服务提供异步解决任务需求的
5 Celery架构
Celery的架构由三部分组成,消息中间件(message broker)、任务执行单元(worker)和 任务执行结果存储(task result store)组成
#消息中间件
Celery本身不提供消息服务,但是可以方便的和第三方提供的消息中间件集成。包括,RabbitMQ, Redis等等
# 任务执行单元
Worker是Celery提供的任务执行的单元,worker并发的运行在分布式的系统节点中。
# 任务结果存储
Task result store用来存储Worker执行的任务的结果,Celery支持以不同方式存储任务的结果,包括AMQP, redis等
2.5.1安装
pip install celery