Redis代码阅读1--Redis启动原理


前面写了一篇文章简单介绍Redis的list结构。再写完之后,我觉得有必要熟悉Redis的启动过程和如何读取Redis的命令,因此本文将通过分析代码来介绍Redis的启动过程,通过查看Redis 的启动脚本,得知Redis的启动时从Redis.c的main方法开始的。Redis启动可以分为以下几个步骤:

  1. 初始化Redis服务器全局配置
  2. 重置服务器Save参数(具体下文详解)和加载配置文件
  3. 初始化服务器
  4. 加载数据库
  5. 开始网络监听

   一,初始化Redis服务器全局配置。这一步骤主要是主要是根据Redis.h中设置的Static值来初始化Redis服务器配置,这里设置是Redis服务器的默认配置。如:

  • TCP Port,Redis Client的缺省Timeout;
  • Redis缺省的数据库数目;
  • Redis Append 持久化方式的参数设置;
  • Redis的所支持的各种数据结构的缺省值的设置;
  • Redis内存Swap相关设置;
  • Redis Master & Slave相关的配置;
  • Redis Command Table初始化。

  二,加载配置文件:

      这一步是通过读取的配置文件来对Redis服务器进行设置,将会覆盖上一步的某些缺省设置。打开下载下来的Redis源代码,我们可以看到其根目录下有一个默认的配置文件redis.conf。需要注意的是,如果在启动Redis的时候没有指定配置文件,则Redis服务器在启动的时候是不会加载这个默认的配置文件进行配置的。而且这个默认的配置文件和第一步中得全局默认缺省配置不尽相同,比如针对Redis的Append模式的数据保存策略的配置,redis.conf里面的设置是:

save 900 1 -------15分钟内一次更新
save 300 10 ------5分钟内10次更新
save 60 10000 ---1分钟内10000次更新。

而上一步里面的默认缺省配置确实:

save 60*60 1 -------一个小时内1次更新
save 300 100 ------5分钟内100次更新
save 60 10000 ---1分钟内10000次更新。

    因此我们在启动Redis的时候如果默认配置不能满足要求,则需要指明配置文件进行配置。

 

   三,初始化服务器:

   初始化服务器是在initServer()方法中完成的,次方法利用上两步设置的参数进一步初始化服务器:

  • 创建用来维护clients和slaves的list
  • 创建共享对象。redisObject这个struct里有个变量叫做refcount,这个变量就是用来实现共享的。Redis的对象目前Redis只支持共享StringObject。Redis的共享对象有两大类比:第一类:Redis server的各种操作需要经常用到的各类对象,如:Redis Command的分隔符 "\r\n",用于Redis command的reply的"+OK\r\n"或者"-ERR\r\n"等对象,因为在Redis的各种操作这类对象要被频繁使用,所以就在启动Redis的时候创建好,然后共用这些对象,减少时间成本和空间成本;第二,类的共享对象就是对应于数字的StringObject,如:Set
    "olylakers1" 1234; Set "olylakes2" 1234;在Redis内部,"olylakers1"和"olylakers2"这两个key都指向由数字1234转化的StringObject。这样在海量数据和特定存储内容下,可以节省大量的内存空间。可用通过REDIS_SHARED_INTEGERS这个参数来指定Redis启动的时候创建多少个第二类共享对象,默认的参数是10000,即创建的StrongObject个取值范围是0-9999之间。
  • 创建Pub/Sub通道
  • 初始化网络监听EventLoop的相关内容,如eventLoop,timeEvent,fileEvent等
  • 如果开启了VM,则初始化虚拟内存相关的IO/Thread

  四,加载数据:

   根据配置的不同,Redis加载数据的源也不一样,如果在配置文件里设置了appendonly  yes(默认是no),那么就从appendfile加载数据,反之则从RedisDb加载数据

  •   从appendfile加载数据:我们先来看一下appendfile的内容是什么。下面的一条记录摘取自appendfile:SET $9 olylakers $3 oly。很显,appendfile保存的就是redis server接收到的各种命令,那么从appendfile加载数据就是redis server从appenfile里面读取这些命令的记录,然后重新把这些命令执行一遍即可。需要注意的是,如果开启了VM,那么在从appendfile加载数据的时候可能要涉及swap操作。
  • 从redisdb加载数据:如果没有开启appendonly,那么则需要从db file加载数据到内存,其过程是:
    1. 通过处理select命令,选择DB
    2. 然后从db file读取key和value
    3. 检查key是否过期,如果过期则跳过这个key,如果不过期,则把数据Add到对应的db的dict中
    4. 如果开启了VM,则从db file中load数据,也可能涉及到swap操作

  五,开始网络监听:

         Redis的网络监听没有采用libevent等,而是自己实现了一套简单的机遇event驱动的API,具体见ae.c。因为这一部分内容比较多,因此后面会单独写篇文章来描述其过程。

 

   以上五个部分就是Redis启动的全部过程,

http://olylakers.iteye.com/blog/1228198

