设为首页 收藏本站
查看: 1326|回复: 0

[经验分享] understanding redis internal

[复制链接]

尚未签到

发表于 2016-12-20 11:43:26 | 显示全部楼层 |阅读模式
  一. redis的定义 
   官方wiki对redis的定义是:a disk backed in-memory database
   从这个可以理解实际上使用redis的场景应该大部分情况下你的数据集应该是在内存中操作的,同时提供了落地的功能


二. redis 主体框架与启动流程


    redis主体上是一个单线程基于事件机制的一个模型,使用了一套事件处理框架 aeEvent,基本上这个东西和libevent做的是相同的工作,提供事件处理机制以及封装不同平台的IO事件模型   



    redis启动流程大体如下(有兴趣可以参照函数名翻阅源代码,暂时忽略vm选项处理细节):
   
    initServerConfig()    //初始化全局struct server数据结构,给每个成员赋予默认值        
    loadConfig()          //如果指定了配置文件,会读取redis.conf重新赋值给struct server实例
    initServer()          //初始化其它数据结构,创建db 对应dict数据结构等,bind,listen启动网络服务
           
    initServer函数里最重要的是下面2行代码
        aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL); //添加定时器事件
        aeCreateFileEvent(server.el, server.fd, AE_READABLE,acceptHandler, NULL);  //添加IO事件


        initServer函数在这里向aeEvent 添加了2个事件:
        1. 事件启动后的下一毫秒调用 serverCron 函数,
           实际这个serverCron在执行完后会被重新设置加入调度事件中,以后每隔100 毫秒执行一次


           (这里aeEvent框架使用的是链表来保存定时器事件的,也就是说查找超时事件是O(n)的复杂度,且              处理了一个超时事件后,需要重新定位到队头重新扫描一遍,对比libevent的minheap数据结构               O(1)复杂度应该差一些)


        2. 注册网络监听accept 客户端连接事件,客户端连接建立成功后,回调acceptHandler方法
           需要说明的是这里只是注册了这个事件并没有真正启动事件处理,对于epoll来说只是调用了                 epoll_ctl的add,需要等待调用epoll_wait后才开始调度io事件,所以前面虽然已经调用了socket            的bind,listen,实际上redis还没有准备好提供服务


           (这里的网络细节处理实际上是:服务器可以与客户端发来的syn进行tcp的3次握手,但是最后这个              已连接fd会被放入tcp的已完成队列中,等待accept操作来把这个fd取走)


    initServer()函数结束后,会根据配置来加载数据文件,如果是第一次启动当然没有这个了


    if (server.appendonly) {
        if (loadAppendOnlyFile(server.appendfilename) == REDIS_OK) ...            
    } else {
        if (rdbLoad(server.dbfilename) == REDIS_OK) ...           
    }
  
    根据配置是appendonly的aof文件还是快照保存的rdb文件来加载数据


    最后通过aeMain来启动事件处理框架,实际对应网络io api,也就是调用最终的epoll_wait或者select()函     数


    整个server启动完毕,可以看到启动后事件框架中主要处理2个事件:
    
    1. redis的网络io accept及读写事件
    2. 每隔100毫秒执行一次的定时器事件serverCron


    整个流程暂时忽略vm选项,那个处理的细节比较多暂时没梳理清楚,所以先忽略下
      
        
 三. serverCron定时器事件处理流程
     
     再来看下serverCron这个每100毫秒执行一次的函数都干了什么:


     1. 打印非空db的一些信息,log功能
     2. 如果当前没有后台运行dump数据保存到文件的进程,则可以根据内存使用情况重新调整hashTables大小
     3. 日志输出一些client的连接信息
     4. 检测idle的client 连接,关闭idle连接
     5. 判断是否有正在进行dump数据到文件的后台进程
          如果有判断是否已经结束,进行结束后的一些工作(这个跟replication有关,后续详细说明)
          没有则判断是否需要启动新的进程dump数据到文件
     6. 处理expired的key
     7. vmSwapOut功能,如果启动了vm选项,则判断是否超过vmMaxMemory,如果超过进行value的swap
     8. 判断如果server是slave,则连接master,发送sync命令,和master同步数据
转:http://blog.sina.com.cn/s/blog_6a0c5f190100obi7.html

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-316973-1-1.html 上篇帖子: Redis 下篇帖子: 使用Tornado和Redis构建简易聊天室
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表