二. serverCron函数

  2.3 更新服务器每秒执行命令次数

    serverCron函数中的trackOperationsPerSecond函数会以每100毫秒一次的频率执行,这个函数以抽样计算的方式,估算并记录服务器在最近一秒钟处理的命令请求数量,这个值可以通过info status命令的instantaneous_ops_sec域查看:

        127.0.0.1:> info stats
# Stats
total_connections_received:
total_commands_processed:
//服务器在最近一秒钟处理的命令请求数量
instantaneous_ops_per_sec:

  关于trackOperationsPerSecond函数的内部实现就不再介绍,大致是当客户端执行INFO命令时,服务器就会调用getOperationsPerSecond函数,根据ops_sec_samples环形数组中的抽样结果,计算出instantaneous_ops_per_sec属性的值。

  

  2.4 更新服务器内存

    服务器状态redisServer结构的stat_peak_memory属性记录了服务器的内存峰值大小,每次serverCron函数执行时,程序都会查看服务器当前使用的内存数量,并与stat_peak_memory保存的数值进行比较,如果当前的内存数量比stat_peak_memory属性记录的值要大,那么程序就将当前使用的内存数量记录到stat_peak_memory属性记录中。INFO memory命令的used_memory_peak和used_memory_peak_human两个域分别以两种格式记录了服务器的内存峰值。

    127.0.0.1:> info memory
# Memory
used_memory_peak:
used_memory_peak_human:.82K

    这两个是域是指过去Redis内存使用的峰值,是反映了内存过去最高峰值,而不是当前使用内存的值。

  2.5 处理sigterm信号

    在启动服务器时,redis会为服务器进程的singterm信号关联处理器singtermHandler函数,这个信息处理器负责在服务器接收到singterm信号时,打开服务器状态的shutdown_asap标识。 每次serverCron函数运行时,程序都会对服务器状态redisServer结构函数的shutdown_asap属性进行检查,并根据属性的值决定是否关闭服务器。

        static void  sigtermHandler(int sig){
//打印日志
redisLogFromHandler(reids_warning,"received sigterm, scheduling shutdown...");
//打开关闭标识
server.shutdown_asap=;
}
      //下面先打开日志功能,在redis.conf文件中设置日志文件路径,保存配置文件,重启服务。
logfile /usr/local/redis/redis.log
[root@xuegod64 redis]# redis-server redis.conf //当在客户端执行shutdown关闭服务器时,服务器在接到sigterm信号之后,关闭服务器并打印相关日志。
127.0.0.1:> shutdown
not connected>  

    日志显示可以看到,服务器在关闭自身之前会进行RDB持久化操作,这也是服务器拦截sigterm信号的原因,日志信息如下:

          :M  Dec ::42.562 # User requested shutdown...

          :M  Dec ::42.562 * Saving the final RDB snapshot before exiting.

          :M  Dec ::42.565 * DB saved on disk

          :M  Dec ::42.565 * Removing the pid file.

          :M  Dec ::42.565 # Redis is now ready to exit, bye bye...

  

  2.6 管理客户端资源

    serverCron函数每次执行都会调用clinetsCron函数,该函数会对一定数量的客户端进行检查,包括1.如果客户端与服务器的连接已经超时(如很长时间没有互动),那么程序会释放这个客户端。2.如果客户端在上一次执行命令请求之后,输入缓冲区的大小超过了一定的长度,那么程序会释放客户端当前的输入缓冲区。

  2.7 执行被延迟的bgrewriteaof

    说到bgsave和bgrewriteaof二个客户端命令,前者针对RDB持久化,后者针对AOF 持久化。在服务器执行bgsave命令的期间,如果客户端向服务器发送了bgrewriteaof命令,那么服务器会将bgrewriteaof命令的执行时间延迟到bgsave命令执行完毕之后。每次serverCron函数执行时,都会检查bgsave命令或者bgrewriteaof命令是否正在执行,如果这两个命令都没在执行,并且aof_rewrite_scheduled属性的值为1,那么服务器就会执行之前被推延的bgrewriteaof命令。

        struct redisServer {
//如果值为1, 那么表示有bgrewriteaof命令被延迟了
int aof_rewrite_scheduled;
}

  

  2.8 检查持久化操作的运作状态

    服务器状态使用redisServer结构的rdb_child_pid属性和aof_child_pid属性记录执行bgsave命令和bgrewriteaof命令的子进程的ID,这两个属性也可以用于检查bgsave命令或者bgrewriteaof命令是否正在执行。

    struct redisServer {

            //记录执行bgsave命令的子进程的ID
//如果服务器没有在执行bgsave,那么这个属性的值为-1.
pid_t rdb_chlid_pid; //记录执行bgrewriteaof命令的子进程的ID
//如果服务器没有在执行bgrewriteaof,那么这个属性的值为-1.
pid_t aof_chlid_pid;
}

    每次serverCron函数执行时,程序都会检查rdb_chlid_pid和aof_child_pid两个属性值,只要其中一个属性的值不为-1, 代表正在执行,程序就会执行一次wait3函数,检查子进程是否有信号发给服务器主进程。如果有信号到达:那么对于bgsave命令来说,新的rdb文件已经生成; 对于bbgrewriteaof命令来说,AOF文件已经重写完成; 服务器需要进行相应命令的后续操作,比如用新的RDB文件替换现有RDB文件,或者用重写后的AOF文件替换现有的AOF文件。如果没有信号到达,那么表示持久化操作未完成,程序不做动作。

