前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >02.redis的线程IO和通讯协议

02.redis的线程IO和通讯协议

作者头像
Share猿
发布2019-08-16 15:50:18
6530
发布2019-08-16 15:50:18
举报
文章被收录于专栏:Share猿Share猿

1.redis的线程IO

线程IO

Redis是个单线程程序!但是他有高并发特性,单个节点可以支持10w的QPS。除了redis是单线程,Nginx也是单线程的。单线程为什么如此之快?单线程有如何处理多并发的客户端连接?下面让我们带着这些问题一起深究redis的线程IO。

1.1.5种IO模型学习

  • 阻塞IO模型
  • 非阻塞IO模型
  • IO复用模型
  • 信号驱动的IO模型
  • 异步IO模型
1.1.1.阻塞IO模型

进程发起IO系统调用后,进程被阻塞,转到内核空间处理,整个IO处理完毕后返回进程。操作成功则进程获取到数据。

类比

老李去火车站买票,排队三天买到一张退票。

耗费:在车站吃喝拉撒睡 3天,其他事一件没干。

典型应用
  • 阻塞socket
  • java BIO
特点
  • 进程阻塞挂起不消耗CPU资源,及时响应每个操作;
  • 实现难度低、开发应用较容易;
  • 适用并发量小的网络应用开发;

不适用并发量大的应用:因为一个请求IO会阻塞进程,所以,得为每请求分配一个处理进程(线程)以及时响应,系统开销大。

1.1.2.非阻塞IO模型

进程发起IO系统调用后,如果内核缓冲区没有数据,需要到IO设备中读取,进程返回一个错误而不会被阻塞;进程发起IO系统调用后,如果内核缓冲区有数据,内核就会把数据返回进程。

类比

老李去火车站买票,隔12小时去火车站问有没有退票,三天后买到一张票。

耗费:往返车站6次,路上6小时,其他时间做了好多事。

典型应用
  • socket是非阻塞的方式(设置为NONBLOCK)
特点
  • 进程轮询(重复)调用,消耗CPU的资源;
  • 实现难度低、开发应用相对阻塞IO模式较难;
  • 适用并发量较小、且不需要及时响应的网络应用开发;
1.1.3.IO复用模型

多个的进程的IO可以注册到一个复用器(select)上,然后用一个进程调用该select, select会监听所有注册进来的IO;

如果select没有监听的IO在内核缓冲区都没有可读数据,select调用进程会被阻塞;而当任一IO在内核缓冲区中有可数据时,select调用就会返回;

而后select调用进程可以自己或通知另外的进程(注册进程)来再次发起读取IO,读取内核中准备好的数据。

可以看到,多个进程注册IO后,只有另一个select调用进程被阻塞。

类比

是找一个宿管大妈来帮你监视下楼的女生, 这个期间你可以些其他的事情. 例如可以顺便看看其他妹子,玩玩王者荣耀, 上个厕所等等. IO复用又包括 select, poll, epoll 模式. 那么它们的区别是什么?

  • select

每一个女生下楼, select大妈都不知道这个是不是你的女神, 她需要一个一个询问, 并且select大妈能力还有限, 最多一次帮你监视1024个妹子

  • poll

不限制盯着女生的数量, 只要是经过宿舍楼门口的女生, 都会帮你去问是不是你女神

  • epoll

不限制盯着女生的数量, 并且也不需要一个一个去问. 那么如何做呢? epoll大妈会为每个进宿舍楼的女生脸上贴上一个大字条,上面写上女生自己的名字, 只要女生下楼了, epoll大妈就知道这个是不是你女神了, 然后大妈再通知你.

典型应用
  • select
  • poll
  • epoll三种方案
  • nginx都可以选择使用这三个方案
  • Java NIO;
特点
  • 专一进程解决多个进程IO的阻塞问题,性能好;Reactor模式;
  • 实现、开发应用难度较大;
  • 适用高并发服务应用开发:一个进程(线程)响应多个请求
形成原因

