Redis的原理及应用
Redis是一个开源(BSD许可)的内存中的数据结构存储系统,可以用作数据库、缓存和消息中间件,支持多种类型的数据结构,例如String(字符串)、Hash(散列)、List(列表)、Set(集合)、ZSet(有序集合)、Bitmap(位图)、HyperLogLog(超级日志)和Geospatial(地理空间)。Redis内置了复制、Lua脚本、LRU驱动事件、事务和不同级别的磁盘持久化,并通过Redis哨兵(Sentinel)模式和集群模式(Cluster)提供高可用性(HighAvailability)。
Redis的原理
Redis不但支持丰富的数据类型,还支持分布式事务、数据分片、数据持久化等功能,是分布式系统中不可或缺的内存数据库服务。
Redis的数据类型
(1)String:String是Redis基本的数据类型,一个key对应一个value。String类型的值最大能存储512MB数据。Redis的String数据类型支持丰富的操作命令,常用的String操作命令。
(2)Hash:RedisHash是一个键值(keyvalue)对集合。Redis的Hash列表支持的操作。
(3)List:RedisList是简单的字符串列表,按照插入顺序排序。我们可以添加一个元素到列表的头部(左边)或者尾部(右边)。列表最多可存储2311(42949672954亿多)个元素。
(4)Set:Set是String类型的无序集合。集合是通过散列表实现的,所以添加、删除、查找的复杂度都是O(1)。
(5)ZSet:RedisZSet和Set一样也是String类型元素的集合,且不允许有重复的成员,不同的是,每个元素都会关联一个double类型的分数。Redis正是通过分数来为集合中的成员进行从小到大的排序的。
(6)Bitmap:通过操作二进制位记录数据。
(7)HyperLogLog:被用于估计一个Set中元素数量的概率性的数据结构。
(8)Geospatial:用于地理空间关系计算。
Redis管道
Redis是基于请求响应协议的TCP服务。在客户端向服务器发送一个查询请求后,需要监听Socket的返回,该监听过程一直阻塞,直到服务器有结果返回。由于Redis集群是部署在多个服务器上的,所以Redis的请求响应模型在每次请求时都要跨网络在不同的服务器之间传输数据,这样每次查询都存在一定的网络延迟(服务器之间的网络延迟一般在20ms左右)。由于服务器一般采用多线程处理业务,并且内存操作效率很高,所以如果一次请求延迟20ms,则多次请求的网络延迟会不断累加。也就是说,在分布式环境下,Redis的性能瓶颈主要体现在网络延迟上。
Redis的管道技术指在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。管道技术能减少客户端和服务器交互的次数,将客户端的请求批量发送给服务器,服务器针对批量数据分别查询并统一回复,能显著提高Redis的性能。
Redis管道技术基于SpringBoot的使用如下:
以上代码使用redisTemplate。executePipelined()在SpringBoot中实现了基于Redis的管道操作。具体的步骤为:新建RedisCallback对象并覆写doInRedis();在doInRedis()中通过connection。openPipeline()开启Pipeline操作;在for循环中批量进行Redis数据写操作;最终将批量操作结果返回。
Redis的事务
Redis支持分布式环境下的事务操作,其事务可以一次执行多个命令,事务中的所有命令都会序列化地顺序执行。事务在执行过程中,不会被其他客户端发送来的命令请求打断。服务器在执行完事务中的所有命令之后,才会继续处理其他客户端的其他命令。Redis的事务操作分为开启事务、命令入队列、执行事务三个阶段。Redis的事务执行流程如下。
(1)事务开启:客户端执行Multi命令开启事务。
(2)提交请求:客户端提交命令到事务。
(3)任务入队列:Redis将客户端请求放入事务队列中等待执行。
(4)入队状态反馈:服务器返回QURUD,表示命令已被放入事务队列。
(5)执行命令:客户端通过Exec执行事务。
(6)事务执行错误:在Redis事务中如果某条命令执行错误,则其他命令会继续执行,不会回滚。可以通过Watch监控事务执行的状态并处理命令执行错误的异常情况。
(7)执行结果反馈:服务器向客户端返回事务执行的结果。
Redis事务的相关命令有Multi、Exec、Discard、Watch和Unwatch。
Redis事务基于SpringBoot的使用如下:
以上代码定义了名为transactionSet()的Redis事务操作方法,该方法接收事务命令commandList并以事务命令列表在一个事务中执行。具体步骤为:开启事务权限、开启事务、执行事务命令、提供事务和回滚事务。
Redis发布、订阅
Redis发布、订阅是一种消息通信模式:发送者(Pub)向频道(Channel)发送消息,订阅者(Sub)接收频道上的消息。Redis客户端可以订阅任意数量的频道,发送者也可以向任意频道发送数据。图87展示了1个发送者(pub1)、1个频道(channe0)和3个订阅者(sub1、sub2、sub3)的关系。由于3个订阅者sub1、sub2、sub3都订阅了频道channel0,在发送者pub1向频道channel0发送一条消息后,这条消息就会被发送给订阅它的三个客户端。
Redis常用的消息订阅与发布命令如表
Redis集群数据复制的原理
Redis提供了复制功能,可以实现在主数据库(Master)中的数据更新后,自动将更新的数据同步到从数据库(Slave)。一个主数据库可以拥有多个从数据库,而一个从数据库只能拥有一个主数据库。
(1)一个从数据库在启动后,会向主数据库发送SYNC命令。
(2)主数据库在接收到SYNC命令后会开始在后台保存快照(即RDB持久化的过程),并将保存快照期间接收到的命令缓存起来。在该持久化过程中会生成一个rdb快照文件。
(3)在主数据库快照执行完成后,Redis会将快照文件和所有缓存的命令以rdb快照文件的形式发送给从数据库。
(4)从数据库收到主数据库的rdb快照文件后,载入该快照文件到本地。
(5)从数据库执行载入后的rdb快照文件,将数据写入内存中。以上过程被称为复制初始化。
(6)在复制初始化结束后,主数据库在每次收到写命令时都会将命令同步给从数据库,从而保证主从数据库的数据一致。
在Redis中开启复制功能时需要在从数据库配置文件中加入如下配置,对主数据库无须进行任何配置:
在上述配置中,slaveof后面的配置分别为主数据库的IP地址和端口,在主数据库开启了密码认证后需要将masterauth设置为主数据库的密码,在配置完成后重启Redis,主数据库上的数据就会同步到从数据库上。
Redis的持久化
Redis支持RDB和AOF两种持久化方式。
(1)RDB(RedisDataBase):RDB在指定的时间间隔内对数据进行快照存储。RDB的特点在于:文件格式紧凑,方便进行数据传输和数据恢复;在保存rdb快照文件时父进程会fork出一个子进程,由子进程完成具体的持久化工作,所以可以最大化Redis的性能;同时,与AOF相比,在恢复大的数据集时会更快一些。
(2)AOF(AppendOfFlie):AOF记录对服务器的每次写操作,在Redis重启时会重放这些命令来恢复原数据。AOF命令以Redis协议追加和保存每次写操作到文件末尾,Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。AOF的特点有:可以使用不同的fsync策略(无fsync、每秒fsync、每次写的时候fsync),只有某些操作追加命令到文件中,操作效率高;同时,AOF文件是日志的格式,更容易被操作。
Redis的集群模式及工作原理
Redis有三种集群模式:主从模式、哨兵模式和集群模式。
(1)主从模式:所有的写请求都被发送到主数据库上,再由主数据库将数据同步到从数据库上。主数据库主要用于执行写操作和数据同步,从数据库主要用于执行读操作缓解系统的读压力。
(2)哨兵模式:在主从模式上添加了一个哨兵的角色来监控集群的运行状态。哨兵通过发送命令让Redis服务器返回其运行状态。哨兵是一个独立运行的进程,在监测到Master宕机时会自动将Slave切换成Master,然后通过发布与订阅模式通知其他从服务器修改配置文件,完成主备热切。
(3)集群模式:Redis集群实现了在多个Redis节点之间进行数据分片和数据复制。基于Redis集群的数据自动分片能力,我们能够方便地对Redis集群进行横向扩展,以提高Redis集群的吞吐量。基于Redis集群的数据复制能力,在集群中的一部分节点失效或者无法进行通信时,Redis仍然可以基于副本数据对外提供服务,这提高了集群的可用性。
Redis集群遵循如下原则。
所有Redis节点彼此都通过PINGPONG机制互联,内部使用二进制协议优化传输速度和带宽。
在集群中超过半数的节点检测到某个节点Fail后将该节点设置为Fail状态。
客户端与Redis节点直连,客户端连接集群中任何一个可用节点即可对集群进行操作。
RedisCluster把所有的物理节点都映射到0~16383的slot(槽)上,Cluster负责维护每个节点上数据槽的分配。Redis的具体数据分配策略为:在Redis集群中内置了16384个散列槽;在需要在Redis集群中放置一个KeyValue时,Redis会先对Key使用CRC16算法算出一个结果,然后把结果对16384求余数,这样每个Key都会对应一个编号为0~16383的散列槽;Redis会根据节点的数量大致均等地将散列槽映射到不同的节点。
Redis的应用
1安装RedisRedis的安装分Redis单机版安装、Redis主从模式安装、Redis哨兵模式安装和Redis集群模式安装。下面介绍Redis集群模式的安装,该模式也是最复杂的一种模式。其他Redis模式的安装请读者参考官网教程。
(1)下载Redis软件。执行以下命令从官网下载稳定版本的Redis并解压:
(2)编译和安装。执行以下命令进入Redis的安装目录编译和安装Redis:
(3)创建Redis节点。执行以下命令在Redis根目录下创建节点目录:
以上命令分别建立了7000、7001、7002、7003、7004、7005共6个目录,用于存放6个节点的配置文件信息。将redis。conf文件分别复制到7000、7001、7002、7003、7004、7005目录下,并修改端口号和clusterconfigfile。
(4)配置Redis集群。分别修改7000、7001、7002、7003、7004、7005目录下的redis。conf配置文件:
在以上配置中,port用于指定Redis服务端口,clusterenabled用于设置Redis为集群模式,clusterconfigfile用于设置集群配置文件。
(5)启动节点。执行以下命令分别启动6个节点
(6)创建集群。执行以下命令创建集群:
在以上命令中,cluster表示该命令是集群相关的命令;create表示创建一个集群,create后面的参数为参与集群创建的节点;clusterreplicas表示集群中的副本数。在创建集群的过程中命令行会列出集群的配置让我们确认,确认时输入yes即可。这样便在一个服务器上安装了一个Reds集群,在该集群中共有6个节点,节点的IP地址为127。0。0。1,节点的端口号分别为7000、7001、7002、7003、7004和7005。
2应用RedisSpringBoot
在SpringBoot中使用Redis的步骤为:引入jar包、配置application。properties,以及配置和使用RedisTemplate,如下所述。
(1)引入jar包。按照如下代码在SpringBoot项目中加入Redis的jar包依赖:
(2)配置application。properties:在resource目录的application。properties加入以下Redis配置:
在以上配置中,spring。redis。cluster。nodes为Redis集群节点的服务地址,在多个服务地址之间使用逗号隔开;spring。redis。password为Redis服务密码,如果没有密码,则将其设置为空即可。需要注意的是,以上是集群模式下的Redis配置,如果Redis是主从模式,则将spring。redis。cluster。nodes地址修改为主从节点的服务地址即可;如果是哨兵模式,则注释掉spring。redis。cluster。nodes配置,在spring。redis。sentinel。master和spring。redis。sentinel。nodes中分别配置哨兵的名称和哨兵的节点即可;如果是单机模式,则注释掉spring。redis。sentinel。nodes的配置,通过spring。redis。host配置Redis服务的地址,并通过spring。redis。port配置Redis服务的端口即可。
(3)配置RedisTemplate。SpringBoot默认配置了RedisTemplate,在应用时注入、使用即可,也可以创建自定义的RedisTemplate。具体代码如下:
以上代码定义了RedisConfig类,并通过Configuration开启配置文件注解,通过AutoConfigureAfter配置自动注解类。在RedisConfig类中定义了RedisTemplate用于对Redis数据库进行操作。
(4)使用RedisTemplate。新建测试类,并在测试类中加入以下测试代码:
RedisTemplate基于Jedis对Redis数据库的操作进行了二次封装,使得操作Redis数据库更加方便。以上代码在测试类中依赖注入了RedisTemplate,并通过redisTemplate。opsForValue()实现了对Redis数据的插入、查询和删除操作。
分布式缓存设计的核心问题
分布式缓存设计的核心问题是以哪种方式进行缓存预热和缓存更新,以及如何优雅解决缓存雪崩、缓存穿透、缓存降级等问题。这些问题在不同的应用场景下有不同的解决方案,下面介绍常用的解决方案。
缓存预热
缓存预热指在用户请求数据前先将数据加载到缓存系统中,用户查询事先被预热的缓存数据,以提高系统查询效率。缓存预热一般有系统启动加载、定时加载等方式。
缓存更新
缓存更新指在数据发生变化后及时将变化后的数据更新到缓存中。常见的缓存更新策略有以下4种。
定时更新:定时将底层数据库内的数据更新到缓存中,该方法比较简单,适合需要缓存的数据量不是很大的应用场景。
过期更新:定时将缓存中过期的数据更新为最新数据并更新缓存的过期时间。
写请求更新:在用户有写请求时先写数据库同时更新缓存,这适用于用户对缓存数据和数据库的数据有实时强一致性要求的情况。
读请求更新:在用户有读请求时,先判断该请求数据的缓存是否存在或过期,如果不存在或已过期,则进行底层数据库查询并将查询结果更新到缓存中,同时将查询结果返回给用户。
缓存淘汰策略
在缓存数据过多时需要使用某种淘汰算法决定淘汰哪些数据。常用的淘汰算法有以下几种。FIFO(FirstInFirstOut,先进先出):判断被存储的时间,离目前最远的数据优先被淘汰。
LRU(LeastRecentlyUsed,最近最少使用):判断缓存最近被使用的时间,距离当前时间最远的数据优先被淘汰。
LFU(LeastFrequentlyUsed,最不经常使用):在一段时间内,被使用次数最少的缓存优先被淘汰。
缓存雪崩
缓存雪崩指在同一时刻由于大量缓存失效,导致大量原本应该访问缓存的请求都去查询数据库,而对数据库的CPU和内存造成巨大压力,严重的话会导致数据库宕机,从而形成一系列连锁反应,使整个系统崩溃。一般有以下3种处理方法。
请求加锁:对于并发量不是很多的应用,使用请求加锁排队的方案防止过多请求数据库。失效更新:为每一个缓存数据都增加过期标记来记录缓存数据是否失效,如果缓存标记失效,则更新数据缓存。
设置不同的失效时间:为不同的数据设置不同的缓存失效时间,防止在同一时刻有大量的数据失效。
缓存穿透
缓存穿透指由于缓存系统故障或者用户频繁查询系统中不存在(在系统中不存在,在自然数据库和缓存中都不存在)的数据,而这时请求穿过缓存不断被发送到数据库,导致数据库过载,进而引发一连串并发问题。
比如用户发起一个userName为zhangsan的请求,而在系统中并没有名为zhangsan的用户,这样就导致每次查询时在缓存中都找不到该数据,然后去数据库中再查询一遍。由于zhangsan用户本身在系统中不存在,自然返回空,导致请求穿过缓存频繁查询数据库,在用户频繁发送该请求时将导致数据库系统负载增大,从而可能引发其他问题。常用的解决缓存穿透问题的方法有布隆过滤器和cachenull策略。
布隆过滤器:指将所有可能存在的数据都映射到一个足够大的Bitmap中,在用户发起请求时首先经过布隆过滤器的拦截,一个一定不存在的数据会被这个布隆过滤器拦截,从而避免对底层存储系统带来查询上的压力。
cachenull策略:指如果一个查询返回的结果为null(可能是数据不存在,也可能是系统故障),我们仍然缓存这个null结果,但它的过期时间会很短,通常不超过5分钟;在用户再次请求该数据时直接返回null,而不会继续访问数据库,从而有效保障数据库的安全。其实cachenull策略的核心原理是:在缓存中记录一个短暂的(数据过期时间内)数据在系统中是否存在的状态,如果不存在,则直接返回null,不再查询数据库,从而避免缓存穿透到数据库上。
缓存降级
缓存降级指由于访问量剧增导致服务出现问题(如响应时间慢或不响应)时,优先保障核心业务的运行,减少或关闭非核心业务对资源的使用。常见的服务降级策略如下。
写降级:在写请求增大时,可以只进行Cache的更新,然后将数据异步更新到数据库中,保证最终一致性即可,即将写请求从数据库降级为Cache。
读降级:在数据库服务负载过高或数据库系统故障时,可以只对Cache进行读取并将结果返回给用户,在数据库服务正常后再去查询数据库,即将读请求从数据库降级为Cache。这种方式适用于对数据实时性要求不高的场景,保障了在系统发生故障的情况下用户依然能够访问到数据,只是访问到的数据相对有延迟。
汉初陈平到底有多狗提起刘邦手下的牛逼人物,大家第一时间想到的肯定是汉初三杰韩信张良萧何三人。战必胜攻必克,兵仙韩信打仗无人能及。运筹帷幄之中,决胜千里之外,张良即是谋臣也是军事家。在那个硝烟四起战乱
南宫地名肇源刍议羲之好鹅,世人说他是闲人是痴汉!殊不知,在书圣看来,无癖之人无至情,此辈最堪忧也!试问,斯忧何在?关于南宫地名的由来,目前存在多种推论,较流行的有三说。一是源于南宫适,二是源于庇商
雅迪电动自行车YS500测评28寸轮毂9级变速,续航达300公里阅读本文前,请您先点击上面的关注,可以免费订阅我们的最新内容,感谢支持中国曾经被称为自行车王国,更是世界上单车生产最多的国家,但在国内,自行车作为主流代步工具的时代已经过去了,以功
互换队长!30岁国手接替周鹏,对韩国狂砍22分,杜锋提前培养双核今年开始广东男篮进入重建阶段已经是不可逆转的事实,这个夏天多名关键球员合同到期,因为收入吃紧,朱芳雨没法满足所有人的薪资要求,如果说王薪凯汤杰离队合情合理,那么放走队长周鹏确实让不
被讨厌的勇气读书笔记这本书的写作形式时青年和哲人之间的对话。竟然发现自己也有不少世俗的想法是和青年是类似,跟随者哲人的思路读完本是,也感觉人生通透了许多。读这本书时,已经在模糊和微弱的光中地度过了自己
38岁女人再婚,嫁28岁的年轻小伙,90天就后悔我变得害怕深夜了文陶陛口述王晴晴(化名)老人说女大三,抱金砖。现在流行女大三十,抱江山。姐弟恋还是哥妹恋也罢,都有一个共性,双方都是有所图。要不是因为我离过一次婚,根本无法接受小我整整十岁的男人,
新郎爱上按摩女,按摩房内绽放纯洁爱情一深夜定婚车我在电脑上一边浏览着唐山的恶劣刑事案件,一边不经意地瞄了下电脑右下角的时间。已经到23点了。我喃喃的自言自语到,在婚车店内坐了一天,除了有两个客人询问之后,一单也没有定
全国城市房价跌幅排行榜前十位近日,国家统计局发布了70个大中城市商品住宅销售价格最新变动数据。之前各大城市出台的救市政策,没想到仅仅是提振了一下市场。部分城市6月销售额上升,7月又回落了!已经有一半以上的城市
秦始皇陵墓中的水银竟然出自一寡妇之手在了解秦始皇陵墓的秘密之前,先让我们来简单了解一下秦始皇这个人,想直接了解秦始皇陵墓中的水银秘密,直接翻到文章最后秦始皇姓嬴名政,赵氏,又称赵政祖龙出生于公元前259年,自前230
6年前,那个把自己整容成刘亦菲的女孩,如今过得如何?你有容貌焦虑么?一般情况下,容貌焦虑是指对自己长相不自信,觉得自己不好看而产生的焦虑。事实上,容貌焦虑这种问题已经变得很内卷,很多面容姣好的男孩女孩,依然会为自己的长相而焦虑。李奕
新疆8天感染超200例并外溢,一市两县跨省游熔断除了三亚北海之外,另一个暑期旅游热门目的地新疆伊犁,近期也遇到了疫情问题。新疆维吾尔自治区卫生健康委通报,8月6日024时,新疆维吾尔自治区无新增报告确诊病例新增无症状感染者52例
智能机器人将我们变成懒惰人类吗?在过去几十年中,人工智能技术的快速发展已经改变了人类生活的方方面面,而智能机器人则是其中一个最显著的例子。从工厂生产线到家庭助理,这些机器人已经开始在各个领域中发挥作用。然而,这些
国内首次检测出XBB。1。5本土病例近日,国内首次检测出XBB。1。5登上了微博热搜,该消息来源自中国疾控中心发布的中国疾病预防控制中心一文,文中显示,2022年12月1日至2023年2月16日期间,共发现重点关注变
地球的肺,可能要废一项为期十年的亚马逊河流域温室气体研究结果表明,亚马逊雨林大约20的面积已经成为大气中二氧化碳的净来源。什么意思?在过去的近10年中,巴西的一组科学家,经常都会利用装有监测温室气体
发现这位优雅妈妈,我才相信过膝裙气质短发,才是变美的秘诀爱美之心人皆有之,当年龄优势不在后,很多中年妈妈们会通过恰当的穿衣打扮展现自身气质。不过对于中年妈妈来说,穿衣失败对形象的打击也很大,想要轻松穿出优雅时髦感,那么不妨借鉴一些同龄人
周报电竞运营商英雄体育VSPO募资超2亿美元,与中东走得更近本周最值得关注的要闻电竞运营商英雄体育VSPO获2。65亿美元投资,与中东市场走得更近电竞赛道也重新热闹了起来。本周四,PIF(沙特主权财富基金)的子公司SavvyGamesGro
国际米兰向马库斯图拉姆提供了一份为期五年的合同国际米兰向马库斯图拉姆提供了一份为期五年的合同门兴格拉德巴赫前锋马库斯图拉姆正在与国际米兰进行谈判,Calciomercato报道。蓝黑军团是这位25岁法国人在一月份的主要竞争者之
松山湖高品质载体空间35国际创新创业社区编者按投资松山湖,发展天地宽!2023年2月20日,东莞松山湖载体空间专题招商大会将隆重举办。今年,松山湖将推出全年度招商引资系列品牌活动,打出招商组合拳,全力抓牢招商头等大事,为
我们国家最近的货币数据相当引人注目图片来源于网络我们国家最近的货币数据相当引人注目,截至2023年1月底,M2(广义货币供应量)达到惊人的273。81万亿元,同比增长12。6。单月社会融资增加了5。98万亿元,人民
A股大势已定,下周抄底?不废话,直接上答案周末被注册制刷屏,昨天该说的包拯都已经说了,无论利空也好,利多也罢,不可否认A股即将进入一个新时代,与其抱怨不如改变,当你自身能力不足时,那就只能被淘汰。包拯有幸在A股市场生存多年
太离谱!女子应聘助理被要求和经理同生活最近,一篇名为太离谱!八千元就想找个保姆兼情人兼员工,女子应聘助理被要求和经理同生活的新闻引发了广泛的讨论和争议。据报道,一名女子应聘一份保姆兼情人兼员工的工作,但被要求与公司经理
金代时期帝后谥封号的用字分析谥号是古人根据死者生前所有的品行和事迹,为之而立的带有评定性质的称号。金代帝后的谥号的用字依据其生前品行事迹,群采故实,以今况古,务求厥衷,更当迹行累功,用节大惠。主要是为了彰显帝