3. 高性能IO模型,探究Redis单线程为何很快

1. Redis单线程

  • 通常说Redis单线程是指Redis的网络IO和键值对读写是由一个线程完成的
但Redis的其他功能,比如持久化,异步删除,集群数据同步等都是由额外的线程完成的

2. 为什么Redis使用单线程


2.1 多线程的开销

  • 问题:
    • 通常情况,假如没有良好的设计,在刚开始增加线程数时,吞吐率会有所增加,但进一步增加线程时,吞吐率就会增长迟缓甚至会出现下降情况
  • 原因:
    • 系统中常会存在被多线程同时访问的共享资源,比如一个共享的数据结构,当多个线程要修改共享资源时,就要有额外的机制来保证共享资源准确性,就会带来额外的开销
    • 比如,redis中的lpush和lpop操作,假如两个线程同时对list分别做lpush和lpop操作,就会遇到这个问题
  • 问题就是多线程编程面临的共享资源的并发访问控制问题

2.2 其他原因

  • 多线程开发一般会引入同步原语来保护共享资源并发访问,会降低系统的调试和维护性

3. 为什么那么快

  • 大部分操作内存中完成
  • 高效的数据结构设计(如哈希表和跳表)
  • 采用多路复用机制

4. 基本IO模型和阻塞点

4.1 SimpleKV处理GET请求,IO示例如下图,依次执行如下操作:

Redis基本IO模型
  • 潜在阻塞点如下:
    • accept()
      • 当 Redis 监听到一个客户端有连接请求,但一直未能成功建立起连接时,会阻塞在 accept() 函数这里,导致其他客户端无法和 Redis 建立连接
    • recv()
      • 当 Redis 通过 recv() 从一个客户端读取数据时,如果数据一直没有到达,Redis 也会一直阻塞在 recv()。

4.2 socket的非阻塞模式

socket 模型,不同操作调用后会返回不同的套接字类型。
image.png
    1. socket() 方法会返回主动套接字,
    1. 调用 listen() 方法,将主动套接字转化为监听套接字,此时,可以监听来自客户端的连接请求。
    1. 调用 accept() 方法接收到达的客户端连接,并返回已连接套接字。
1. 针对监听套接字,可以设置非阻塞模式:当Redis调用accept()但一直未有连接请求到达时,Redis线程可以返回处理其他操作,不用一直等待。但调用accept()时,已经存在监听套接字了
2. 同理,也可以对已连接套接字设置非阻塞模式,如数据没有到达,可以返回处理其他操作
3. 问题:需要有机制,在监听套接字等待后续连接(有请求时通知Redis),继续监听已连接套接字,在有数据到达时通知Redis

Redis机制:基于多路复用的高性能I/O模型

引言:

  • linux中IO多路复用:指一个线程处理多个IO流,也就是select/epoll机制
  • Redis中:在一个内核中,同时存在多个监听套接字和已连接套接字。内核会一直监听这些套接字上的连接请求或数据请求。有请求到达,就交给redis线程处理

基于多路复用的Redis高性能IO模型

Redis高性能IO模型
    1. 图中的多个FD指多个套接字。Redis网络框架调用epoll机制,让内核监听这些套接字。这样,Redis线程不会阻塞在某个特定的监听或已连接套接字(不会阻塞在某一个特定的客户端请求处理)。所以,Redis可以同时和多个客户端连接并处理请求,提升并发性
    1. 为了在请求到达时通知到Redis,select/epoll提供了基于事件的回调机制(针对不同事件发生,调用相应处理函数)

回调机制

  • select/epoll一旦监测到FD上有请求,出发相应事件将事件放进一个队列,Redis单线程对该事件队列不断进行处理
  • 以连接请求和读数据请求为例:
    • 两个请求分别对应Accept事件和Read事件,Redis分别对这两个事件注册accept和get回调函数。当linux内核监听到有连接请求或读数据请求时,就会触发Accept事件和Read事件,此时,内核就会回调Redis相应的accept和get函数进行处理

总结:

  • Redis单线程是指它对网络IO和数据读写的操作采用了一个单线程,核心原因是避免多线程开发的并发控制问题
  • Redis单线程获得高性能的原因在:
    • 多路复用的IO模型:避免了accept()和send()/recv()潜在的网络IO操作点
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,367评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,959评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,750评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,226评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,252评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,975评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,592评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,497评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,027评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,147评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,274评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,953评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,623评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,143评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,260评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,607评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,271评论 2 358