Redis简介Redis是一个用C语言开发的开源高性能键值对内存数据库。可用于数据库、缓存、消息中间件等场景。它是一个NoSQL(不仅是sql,非关系数据库)数据库。Redis具有出色的性能。数据存储在内存中,读写速度非常快。可支持并发10WQPS。单线程但进程,线程安全,采用IO多路复用系统,可作为分布式锁,支持五种数据类型,支持数据持久化到磁盘,可作为消息中间件,支持消息发布订阅.数据类型下表列出了五种数据类型的特点及其使用场景。缓存数据缓存是Redis最重要的场景。它是为缓存而生的。在springboot中,一般有两种使用方式:直接通过RedisTemplate通过SpringCache集成Redis时遇到的问题(即注解的方式)在使用缓存时(1)数据一致性在分布式环境中,容易出现缓存和数据库到数据一致性问题。如果项目对缓存有强一致性要求,那么就不要使用缓存。我们只能在项目中使用策略来降低缓存和数据库一致性的概率,但是我们不能保证两者的强一致性。总体策略包括缓存更新机制,更新数据库后及时更新缓存,缓存失效时加入重试机制。(2)缓存雪崩在了解雪崩之前,我们先来了解一下什么是缓存雪崩现象。假设系统A每秒需要处理5000个请求,而数据库每秒只能处理4000个请求。有一天,缓存机器崩溃了。这时候,所有的请求一下子落到数据库上,数据库肯定处理不了,告警挂了。如果此时不采用缓存设施,数据库急于使用。重启数据库,刚重启完成(可能还没有启动),请求又进来了,数据库立马挂了。这就是雪崩事件,这是Redis缓存中最致命的问题之一(一个是穿透)。你可以看看下面的图片:雪崩事件发生后,不要着急或惊慌。我们可以从事故前、事故中、事故后三个方面来思考解决方案:事故前:redis高可用方案,主从+哨兵,集群方案,避免全盘崩溃;事故中:压力小数据库,本地Ehcache缓存+限流降级,避免数据库超压;事故发生后:做Redis持久化,一旦Redis重启,数据可以快速从磁盘恢复。我们来看看修改后的数据流。假设用户A发送请求,系统首先请求本地Ehcache是??否有数据。如果没有,那就去Redis去请求数据。如果没有,那就去数据库请求数据。获取到数据后,会同步到Ehcache和redis。限流组件的作用:可以设置每秒的请求数,有多少通过请求,其余失败的可以降级,返回一些默认值,或者友好提醒等默认操作。具体流程见下图:这样做的好处是:数据库安全:当限流组件可用时,数据库不会挂掉,限流基础保证了每秒可以通过多少个请求;部分请求可以处理:如果数据库没有宕机,说明至少有2/5的请求可以处理;有些请求在高峰期无法处理,需要用户多次点击,因为只处理了2/5的请求,剩下的请求用户刷不了。当你从界面出来时,需要点击几次;redis设置的缓存过期时间不设置为同一时间,可以根据功能、业务、请求接口灵活设置缓存时间:setRedis(key,value,time+Math.random()*10000);(3)缓存穿透缓存穿透是指不在缓存或数据库中的数据。用户(黑客)不断发起请求,导致请求直接查询数据库。这种恶意行为攻击场景会直接导致数据库挂掉。数据流向如下图所示:处理这种情况比较简单。这种情况下,就是绕过redis或者本地缓存,直接到达数据库。可以采用如下方案:可以在请求接口层做一些校验,比如用户签名,参数校验,非法请求直接返回;也可以对有效的id进行鉴权或者直接截取,不合格的id直接过滤或者统一key保存到redis。下次请求非法id时,直接从缓存中获取数据;使用redis的高级接口BloomFilter,使用高效的数据结构和算法快速判断你的key是否存在于数据库中,如果不存在,直接返回,如果存在,可以查看DB,刷新KV,然后返回。(4)缓存击穿上面说的穿透是针对大面积的数据请求,所以击穿是针对一个点(一个key)导致redis异常,但是某个key很热,请求很频繁,而且是在集中访问现象中,当key失效(过期)时,大量的请求会穿透缓存,直接请求数据库,就像在屏障上挖了个洞一样。缓存击穿方案的数据在不同场景下基本不变:当热点数据的值基本不更新时,可以设置为永不过期。软件的分布式互斥或本地互斥保证少量请求可以请求数据库并重新更新缓存,其他进程只有在锁释放后才能访问新的缓存重建缓存或延长过期时间到确保所有请求始终可以访问缓存。为什么Redis这么快?Redis官方介绍可以达到10W+QPS。这个数据不比MEMCache差,而且Redis是单进程单线程模型,完全基于内存操作,CPU不是Redis的瓶颈。Redis的瓶颈是内存和网络带宽。它具有以下特点:利用类似于HashMap的原理,HashMap的查询和操作的时间复杂度为O(1),大部分请求都是纯粹的破内存操作,数据存储在内存中;数据结构简单,数据操作也简单,基于KV;死锁现象采用单线程运行,避免了不必要的上下文切换和竞争条件,不存在CPU切换现象,意味着不存在考虑各种锁的问题;使用非阻塞IO,多路复用IO模型。Redis淘汰策略volatile前缀的策略从过期数据集中淘汰。以allkeys为前缀的策略是消除所有键。LRU(leastrecentlyused)就是最近最少使用。LFU(LeastFrequentlyUsed)是最不常用的。它们的触发条件是当Redis使用的内存达到阈值时。Redis持久化Redis的持久化策略有两种:RDB:快照形式是直接将内存中的数据保存到一个dump文件中,定时保存,保存策略。AOF:将所有修改Redis服务器的命令保存在一个文件中,命令的集合。Redis默认是快照RDB的持久化方式。如果你非常在意你的数据,但又能忍受几分钟内数据丢失,那么你可以直接使用RDB持久化。AOF将Redis执行的每个命令附加到磁盘。处理大量写入会降低Redis的性能。不知道你能不能接受。数据库备份和容灾:定时生成RDB快照,非常方便数据库备份,RDB恢复数据集的速度比AOF恢复快。当然Redis同时支持RDB和AOF。系统重启后,Redis会优先使用AOF恢复数据,这样丢失的数据会最少。Redis主从复制从节点执行slaveof[masterIP][masterPort]保存主节点信息;从节点中的定时任务发现主节点信息,与主节点建立Socket连接;从节点发送Ping信号,主节点返回Pong,双方可以互相通信;连接建立后,主节点将所有数据发送给从节点(数据同步);主节点将当前数据同步到从节点后,复制建立过程完成;接下来,主节点会不断地向从节点发送写命令,以保证主从数据的一致性。Redis哨兵模式先说主从复制的问题:一旦主节点宕机,从节点提升为主节点,同时需要应用端主节点的地址被修改,需要命令所有从节点复制新的主节点。整个过程需要人工干预。master节点的写入能力受限于单机。主节点的存储容量受单机限制。nativereplication的缺点在早期版本中也会更加突出,例如:Redis复制中断后,slave节点会发起psync。此时如果同步不成功,则会进行全量同步。主库在进行全量备份时,可能会造成毫秒级甚至秒级的延迟。Sentinel的架构模式如下:系统可以执行以下四个任务:监控:不断检查主服务器和从服务器是否正常运行。通知:当被监控的Redis服务器出现问题时,Sentinel通过API脚本通知管理员或其他应用程序。自动故障转移:当主节点无法正常工作时,Sentinel会启动自动故障转移操作,将其中一个与故障主节点具有主从关系的从节点升级为新的主节点,而另一个从节点nodes指向新的主节点,因此可以避免人工干预。Configurationprovider:在RedisSentinel模式下,客户端应用连接初始化时设置的Sentinel节点,并从中获取master节点的信息。
