Redis为什么这么快

前言 本篇博客已被收录GitHub:https://zhouwenxing.github.io/

在日常开发中,为了保证数据的一致性,我们一般都选择关系型数据库来存储数据,如 MySQL,Oracle 等,因为关系型数据库有着事务的特性。然而在并发量比较大的业务场景,关系型数据库却又往往会成为系统瓶颈,无法完全满足我们的需求,所以就需要使用到缓存,而非关系型数据库,即 NoSQL 数据库往往又会成为最佳选择。

NoSQL 数据库最常见的解释是 non-relational,也有人解释为 Not Only SQL。非关系型数据库不保证事务,也就是不具备事务 ACID 特性,这也是非关系型数据库和关系型数据库最大的区别,而我们即将介绍的 Redis 就属于 NoSQL 数据库的一种。

什么是 Redis

Redis 全称是:REmote DIctionary Service,即远程字典服务。Redis 是一个开源的(遵守 BSD 协议)、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库。
Redis 具有以下特性:

1、支持丰富的数据类型:字符串(strings),散列(hashes),列表(lists),集合(sets),有序集合(sorted sets),位图等。

2、功能丰富:提供了持久化机制,过期策略,订阅/发布等功能。

3、高性能,高可用且支持集群。

4、提供了多种语言的 API。

Redis 的安装

1、下载对应版本的安装包,如:Redis 5.0.5 版本,其他版本也可以点击这里进行下载。

2、下载好之后传到服务器指定目录,执行命令 tar -zxvf redis-5.0.5.tar.gz 进行解压。

3、解压成功之后,进入 Redis 主目录,执行命令 make && make install PREFIX=http://www.likecs.com/xxx/xxx/redis-5.0.5 进行安装,如果不指定目录,则默认是安装在 /usr/local 目录下。

4、安装成功之后可以看到 Redis 主目录下多了一个 bin 目录,bin 目录内包含了一些可执行脚本。

5、回到 Redis 主目录下,找到 redis.conf 配置文件,将其中的配置 daemonize no 修改为 daemonize yes,表示在后台启动服务。

6、然后就可以执行命令 /xxx/xxx/redis-5.0.5/bin/redis-server /xxx/xxx/redis-5.0.5/redis.conf 启动 Redis 服务。

Redis 到底有多快

大家可能都知道 Redis 很快,可是 Redis 到底能有多快呢,比如 Redis 的吞吐量能达到多少?我想这就不是每一个人都能说的上来一个具体的数字了。

Redis 官方提供了一个测试脚本,可以供我们测试 Redis 的 吞吐量。

redis-benchmark -q -n 100000 可以测试常用命令的吞吐量。

redis-benchmark -t set,lpush -n 100000 -q 测试 Redis 处理 set 和 lpush 命令的吞吐量。

redis-benchmark -n 100000 -q script load "redis.call('set','foo','bar')" 测试 Redis 处理 Lua 脚本等吞吐量。

下图就是我这边执行第一条命令的自测结果,可以看到大部分命令的吞吐量都可以达到 4 万以上,也就是说每秒钟可以处理 4 万次以上请求:

Redis为什么这么快

但是如果你以为这就是 Redis 的真实吞吐量,那就错了。实际上,Redis 官方的测试结果是可以达到 10 万的吞吐量,下图就是官方提供的一个基准测试结果(纵坐标就是吞吐量,横坐标是连接数):

Redis为什么这么快

Redis 是单线程还是多线程

这个问题比较经典,因为在很多人的认知里,Redis 就是单线程的。然而 Redis 从 4.0 版本开始就有了多线程的概念,虽然处理命令请求的核心模块确实是保证了单线程执行,然而在其他许多地方已经有了多线程,比如:在后台删除对象,通过 Redis 模块实现阻塞命令,生成 dump 文件,以及 6.0 版本中网络 I/O 实现了多线程等,而且在未来 Redis 应该会有越来越多的模块实现多线程。

所谓的单线程,只是说 Redis 的处理客户端的请求(即执行命令)时,是单线程去执行的,并不是说整个 Redis 都是单线程。

Redis 为什么选择使用单线程来执行请求

Redis 为什么会选择使用单线程呢?这是因为 CPU 成为 Redis 瓶颈的情况并不常见,成为 Redis 瓶颈的通常是内存或网络带宽。例如,在一个普通的 Linux 系统上使用 pipelining 命令,Redis 可以每秒完成 100 万个请求,所以如果我们的应用程序主要使用 O(N) 或 O(log(N)) 复杂度的命令,它几乎不会使用太多的 CPU。

那么既然 CPU 不会成为瓶颈,理所当然的就没必要去使用多线程来执行命令,我们需要明确的一个问题就是多线程一定比单线程快吗?答案是不一定。因为多线程也是有代价的,最直接的两个代价就是线程的创建和销毁线程(当然可以通过线程池来一定程度的减少频繁的创建线程和销毁线程)以及线程的上下文切换。

在我们的日常系统中,主要可以区分为两种:CPU 密集型 和 IO 密集型。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgzsj.html