redis 总结

概述

redis 是一个内存的缓存数据库,用于做缓存的。为各个服务做集中缓存服务。支持多种缓存数据结构。如 string、hash、list、set、sortset,也支持简单的发布订阅、和消息队列、lua 脚本自己支持的缓存服务和事务等一些其它服务。

redis 架构模式

单机到集群

  1. 单机模式

    ​ 适合于不重要的缓存数据,可以快速重建,失效对系统影响不大的数据。缺点:单点,数据容易丢失。

  2. 主从模式

    ​ 能实用于大多的应用场景。主失败后需要人工介入切入从,或者走keepalive ip 漂移。缺点:主redis服务中断,切换时间内redis服务不可用,缓存容量不可用扩展。

  3. 哨兵模式

    ​ 1.Redis哨兵主要功能

    (1)集群监控:负责监控Redis master和slave进程是否正常工作

    (2)消息通知:如果某个Redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员

    (3)故障转移:如果master node挂掉了,会自动转移到slave node上

    (4)配置中心:如果故障转移发生了,通知client客户端新的master地址

    ​ 2.Redis哨兵的高可用

    img

    原理:当主节点出现故障时,由Redis Sentinel自动完成故障发现和转移,并通知应用方,实现高可用性。哨兵机制建立了多个哨兵节点(进程),共同监控数据节点的运行状况。同时哨兵节点之间也互相通信,交换对主从节点的监控状况。每隔1秒每个哨兵会向整个集群:Master主服务器+Slave从服务器+其他Sentinel(哨兵)进程,发送一次ping命令做一次心跳检测。这个就是哨兵用来判断节点是否正常的重要依据,涉及两个新的概念:主观下线和客观下线。一个哨兵节点判定主节点down掉是主观下线,只有半数哨兵节点都主观判定主节点down掉,此时多个哨兵节点交换主观判定结果,才会判定主节点客观下线。基本上哪个哨兵节点最先判断出这个主节点客观下线,就会在各个哨兵节点中发起投票机制Raft算法(选举算法),最终被投为领导者的哨兵节点完成主从自动化切换的过程。

  4. cluster集群模式

    集群模式有多种,有的用代理模式加哨兵主从模式,proxy 对请求进行分布。有的也用redis 新的cluster模式,client 用一致性hash + 2 20次方的虚拟节点的哈希分布方式。

数据持久化

Redis 是内存型数据库,为了保证数据在断电后不会丢失,需要将内存中的数据持久化到硬盘上。Redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。

  1. rdb

    简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本。如果系统发生故障,将会丢失最后一次创建快照之后的数据。如果数据量大,保存快照的时间会很长

2.AOF

​ 换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把 这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。将写命令添加到 AOF 文件(append only file)末尾

3.配置选项说明

使用 AOF 持久化需要设置同步选项,从而确保写命令同步到磁盘文件上的时机。这是因为对文件进行写入并不会马上将内容同步到磁盘上,而是先存储到缓冲区,然后由操作系统决定什么时候同步到磁盘。选项同步频率always每个写命令都同步,eyerysec每秒同步一次,no让操作系统来决定何时同步,always 选项会严重减低服务器的性能,everysec 选项比较合适,可以保证系统崩溃时只会丢失一秒左右的数据,并且 Redis 每秒执行一次同步对服务器几乎没有任何影响。no 选项并不能给服务器性能带来多大的提升,而且会增加系统崩溃时数据丢失的数量。随着服务器写请求的增多,AOF 文件会越来越大。Redis 提供了一种将 AOF 重写的特性,能够去除 AOF 文件中的冗余写命令。

其实RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。如果你没有数据持久化的需求,也完全可以关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库。

常见问题

1.并发设置key及分布式锁

Redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘。由于单线程所以Redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端对Redis进行并发访问时会出现问题。比如多客户端同时并发写一个key,一个key的值是1,本来按顺序修改为2,3,4,最后是4,但是顺序变成了4,3,2,最后变成了2。使用分布式锁防止并发设置Key的原理及代码见:使用Redis实现分布式锁及其优化,另外一种方式是使用消息队列,把并行读写进行串行化。

2.热key问题

热key问题说来也很简单,就是瞬间有几十万的请求去访问redis上某个固定的key,从而压垮缓存服务的情情况。其实生活中也是有不少这样的例子。比如XX明星结婚。那么关于XX明星的Key就会瞬间增大,就会出现热数据问题。那么如何发现热KEY呢:

1.凭借业务经验,进行预估哪些是热key

2.在客户端进行收集

