前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis 为什么这么快?

Redis 为什么这么快?

作者头像
CSDN技术头条
发布2019-11-19 14:43:34
6050
发布2019-11-19 14:43:34
举报
文章被收录于专栏:CSDN技术头条CSDN技术头条

所有与 Java 相关的面试都会问到缓存的问题,基础一点的会问到什么是“二八定律”、什么是“热数据和冷数据” ,复杂一点的会问到缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题,这些看似不常见的概念,都与我们的缓存服务器相关,一般常用的缓存服务器有 Redis、Memcached 等,而笔者目前最常用的也只有 Redis 这一种。

如果你之前面试还没遇到过这样的问题,那你看到这篇文章是真的很幸运!接下来就探讨一下 Redis 是什么,Redis 为什么这么快、然后再探讨一下为什么 Redis 是单线程的?

一、Redis 简介

Redis 是一个开源的内存中的数据结构存储系统,它可以用作:数据库、缓存和消息中间件。它支持多种类型的数据结构,如字符串(Strings)、散列(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set 或者是 ZSet)与范围查询、Bitmaps、Hyperloglogs 和地理空间(Geospatial)索引半径查询。其中常见的数据结构类型有:String、List、Set、Hash、ZSet 这 5 种。

Redis 也提供了持久化的选项,这些选项可以让用户将自己的数据保存到磁盘上面进行存储。根据实际情况,可以每隔一定时间将数据集导出到磁盘(快照),或者追加到命令日志中(AOF 只追加文件),他会在执行写命令时,将被执行的写命令复制到硬盘里面。您也可以关闭持久化功能,将 Redis 作为一个高效的网络的缓存数据功能使用。

Redis 不使用表,他的数据库不会预定义或者强制去要求用户对 Redis 存储的不同数据进行关联。数据库的工作模式按存储方式可分为:硬盘数据库和内存数据库。Redis 将数据储存在内存里面,读写数据的时候都不会受到硬盘 I/O 速度的限制,所以速度极快。

1、硬盘数据库的工作模式:

2、内存数据库的工作模式:

看完上述的描述,对于一些常见的 Redis 相关的面试题,是否有所认识?例如:什么是 Redis、Redis 常见的数据结构类型有哪些、Redis 是如何进行持久化的等。

二、Redis 到底有多快

Redis 采用的是基于内存的采用的是单进程单线程模型的 KV 数据库,由 C 语言编写,官方提供的数据是可以达到 100000+ 的 QPS(每秒内查询次数)。这个数据不比采用单进程多线程的同样基于内存的 KV 数据库 Memcached 差!有兴趣的可以参考官方的基准程序测试:https://redis.io/topics/benchmarks

横轴是连接数,纵轴是 QPS。此时,这张图反映了一个数量级,希望大家在面试的时候可以正确的描述出来,不要问你的时候,你回答的数量级相差甚远!

三、Redis 为什么这么快

1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是O(1);

2、数据结构简单,对数据操作也简单,Redis 中的数据结构是专门进行设计的;

3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

4、使用多路 I/O 复用模型,非阻塞 IO;

5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis 直接自己构建了 VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

以上几点都比较好理解,下边我们针对多路 I/O 复用模型进行简单的探讨:

多路 I/O 复用模型

多路 I/O 复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。

这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响 Redis 性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量。

四、Redis 为什么是单线程

我们首先要明白,上边的种种分析,都是为了营造一个 Redis 很快的氛围!官方 FAQ 表示,因为 Redis 是基于内存的操作,CPU 不是 Redis 的瓶颈,Redis 的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且 CPU 不会成为瓶颈,那就顺理成章地采用单线程的方案了(毕竟采用多线程会有很多麻烦!)。可以参考:https://redis.io/topics/faq

看到这里,你可能会气哭!本以为会有什么重大的技术要点才使得 Redis 使用单线程就可以这么快,没想到就是一句官方看似糊弄我们的回答!但是,我们已经可以很清楚的解释了为什么 Redis 这么快,并且正是由于在单线程模式的情况下已经很快了,就没有必要在使用多线程了!

但是,我们使用单线程的方式是无法发挥多核 CPU 性能,不过我们可以通过在单机开多个 Redis 实例来完善!

警告 1:这里我们一直在强调的单线程,只是在处理我们的网络请求的时候只有一个线程来处理,一个正式的 Redis Server 运行的时候肯定是不止一个线程的,这里需要大家明确的注意一下!例如 Redis 进行持久化的时候会以子进程或者子线程的方式执行(具体是子线程还是子进程待读者深入研究);例如我在测试服武器上查看 Redis 进程,然后找到该进程下的线程:

ps 命令的“-T”参数表示显示线程(Show threads, possibly with SPID column.)“SID”栏表示线程 ID,而“CMD”栏则显示了线程名称。

警告2:在上图中 FAQ 中的最后一段,表述了从 Redis 4.0 版本开始会支持多线程的方式,但是,只是在某一些操作上进行多线程的操作!所以在以后的版本中是否还为单线程需要读者考证!

五、扩展

知道以下几种模型,助你面试一臂之力!

1、单进程多线程模型:MySQL、Memcached、Oracle(Windows 版本);

2、多进程模型:Oracle(Linux 版本);

3、Nginx 有两类进程,一类称为 Master 进程(相当于管理进程),另一类称为Worker 进程(实际工作进程)。启动方式有两种:

(1)单进程启动:此时系统中仅有一个进程,该进程既充当 Master 进程的角色,也充当 Worker 进程的角色。

(2)多进程启动:此时系统有且仅有一个 Master 进程,至少有一个 Worker 进程工作。

(3)Master 进程主要进行一些全局性的初始化工作和管理 Worker 的工作;事件处理是在 Worker 中进行的。

本文作者徐刘根老师不仅对 Redis 有很深的研究,在他的课程《Java 多线程编程核心技术》中也详细讲解了多线程编程如何最大限度的利用计算资源来提高软件服务质量,掌握多线程编程已经成为广大开发人员所必备的技能,系统学习必不可少——

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 GitChat精品课 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Redis 简介
  • 二、Redis 到底有多快
  • 三、Redis 为什么这么快
  • 四、Redis 为什么是单线程
  • 五、扩展
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档