Redis作为一种Key-Value形式的NoSQL,因其极高的读写速度深受开发者喜爱,在web、分布式等领域有非常广泛的应用。

根据runoob的介绍, Redis能读的速度是110000次/s,写的速度是81000次/s。

Redis的快只是因为它是基于内存的吗?这里有一篇详细的文章对比了目前最流行的两种NoSQL—— Redis和MongoDB的性能,Redis vs. MongoDB: Comparing In-Memory Databases with Percona Memory Engine,其中MongoDB使用了Percona内存引擎,因此可以认为实验中的MongoDB和Redis (3.2.8)都是基于内存读写的(不然就没有比较的意义了)。文中做了三组对比实验,分别是:

  • 1.数据插入 —— 100%写,数据量为250万
  • 2.任务A —— 重读写,50% 读 + 50% 写,250万次操作
  • 3.任务B —— 重读取,95%读 + 5% 写,250万次操作

实验结果分别如下:

可以发现,即使是利用了所有CPU核心的mongoDB,吞吐量在大多场景中仍然比不上单线程的Redis。

所以Redis为什么这么快呢?总结起来大约以下三点:

  • 1.基于内存
  • 2.单线程
  • http://3.IO 多路复用

Redis 6.0引入了多线程机制,性能将会有进一步的提高,可参考Redis 6.0 多线程来袭。但本文不讨论这一点,主要讨论为什么在单线程的情况下,Redis为什么仍然能做到这么高的读写?

单线程的优势

多线程的效率一定比单线程更高吗?

熟悉Java的同学应该知道,Java中与Hash相关的集合有HashMap,HashTable,ConcurrentHashMap等,其中HashMap是线程不安全的,就是如果多线程环境中有多个线程同时操作该集合的话,可能导致数据污染的问题,因而有了HashTable的出现。但是在实际操作中,发现HashTable的性能比较低,因为HashTable靠一把锁来维护全部的数据,所有的线程在操作数据时只能去竞争那一把锁,造成线程等待,故而性能降低。为了克服这个问题,在JDK1.5~1.7版本,Java使用了分段锁机制实现ConcurrentHashMap。这就是多线程中锁机制造成的性能降低,此外,还有上下文切换的代价。

CPU的每个核在一个时刻只能运行一个线程,当在运行一个线程的过程中转去运行另外一个线程,这个叫做线程上下文切换。由于可能当前线程的任务并没有执行完毕,所以在切换时需要保存线程的运行状态,以便下次重新切换回来时能够继续切换之前的状态运行。每一次切换都是需要花时间的,所以在计算密集型的任务中,多线程(或多进程)的数量不宜超过CPU的核心数,超过之后CPU只是会徒劳的花时间在上下文切换上。

而Redis使用单线程,就不需要考虑上述问题了。

IO多路复用

然而单线程的问题也很大,由于线程的执行过程是顺序执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以 I/O 操作在一般情况下往往不能直接返回,这会导致某一文件的 I/O 阻塞导致整个进程无法对其它客户提供服务。为了解决这个问题,因此有了IO多路复用。

I/O多路复用的核心是用户进程调用select函数被阻塞,同时内核轮询监听所有select 负责的socket,当任何一个socket有数据准备好了,select就将控制权返回用户进程。多路复用的具体实现方式有select / poll / epoll等,Redis内部实现采用epoll,采用了epoll+自己实现的简单的事件框架,。相比select和poll,epoll有以下几个优势:

  • epoll没有最大连接数限制 (select 的最大限制为1024)
  • Epoll 最大的优点就在于它只管你“活跃”的连接 ,而跟连接总数无关,因此在实际的网络环境中, Epoll 的效率就会远远高于 select 和 poll,参考下图:
  • 内存拷贝, select 和poll 在数据准备好之后,需要把数据从内核拷贝到用户进程,Epoll使用了“共享内存”,避免了内存拷贝。
  • epoll线程安全

总结

Redis 使用了I/O多路复用,保证了redis在进行I/O操作时依然能处理socket请求,不会在I/O上浪费时间,单线程机制也避免了不必要的上下文切换和锁机制。而Redis的每一次I/O操作都是基于内存的,非常高效。可以说,redis的这三个特性相辅相成,共同造就了Redis的高并发。

参考

1.Redis vs. MongoDB: Comparing In-Memory Databases with Percona Memory Engine

2.知乎-IO 多路复用是什么意思

3.Redis到底是多线程还是单线程?线程安全吗,还需要加锁吗?

