目录
Redis特性
Redis是一个在内存中存储数据的中间件,用于作为数据库、数据缓存。Redis在分布式系统中有着较为突出的特性(有点)
在官方文档中,对Redis的特性给出了如下几点
- In-memory data structures(在内存中存储数据)
- Programmability(可编程性)
- Extensibility(可扩展性)
- Persistence(持久化)
- Clustering(集群)
- High availability(高可用)
在内存中存储数据
在数据库的场景中,较为出名的肯定是MySQL,我们就拿MySQL与Redis进行对比
MySQL主要是通过"表"的方式来存储组织数据的。
对于MySQL这类"表"存储数据的数据库,我们称之为"关系型数据库"
对于其他非"表"结构存储数据的数据库,我们称之为"非关系型数据库"
而Redis作为数据库时就是非关系型数据库的一个典型代表!
Redis主要是通过"键值对"的方式来存储组织数据的
- Redis中支持很多种数据结构,例如:字符串、哈希、列表...。Redis就是在内存中通过管理这些数据结构的方式实现的数据存储
- Redis存储数据时,一般key是字符串类型,而value可以是Redis支持的数据结构中的任意一种
可编程性
使用Redis时,可以直接通过简单的交互式命令进行操作。也可以通过一些脚本语言的方式,批量执行一批操作(可以带有一些逻辑)
Redis的脚本语言通常使用Lua。
可扩展性
Redis中提供了一组API,分别有C、C++、Rust。这使得程序员可以在Redis原有的功能基础上进一步的扩展,例如Redis中不支持的某些数据结构或者命令,可以由程序员自己扩展实现!
通过上述几个语言实现的Redis扩展,本质上就是一个动态库。
持久化
我们说过,在内存中存储数据是Redis的特性之一。
但内存中的数据是易失的。当进程退出或者系统重启时,内存中的数据就没了!针对这个问题,Redis给出了持久化的方案!
所谓的持久化指的就是Redis在内存中存储数据的基础上,还会在硬盘中生成一个备份。理论上来说硬盘中的数据是永久的。当内存中数据未保存,下次还需使用时,只需要从硬盘中再把数据拷贝到内存即可。
简而言之Redis会生成一个数据备份,保存在硬盘中!
集群
集群指的就是分布式系统中的分库分表,也就是说一个Redis保存的数据内存空间是有限的,但可以引入多个Redis,即引入多个主机。将原先的数据分批保存在多个主机当中
Redis作为一个分布式系统中的中间件,能够支持集群是非常重要的!
高可用
高可用总结来说就是冗余与备份
Redis自身支持分布式系统中的"主从"结构,从节点就相当于主节点的数据备份。当主节点因为某些突发情况崩溃时,Redis可以把从节点变为主节点,从而使得系统整体稳定性大大提升!
补充特性
在当今互联网当中,Redis应用是非常广泛的,而使得大多数企业都选择Redis的原因归根结底就是因为它"快"。
那么为什么Redis快呢?(与MySQL相比),有如下原因:
- 在内存中存储数据:访问内存显然是比访问硬盘这种外设要快的!
- Redis的核心功能都是比较简单的逻辑,一般核心功能都是操作内存中的一些数据结构。这些操作都是非常快的!一般不会过多占用CPU资源
- 从网络角度来看,Redis使用了IO多路复用的技术(epoll)!
- Redis使用的是单线程模型(最新Redis可能采用多线程,但多线程也仅仅是简单的IO处理。不涉及一些业务逻辑的多线程),这样的单线程模型,减少了不必要的线程之间的竞争开销。例如说访问临界区的互斥问题,同步问题...
需要注意的是:我们经常听说多线程会比单线程要看,但具体的我们得根据业务场景来分析。对于一些CPU密集型的作业,我们采用多线程可以使得CPU多核资源被有效利用。但Redis的核心功能都是操作一些数据结构的简单逻辑。在这种情况下,若引入多线程反而会花费大量CPU资源去维护线程间的关系,属于是捡了芝麻丢了西瓜!
Redis的应用场景
在官方文档中,对Redis的应用场景做出了如下概括:
- Real-time data store:把Redis作为数据库
- Caching & session storage : 把Redis作为缓存或会话存储
- Streaming & messaging : 把Redis作为消息队列
数据库
在现在大部分的企业考虑数据库时,优先考虑的是存储大小,但是仍然有一些场景,优先考虑的是效率。而优先考虑的是效率的时候,就可以采用Redis
例如:一些互联网大厂的搜索引擎对于效率要求非常高,那么他们就不会采用类似MySQL这样的数据库,而是使用Redis将所有需要检索的数据都存储在内存中。
但对于中小厂来说,不得不考虑的是使用Redis作为数据库的成本,因为内存资源一般成本较大(与硬盘相比)
在Redis作为数据库的这个场景中,Redis中存储的是全量的数据,这些数据是不能丢的!
缓存
根据二八原则,业务中大多数使用的数据都是热点数据,而热点数据在全量数据中终究是占少数的,那么我们可以把Redis作为一个缓存,把20%的热点数据用Redis存储,而MySQL则存储的是全量数据。
通过这种设计方案,即保证了一定程度上的效率问题,而成本相较于把Redis作为数据库来说也是能接受的!
在Redis作为缓存的这个场景来说,Redis存储的是部分数据,哪怕Redis中的数据丢了,也能从MySQL中重新拷贝一份!
会话存储
我们在分布式系统中说过,如果发送到服务器后端的业务请求过大,一台服务器无法处理,那么我们可以采用多台应用服务器同时处理的方案。
但在网络协议当中,诸如Http...,服务器要识别客户端的会话信息。但负载均衡器的分配算法是不一定的。假设应用服务器a中之前已经保存了张三的会话信息,但负载均衡器却把张三的本次请求分配给了应用服务器b,这种情况怎么办呢?难道每台服务器上都要保存一份张三的会话信息吗?
实际上,解决这种问题有两种方案:
第一种方案:重新设定负载均衡器的分配算法,使得当同一个用户请求到来的时候,能自动发送到之前已经保存了该用户会话的应用服务器
第二种方案:更推荐的是在后端加入一台Redis会话存储服务器,这个服务器当中保存了所有的会话信息,每一个应用服务器要识别会话信息时,都从该服务器中拿取即可!而这就是Redis作为会话存储的使用场景
消息队列中间件
把Redis作为消息队列中间件,是Redis被创立的初心,但经过长期的实践,发现在内存中存储数据反而是Redis的强大之处,而现在我们一般不会拿Redis作为消息队列中间件,因为业界有着更强大的消息队列,诸如RabbitMQ、Kafka、RocketMQ....
除非你的业务中只需要一个最基础的消息队列功能,而你又不想让该业务模块有新的依赖,那么可以采用Redis(非常少见!)