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