4.Redis IO多路复用技术以及epoll实现原理

5.并发编程

6.Redis单线程?别逗了,Redis6.0多线程重磅来袭!

socket什么意思_浅析Redis为什么这么快相关推荐

  1. curl 请求没反应_理解Redis的反应堆模式

    本文首发于: 理解Redis的反应堆模式​mp.weixin.qq.com 微信公众号:后端技术指南针 欢迎关注 接收最新文章! 1. Redis的网络模型 Redis基于Reactor模式(反应堆模 ...

  2. linux redis客户端_为什么单线程Redis能那么快?

    我们通常说,Redis 是单线程,主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程.但 Redis 的其他功能,比如持久化.异步 ...

  3. redis一般用来干嘛_谈谈redis的热key问题如何解决

    公众号:孤独烟 ,作者:孤独烟 引言 今天我们来写redis方面的内容,谈谈热key问题如何解决. 其实热key问题说来也很简单,就是瞬间有几十万的请求去访问redis上某个固定的key,从而压垮缓存 ...

  4. redis 所有模糊key 查询_写完这篇Redis由浅入深剖析快自闭了!

    前言 常用的SQL数据库的数据都是存在磁盘中的,虽然在数据库底层也做了对应的缓存来减少数据库的IO压力,但由于数据库的缓存一般是针对查询的内容,而且粒度也比较小,一般只有表中的数据没有发生变动的时候, ...

  5. 02 | 高性能 IO 模型:为什么单线程 Redis 能那么快?

    我们通常说,Redis 是单线程,主要是指Redis 的网络 IO和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程.但 Redis 的其他功能,比如持久化.异步删除 ...

  6. 为什么单线程的Redis能这么快?

    1 为什么是单线程 总结 Redis 的普通 KV 存储瓶颈不在 CPU,而往往可能受到内存和网络 I/O 的制约. Redis 中有多种类型的数据操作,甚至包括一些事务处理,如果采用多线程,则会被多 ...

  7. Redis为什么这么快?

    Redis为什么这么快? 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列文章. 前言 说起当前主流NoSql数据库非 ...

  8. Redis为什么这么快?Redis的线程模型与Redis多线程

    一.Redis有多快? Redis是基于内存运行的高性能 K-V 数据库,官方提供的测试报告是单机可以支持约10w/s的QPS 二.Redis为什么这么快? (1)完全基于内存,数据存在内存中,绝大部 ...

  9. Redis高性能原理:Redis为什么这么快?

    前言:Redis 为了高性能,从各方各面都进行了优化.学习一门技术,通常只接触了零散的技术点,没有在脑海里建立一个完整的知识框架体系.这样会很吃力,而且会出现一看好像自己会,过后就忘记的懵逼情况.知识 ...

最新文章

  1. UIButton的竖排图片和文本
  2. 使用腾讯云提供的针对Nuget包管理器的缓存加速服务
  3. Java 进程间文件锁FileLock详解
  4. Spring Boot基础学习笔记15:实现文件下载功能
  5. Glibc 和 uClibc的区别
  6. Libbpf-tools: Tracing工具
  7. 你见过“最没见过世面”的女孩子是什么样的?
  8. Ajax+Input的File控件上传时的超级简单实时进度条
  9. 现代控制理论概念梳理(脑图)
  10. 自豪地采用WordPress,如何删除链接?
  11. PCL RANSAC点云配准
  12. vscode设置默认浏览器
  13. mermaid 饼图使用指南
  14. 计算机word基础知识ppt,计算机一级练习题(word 、excel、ppt以及计算机基础知识练习)...
  15. 百度地图 鼠标绘制工具BUG修复(地图自动平移)
  16. 如何看待人生与技术的价值
  17. 自制F1C200S demo板(一、电路)
  18. 夺命聘礼【三】- 原创中篇小说
  19. 悦读 | 公布你的原则,读瑞.达利欧的《原则》
  20. 关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究[转]...

热门文章

  1. IIS6.0发布后对路径“D:\xxx\xxxx\web.config”的访问被拒绝问题的解决方法
  2. 在vue中,Echarts雷达图中indicator的点击事件,不能改变data中的值的解决方法
  3. python基础之异常处理
  4. python 如何跳过异常继续执行
  5. 在外壳中获取程序执行时间
  6. Python基础:第一个Python程序(2)
  7. Spring_总结_02_依赖注入
  8. node.js浅入深出---之fs模块
  9. XSLT模板转换XML文档
  10. 开关电源过流保护-打嗝模式