Redis的应用

目录

缓存

缓存的一些问题

内存淘汰

缓存不一致问题

分布式锁

redis为什么能作为分布式锁

SETNX命令

消息队列 


缓存

Redis是内存数据库、过期,适合存储一些热点数据、频繁读、少写

缓存的一些问题

  • 缓存穿透:
    • 问题介绍:用户请求了缓存中没有的Key,导致请求穿透缓存直接打到数据库,由于数据库也没有,导致无法缓存
    • 解决方案:缓存空对象(占内存),布隆过滤无效Key(有一定误杀)
  • 缓存雪崩:
    • 问题介绍:缓存大面积失效、或缓存宕机,导致太多请求打向数据库
    • 方案:Redis缓存高可用(主从、哨兵、集群)、设置随机过期时间,Hystrix熔断器降级(发现缓存挂掉后,降级处理,返回默认值,防止服务雪崩)

内存淘汰

  • 随机淘汰
  • 不淘汰,保证数据不被丢失,内存满时报异常,可能要扩容
  • 按过期时间淘汰
  • LRU、LFU

缓存不一致问题

问题概述:在写操作时,对缓存和数据库修改是非原子的,可能存在一段时间内缓存和数据库中数据不一致的问题,因为没法同时更新缓存和数据库     

方案列表:

  • 先更新缓存,后更新数据库
    • 如果更新数据库失败,会导致缓存存脏数据
  • 先更新数据库,后更新缓存
    • 两个线程同时更新时,1、线程A更新了数据库;2、线程B更新了数据库;3、线程B更新了缓存;4、线程A更新了缓存。            不一致
      注:缓存更新不一定会被读取,所以删除优于更新
  • 先删除缓存,后更新数据库
    • 删除缓存后,有线程查询,导致缓存又被写上旧数据,更新数据库后,缓存存的是脏数据
  • 先更新数据库,后删除缓存
    • 可能缓存删除失败,可以用消息队列来保存删除缓存的请求重复删除)
       

分布式锁

用处:分布式场景下多进程协作,如数据一致性

redis为什么能作为分布式锁

  • 锁构建在Redis里面,能被所有客户端可见
  • 多客户端对Redis的连接不存在竞争关系,单进程单线程,采用队列模式将并发访问变成串行访问
  • SETNX命令(IF NOT EXIST THEN SET 保证唯一性 ),原子级键值对操作、过期

SETNX命令

  • 在键不存在时时为键创建值,适合做获取锁的命令
  • 获取锁失败时,不断重试,直至超时、成功
  • 参数里加入过期时间,保证不会宕机永久持有锁
    • value里加上自己进程的标识,保证不会误删别人的锁
    • watch监视锁是否被修改,事务来删除锁
#加锁
def acquire_lock(conn,lockname,timeout):
	identifier = str(uuid.uuid4())
	end = time.time()+timeout
	#重试直至超时
	while(time.time()<end):
		if conn.setnx('lock:'+lockname,identifier):#尝试获取锁
			return identifier
		time.sleep(.001)
	return False

#解锁
def release_lock(conn,lockname,identifier):
	pipe = conn.pipeline(True) #事务
	lockname = 'lock:'+lockname
	while True:
		try:
			pipe.watch(lockname)#监测到lockname未变化 事务才会成功
			if pipe.get(lockname) == identifier: #检查进程是否仍持有锁
				pipe.multi()
				pipe.delete(lockname)
				pipe.execute()
				return True
			pipe.unwatch()
			break
		except redis.exceptions.WatchError:	
			pass
	return False
复杂的命令可以用lua脚本实现原子操作

消息队列 

  • list数据结构,rpush产生消息,rpop消费消息
  • 发布-订阅模式,1-M
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值