三.初始化服务器

    一个Redis服务器启动后,需要经过一系列的初始化和设置过程。比如(3.1)初始化服务器状态;(3.2)接受用户指定的服务器配置;(3.3)创建相应的数据结构和网络连接等。

  3.1 初始化服务器状态结构

    初始化服务器第一步就是创建一个struct redisServer类型的实例变量server作为服务器状态,并为结构中的各个属性设置默认值。初始化server变量的工作由redis.c/initServerConfig函数完成。主要包括:设置服务器运行ID(info 命令信息中的run_id);设置服务器的默认运行频率(hz,在18 事件篇中有讲);设置服务器的默认文件路径(info 命令信息中的config_file) ;设置服务器运行架构(info 命令信息中的arch_bits) ;设置服务器的默认端口号(info 命令信息中的tcp_port) ;设置服务器的默认RDB持久化条件和AOF持久化条件;初始化服务器的LRU时钟;创建命令表。 该initServerConfig函数没有创建服务器状态的其他数据结构;数据库;慢查询日志;LUA环境;共享对象,这些数据结构在之后的步骤才会被创建出来

127.0.0.1:> info
# Server
redis_version:4.0.
redis_git_sha1:
redis_git_dirty:
redis_build_id:836bbbcc913c7a57
redis_mode:standalone
os:Linux 3.10.-.el7.x86_64 x86_64
arch_bits:
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:4.8.
process_id:
run_id:b0694f86c7e794bf851f6193f1f96d85f993f325
tcp_port:
uptime_in_seconds:
uptime_in_days:
hz:
lru_clock:
executable:/usr/local/redis/redis-server
config_file:/usr/local/redis/redis.conf

  

  3.2 载入配置选项

    在启动服务器时,用户可以通过给定配置参数或者指定配置文件来修改服务器的默认配置,当服务器在用initServerConfig函数初始化完server变量之后,就会开始载入用户给定的配置参数和配置文件,并根据用户设定的配置,对server变量相关属性的值进行修改。

    例1:用户在终端中指定redis服务器端口号,默认端口从6379变为了10086,启动服务

         [root@xuegod64 redis]# redis-server --port
:C Dec ::05.183 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
//下面通过另一个客户端,指定端口,连接到服务器,通过info来查看,是没有config_file的配置路径。
[root@xuegod64 ~]# redis-cli -h 127.0.0.1 -p
127.0.0.1:>info
# Server
redis_version:4.0.
....

    例2: 用户通过加载redis.conf配置文件,这是最常见的启动服务。通过info来查看,这种是有config_file的配置路径的

    [root@xuegod64 redis]# redis-server redis.conf

      通过上面案例知道,如果用户为服务器状态属性指定了新的值,那么服务器就会更新相应的属性值,如果没有为属性设置新的值,那么服务器就用之前initServerConfig函数为属性设置的默认值。

  

  3.3 初始化服务器数据结构

    服务器在载入用户指定的配置选项,并对server状态进行更新之后,服务器就可以进入初始化第三个阶段,此时服务器创建的数据结构还包括:server.clients链表;server.db数组;保存频道订阅信息的server.pubsub_channels字典以及server.pubsub_patterns链表; 用于执行Lua脚本的server.lua;  用于保存慢日志的server.slowlog属性。

    接着服务器将调用initServer函数,为以上的数据结构分配内存,该函数设置还包括:为服务器设置进程号处理器;创建共享对象;打开服务器监听端口;为serverCron函数创建时间事件;做好AOF持久化写入准备;初始化服务器后台I/O模块。当initServer函数执行完后,服务器将用ascll字符在日志中打印出redis的图标,以及redis的版本号信息。

    

3.4 还原数据库状态

    在完成了对服务器状态server变量的初始化之后,服务器需要载入RDB文件或者AOF文件,并根据文件记录的内容来还原服务器的数据库状态。如果服务器启用了AOF持久化功能,那么服务器使用AOF文件来还原数据库状态;相反 如果服务器没有启用AOF持久化功能,那么服务器使用RDB文件来还原数据库状态。

    :M  Dec ::15.343 * DB loaded from disk: 0.000 seconds    