如果一个I/O流进来,我们就开启一个进程处理这个I/O流。那么假设现在有一百万个I/O流进来,那我们就需要开启一百万个进程一一对应处理这些I/O流(——这就是传统意义下的多进程并发处理)。思考一下,一百万个进程,你的CPU占有率会多高,这个实现方式及其的不合理。所以人们提出了I/O多路复用这个模型,一个线程,通过记录I/O流的状态来同时管理多个I/O,可以提高服务器的吞吐能力。

1.1.4.信号驱动的IO模型

当进程发起一个IO操作,会向内核注册一个信号处理函数,然后进程返回不阻塞;当内核数据就绪时会发送一个信号给进程,进程便在信号处理函数中调用IO读取数据。

特点
  • 回调机制,实现、开发应用难度大;
1.1.5异步IO模型

当进程发起一个IO操作,进程返回(不阻塞),但也不能返回果结;内核把整个IO处理完后,会通知进程结果。如果IO操作成功则进程直接获取到数据。

特点
  • 不阻塞,数据一步到位;Proactor模式
  • 需要操作系统的底层支持,LINUX 2.5 版本内核首现,2.6 版本产品的内核标准特性;
  • 实现、开发应用难度大;
  • 非常适合高性能高并发应用
典型
  • JAVA7 AIO
  • 高性能服务器应用

通过学习5种IO模型,我们知道了Redis就是使用的IO复用模型里面的select。

1.2.指令队列

Redis 会将每个客户端套接字都关联一个指令队列。客户端的指令通过队列来排队进行顺序处理,先到先服务。也就是说指令的请求顺序是通过队列来进行约束的。

1.3.响应队列

每个客户端关联一个响应队列。然后服务端通过响应队列将数据返回给客户端。

1.4.定时任务

服务器处理要响应 IO 事件外,还要处理其它事情。比如定时任务就是非常重要的一件事。如果线程阻塞在 select 系统调用上,定时任务将无法得到准时调度。那 Redis 是如何解决这个问题的呢?

如果面试官问到这个问题我肯定是处于懵逼状态。老钱书中写到,redis会把定时任务记录到一个叫最小堆的数据结构中,每个周期循环redis会立即处理堆最上面的数据。

2.redis的通讯协议

2.1RESP协议简介

Redis 的客户端和服务端之间采取了一种独立名为 RESP(REdis Serialization Protocol) 的协议,作者主要考虑了以下几个点:

  • 容易实现
  • 解析快
  • 人类可读

注意:RESP 虽然是为 Redis 设计的,但是同样也可以用于其他 C/S 的软件。

2.2.数据类型及示例

RESP 主要可以序列化以下几种类型:整数,单行回复(简单字符串),数组,错误信息,多行字符串。Redis 客户端向服务端发送的是一组由执行的命令组成的字符串数组,服务端根据不同的命令回复不同类型的数据,但协议的每部分都是以 “\r\n” (CRLF) 结尾的。另外 RESP 是二进制安全的,不需要处理从一个进程到另一个进程的传输,因为它使用了前缀长度进行传输。

在 RESP 中, 一些数据的类型通过它的第一个字节进行判断:

  • 单行回复:回复的第一个字节是 “+”
  • 错误信息:回复的第一个字节是 “-”
  • 整形数字:回复的第一个字节是 “:”
  • 多行字符串:回复的第一个字节是 “\$”
  • 数组:回复的第一个字节是 “*”

RESP 协议还是相对易于理解的,另外理解了协议也方便对 Redis 一些问题的定位及客户端的实现。

Redis 协议里有大量冗余的回车换行符,但是这不影响它成为互联网技术领域非常受欢迎的一个文本协议。有很多开源项目使用 RESP 作为它的通讯协议。在技术领域性能并不总是一切,还有简单性、易理解性和易实现性,这些都需要进行适当权衡。

▌本文来源:share猿

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

本文分享自 Share猿 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.1.5种IO模型学习
    • 1.1.1.阻塞IO模型
      • 1.1.2.非阻塞IO模型
        • 1.1.3.IO复用模型
          • 1.1.4.信号驱动的IO模型
            • 1.1.5异步IO模型
            • 1.2.指令队列
            • 1.3.响应队列
            • 1.4.定时任务
            • 2.redis的通讯协议
              • 2.2.数据类型及示例
              相关产品与服务
              云数据库 Redis
              腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档