一、Redis双写一致

1、实现逻辑

当系统中增加了缓存服务器,读写操作都需要针对缓存数据实现管理逻辑,其中当写数据的时候(增删改)必须保证缓存中数据和数据库中数据的一致,至少保证绝对没有脏数据。这种缓存的管理被称为双写一致。
访问数据库,增删改的时候,同时访问缓存,实现增删改或者淘汰缓存。
双写不是MySQL数据库和Redis数据库,是RDBMS关系型数据和其他。
其他可以是Redis、ElasticSearch、MongoDB等任何看可以保存数据的数据源。

2、如何保证书写一致

保证双写一致有一个原则,称为Cache Aside Pattern。即边路缓存思想(适用于Redis)。
定义了读和写的时候有缓存数据的时候缓存该如何执行。
读:

  1. 访问缓存,查询数据,如果有缓存直接返回缓存内容
  2. 如果缓存没有数据,访问数据库(RDBMS)查询数据。
  3. 把RDBMS中的数据保存到缓存中。

写:

  1. 写入数据库RDBMS
  2. 淘汰缓存(删除缓存)

    3、缓存淘汰

    原因:写操作缓存淘汰的原因:同步缓存(新增或者修改缓存),有时间代价和数据不一致的冲突。
    举个栗子:
    多线程情况下有A和B两个线程同时操作一组数据。设A和B对数据M进行操作,当前两个线程读取M的值均为20 。A对M的值进行了修改,修改为10,但是CPU时间片到了,A线程进入阻塞的状态。这时B对M的值也进行了修改,修改为30。然后进行写入缓存的操作,缓存中的M为30。这时A线程分配到了时间片执行到写入缓存的操作,更新缓存中M的值为10 。
    这个时候数据库中M的值为30,但是缓存中M的值为10 。10即为脏数据,实际的值应该为30 。这是同步缓存导致的数据不一致冲突。
    Spring Data Redis - 图1

    缓存黑洞

    缓存服务器中保存的数据,必须永久保存,且这些缓存数据理论上没有上限。
    这种情况一旦发生,称为缓存黑洞。如微信朋友圈、QQ说说、facebook分享等。在一些特定的环境中,不作为缓存问题。解决方便,但是有些情况是不能解决的。

    缓存雪崩

    缓存服务器中的数据,在某一时刻,大面积过期失效,导致查询逻辑,大量请求访问数据库,执行数据查询。导致数据库响应变慢,最严重造成数据库宕机。这种情况称为缓存雪崩。
    解决方案:

  3. 把缓存服务器中的有效时间分散。尽量保证同一时刻, 只有少量数据过期失效。甚至是个别数据,过期失效。通常使用固定有效时常+-随机有效时长。

  4. 使用定时任务,周期的查询数据库中的数据,保存到缓存服务器中,设置有效时长。有效时长,大于定时任务的周期。需要配合大数据系统实现。让大数据系统分析,什么数据需要缓存,定时任务,查询需要缓存的数据,保存到Redis中。

    缓存击穿

    当缓存服务器中的某数据过期失效后,有高并发的客户端请求,同时查询这一个数据数据。导致高并发请求,击穿缓存,进入数据库执行查询逻辑。导致数据库响应变慢,最严重导致数据库宕机。称为缓存击穿。(有人也叫缓存穿透)。
    解决方案:使用技术手法,让一个请求进入数据库查询数据,并把查询结果保存到缓存服务器中。其他请求,阻塞等待,阻塞结束后,从缓存服务器中查询数据并返回。
    使用分布式锁,让多进程、多线程环境中,只有一个请求线程,访问数据库。

    缓存穿透

    读穿透。当高并发请求,查询一个缓存服务器不存在、且数据库中也不存在的数据,无分布式锁处理。导致高并发请求,反复访问数据库,查询不存在的数据,数据库压力升高,最严重导致数据库宕机。这种情况称为缓存穿透,一般发生在恶意攻击时。
    解决方案:如果数据库查询结果不存在,则创建一个托底数据,短期保存在缓存服务器中,做降级处理。

    持久化方案

    淘汰策略

    Redis持久化方案有哪些?特点分别是什么?
    AOF RDB
    如果Redis服务器内存不足了,如何实现数据淘汰?(Redis中的数据淘汰策略有哪些?(Redis中的key过期了,如何实现淘汰?))
    key过时,如何淘汰:周期淘汰+延迟淘汰。
    周期:redis周期启动一个淘汰过期key的任务。分析部分key,是否过时,如果过时,则删除淘汰。
    延迟:访问key的时候,检查是否过时。
    内存不足,添加新键值对,如何淘汰旧数据:8种
    LRU : 最少使用
    all - 所有key中,最少使用的,淘汰
    volitail - 所有有有效期的key中,最少使用的,淘汰
    LFU : 最少频率
    all - 所有key中,最少频率的,淘汰
    volitail - 所有有有效期的key中,最少频率的,淘汰
    Rondom :
    all - 所有key中,随机淘汰
    volitail - 所有有有效期的key中,随机淘汰
    TTL - 淘汰剩余有效期最短的key。
    noeviction - 不淘汰任何旧数据,报错。默认的淘汰机制