【Redis】初识 Redis
🥰🥰🥰来都来了,不妨点个关注叭!
👉博客主页:欢迎各位大佬!👈
文章目录
- 1. Redis是什么
- 2. 浅谈分布式
- 3. Redis的特性
- 3.1 在内存中存储
- 3.2 可编程性
- 3.3 扩展性
- 3.4 持久化
- 3.5 集群
- 3.6 高可用
- 3.7 核心特点 —— 快!!!
- 4. Redis的适用场景
1. Redis是什么
Redis 是一个在内存中存储数据的中间件,用于作为数据库,用于作为数据缓存,在分布式系统中,能够大展拳脚~
从 Redis 官网可以看出,官方对于 Redis 给的定义如下:
(更新太快~再去看官网,已经更新啦)
Redis可以作为:缓存、容器、数据库
- database 数据库:Redis 可以作为数据库使用,因为它快!(这个快是从定性的角度,可以知道 Redis 快很多,但是很难定量衡量) 与 MySQL 相比,MySQL的最大问题在于,访问速度比较慢(访问硬盘),要知道,很多互联网产品对于性能的要求是很高的,而 Redis 的最大劣势就是存储空间是有限的
- cache 缓存:存储数据,即在内存中存储
- streaming engine and message broker 消息队列:Redis 的初心,最初 Redis 就是用来作一个"消息中间件",是分布式系统下的生产者消费者模型,但是,当前很少会直接使用 Redis 作为消息队列(因为业界有更多更专业的消息中间件,如:RabbitMQ、Kafka)
【问题一】
Q:那如何实现存储的数据量大并且很快呢?
A:典型的方案 —— 可以把 MySQL 和 Redis 结合起来使用~
(这里介绍一个"二八原则",即满足20%的热点数据,能满足80%的访问需求,MySQL 和 Redis 结合起来使用的方案,就是可以将这些热点数据放在 Redis 存储,但是这样系统的复杂程度大大提升!而且,如果数据发生修改,那就还涉及到 Redis 和 MySQL 之间数据同步的问题)
【问题二】
Q:Redis 就是将数据存储在内存中,那我直接将数据存在变量里,不就也很快嘛?
如果将数据直接存储在变量中,进程具有隔离性,每个进程都有独立的内存空间,那如何实现多个服务器共享同一份数据呢?
A:因此,Redis 是在分布式系统中,才能发挥威力的!如果只是单机程序,直接通过变量存储数据的方式,是比使用 Redis 更好的选择,进程间通信是通过网络的,Redis 就是基于网络,可以把自己内存中的变量给别的进程甚至别的主机的进程进行使用
这里提到了分布式系统,下面我们简单了解一下什么是分布式系统
2. 浅谈分布式
可能小伙伴们经常听到分布式一词,觉得很高大上,其实并没有哦,我们一起来了解了解(在没了解前,感觉啥都很高级hhh)
所谓分布式系统,就是想办法引入更多的硬件资源!!!
- 单机架构:只有一台服务器,这个服务器负责所有工作
【问题】如果业务进一步增长,用户量和数据量都非常大,一台主机难以应付的时候,就需要引入更多的主机,引入更多的硬件资源,因为一台主机的硬件资源是有上限的(硬件资源包括不限于以下几种:1.CPU 2. 内存 3. 硬盘 4.网络 5…)服务器每次收到一个请求,都是需要消耗上述资源的,如果同一时刻,处理的请求多了,此时,就可能会导致某个硬件资源不够用了,无论哪个方面不够用,都可能导致服务器处理请求的时间变长,甚至于处理出错!
【解决】如果真的遇到这种情况,服务器不够用的场景,怎么处理呢?
两种解决方案:
1)开源:简单粗暴的方式,增加更多的硬件资源
一个主机上面能增加的硬件资源有限,取决于主板的扩展能力,一台主机扩展到极限,但是还不够,就只能引入多台主机,一旦引入多台主机,我们的系统就可以称为"分布式系统"了。其实引入分布式,是万不得已的做法,实在是无奈之举,因为引入分布式,系统的复杂程度大大提高,出现 bug 的概率也会变高!(现在计算机硬件,发展速度非常快,哪怕只有一台主机,这台主机的性能也是很高的,可以支持非常高的并发和非常大的数据处理,所以,并不能说引入分布式有多么的好,凡事有利有弊~)
2)节流:软件上优化(需要通过性能测试,找到是哪个环节出现瓶颈,再对症下药,解决优化)
- 应用服务与数据库服务分离:
1)应用服务器:里面可能包含很多业务逻辑,可能会吃 CPU 和 内存
2)数据库服务器:比如 MySQL,数据存储在硬盘,则需要更大的硬盘空间,更快的数据访问速度,可以配置更大硬盘的服务器,甚至可以上SSD(固态硬盘)
通过优化两者,达到更高的性价比~
- 引入负载均衡,引入更多的服务器节点:
【负载均衡】负责分配任务,就好比公司的一个领导,负责管理,将任务分配给每个组员
应用服务器可能会比较吃 CPU 和内存,如果把 CPU 或者内存吃没了,此时应用服务器就撑不住了~
因此,引入更多的应用服务器,就可以有效解决上述问题
具体的流程是,用户的请求,先到达负载均衡器/网关服务器(这是单独的服务器)
假设有 2w 个用户请求,有2个服务器,此时按照负载均衡的方式,就可以让每个应用服务器各自承担 1w 的访问量(对于负载均衡器来说,有很多负载均衡的具体算法,并不一定非得是均分)
【注意】有的小伙伴可能会思考,负载均衡器,看起来不是承担了所有的请求嘛~它就可以顶住了嘛!
负载均衡器,对于请求量的承担能力,要远远超过应用服务器的!!!
可以想象一个这样的场景:在一个公司中,
负载均衡器 —— 领导,分配工作(分配任务可比完成任务简单多啦!)
应用服务器 —— 员工,执行任务(任务的完成需要消耗大量的资源,任务越多,就忙不过来了!)
当然,也有可能会出现请求量大到负载均衡器也扛不住的时候,引入更多的负载均衡器~(引入多个机房,就是多招点领导一起来分配任务)
- 引入读写分离,数据库主从结构:
在实际的应用场景中,读的频率比写的频率高很多!!! 因此,引入读写分离~
主服务器一般是一个,从服务器可以有很多个(一主多从),同时从数据库通过负载均衡的方式,让应用服务器进行访问~
- 引入缓存,冷热数据分离:
数据库有个天然的问题,响应速度更慢!!!
为解决这个问题,可以把数据区分"冷热",热点数据放到缓存中,缓存的访问速度往往比数据库要快很多~热点数据即为频繁访问的数据,但只放一小部分,因为缓存存储内容有限,而从数据库存的仍然是全部的数据,只是把经常访问到的数据,提取出来,放在缓存服务器中
- 引入分库分表,数据库能够进一步扩展存储空间:
针对数据库进一步拆分,分库分表,本来是一个数据库服务器,这个服务器上有多个数据库(这个数据库指的是逻辑上的数据集合,即 create database 创建的那个东西),现在就可以引入多个数据库服务器,每个数据库服务器存储一个或者一部分数据库,如果某个表特别大,大到一台主机都存储不下,也可以针对表进行拆分
具体如何分库分表,如何展开实践,需要结合实际的业务场景来展开~
- 引入微服务,从业务上进一步拆分应用服务器:
之前的应用服务器,一个服务器程序里面做了很多任务,这就可能导致这一个服务器代码变得越来越复杂,为了更方便维护代码,就可以把复杂的服务器,拆分成更多的,功能更单一的,但是更小的服务器(微服务,服务器的种类和数量就增加了)
当应用服务器复杂了,就需要更多的人来维护,当人多了,就需要配套的管理,把这些人组织好,划分组织结构,分成多个组,每个组分别配备领导进行管理,分成多个组,就需要进行分工,按照功能,拆分成多组微服务,就可以有利于上述,人员的组织结构分配了
微服务有以下优势与劣势:
【优势】
- 有利于人员的组织结构分配(解决了"人"的问题)
- 使用微服务,可以更方便功能复用
- 可以给不同的服务进行部署
【劣势】
- 系统的性能下降,要想保证性能下降不太多,只能引入更多机器,更多的硬件资源,这需要资金支撑,同时,拆出来的更多服务,多个功能之间要更依赖网络通信(网络通信的速度很可能是比硬盘还要慢的,幸运的是,随着时代的发展,硬件技术的发展,网卡现在有万兆网卡,读写速度已经能超过硬盘的读写了,当然也比较贵!)
- 系统的复杂程度提高,可用性受到影响,服务器更多了,出现问题的概率更大了,这就需要一系列的手段,来保证系统的可用性
3. Redis的特性
3.1 在内存中存储
Redis 在内存中存储数据,存储数据的方式,是以键值对的方式存储
MySQL 主要是通过"表"的方式来存储组织数据的 “关系型数据库”
Redis 主要是通过"键值对"的方式来存储组织数据的 “非关系型数据库”,其中:
- key 都是 String
- value 则可以是String,hash,list,set等数据结构
3.2 可编程性
针对 Redis 的操作,可以直接通过简单的交互式命令进行操作,也可以通过脚本的方式,批量执行一些操作(比如使用 Lua 编程语言)
3.3 扩展性
可以在 Redis 原有的功能基础上在进行扩展,Redis 提供了一组 API(通过C,C++,Rust等编程语言编写 Redis 扩展,其本质就是一个动态链接库),可以自己去扩展 Redis 功能,比如,Redis 自身已经提供了很多的数据结构和命令,通过扩展,让 Redis 支持更多的数据结构以及支持更多的命令
【动态链接库】
相当于 Windows 上的 dll,可以让 exe 去调用,里面包含很多代码
Linux 的动态库是 .so 虽然和 dll 的格式不一样,但是本质是一样的
3.4 持久化
Redis 是把数据存储在内存上的,内存数据是"易失"的,进程退出或者系统重启,数据就会不见了,Redis 会把数据存储在硬盘上,内存为主,硬盘为辅
(硬盘相当于对内存的数据备份了,如果 Redis 重启了,就会在重启时加载硬盘中的备份数据,使 Redis 的内存恢复到重启前的状态)
3.5 集群
Redis 作为一个分布式系统的中间件,能够支持集群是很关键的,这个水平扩展,类似于"分库分表",一个 Redis 能存储的数据是有限的,内存空间有限,引入多个主机,部署多个 Redis 节点,每个 Redis 存储数据的一部分
3.6 高可用
高可用,等价于 冗余 / 备份
Redis 自身也是支持 "主从"结构的,从节点就相当于主节点的备份了~
3.7 核心特点 —— 快!!!
为什么 Redis 快(敲重点啦!!!)
【原因】
- Redis 数据在内存中,就比访问硬盘的数据库,要快很多
- Redis 核心功能都是比较简单的逻辑,核心功能都是比较简单的操作内存的数据结构
- 从网络角度上,Redis 使用了 IO 多路复用的方式
- Redis 使用的是单线程模型,这样的单线程模型,减少了不必要的线程之间的竞争开销
(虽然更高版本的 Redis 引入了多线程,但并不是所有情况下使用多线程就可以提高效率,多线程提高效率的前提是,CPU 密集型任务,使用多个线程可以充分利用 CPU 多核资源)
4. Redis的适用场景
【适合场景】
- 数据库:大多数情况下,考虑到数据存储,优先考虑的是"大",但是,仍然有一些场景,考虑的是"快",考虑快的时候,可以考虑 Redis 作为数据库
- 缓存&会话存储:使用二八原则,把热点数据存储在 Redis 中的,Redis 存的是部分数据,全量数据都是以 MySQL 为主,就算 Redis 的数据没了,还可以从 MySQL 这边再加载回来
【会话存储 session storage】又是什么呢?
cookie 实现用户身份信息的保存,需要搭配 session 使用(不一定非要搭配 session)
cookie 只是在浏览器这边存储了一个用户的身份标识,即 sessionId
seesion,服务这里存储真正的用户数据
如果用户登录成功,分配到应用服务器1处理该用户请求,用户再访问,假如被分配到应用服务器2处理请求,但是应用服务器2并没有记录之前用户登录的 session 信息,在应用服务器1那里,用户就无法访问了,则需要重新登陆
如何解决上述问题?
1.想办法让负载均衡器,把同一个用户的请求始终打到同一台机器上
2.把会话数据单独拿出来,放到一组独立的机器上存储(Redis),共同的!应用程序重启,会话不丢失(这里 Redis 就是作为会话存储的功能)
- 消息队列:消息队列(服务器),基于这个可以实现一个网络版本的生产者消费者模型(本文开始介绍了,业界已经有很多知名的消息队列,如果当前场景中,对于消息队列的功能依赖不是很多,并且又不想引入额外的依赖,Redis 可以作为一个选择)
【不适合场景】
不适合存储大量数据!!!
💛💛💛本期内容回顾💛💛💛
✨✨✨本期内容到此结束啦~