一、redis字符串的操作
# redis的vlaue有五大数据类型:字符串,列表,hash,集合,有序集合 # 关于字符串的操作有17种 import redis conn = redis=Redis() 1 set(name, value, ex=None, px=None, nx=False, xx=False) # ex,过期时间(秒) # px,过期时间(毫秒) # nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果 # xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值 conn.set('name','lqz') # value只能是字符串或者是bytes类型 conn.set('name', 'jason',ex=3) # 3秒之后就会过期 conn.set('name','tony',px=3000) # 也是3秒之后过期 conn.set('name','kevin',nx=True) # 只有key不存在时才会设置 存在就不会操作 conn.set('name','oscar',xx=True) # 只有key存在才会操作 value就会被修改 不存在不会操作 2 setnx(name, value) # 就是:set nx=True coon.setnx('name','owen') # 就是当key不存在的时候就会设置 存在就不会操作 3 psetex(name, time_ms, value) # 就是 set px这是过期时间 coon.pasetex('age',3000,'18') # 3秒后过期 4 mset(*args, **kwargs) # 字典新式批量设置 conn.mset({'name':'tony','age':18}) # 就会有两个值设置进去了 name是库中的key tony是key中值 数据类型是字符串 5 get(name) # 获取值 取到的是bytes 如果在Redis中指定decode_responses=True,就完成转换 print(coon.get('name')) # 就会把key为name的值取出来 6 mget(keys, *args) #批量获取 coon.mget('name', 'age') # 会把key为name和age的值给提取出来 conn.mget(['name','age']) # 也可以写成列表 7 getset(name, value) # 先获取,再设置 conn.getset('name', 'lqz') # 会把之前的值获取出来 然后再把后面的值修改进去 8 getrange(key, start, end) # 取的是字节,前闭后闭区间 conn.getrange('name',0,1) # 会把key为name的值 会把0到1的字节取出来 前闭后闭区间 9 setrange(name, offset, value) # 从某个起始位置开始替换字符串 coon.setrange('name', 1,'xxx') # 会把1个字节开始替换成xxx后面没被替换的还是一样 是从0开始 10 setbit(name, offset, value) # 因为redis存储是按照bytes的 所以是一推0101数字组成 这个就是 把那个位置的数字替换掉 conn.setbit('name',2,0) #把第二个比特位换成0 如果本来是 00100000 那么现在就会变成 00000000 11 getbit(name, offset) # 获取那个位置的 bit 要么为0要么为1 conn.getbit('name', 2) 12 bitcount(key, start=None, end=None) # 从其实位置到结尾位置获取中间有几个 key conn.bitcount('name', 1,3) # 就是从0到3中间有几个1bit 13 strlen(name) # 统计字节长度 coon.strlen('name') # 统计可以为name的值有几个bytes 14 incr(self, name, amount=1) # 计数器 就是访问一次就会加一 coon.incr('age', amout=2) # 操作一次就会加二 如果不写amout默认为1 15 incrbyfloat(self, name, amount=1.0) # 加小数 conn.incrbyfloat('age') # 默认加1.0 16 decr(self, name, amount=1) # 减一 conn.decr('name') # 默认减一 17 append(key, value) # 会在末尾添加 conn.append('name', 'nb')
coon.close()
二、hash操作
import redis coon = redis.Redis() 1 hset(name, key, value) # 设置值 conn.hset('userinfo','name','wzh') # 库中的key为userinfo 值中的key为name值中的value为wzh conn.hset('userinfo', 'age', '32') conn.hset('xx',mapping={'name':'xxx','hobby':'篮球'}) # 可以批量设置 2 hmset(name, mapping) # 弃用了 就是hset 加 mapping conn.hmset('yy',{'a':'a','b':'b'}) 3 hget(name,key) # 获取值 conn.hget('userinfo','age') # 虎丘userinfo中的age的值为多少 4 hmget(name, keys, *args) # 批量获取 conn.hmget('userinfo',['name','age']) 5 hgetall(name) # 一次性获取全部 慎用 很有可能造成阻塞 尽量不要在生产代码中使用 conn.hgetall('userinfo') 6 hlen(name) # 计算有多少个K:V conn.hlen('userinfo') 7 hkeys(name) # 获取K conn.hkeys('userinfo') # 获取userinfo中的所有key 8 hvals(name) # 获取V conn.hvals('userinfo') # 获取userinfo中的所有value 9 hexists(name, key) # 判断有没有key conn.hexists('userinfo','hobby') # 判断userinfo中有没有hobby这个key 存在返回True 不存在返回False 10 hdel(name,*keys) # 删除key conn.hdel('userinfo', 'hobby') # 删除key为hobby的K:V键值对 11 hincrby(name, key, amount=1) # 访问一次默认加一 conn.hincrby('userinfo', 'age') # 访问一次 age的值加1 12 hincrbyfloat(name, key, amount=1.0) # 访问一次默认加1.0 小数 conn.hincrbyfloat('userinfo','age', 2.3) # 访问一次 加2.3 13 hscan和hscan_iter 其实可以一起讲 # 我们尽量不用使用hgetall 我们可以使用分片取值 # hash类型没有顺序---》python字典 之前没有顺序,3.6后有序了 for i in range(1000): conn.hset('test_hash','key_%s'%i,'鸡蛋%s号'%i) # 我们先往text_hash中存一千条数据 # 尽量不要使用hgetall一次性取出 我们可以先使用hscan hscan(name, cursor=0, match=None, count=None) # count 是要取的条数,但是不准确,有点上下浮动 # 它一般步单独用 res=conn.hscan('test_hash',cursor=0,count=19) print(res) print(res[0]) print(res[1]) print(len(res[1])) # 所以我们使用hscan_iter内部封装了 hscan 做成了生成器,分批取hash类型所有数据 14 hscan_iter(name, match=None, count=None) res = conn.hscan_iter('test_hash',count=100) print(res) # 生成器 for item in res: print(item) # 会先去100条 取完 在取100条 这样就不会一次性取出 conn.close()
三、列表操作
import redis conn = redis.Redis() 1 lpush(name,values) # 添加值 从左侧加入 [dlrb, lyf] conn.lpush('girls', 'lly') conn.lpush('girls','dlrb') 2 lpushx(name,value) # 只有name已经存在时,值添加到列表的最左边 conn.lpushx('girls', 'yy') # 存在才会添加 conn.lpushx('boys', 'la') # 不存在不会操作 3 rpushx(name, value) # 表示从右向左操作 conn.rpushx('girls', 'yy') # 存在才会添加 conn.rpushx('boys', 'la') # 不存在不会操作 4 llen(name) conn.llen('girls') # 计算girls列表有几个值 5 linsert(name, where, refvalue, value)) # 添加值 conn.linsert('girls', where='after', refvalue='lyf', value='李清照') # 往lyf后面添加李清照 conn.linsert('girls', where='before', refvalue='lyf', value='李清照') # 往lyf前面添加李清照 6 lset(name, index, value) # 将索引变成某某 conn.lset('girls',0,'xx') # 将索引为0的值变成xx 7 lrem(name,count ,value) # count放数字,可以写负数,表示从右往前删除 0 表示全删 conn.lrem('girls',0, '李清照') # 将全部李清照给删除了 conn.lrem('girls',1,'李清照') # 从左到有删除一个李清照 8 lpop(name) # 弹出值 conn.lpop('userinfo') 9 lindex(name, index) conn.lindex('dirls', 2) # 获取所有为2的值 10 lrange(name, start, end) # 前闭后闭 conn.lrange('girls',0,2) # 获取所有为0到2的值 11 ltrim(name, start, end) # 修建 conn.ltrim('girls',1,2) # 将所索引为1和2中间的值给删除 留下两头 12 rpoplpush(src, dst) # 弹出 插值 conn.rpoplpush('girls','boys') # 将girls的值弹出 然后给boys 13 blpop(keys, timeout) 阻塞式弹出,如果列表中没有值,会阻塞在这,直到有值,再弹出,它可以做消息队列,做分布式的系统 res=conn.blpop('boys',timeout=3) # 可以3秒后执行 如果没有值 就会阻塞 知道有值为止 14 brpoplpush(src, dst, timeout=0) # 跟上面是一样的 只不过有时间 会有超时时间 15 自定义增量迭代 res=conn.lrange('girls',0,conn.llen('girls')) # 获取全部 print(res) # 但是这样是不好的 可以自定义增量迭代 def scan_list(name, count=2): index = 0 while True: data_list = coon.lrange(name, index, count + index - 1) # 第一次:0,1 第二次:2,3 ... if not data_list: # 如果没有值 就会直接返回 return index += count # 索引加一 for item in data_list: yield item # 变成生成器 print(coon.lrange('test', 0, 100)) # 一次性取出100个 for item in scan_list('test', 5): # 五个五个的取 print('---') print(item) coon.close()
四 redis管道
# mysql 事物有四大特性:原子性,一致性,隔离性,持久性, # 隔离又有四大隔离级别:读未提交,读已提交,可重复读,串行读 # redis事物机制只有 一致性和隔离性,无法保持持久性,但是对于reids是内存数据库,所以持久性不是必须属性,原子性需要自身检查,尽可能保证 # redis 不像mysql一样,支持强事务,事务的四大特性不能全部满足,但是能满足一部分,通过redis的管道实现的 # redis本身不支持事务,但是可以通过管道,实现部分事务 # redis 通过管道,来保证命令要么都成功,要么都失败,完成事务的一致性,但是管道只能用在单实例,集群环境中,不支持pipline
4.1 代码实现
import redis conn = redis.Redis() pipline = conn.pipeline(transaction=True) pipline.decr('a', 2) # a减2 raise Exception('我崩了') # 模拟报错了 pipline.incr('b', 2) # b加2 pipline.execute() conn.close() # 如果不加管道的话 a减2的同时程序崩溃的话 b是不会加的 那么a就白扣了 # 如果不报错的话 会正常运行 a减2 b加2 # 如果加了管道 程序崩溃的话 a不会减2 b也不会加2
五、redis其他操作
# 集合,有序集合 --- redis模块提供的方法API # 通用操作:无论是5大类型的那种,都支持 import redis conn = redis.Redis() # 1 delete(*names) conn.delete('age', 'name') # 2 exists(name) res=conn.exists('xx') print(res) # 0 # 3 keys(pattern='*') res=conn.keys('*o*') res=conn.keys('?o*') print(res) # 4 expire(name ,time) conn.expire('test_hash',3) # 5 rename(src, dst) # 对redis的name重命名为 conn.rename('xx','xxx') # 6 move(name, db) # 将redis的某个值移动到指定的db下 # 默认操作都是0 库,总共默认有16个库 conn.move('xxx',2) # 7 randomkey() 随机获取一个redis的name(不删除) res=conn.randomkey() print(res) # 8 type(name) 查看类型 res = conn.type('aa') # list hash set print(res) conn.close()
六、django集成redis
# 方式一:直接使用 from user.POOL import pool import redis def index(request): conn = redis.Redis(connection_pool=pool) conn.incr('page_view') res = conn.get('page_view') return HttpResponse('被你看了%s次' % res) # 方式二:使用第三方模块:django-redis -下载 -配置文件配置 CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/0", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 100} # "PASSWORD": "123", } } } -使用 from django_redis import get_redis_connection def index(request): conn = get_redis_connection(alias="default") # 每次从池中取一个链接 conn.incr('page_view') res = conn.get('page_view') return HttpResponse('被你看了%s次' % res) # 方式三:借助于django的缓存使用redis -如果配置文件中配置了 CACHES ,以后django的缓存,数据直接放在redis中 -以后直接使用cache.set 设置值,可以传过期时间 -使用cache.get 获取值 -强大之处在于,可以直接缓存任意的python对象,底层使用pickle实现的 def index(request): # cache.set('pv', '10', 3) # 之前缓存在内存中,现在缓存在redis中 # 缓存强大在,可以缓存任意的python数据类型 p = Person() p.name = 'lqz' cache.set('p', p) # 把p这个对象给存储到redis中了 本来是不能够存储的 return HttpResponse('把p缓存起来了') def test(request): p=cache.get('p') print(p.name) return HttpResponse('把p取出来了')
七 celery简绍
# celery:翻译过来叫芹菜,它是一个 分布式的异步任务 框架 # celery有什么用? 1 完成异步任务:可以提高项目的并发量,之前开启线程做,现在使用celery做 2 完成延迟任务 3 完成定时任务 # 架构 -消息中间件:broker 提交的任务(函数)都放在这里,celery本身不提供消息中间件,需要借助于第三方:redis,rabbitmq -任务执行单元:worker,真正执行任务的地方,一个个进程,执行函数 -结果存储:backend,函数return的结果存储在这里,celery本身不提供结果存储,借助于第三方:redis,数据库,rabbitmq
标签:name,res,redis,value,celery,key,luffy,conn From: https://www.cnblogs.com/stephenwzh/p/16893678.html