应用场景
存放频繁操作的数据,以及一些无须保存到数据库的中间值
应用:
- 配合django做缓存,常用且不易修改的数据放进来(博客) - 购物车信息 - Session - 缓存配置文件 - session配置文件中指定使用缓存 - rest api中访问频率控制 - 基于flask、websocket实现的投票系统(redis做消息队列) - scrapy中 - 去重规则 - 调度器:先进先出、后进先出、优先级队列 - pipelines - 起始URL - 商品热点信息 - 计数器 - 排行
主从复制
为什么redis要做主从复制?
目的是对redis做高可用,为每一个redis实例创建一个备份称为slave,让主和备之间进行数据同步,save/bsave。
- 主:写
- 从:读
优点:
- - 性能提高,从分担读的压力。
- - 高可用,一旦主redis挂了,从可以直接代替。
存在问题:当主挂了之后,需要人为手工将从变成主。
redis的sentinel是什么?
帮助我们自动在主从之间进行切换
检测主从中 主是否挂掉,且超过一半的sentinel检测到挂了之后才进行进行切换。
如果主修复好了,再次启动时候,会变成从。
集群方案
- redis cluster 官方提供的集群方案。
- codis,豌豆荚技术团队。
- tweproxy,Twiter技术团队。
redis cluster 需要安装 redis-py-cluster
具体参考 : Linux中操作redis
过期策略
相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:
- voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
- volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
- volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
- allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
- allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰 no-enviction(驱逐):禁止驱逐数据
事务
import redis pool = redis.ConnectionPool(host='10.211.55.4', port=6379) conn = redis.Redis(connection_pool=pool) # transaction默认为False,只可以完成批量提交的作用,节省网络延时 # 改为True后可以实现事务功能 # pipe = r.pipeline(transaction=False) pipe = conn.pipeline(transaction=True) # 开始事务 pipe.multi() pipe.set('name', 'alex') pipe.set('role', 'sb') pipe.lpush('roless', 'sb') # 提交 pipe.execute()
单redis服务器锁
import redis conn = redis.Redis(host='127.0.0.1',port=6379) # conn.set('count',1000) val = conn.get('count') print(val) with conn.pipeline(transaction=True) as pipe: # 监视,自己的值没有被修改过 conn.watch('count') # 执行操作 pipe.multi() old_count = conn.get('count') count = int(old_count) print('现在剩余的商品有:%s',count) input("问媳妇让不让买?") pipe.set('count', count - 1) # 执行,把所有命令一次性推送过去 pipe.execute()
分布式锁
原理 : 设置一个值并设置过期时间,当其他的连接要修改数据时会去读取那个值,如果有说明是被锁住的.(需要注意过期时间, 防止加锁时,或者数据没有修改完成锁就失效)
成功条件 : 超过一半的redis实例设置成功
官方提供的包下载解压缩,切换到文件中
- python setup.py build
- python setup.py install
使用 :
from redlock import Redlock dlm = Redlock( [ {"host": "localhost", "port": 6379, "db": 0}, {"host": "localhost", "port": 6379, "db": 0}, {"host": "localhost", "port": 6379, "db": 0}, ] ) # 加锁,acquire my_lock = dlm.lock("my_resource_name",10000) # 第一个参数就是设置的键 if my_lock: # 进行操作 # 解锁 dlm.unlock(my_lock) else: print('获取锁失败')