redis的运行维护

一、什么时候使用redis ?
    使用redis主要从两个角度去考虑:性能和并发。
 
    1、性能:再碰到需要执行耗时非常久,且结果不频繁变动的SQL,就特别适合将运行结果放入缓存。后面的请求就去缓存中读取,使得请求能够迅速响应。
    2、并发:①在大并发的情况下,所有请求直接访问数据库,数据库就会出现连接异常。
                    ②使用redis做一个缓冲操作,处理能力提高,并且数据库压力减小
 
二、redis的缺点 
    1、缓存和数据库双写一致性问题
    2、缓存雪崩问题
    3、缓存击穿问题
    4、缓存的并发竞争问题
 
三、redis为什么这么快?
    1、纯内存操作
    2、单线程操作,避免了频繁的上下文切换
    3、采用了非阻塞I/O多路复用机制
 
四、redis的数据类型,以及每种数据类型的使用场景
    1、String
    通过set/get操作,Value可以是String也可以是数字,一般做一些复杂的计数功能的缓存。
    
    2、Hash
    这里Value存放的是结构化对象,比较方便的就是操作其中的某个字段。
    
    3、List
    使用list的结构数据,可以做简单的消息队列功能,还有一个就是可以利用lrange命令,做基于Redis的分页功能,性能极佳。
    
    4、Set
    Set堆放的是一堆不重复值的集合,所以可以做全局去重功能,但是代码里可以利用set集合的交集、并集、差集等操作,不必再起一个公共服务。
 
    5、Sorted Set
    Sorted Set多了一个全重参数Score,集合中的元素能够按Score进行排序。
    可以做排行耪应用,取TOP N操作。Sorted Set可以用来做延时任务,最后一个应用就可以做范围查找
 
五、Redis的过期策略以及内存淘汰机制
例子:①redis如果只能存5G数据,可是你写了10G,会如何删除多余的5G数据
          ②数据设置了过期时间,但是时间到了,内存占用率还是比较高
答案:Redis采用的是定期删除+惰性删除策略
 
问:为什么不用定时删除策略
答:定时删除,用一个定时器来负责监视Key,过期自动删除,虽然内存及时释放,但十分消耗CPU资源。在大并发情况下,CPU要将时间应用在处理请求,而不是删除Key
 
问:定期删除+惰性删除是如何工作的
答:定期删除,Redis默认每个100ms随机抽取进行检查,发现过期key则删除
       惰性删除,在你获取某个key时,Redis会检查一下,这个key如果超过了设置的过期时间,那么就会删除。
 
问:当定期删除和惰性删除都没删除掉的key,这样redis的内存会越来越高时,怎么办
答:redis.conf有一行配置:#maxmemory-policy volatile-lru,该配置就是配内存淘汰策略的。
noeviction:当内存不足以容纳新写入的数据时,新写入操作会报错
allkeys-lru:当内存不足以容纳写入数据时,移除最近最少使用的key
allkeys-random:当内存不足以容纳新写入数据时,随机移除某个key
volatile-lru:当内存不足一容纳新数据时,在设置了过期时间的库中,删除最近最少使用的key
volatile-random:当内存不足以容纳新数据时,在设置了过期时间的库中,删除最近最少使用的key
volatile-ttl:当内存不足以容纳新数据时,在设置了过期时间的库中,有更早过期时间的key优先移除
 
六、Redis和数据库的双写一致性问题
1、访问时优先访问缓存,再缓存没有的情况下再去数据库读写。(可能存在去访问数据库时缓存又有了)
2、删除key时,先更新数据库,在删除缓存。(可能存在删除key失败的问题)
答:如果对数据有强一致性的要求,不能放缓存
 
七、如何应对缓存穿透和缓存雪崩问题
注:中小型传统软件企业很难碰到这个问题,如果有大并发的项目,这两个问题一定要深刻考虑
    1、缓存穿透:即黑客故意去请求缓存中不存在的数据,导致所有的请求都传到数据库上,从而导致数据库连接异常。
    缓存穿透解决方案:
        ①、利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库,没得到锁,则休眠一段时间重试。
        ②、采用异步更新策略,无论Key是否取到值,都直接返回。 Value 值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。
        ③、 Value 值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。
 
    2、缓存雪崩:即缓存同一时间大面积的失效,这个时候又来了一拨请求,导致请求都到了数据库上,从而导致数据库连接异常。
        ①、 给缓存的失效时间,加上一个随机值,避免集体失效。
        ②、使用互斥锁,但是该方案吞吐量明显下降了。
        ③、双缓存。我们有两个缓存,缓存 A 和缓存 B。缓存 A 的失效时间为 20 分钟,缓存 B 不设失效时间。自己做缓存预热操作。
        (注: 从缓存 A 读数据库,有则直接返回;A 没有数据,直接从 B 读数据,直接返回,并且异步启动一个更新线程,更新线程同时更新缓存 A 和缓存 B。)
 
八、如何解决Redis的并发竞争Key问题
1、没做分片就用Redis的事务机制
2、做过分片的集群,有两种方案,①、准备一个分布式锁,大家去枪锁,强到就去做set操作。
                                                     ②、数据库写入数据时,保存一个时间戳。
                                                     ③、利用队列,将set方法变成串行访问。
 
posted @ 2018-06-14 11:49  caibaofei  阅读(248)  评论(0编辑  收藏  举报