REDIS是单线程处理所有请求,和一般经典实际上推荐的方式相反,那么单线程串行处理,为什么依然能够做到很快呢?知乎上的一个答案如下,其中线程切换和锁不是性能主要影响因素的观点和一般的答案都不同
作者:杨海坡
链接:https://www.zhihu.com/question/19764056/answer/20241839
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

纯内存数据库,如果只是简单的 key-value,内存不是瓶颈。一般情况下,hash 查找可以达到每秒数百万次的数量级。

瓶颈在于网络 IO 上。

根据你测的的 10000/s 来看,客户端和 redis 应该是部署在两台不同的机器,并且是使用同步的方式请求 redis. 每次请求需要通过网络把请求发送到 redis 所在的机器,然后等待 redis 返回数据。时间大部分消耗在网络传输中。

如果把 redis 和客户端放在同一台机器,网络延迟会更小,一般情况下可以打到 60000 次每秒甚至更高,取决于机器性能。

锁不是影响性能的主要因素。线程锁 (mutex_lock) 只有在遇到冲突的情况下性能会下降,而正常情况下,遇到冲突的概率很低。如果只是简单的加锁、释放锁速度是非常快的,每秒钟上千万次没问题。memcache 内部用到了大量的锁,并没有见到性能降低。

线程也不是影响吞吐量的重要因素。如第一点来说,一般情况下,程序处理内存数据的速度远高于网卡接收的速度。使用线程好处是可以同时处理多条连接,在极端情况下,可能会提高响应速度。

使用 epoll 或 libevent 等因为异步非阻塞 IO 编程只能这么做。与之对应的是同步阻塞 IO 编程,使用多进程或多线程实现多条连接的处理,比如 apache。一般情况下,异步非阻塞 IO 模型性能是远高于同步阻塞 IO 模型的,可以参考 nginx 与 apache 性能的对比。

libevent 并不比 redis 自己实现的 ae_event 慢,代码多是应为 ae_event 只实现了 redis 需要的功能,而 libevent 则具有更多的功能,比如更快的定时器、buffer event 模型,甚至自带了 DNS、HTTP 协议的处理。并且 libevent 更通用,而 redis 只专注于 linux 平台。

最后回答题主问题,快在哪?
1、纯内存操作
2、异步非阻塞 IO

 
本博客的个人观点:
1. REDIS很注重让线程的每次操作都尽量简短,会将功能细分成多个逻辑块,每个逻辑块都分别让线程在自己的独立的时间片完成,而不是一个时间片做整个功能。
    比如,主从服务器的复制功能。从服务器收到SLAVE OF的命令后,会记录信息,然后交由serverCron来进行socket建链,然后再次交由serverCron进行slave向master的ping操作,然后再次交由serverCron进行Pong的接收。这样其他功能在每次功能块执行结束后都能被执行,而不至于线程的时间都堵塞在某一个功能上。
 
REDIS epoll 讲解
https://www.cnblogs.com/yuxingfirst/archive/2012/11/18/2776012.html
 
/* Include the best multiplexing layer supported by this system.
 * The following should be ordered by performances, descending. */
#ifdef HAVE_EVPORT
#include "ae_evport.c"
#else
    #ifdef HAVE_EPOLL
    #include "ae_epoll.c"
    #else
        #ifdef HAVE_KQUEUE
        #include "ae_kqueue.c"
        #else
        #include "ae_select.c"
        #endif
    #endif
#endif

建链流程:
2 initServer->aeCreateEventLoop->aeApiCreate  创建epoll实例  state->epfd = epoll_create(1024);
3.initServer->listenToPort->anetUnixServer->anetTcpServer 创建本地socket fd-1
4. initServer->aeCreateFileEvent->aeApiAddEvent->epoll_ctl(epfd,fd-1);把处理函数acceptTcpHandler注册到wfileProc/rfileProc

5. main->acMain->aeProcessEvents->aeApiPoll->epoll_wait->如果有数据->wfileProc/rfileProc 回调到 acceptTcpHandler->accept,建链完成
建链完成后,会针对这个新的fd创建redis client结构

