1、缓存雪崩
    数据未加载到缓存或者缓存大面积失效,或者缓存故障,所有请求直接落到数据库。数据库扛不住。
    解决方案:
    事前:redis高可用,避免全盘崩溃。失效时间加个随机数。本地 ehcache 缓存。
    事中:是否能够快速从RDB或者AOF文件快速恢复缓存。是否能够限流或者降级避免数据库被打死。
    事后:检查缓存数据恢复情况。问题期间影响的业务数据恢复。
2、缓存击穿
    热点key失效的瞬间,有大量的请求拥入数据库。
    解决方案:
    1)热点key长时间有效,然后定时同步或者使用发布订阅机制。
    2)key失效,构建加锁,从数据库里面获取数据,其他请求隔段时间访问该key,直到获取数据之后,锁失效。
3、缓存穿透
    redis尽管没有挂掉,但是查询太多不存在的数据,就会导致会有太多的无效请求进入数据库,也会导致数据库超负荷。
    解决方案:
    1)不存在的key也维护起来,并且维护过期时间。
    2)对于相对稳定不变的数据,可以使用布隆过滤器,但是要有过期时间。
    3)在入口校验掉不合法的请求。
4、缓存并发
    主要是写竞争,get和set分开执行了。
    解决方案:放在队列中或者加锁。
5、缓存预热
    系统上线时,先把数据库的数据,加载到缓存中。避免上线瞬间,大量的请求拥入数据库。
6、大key问题
    value大或者hash、list等节点个数多。存在的问题:
    a)内存使用不均衡;
    b)超时阻塞,操作bigkey比较耗时,由于redis单线程的特性,意味着超时阻塞的可能性增大;
    c)网络拥塞,获取bigkey产生的网络流量较大。
    Redis大key多key拆分方案 - -零 - 博客园
    Redis大Key导致性能下降及处理_FserSuN的博客-CSDN博客
7、多key问题
    key的个数很多。redis的数据存储在内存上,key太多,如果保存在了swap区,会导致性能下降。
参考:redis缓存雪崩、穿透、击穿概念及解决办法 - 进阶的马龙 - 博客园
你似乎来到了没有知识存在的荒原 - 知乎

redis实现分布式锁:要设置过期时间;不能误释放其他服务的锁,需要保存随机id为value;判断是否属于当前服务线程的锁然后再释放,需要使用lua保证原子性。
参考:如何优雅地用Redis实现分布式锁
缺点:由于存在脑裂问题,会导致锁失效。
可重入锁
方案一、使用hash,保存对应线程ID的重入次数。参考:Redis可重入锁的实现设计_JavaEdge全是干货的技术号-CSDN博客_redis可重入锁
方案二、使用ThreadLocal类存储锁的value值,每次获取锁时和TreadLocal的值比较。参考:【分布式锁】Redis实现可重入的分布式锁 - 烟味i - 博客园 (cnblogs.com)

redis和zk分布式锁的区别:zk强一致性,redis性能高。
zk每次要获取序号最小的ZNode,是为了确保锁的公平性。
参考:常用的分布式锁和redis和zk两种分布式锁的对比 - 森林木马 - 博客园
Zookeeper 分布式锁 - 图解 - 秒懂_架构师-尼恩的博客-CSDN博客_zookeeper 锁

Redis单进程单线程,为什么还这么快?
1、数据存储在内存,类似于hashmap,时间复杂度o(1)。
2、单线程,避免了不必要的上下文切换、线程切换、锁操作。
3、数据结构简单。
4、使用I/O多路复用模型,非阻塞IO。
    I/O多路复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。
    **这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。**采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响Redis性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量。
参考:为什么说Redis是单线程的以及Redis为什么这么快!_徐刘根的博客-CSDN博客_redis是单线程

redis vs memcached
redis支持持久化。
    RDB(Redis DataBase,是将redis某一时刻的数据持久化到磁盘中,是一种快照式的持久化方法),恢复快,但是不完整 。
    AOF(Append Only File,AOF方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍),增加了个中间过程的临时文件,确保数据不丢失。秒级同步,最多丢一秒的数据。
参考:Redis AOF 持久化- Redis源码分析 - 我们
redis的数据结构更丰富。
redis是单核,memcache多核,少数据量时,redis快,大数据量时,memcache快。
memcache不提供集群模式。
memcache使用CAS保持一致性。redis将MULTI、EXEC(exec命令一直没有收到,可能会一直得不到执行)里面的放到队列里面然后一起执行,并使用DISCARD放弃事务的执行,但是没有天然的失败回滚机制,对事务支持比较弱。
参考:超强、超详细Redis入门教程_liqingtx的博客-CSDN博客_redis

mysql + redis
redis本身可以持久化,为啥还要mysql配合呢?
    redis为内存型数据库,不可能存储过大的数据。
    MySQL是关系型数据库,redis无法替换。
    经常被查询的数据,写操作不多的,可以放到redis里面。
    查询频率高,但是对实时性要求不高的,可以将计算结果放在redis里面。
redis+mysql配合:
1、同时写redis和mysql。
2、写mysql,使用Gearman调用MySQL的UDF,完成对Redis的写。
3、写Mysql,监听binlog,数据放入队列写Redis,如阿里的canel。
4、写redis,使用消息队列写入MySQL。
参考:MySQL和Redis的区别_一点一滴g的博客-CSDN博客_redis和mysql区别
为什么redis不能代替mysql进行数据存储 - 知乎

本地缓存 vs redis
1、性能要求更高的可以考虑使用本地缓存。
2、单机本地缓存。
3、无单个key的失效时间,只有整体失效时间。
4、是对redis的补充,解决缓存雪崩带来的影响等。

redis的高可用方案(异步复制):
主备:keepalived
master/slave模式:为了分担读压力。
    发送SYNC命令同步,分为全量同步、增量同步。
基于主从的哨兵模式:
    Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:
    监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
    提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
    自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会进行选举,将其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
集群模式gossip
    最小配置6个节点以上(3主3从),其中主节点提供读写操作,从节点作为备用节点,不提供请求,只作为故障转移使用。
    优点:
    1、无中心架构
    2、数据按照slot存储分布在多个节点,节点间数据共享,可动态调整数据分布。
    3、可扩展性,可线性扩展到1000多个节点,节点可动态添加或删除。
    4、高可用性,部分节点不可用时,集群仍可用。通过增加Slave做standby数据副本,能够实现故障自动failover,节点之间通过gossip协议交换状态信息,用投票机制完成Slave到Master的角色提升。
    5、降低运维成本,提高系统的扩展性和可用性。
    缺点:
    1、Client实现复杂。
    2、节点会因为某些原因发生阻塞(阻塞时间大于clutser-node-timeout),被判断下线,这种failover是没有必要的。
    3、多个业务使用同一套集群时,无法根据统计区分冷热数据,资源隔离性较差,容易出现相互影响的情况。
    4、Slave在集群中充当“冷备”,不能缓解读压力,当然可以通过SDK的合理设计来提高Slave资源的利用率。
参考:redis集群简介 - vietaKo - 博客园
Redis集群搭建的三种方式 - 乔克爱运维 - 博客园

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