3.在Proxy层做收集

4.用redis自带命令(monitor命令、hotkeys参数)

5.自己抓包评估

解决方案:

1.利用二级缓存,比如利用ehcache,或者一个HashMap都可以。在你发现热key以后,把热key加载到系统的JVM中。

2.备份热key,不要让key走到同一台redis上。我们把这个key,在多个redis上都存一份。可以用HOTKEY加上一个随机数(N,集群分片数)组成一个新key。

3.热点数据尽量不要设置过期时间,在数据变更时同步写缓存,防止高并发下重建缓存的资源损耗。可以用setnx做分布式锁保证只有一个线程在重建缓存,其他线程等待重建缓存的线程执行完,重新从缓存获取数据即可。

3.缓存穿透

缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,但是出于容错的考虑,如果从存储层查不到数据则不写入缓存层。缓存穿透将导致不存在的数据每次请求都要到存储层去查询,失去了缓存保护后端存储的意义。造成缓存穿透的基本有两个。第一,业务自身代码或者数据出现问题,第二,一些恶意攻击、爬虫等造成大量空命中,下面我们来看一下如何解决缓存穿透问题。解决缓存穿透的两种方案:

1)缓存空对象

缓存空对象会有两个问题:

第一,空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间 ( 如果是攻击,问题更严重 ),比较有效的方法是针对这类数据设置一个较短的过期时间,让其自动剔除。

第二,缓存层和存储层的数据会有一段时间窗口的不一致,可能会对业务有一定影响。例如过期时间设置为 5 分钟,如果此时存储层添加了这个数据,那此段时间就会出现缓存层和存储层数据的不一致,此时可以利用消息系统或者其他方式清除掉缓存层中的空对象。

2)布隆过滤器拦截

如下图所示,在访问缓存层和存储层之前,将存在的 key 用布隆过滤器提前保存起来,做第一层拦截。如果布隆过滤器认为该用户 ID 不存在,那么就不会访问存储层,在一定程度保护了存储层。有关布隆过滤器的相关知识,可以参考: 布隆过滤器,可以利用 Redis 的 Bitmaps 实现布隆过滤器,GitHub 上已经开源了类似的方案,读者可以进行参考:redis bitmaps实现布隆过滤器

img

缓存空对象和布隆过滤器方案对比

img

4.缓存雪崩

数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。

img

可以从以下几个方面防止缓存雪崩:

1)保证缓存层服务高可用性

和飞机都有多个引擎一样,如果缓存层设计成高可用的,即使个别节点、个别机器、甚至是机房宕掉,依然可以提供服务,例如前面介绍过的 Redis Sentinel 和 Redis Cluster 都实现了高可用。

2)Redis备份和快速预热

Redis备份保证master出问题切换为slave迅速能够承担线上实际流量,快速预热保证缓存及时被写入缓存,防止穿透到库。

3)依赖隔离组件为后端限流并降级

无论是缓存层还是存储层都会有出错的概率,可以将它们视同为资源。作为并发量较大的系统,假如有一个资源不可用,可能会造成线程全部 hang 在这个资源上,造成整个系统不可用。降级在高并发系统中是非常正常的:比如推荐服务中,如果个性化推荐服务不可用,可以降级补充热点数据,不至于造成前端页面是开天窗。

在实际项目中,我们需要对重要的资源 ( 例如 Redis、 MySQL、 Hbase、外部接口 ) 都进行隔离,让每种资源都单独运行在自己的线程池中,即使个别资源出现了问题,对其他服务没有影响。但是线程池如何管理,比如如何关闭资源池,开启资源池,资源池阀值管理,这些做起来还是相当复杂的,这里推荐一个 Java 依赖隔离工具Hystrix(https://github.com/Netflix/Hystrix),如下图所示。

4)提前演练

在项目上线前,演练缓存层宕掉后,应用以及后端的负载情况以及可能出现的问题,在此基础上做一些预案设定。

5.缓存预热

缓存预热就是系统上线前,将相关的缓存数据直接加载到缓存系统。这样就可以避免上线后在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!

六.Redis内存模型

**Redis为什么这么快?一文深入了解Redis内存模型!
**

一文揭秘单线程的Redis为什么这么快?

参考文章:

学Redis这篇就够了

Redis缓存的设计、性能、应用与数据集群同步

Redis哨兵、复制、集群的设计原理,以及区别

图示Redis集群架构详解

谈谈redis的热key问题如何解决

如何解决Redis雪崩、穿透、并发等5大难题

Redis架构之防雪崩设计:网站不宕机背后的兵法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值