而在client的创建过程中,createClient会再次注册一个event,回调函数readQueryFromClient,来进行从这个新socket的数据的接收

单线程的REDIS为什么这么快?的更多相关文章

  1. 性能测试 | 理解单线程的Redis为何那么快?

    前言 Redis是一种基于键值对(Key-Value)的NoSQL数据库,Redis的Value可以由String,hash,list,set,zset,Bitmaps,HyperLogLog等多种数 ...

  2. Redis 为什么这么快?

    1. 纯内存操作,肯定快 数据存储在内存中,读取的时候不需要进行磁盘的 IO 2. 单线程,无锁竞争损耗 单线程保证了系统没有线程的上下文切换 使用单线程,可以避免不必要的上下文切换和竞争条件,没有多 ...

  3. Redis为什么这么快?

    Redis为什么这么快?

  4. 硬核!15张图解Redis为什么这么快

    作为一名服务端工程师,工作中你肯定和 Redis 打过交道.Redis 为什么快,这点想必你也知道,至少为了面试也做过准备.很多人知道 Redis 快仅仅因为它是基于内存实现的,对于其它原因倒是模棱两 ...

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

    一. Redis简介 Redis是一个开源的内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(li ...

  6. 为什么说Redis是单线程的以及Redis为什么这么快!

    参考文章:https://blog.csdn.net/xlgen157387/article/details/79470556 redis简介 Redis是一个开源的内存中的数据结构存储系统,它可以用 ...

  7. 为什么说Redis是单线程的以及Redis为什么这么快!(转)

    文章转自https://blog.csdn.net/chenyao1994/article/details/79491337 一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到 ...

  8. Redis为什么是单线程、及高并发快的3大原因详解

    Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接.非阻塞 ...

  9. 《为什么说Redis是单线程的以及Redis为什么这么快!》

    为什么说Redis是单线程的以及Redis为什么这么快!   一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是“二八定律”.什么是“热数据和冷数据”,复杂一点的会问到缓 ...

随机推荐

  1. python打印图形

    i = 0 while i < 5: # print('*****') 效果与下行相同 print('*'*5) i+=1 print('\n\n') i = 1 while i < 6: ...

  2. 使用“1”个参数调用“DownloadString”时发生异常:“操作超时”

    我今天在终端美化时间遇到一个问题是这样的 使用“1”个参数调用“DownloadString”时发生异常:“操作超时” 然后网我看了下,访问链接属于https的东西,根据直觉我觉得是这样的,是由于访问 ...

  3. web网页设计五种布局

    1.大框套小框布局   2.通栏布局   3.导航栏在主视觉下方的布局  4.左中右布局  5.环绕式布局

  4. 关于Matplotlib中No module named 'matplotlib.finance'的解决办法

    最近在研究量化分析,需要用到matplotlib中的一个库,输入from matplotlib.finance import quotes_historical_yahoo_ohlc, candles ...

  5. Docker + node(koa) + nginx + mysql 开发环境搭建

    什么是Docker Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然 ...

  6. CTRL_IKun团队项目总结

    1. 团队项目-总结 这个作业属于哪个课程 课程链接 这个作业要求在哪里 作业要求 团队名称 CTRP-lkun 这个作业的目标 团队项目总结,每个人的收获和感悟 Github地址 Github 2. ...

  7. [校内训练20_01_22]ABC

    1.给出序列A,求序列B,使得bi|ai,lcm(b1,b2,...,bn)=lcm(a1,a2,...,an)且字典序最小. 可以发现,对于某个质数p,它有一个最大的次数k,将pk放在尽可能靠后且能 ...

  8. CF572_Div2_F

    题意 http://codeforces.com/contest/1189/problem/F 思考 由于是子序列,答案只跟选法有关,与顺序无关,先排序. 直接计算答案比较困难.联想到期望的无穷级数计 ...

  9. CSS-03-组选择器

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  10. BBOTSTRAP

    Bootstrap 第一步:下载 第二步: 解压缩 第三步:引入(head内部  link引入) Bootstrap 全局样式 移动设备优先:<meta name="viewport& ...