时间: 2024-10-23 01:55:21

Redis代码阅读1--Redis启动原理的相关文章

Redis代码阅读3--Redis网络监听(2)

 这篇文章接上一篇,主要介绍Redis网络监听流程的各个步骤. aeCreateEventLoop :创建用于循环监听的 eventLoop , Redis 支持主流的三种事件触发机制: select ,epoll, kqueue, 可以通过在 config.h 里面配置 HAVE_EPOLL/ HAVE_KQUEUE 来根据不同的操作系统选择合适的机制:调用 ae_epoll.c/ae_select.c/ae_kqueue.c中的 aeApiCreate:创建 eventLoop 的时候没

Redis代码阅读3--Redis网络监听(3)

 是介绍Redis网络监听的最后一篇文章,着重分析定时时间处理函数serverCron,这个函数其实已经和网络监听没多大关系了,当时因为其绑定在Redis自定义的事件库的定时事件上,所以放到一起来讲.serverCron的这个函数对Redis的正常运行来说很重要,对于Redis的使用者来说,最重要的就是能够迅速直观地看到Redis的当前的运行状况(keys,sizes,memory等),serverCron就能够使用户得知这些信息,此外,serverCron这个方法定时周期地运行,还承担了A

CYQ.Data V5 分布式缓存Redis应用开发及实现算法原理介绍

前言: 自从CYQ.Data框架出了数据库读写分离.分布式缓存MemCache.自动缓存等大功能之后,就进入了频繁的细节打磨优化阶段. 从以下的更新列表就可以看出来了,3个月更新了100条次功能: + View Code 其实更多的时间,是放在ASP.NET Aries 业务开发框架上,上里下外全部重构了一遍. 前几天,决定把Redis集成进来,一鼓作气,解决了. 下面分享一下经历: 最初的想法: 一开始我是拒绝的,不愿动态调用第三方的客户端(关联依赖的dll太多). 最近打算支持Redis,有

简直奔溃,搭建centos+nginx+tomcat+redis做session共享,启动报错

问题描述 简直奔溃,搭建centos+nginx+tomcat+redis做session共享,启动报错 环境是 centos6.4+nginx1.8+tomcat7.0.65+redis3.0.5+jdk1.7.......... 配置应该没有问题,但是启动tomcat的时候报 caused by: org.apache.catalina.LifecycleException: Unable to attach to session handling valve; sessions canno

redis安装,redis项目以来,redis和spring整合,redis的service,redis的service实现类

一.redis安装: Redis-3.2.6.tar.gz安装,参考方式: 用源码工程来编译安装 1.  到官网下载最新stable版,这里使用的是:redis-3.2.6.tar.gz 2.  cd /usr/local   3.  make redis-src 4.  tar -zxvf    redis-3.2.6.tar.gz  -C  ./redis-src/ 2.解压源码并进入目录cd  /usr/local/redis-src/redis-3.2.6 3. 先执行make,检查是否

Kryo简介及代码阅读笔记

更新:2012-08-01 版本 2.16长时间运行可能会导致OOM,版本2.18有bug,不能正确序列化map和collection. 真是悲剧,所用的每一个版本都有bug.不过从代码来看,作者有时的确比较随便..测试用例也少..(比起msgpack少多了) ======================================== Kryo官方网站:https://code.google.com/p/kryo/ 优点:     速度快!见https://github.com/eisha

NoSQL之Redis(三) --- Redis在项目中的运用

NoSQL之Redis(三) --- Redis在项目中的运用            又是一个喧闹的新年,少了的不是年味,变了的是人们的内心.难得的假期静下心来回顾上一年,展望下一年.思考,总结,陪陪家人是否更值得去做?养精蓄锐,是不是又能更好迎接来年的挑战?年轻不是放纵的资本,需要的事更好的珍惜眼前的时光.            本文笔者会简单的描述一下Redis在"jrkj"这个项目中的哪些场景中使用的,以及是如何使用的.            应用场景一            首

Redis集群_3.redis主从自动切换Sentinel(转)

Redis SentinelSentinel(哨兵)是用于监控redis集群中Master状态的工具,其已经被集成在redis2.4+的版本中 一.Sentinel作用:1):Master状态检测 2):如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Master作为Slave3):Master-Slave切换后,master_redis.conf.slave_redis.conf和sentinel.conf的内容都会发生改变,即mast

《Redis官方教程》-Redis安全

原文链接 译者:humyna 本节提供了Redis安全主题概述,包括控制访问.代码安全以及诸于恶意注入攻击拦截等. 对于安全相关的交流可以在github上建一个issue:如果担心沟通的安全,可以使用文末的GPG密钥. Redis一般安全模型 Reids被设计用于在信任的环境中访问的被授权客户端使用,这意味着将Redis直接暴露到internet上,或者直接被环境中的非授权的客户端通过TCP端口访问都不是一个好的主意. 例如,一个web应用使用Redis作为数据库.缓存或者消息系统,前端生成页面