redis 系列20 服务器下的更多相关文章

  1. redis 系列20 服务器上

    一.客户端与服务端交互 本篇简单介绍下服务器,服务器运行涉及的内部原理知识很多,主要了解Redis服务器内部要做哪些事情,需要开发人员去干预的比较少.Redis服务器负责与多个客户端建立网络连接,处理 ...

  2. redis 系列1 linux下安装说明

    一. 安装环境 操作系统:centos 7 ,redis版本4.06,客户端windows 7 ,vs2015. 1.1 安装前的条件 yum -y install gcc-c++ 判断是否安装了gc ...

  3. Redis 系列之CentOS下Redis的安装

    前言 安装Redis需要知道自己需要哪个版本,有针对性的安装,比如如果需要redis GEO这个地理集合的特性,那么redis版本就不能低于3.2版本,由于这个特性是3.2版本才有的.另外需要注意的是 ...

  4. 【目录】redis 系列篇

    随笔分类 - redis 系列篇 redis 系列27 Cluster高可用 (2) 摘要: 一. ASK错误 集群上篇最后讲到,对于重新分片由redis-trib负责执行,关于该工具以后再介绍.在进 ...

  5. redis 系列25 哨兵Sentinel (高可用演示 下)

    一. Sentinel 高可用环境准备 1.1 Sentinel 集群环境 环境 说明 操作系统版本 CentOS  7.4.1708  IP地址 172.168.18.200 网关Gateway 1 ...

  6. redis系列一: windows下安装redis

    一. 下载Redis Redis 支持 32 位和 64 位.这个需要根据你系统平台的实际情况选择,这里我们下载 Redis-x64-xxx.zip压缩包到 C 盘,解压后,将文件夹重新命名为 red ...

  7. redis系列之数据库与缓存数据一致性解决方案

    redis系列之数据库与缓存数据一致性解决方案 数据库与缓存读写模式策略 写完数据库后是否需要马上更新缓存还是直接删除缓存? (1).如果写数据库的值与更新到缓存值是一样的,不需要经过任何的计算,可以 ...

  8. redis系列-14点的灵异事件

    概述 项目组每天14点都会遭遇惊魂时刻.一条条告警短信把工程师从午后小憩中拉回现实.之后问题又神秘消失.是PM喊你上工了?还是服务器给你开玩笑?下面请看工程师如何一步一步揪出真凶,解决问题. 如果不想 ...

  9. 就publish/subscribe功能看redis集群模式下的队列技术(一)

    Redis 简介 Redis 是完全开源免费的,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中 ...

随机推荐

  1. Oracle:select into 查询没有记录的解决办法

    在数据库编程中,select into 语句可以将数据库的某些值赋值给程序的变量,使用起来非常方便.但很多时候也会遇到查询出来没有记录的情况,这时程序会出错. 可以使用 exception when ...

  2. 利用kibana插件对Elasticsearch进行映射

    映射(mapping) 映射是创建索引的时候,可以预先定义字段的类型以及相关属性 Elasticsearch会根据JSON源数据的基础类型去猜测你想要的字段映射.将输入的数据变成可搜索的索引项.Map ...

  3. fidderl 录制导出 jmeter格式文件

    总共需要五步 1.下载扩展脚本 2.将下载后的文件剪切到 fiddler 安装目录下 3.重新启动fillder 4.设置筛选条件 5.录制完成后导出文件 1.下载扩展脚本 首先需要下载支持jmete ...

  4. iOS 上传自己的工程(模块工具类)到cocoapods上遇到坑

    最近在研究把自己写的工具类和模块上传到cocoapods上, 再新构建项目中可以直接使用cocoapods使用  也可以更新之前的版本 便于维护项目. 但是在这个过程中遇到了种种问题 但是最后还是解决 ...

  5. 对象转JSON

    /// <summary> /// 把对象序列化 JSON 字符串 /// </summary> /// <typeparam name="T"> ...

  6. nodejs编译遇到的问题

    src\node_contextify.cc:631: Assertion 'args[1]->IsString()' failed. node 10 版本会出现这个问题, 安装natives后 ...

  7. Nginx如何进行配置优化?

    在日常工作的时候,搭建配置Nginx的时候,我们都会做相应的优化,那一般需要做的配置优化有哪些呢?可能有些小伙伴一听到要进行优化,内心难免有些慌. 今天咱们聊聊Nginx进行常规配置优化,这里需要注意 ...

  8. DCOS实践分享(5):Open DCOS深入分析

    2016/05/18(三) 09:30 OpenDC/OS研討會暨工作坊 指導單位:經濟部.科技部 主辦單位:工業技術研究院.Linker Networks 協辦單位:Microsoft.資通訊產業聯 ...

  9. 微信小程序没有返回按钮怎么办?微信小程序左上角返回按钮怎么调出来?

    如果你发现自己的小程序页面没有返回按钮,请检查是不是用的wx.redirectTo(OBJECT)进行的跳转,如果是那就把它改成wx.navigateTo(OBJECT)就可以了. wx.naviga ...

  10. SIP协议搭建电信级VOIP/IM运营平台--架构篇(sip集群)

    移动互联网的发展为整个VOIP通信行业开拓了新的战场,一时间各类即时通信软件如雨后春筝般冒了出来,再一次创造了移动互联网的发展神话.SIP协议做为音视频通信的首选标准,应用也越来越广泛. ------ ...