
Redis 核心技术与实战
文章平均质量分 93
热门缓存技术
cjh-Java
不积跬步,无以至千里
展开
-
26 _ 缓存异常(下):如何解决缓存雪崩、击穿、穿透难题?
你好,我是蒋德钧。上节课,我们学习了缓存和数据库的数据不一致问题和应对方法。除了数据不一致问题,我们常常还会面临缓存异常的三个问题,分别是缓存雪崩、缓存击穿和缓存穿透。这三个问题一旦发生,会导致大量的请求积压到数据库层。如果请求的并发量很大,就会导致数据库宕机或是故障,这就是很严重的生产事故了。这节课,我就来和你聊聊这三个问题的表现、诱发原因以及解决方法。俗话说,知己知彼,百战不殆。了解了问题的成因,我们就能够在应用Redis缓存时,进行合理的缓存设置,以及相应的业务应用前端设置,提前做好准备。接下来,我.原创 2022-01-21 16:33:38 · 213 阅读 · 0 评论 -
25 _ 缓存异常(上):如何解决缓存和数据库的数据不一致问题?
在实际应用Redis缓存时,我们经常会遇到一些异常问题,概括来说有4个方面:缓存中的数据和数据库中的不一致;缓存雪崩;缓存击穿和缓存穿透。只要我们使用Redis缓存,就必然会面对缓存和数据库间的一致性保证问题,这也算是Redis缓存应用中的“必答题”了。最重要的是,如果数据不一致,那么业务应用从缓存中读取的数据就不是最新数据,这会导致严重的错误。比如说,我们把电商商品的库存信息缓存在Redis中,如果库存信息不对,那么业务层下单操作就可能出错,这当然是不能接受的。所以,这节课我就重点和你聊聊这个问题。关于缓原创 2022-01-20 14:10:30 · 545 阅读 · 0 评论 -
24 _ 替换策略:缓存满了怎么办?
Redis缓存使用内存来保存数据,避免业务应用从后端数据库中读取数据,可以提升应用的响应速度。那么,如果我们把所有要访问的数据都放入缓存,是不是一个很好的设计选择呢?其实,这样做的性价比反而不高。举个例子吧。MySQL中有1TB的数据,如果我们使用Redis把这1TB的数据都缓存起来,虽然应用都能在内存中访问数据了,但是,这样配置并不合理,因为性价比很低。一方面,1TB内存的价格大约是3.5万元,而1TB磁盘的价格大约是1000元。另一方面,数据访问都是有局部性的,也就是我们通常所说的“八二原理”,80%的原创 2022-01-10 17:59:58 · 163 阅读 · 0 评论 -
23 _ 旁路缓存:Redis是如何工作的?
我们知道,Redis提供了高性能的数据存取功能,所以广泛应用在缓存场景中,既能有效地提升业务应用的响应速度,还可以避免把高并发大压力的请求发送到数据库层。但是,如果Redis做缓存时出现了问题,比如说缓存失效,那么,大量请求就会直接积压到数据库层,必然会给数据库带来巨大的压力,很可能会导致数据库宕机或是故障,那么,业务应用就没有办法存取数据、响应用户请求了。这种生产事故,肯定不是我们希望看到的。正因为Redis用作缓存的普遍性以及它在业务应用中的重要作用,所以,我们需要系统地掌握缓存的一系列内容,包括工作原原创 2022-01-10 17:08:21 · 204 阅读 · 0 评论 -
21 _ 缓冲区:一个可能引发“惨案”的地方
今天,我们一起来学习下Redis中缓冲区的用法。缓冲区的功能其实很简单,主要就是用一块内存空间来暂时存放命令数据,以免出现因为数据和命令的处理速度慢于发送速度而导致的数据丢失和性能问题。但因为缓冲区的内存空间有限,如果往里面写入数据的速度持续地大于从里面读取数据的速度,就会导致缓冲区需要越来越多的内存来暂存数据。当缓冲区占用的内存超出了设定的上限阈值时,就会出现缓冲区溢出。如果发生了溢出,就会丢数据了。那是不是不给缓冲区的大小设置上限,就可以了呢?显然不是,随着累积的数据越来越多,缓冲区占用内存空间越来越大原创 2021-12-18 10:43:29 · 593 阅读 · 0 评论 -
20 _ 删除数据后,为什么内存占用率还是很高?
在使用Redis时,我们经常会遇到这样一个问题:明明做了数据删除,数据量已经不大了,为什么使用top命令查看时,还会发现Redis占用了很多内存呢?实际上,这是因为,当数据删除后,Redis释放的内存空间会由内存分配器管理,并不会立即返回给操作系统。所以,操作系统仍然会记录着给Redis分配了大量内存。但是,这往往会伴随一个潜在的风险点:Redis释放的内存空间可能并不是连续的,那么,这些不连续的内存空间很有可能处于一种闲置的状态。这就会导致一个问题:虽然有空闲空间,Redis却无法用来保存数据,不仅会减少原创 2021-12-14 08:47:01 · 302 阅读 · 0 评论 -
18 _ 波动的响应延迟:如何应对变慢的Redis?(上)
在Redis的实际部署应用中,有一个非常严重的问题,那就是Redis突然变慢了。一旦出现这个问题,不仅会直接影响用户的使用体验,还可能会影响到“旁人”,也就是和Redis在同一个业务系统中的其他系统,比如说数据库。举个小例子,在秒杀场景下,一旦Redis变慢了,大量的用户下单请求就会被拖慢,也就是说,用户提交了下单申请,却没有收到任何响应,这会给用户带来非常糟糕的使用体验,甚至可能会导致用户流失。而且,在实际生产环境中,Redis往往是业务系统中的一个环节(例如作为缓存或是作为数据库)。一旦Redis上的请原创 2021-12-11 11:21:58 · 176 阅读 · 0 评论 -
17 _ 为什么CPU结构也会影响Redis的性能?
很多人都认为Redis和CPU的关系很简单,就是Redis的线程在CPU上运行,CPU快,Redis处理请求的速度也很快。这种认知其实是片面的。CPU的多核架构以及多CPU架构,也会影响到Redis的性能。如果不了解CPU对Redis的影响,在对Redis的性能进行调优时,就可能会遗漏一些调优方法,不能把Redis的性能发挥到极限。今天,我们就来学习下目前主流服务器的CPU架构,以及基于CPU多核架构和多CPU架构优化Redis性能的方法。主流的CPU架构要了解CPU对Redis具体有什么影响,我们得先了解原创 2021-12-11 10:57:22 · 529 阅读 · 0 评论 -
16 _ 异步机制:如何避免单线程模型的阻塞?
Redis之所以被广泛应用,很重要的一个原因就是它支持高性能访问。也正因为这样,我们必须要重视所有可能影响Redis性能的因素(例如命令操作、系统配置、关键机制、硬件配置等),不仅要知道具体的机制,尽可能避免性能异常的情况出现,还要提前准备好应对异常的方案。所以,从这节课开始,我会用6节课的时间介绍影响Redis性能的5大方面的潜在因素,分别是:Redis内部的阻塞式操作;CPU核和NUMA架构的影响;Redis关键系统配置;Redis内存碎片;Redis缓冲区。这节课,我们就先学习了解下Red原创 2021-12-11 10:33:02 · 220 阅读 · 0 评论 -
15 _ 消息队列的考验:Redis有哪些解决方案?
现在的互联网应用基本上都是采用分布式系统架构进行设计的,而很多分布式系统必备的一个基础软件就是消息队列。消息队列要能支持组件通信消息的快速读写,而Redis本身支持数据的高速访问,正好可以满足消息队列的读写性能需求。不过,除了性能,消息队列还有其他的要求,所以,很多人都很关心一个问题:“Redis适合做消息队列吗?”其实,这个问题的背后,隐含着两方面的核心问题:消息队列的消息存取需求是什么?Redis如何实现消息队列的需求?这节课,我们就来聊一聊消息队列的特征和Redis提供的消息队列方案。只有把这两转载 2021-12-10 17:22:18 · 182 阅读 · 0 评论 -
14 _ 如何在Redis中保存时间序列数据?
我们现在做互联网产品的时候,都有这么一个需求:记录用户在网站或者App上的点击行为数据,来分析用户行为。这里的数据一般包括用户ID、行为类型(例如浏览、登录、下单等)、行为发生的时间戳:UserID, Type, TimeStamp我之前做过的一个物联网项目的数据存取需求,和这个很相似。我们需要周期性地统计近万台设备的实时状态,包括设备ID、压力、温度、湿度,以及对应的时间戳:DeviceID, Pressure, Temperature, Humidity, TimeStamp这些与发生时间相关的一组原创 2021-12-10 14:07:16 · 927 阅读 · 0 评论 -
13 _ GEO是什么?还可以定义新的数据类型吗?
Redis的5大基本数据类型:String、List、Hash、Set和Sorted Set,它们可以满足大多数的数据存储需求,但是在面对海量数据统计时,它们的内存开销很大,而且对于一些特殊的场景,它们是无法支持的。所以,Redis还提供了3种扩展数据类型,分别是Bitmap、HyperLogLog和GEO。前两种我在上节课已经重点介绍过了,今天,我再具体讲一讲GEO。另外,我还会给你介绍开发自定义的新数据类型的基本步骤。掌握了自定义数据类型的开发方法,当你面临一些复杂的场景时,就不用受基本数据类型的限制,转载 2021-12-10 13:56:48 · 309 阅读 · 0 评论 -
12 _ 有一亿个keys要统计,应该用哪种集合?
在Web和移动应用的业务场景中,我们经常需要保存这样一种信息:一个key对应了一个数据集合。我举几个例子。手机App中的每天的用户登录信息:一天对应一系列用户ID或移动设备ID;电商网站上商品的用户评论列表:一个商品对应了一系列的评论;用户在手机App上的签到打卡信息:一天对应一系列用户的签到记录;应用网站上的网页访问信息:一个网页对应一系列的访问点击。我们知道,Redis集合类型的特点就是一个键对应一系列的数据,所以非常适合用来存取这些数据。但是,在这些场景中,除了记录信息,我们往往还需要对集合原创 2021-12-10 13:43:31 · 136 阅读 · 0 评论 -
11 _ “万金油”的String,为什么不好用了?
从今天开始,我们就要进入“实践篇”了。接下来,我们会用5节课的时间学习“数据结构”。我会介绍节省内存开销以及保存和统计海量数据的数据类型及其底层数据结构,还会围绕典型的应用场景(例如地址位置查询、时间序列数据库读写和消息队列存取),跟你分享使用Redis的数据类型和module扩展功能来满足需求的具体方案。今天,我们先了解下String类型的内存空间消耗问题,以及选择节省内存开销的数据类型的解决方案。先跟你分享一个我曾经遇到的需求。当时,我们要开发一个图片存储系统,要求这个系统能快速地记录图片ID和图片在存转载 2021-12-08 20:24:40 · 151 阅读 · 0 评论 -
10 _ 第1~9讲课后思考题答案及常见问题答疑
第1讲问题:和跟Redis相比,SimpleKV还缺少什么?@曾轼麟、@Kaito 同学给出的答案都非常棒。他们从数据结构到功能扩展,从内存效率到事务性,从高可用集群再到高可扩展集群,对SimpleKV和Redis进行了详细的对比。而且,他们还从运维使用的角度进行了分析。我先分享一下两位同学的答案。@曾轼麟同学:数据结构:缺乏广泛的数据结构支持,比如支持范围查询的SkipList和Stream等数据结构。高可用:缺乏哨兵或者master-slave模式的高可用设计;横向扩展:缺乏集群和分片功能;内原创 2021-12-05 17:32:38 · 483 阅读 · 0 评论 -
09 _ 切片集群:数据增多了,是该加内存还是加实例?
今天我们来学习切片集群。我曾遇到过这么一个需求:要用Redis保存5000万个键值对,每个键值对大约是512B,为了能快速部署并对外提供服务,我们采用云主机来运行Redis实例,那么,该如何选择云主机的内存容量呢?我粗略地计算了一下,这些键值对所占的内存空间大约是25GB(5000万*512B)。所以,当时,我想到的第一个方案就是:选择一台32GB内存的云主机来部署Redis。因为32GB的内存能保存所有数据,而且还留有7GB,可以保证系统的正常运行。同时,我还采用RDB对数据做持久化,以确保Redis实例原创 2021-12-05 17:30:10 · 155 阅读 · 0 评论 -
08 _ 哨兵集群:哨兵挂了,主从库还能切换吗?
上节课,我们学习了哨兵机制,它可以实现主从库的自动切换。通过部署多个实例,就形成了一个哨兵集群。哨兵集群中的多个实例共同判断,可以降低对主库下线的误判率。但是,我们还是要考虑一个问题:如果有哨兵实例在运行时发生了故障,主从库还能正常切换吗?实际上,一旦多个实例组成了哨兵集群,即使有哨兵实例出现故障挂掉了,其他哨兵还能继续协作完成主从库切换的工作,包括判定主库是不是处于下线状态,选择新主库,以及通知从库和客户端。如果你部署过哨兵集群的话就会知道,在配置哨兵的信息时,我们只需要用到下面的这个配置项,设置主库的I原创 2021-12-05 15:29:23 · 334 阅读 · 0 评论 -
07 _ 哨兵机制:主库挂了,如何不间断服务?
之前,我们学习了主从库集群模式。在这个模式下,如果从库发生故障了,客户端可以继续向主库或其他从库发送请求,进行相关的操作,但是如果主库发生故障了,那就直接会影响到从库的同步,因为从库没有相应的主库可以进行数据复制操作了。而且,如果客户端发送的都是读操作请求,那还可以由从库继续提供服务,这在纯读的业务场景下还能被接受。但是,一旦有写操作请求了,按照主从库模式下的读写分离要求,需要由主库来完成写操作。此时,也没有实例可以来服务客户端的写操作请求了,如下图所示:无论是写服务中断,还是从库无法进行数据同步,都是不能原创 2021-12-05 11:42:42 · 159 阅读 · 0 评论 -
06 _ 数据同步:主从库如何实现数据一致?
前两节课,我们学习了AOF和RDB,如果Redis发生了宕机,它们可以分别通过回放日志和重新读入RDB文件的方式恢复数据,从而保证尽量少丢失数据,提升可靠性。不过,即使用了这两种方法,也依然存在服务不可用的问题。比如说,我们在实际使用时只运行了一个Redis实例,那么,如果这个实例宕机了,它在恢复期间,是无法服务新来的数据存取请求的。那我们总说的Redis具有高可靠性,又是什么意思呢?其实,这里有两层含义:一是数据尽量少丢失,二是服务尽量少中断。AOF和RDB保证了前者,而对于后者,Redis的做法就是增加原创 2021-12-03 13:53:47 · 289 阅读 · 0 评论 -
05 _ 内存快照:宕机后,Redis如何实现快速恢复?
上一篇,我们学习了Redis避免数据丢失的AOF方法。这个方法的好处,是每次执行只需要记录操作命令,需要持久化的数据量不大。一般而言,只要你采用的不是always的持久化策略,就不会对性能造成太大影响。但是,也正因为记录的是操作命令,而不是实际的数据,所以,用AOF方法进行故障恢复的时候,需要逐一把操作日志都执行一遍。如果操作日志非常多,Redis就会恢复得很缓慢,影响到正常使用。这当然不是理想的结果。那么,还有没有既可以保证可靠性,还能在宕机时实现快速恢复的其他方法呢?当然有了,这就是我们今天要一起学习的原创 2021-12-01 08:21:39 · 171 阅读 · 0 评论 -
04 _ AOF日志:宕机了,Redis如何避免数据丢失?
如果有人问你:“你会把Redis用在什么业务场景下?”我想你大概率会说:“我会把它当作缓存使用,因为它把后端数据库中的数据存储在内存中,然后直接从内存中读取数据,响应速度会非常快。”没错,这确实是Redis的一个普遍使用场景,但是,这里也有一个绝对不能忽略的问题:一旦服务器宕机,内存中的数据将全部丢失。我们很容易想到的一个解决方案是,从后端数据库恢复这些数据,但这种方式存在两个问题:一是,需要频繁访问数据库,会给数据库带来巨大的压力;二是,这些数据是从慢速数据库中读取出来的,性能肯定比不上从Redis中读取转载 2021-11-24 15:08:12 · 230 阅读 · 0 评论 -
02 _ 数据结构:快速的Redis有哪些慢操作?
一提到Redis,我们的脑子里马上就会出现一个词:“快。”但是你有没有想过,Redis的快,到底是快在哪里呢?实际上,这里有一个重要的表现:它接收到一个键值对操作后,能以微秒级别的速度找到数据,并快速完成操作。数据库这么多,为啥Redis能有这么突出的表现呢?一方面,这是因为它是内存数据库,所有操作都在内存上完成,内存的访问速度本身就很快。另一方面,这要归功于它的数据结构。这是因为,键值对是按一定的数据结构来组织的,操作键值对最终就是对数据结构进行增删改查操作,所以高效的数据结构是Redis快速处理数据的基原创 2021-11-07 14:06:29 · 144 阅读 · 0 评论 -
03 _ 高性能IO模型:为什么单线程Redis能那么快?
今天,我们来探讨一个很多人都很关心的问题:“为什么单线程的Redis能那么快?”首先,我要和你厘清一个事实,我们通常说,Redis是单线程,主要是指Redis的网络IO和键值对读写是由一个线程来完成的,这也是Redis对外提供键值存储服务的主要流程。但Redis的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的。所以,严格来说,Redis并不是单线程,但是我们一般把Redis称为单线程高性能,这样显得“酷”些。接下来,我也会把Redis称为单线程模式。而且,这也会促使你紧接着提问:“原创 2021-11-07 14:05:50 · 168 阅读 · 0 评论