目录
前言:
在当今数字化的时代,高效的数据存储和处理技术成为了各类应用程序的关键支撑。Redis,作为一款高性能的内存数据存储系统,正以其卓越的性能和丰富的功能,在众多领域中崭露头角。当我们深入探索这个充满魅力的技术世界时,Redis 就像一颗璀璨的明珠,散发着独特的光芒。它不仅能够快速地存储和检索数据,还能为复杂的业务场景提供强大的解决方案。今天,就让我们一同走进 Redis 的奇妙世界,揭开它神秘的面纱,探寻其背后的强大力量。
一、Redis是什么?
Redis(Remote Dictionary Server)是一个开源的、基于内存的数据结构存储系统,它可以用作数据库、缓存和消息中间件。
场景带入
假设现在你维护了一个商品服务,它的背后直连MySql,假设现在商品服务需要提供每秒10000次查询,但背后的MySql只能提供每秒5000次查询
那此时Mysql根本顶不住,分分钟被压垮,此类大数据量查询的操作很常见,比如双十一秒杀,春节抢票。
问题来了:有没有办法在MySql数据库不被压垮的同时,让商品服务支持一万次查询呢?
我们的办法是:加一层中间层:redis
一、本地缓存
众所周知:查询内存的速度要比查询磁盘的速度要快,Mysql数据主要存放在磁盘里, 如果能将MySql里的数据放内存里,查询不走磁盘,那必然能提升查询效率。
我们可以想到:在内存中申请一个“字典”,在Java中叫Map(key:商品Id,Value:商品数据),
查询发生时:先去查询内存字典,没结果再去查数据库,再将结果顺手放到字典里,并返回给用户,此时内存字典里就有了这个商品数据,下次再查找这个商品时就不需要查询数据库了,直接查询这个字典,也就是Redis。
有了这样的中间件,查询发生时真正用到数据库的情况就很少,所以我们的查询效率大大的提高
二、远程缓存
问题又来了:往往商品服务不止一个实例,如果每个商品服务都重复缓存一份本地内存,就有点费内存条了
解决方法:将这一部分内存条抽出来,单独做成一个服务,这个就叫做远程缓存服务
问题来了:这么多的商品服务肯定会有高并发的问题。
解决方法:不管有多少个商品服务,都统一塞到同一个线程里面,在一个线程上对字典进行读写
三、支持多种数据类型
不过这种方式过于简陋,现在字典类型只有一个Map类型,Key和Value都是String类型的,于是我们对对字段的Value进行扩展,除了字符串,我们还加入了支持先进先出的队列List,用于去重的Set类型,可以排序的Zset
四、内存过期策略
Redis里头的数据是存放在内存里的,可是内存又小又贵,多了不得爆炸
所以我们设置内存过期时间,把过期的数据定时清理,至于这个定时多久,在后端自己可以设置
4.1缓存淘汰策略
如果大家都不设置过期时间,那内存还是会炸,此时我们就要定义一个缓存淘汰策略:在内存接近上限的时候,根据一些策略删除掉一些内存,比如可以将最近最少使用的内存删除也就是LRU
五、持久化
缓存服务一重启,那原来内存里的数据可就全丢了,这个时候商品服务的请求会全部来到数据库,数据库压力巨大,直接炸,所以我们要尽可能的让Redis更加持久化
实现方法:我们可以加一个异步子进程,他会定期的将内存中的全量内存数据持久化到磁盘文件里
5.1:RDB
将内存数据生成快照,保存到文件里头的方式,叫做RDB,它可以每分钟记录下缓存服务的全量数据
实际应用就是:游戏的存档,或者博客的每隔一段时间保存草稿
5.2:AOF
RDB的数据其实可能会丢,只能保留一大部分,所以此时我们推出了AOF
在写数据的时候将数据写入文件缓存,并且每秒将文件刷入磁盘
问题来了:AOF,这种全量备份,他的文件会不会很大
解决方法:定期重写压缩就好了,比如a被依次赋值 int a=1,int a=2,最终保留a=2就行了
六、简化网络协议
刚刚提到了远程缓存服务对外提供读写能力,是对外提供的Http接口吗?当然不是,我们知道Http接口是基于TCP做的通信,实现了很多笨重的特性,既然当初是为了性能,特地上的缓存服务,那我们就彻底一点,我们直接基于TCP来做传输功能
最后:
总之,Redis 以其出色的性能、丰富的功能和灵活的应用场景,成为了现代软件开发中不可或缺的一部分。无论是在高并发的 Web 应用中,还是在大规模的数据处理系统里,Redis 都展现出了强大的实力。随着技术的不断发展和进步,我们有理由相信,Redis 将继续在数据存储和处理领域发挥重要的作用,为我们带来更多的惊喜和创新。让我们共同期待 Redis 在未来的精彩表现,继续在这个充满挑战和机遇的技术世界中砥砺前行。