已通过os信号请求关闭服务器,redis(一)内部机制的介绍和启动过程

redis(一)内部机制的介绍和启动过程

redis的基本介绍

redis服务端

redis客户端

redis的持久化

redis中的文件事件和时间时间

redis的启动过程

redis的基本介绍

redis是一种非关系型数据库,采用=key,value的形式来存储数据。key是二进制数据,对于value的数据类型,redis支持string、hash、list、set、sorted set五种类型。

对于单个redis实例,内部使用多线程通信,但是对外采用RESP单线程通信协议,在TCP层通过二进制方式进行传输数据,单线程采用同步的请求方式。

redis服务端

redis服务端内部结构为struct redisServer和struct redisDb。redis中默认16个数据库,可以通过配置来修改数据库数量,每一个数据库对应一个redisDb。数据库之间的数据是相互独立的。查询数据的时候,可以通过select指定具体某个数据库。

1 struct redisServer {2 int dbnum;//服务器的数据库数量,值由服务器配置的“databases”选项决定,默认为16

3 redisDb *db;//数组,保存着服务器中的所有数据库

4

5 list *clients;//一个链表,保存了所有客户端状态,每个链表元素都是“redisClient”结构

6

7 time_t unixtime;//保存秒级精度的系统当前UNIX时间戳,减少获取系统当前时间的系统调用次数,100毫秒更新一次

8 long long mstime;//保存毫秒级精度的系统当前UNIX时间戳

9 unsigned lruclock;//默认每10秒更新一次,用于计算数据库键的空转时长,数据库键的空转时长 = 服务器的“lruclock”属性值 - 数据库键值对象的“lru”属性值

10

11 long long ops_sec_last_sample_time;//上一次进行服务器每秒执行命令数量抽样的时间

12 long long ops_sec_last_sample_ops;//上一次进行服务器每秒执行命令数量抽样时,服务器已执行命令的数量

13 long long ops_sec_samples[REDIS_OPS_SEC_SAMPLE];//环形数组,每个元素记录一次服务器每秒执行命令数量抽样结果,估算服务器在最近一秒钟处理的命令请求数量(数组长度默认为16,100毫秒更新一次)

14 int ops_sec_idx;//ops_sec_samples数组的索引值,每次抽样后值增1,等于16时重置为0

15

16 size_t stat_peak_memory;//已使用内存峰值

17

18 int shutdown_asap;//关闭服务器的标识,1表示关闭,0不关闭

19

20 pid_t rdb_child_pid;//记录执行BGSAVE命令的子进程的ID,-1表示服务器没有正在执行BGSAVE

21 pid_t aof_child_pid;//记录执行BGREWRITEAOF命令的子进程的ID,-1表示服务器没有正在执行BGREWRITEAOF

22 int aof_rewrite_scheduled;//1表示有BGREWRITEAOF命令被延迟了(服务器执行BGSAVE期间收到的BGREWRITEAOF会被延迟到BGSAVE执行完成之后执行)

23 struct saveparam *saveparams;//记录了自动保存条件的数组(执行BGSAVE的条件)

24 long long dirty;//修改计数器(上一次执行BGSAVE之后已经产生了多少修改)

25 time_t lastsave;//上一次执行自动保存操作(BGSAVE)的时间

26 sds aof_buf;//AOF缓冲区

27

28 int cronloops;//serverCron函数的运行次数计数器

29

30 lua;//用于执行Lua脚本的Lua环境

31 redisClient *lua_client;//Lua脚本的伪客户端,在服务器运行的整个生命周期一直存在,直至服务器关闭才会关闭

32 dict *lua_scripts;//字典,记录所有载入的Lua脚本,键为某个Lua脚本的SHA1校验和,值为对应的Lua脚本

33 dict *repl_scriptcache_dict;//字典,记录已经传播给所有从服务器的所有Lua脚本,键为脚本的SHA1校验和,值为NULL,用于EVALSHA1命令的复制

34

35 long long slowlog_entry_id;//下一条慢查询日志的ID

36 list *slowlog;//保存了所有慢查询日志的链表

37 long long slowlog_log_slower_than;//服务器配置“slowlog-log-slower-than”选项的值,表示查询慢于多少微秒便记录慢查询日志

38 unsigned long slowlog_max_len;//服务器配置“slowlog-max-len”选项的值,表示服务器最多保存多少条慢查询日志记录,若超出,最久的记录会被覆盖

39

40 monitors;//链表,监视器客户端列表

41

42 dict *pubsub_channels;//字典,保存所有频道的订阅关系,键为某个被订阅的频道,值为链表,记录了所有订阅这个频道的客户端

43 list *pubsub_patterns;//链表,保存所有模式的订阅关系,每个链表节点都包含了订阅的客户端和被订阅的模式

44 };

struct redisDb {

dict*dict;//数据库键空间字典,保存数据库中所有的键值对

dict *expires;//过期字典,保存数据库中所有键的过期时间

dict *watched_keys;//字典,正在被WATCH命令监视的键

};

redisDb中三个字典中的key共享对象,value值不一样。对于过期的键,redis采用惰性删除和定时删除相结合的方式,惰性删除,指执行之前会查看这个key是否过期,定时删除值一段时间之后分多次遍历数据库,每次只删除部分过期的数据。

redis客户端

redis-server通过tcp端口或socket来创建和redis-cli的连接,可以修改redis.conf中的maxclients来指定最大连接数,在建立连接之后,socket会被设置为非阻塞模式,同时创造一个struct redisClient来保存客户端的连接信息。

1 struct redisClient {2 redisDb *db;//记录客户端当前正在使用的数据库,上文提到之前有16个们默认的数据库,可以通过select进行切换数据库

3 int fd;//客户端正在使用的套接字描述符,-1表示伪客户端(AOF文件或者Lua脚本),大于-1表示普通客户端

4 robj *name;//客户端名字

5 int flags;//客户端标志,记录了客户端的角色,以及客户端目前所处的状态

6 sds querybuf;//输入缓冲区,根据输入内容动态地缩小或扩大,但不能超过1GB,否则服务器将关闭这个客户端

7 robj **argv;//命令与命令参数,数组,每个元素都是一个字符串对象,argv[0]为命令,其余元素为参数

8 int argc;//argv数组的长度

9 struct redisCommand *cmd;//当前执行的命令的实现函数,指向命令表中的命令结构

10 char buf[REDIS_REPLY_CHUNK_BYTES];//固定大小输出缓冲区,数组,默认大小为16KB

11 int bufpos;//buf数组目前已使用的字节数量

12 list *reply;//可变大小输出缓冲区,链表

13 obuf_soft_limit_reached_time:记录了“reply”输出缓冲区第一次到达软性限制的时间,用于计算持续超出软性限制的时长,以此决定是否关闭客户端14 int authenticated;//0表示未通过身份验证,1表示已通过身份验证

15 time_t ctime:创建客户端的时间,可用于计算客户端与服务器连接的时间长度16 time_t lastinteraction:客户端与服务器最后一次进行互动的时间,可用于客户端的空转时长17 multiState mstate;//事务状态,包含一个事务队列,以及一个已入列命令计数器

18 };

db:是一个指针,指向Redis服务器状态结构中的“db”数组其中一个元素,表示当前客户端正在使用的数据库。默认情况下,Redis客户端的目标数据库为0号数据库,可以通过select命令切换,所以select命令的实现原理为:修改redisClient.db指针,让它指向服务器中指定的数据库。

fd:连接当前客户端与Redis服务器的套接字描述符。值为-1表示伪客户端(AOF文件或者Lua脚本),值大于-1则表示普通客户端。Redis客户端分为普通客户端与伪客户端两种类型,其中通过网络连接与Redis服务器进行连接的就是普通客户端,反之则是伪客户端了。伪客户端也有两种类型,分别是Lua脚本的伪客户端和AOF文件的伪客户端。Redis服务器状态结构的“lua_client”属性就保存了Lua脚本的伪客户端,它会在Redis服务器初始化时就被创建,负责执行Lua脚本中包含的Redis命令,在服务器运行的整个生命周期一直存在,直至服务器关闭才会关闭。而AOF伪客户端则是在载入AOF文件时被创建,用于执行AOF文件中的Redis命令,在AOF文件载入完成之后被关闭。client list:列出目前所有连接到服务器的普通客户端。

redis的持久化

AOF、RDB指的是redis持久化策略,可以通过redis.conf中的参数来配置。

appendfsync (always/everysec/no)

save [time(s)] [times]

AOF指的是保存操作命令,他会将每一次redis的数据操作命令追加到文件中,当键过期的时候会加入del命令,并且每过一段时间,会对已经生成的文件优化一次,主要指的是操作命令的合并。

RDB指的是执行save或bgsave命令创建一个新的RDB文件,新建一个子进程,把所有的数据写入文件。

redis中的文件事件和时间时间

redis中的事件分为文件事件和时间事件

文件事件:指的是通过epoll实现io多路复用程序来监听多个套接字,对读、写、关闭、连接都支持事务,支持原子操作。

时间事件:指的是redis中在默写特定时间执行操作,主要有定时事件和周期性事件。所有的时间事件会被放在一个无须列表中,新加入的事件会在事件的头部插入。每次执行事件的时候都会去遍历列表。正常情况下只有一个serverCron时间时间,在benchmark模式下,也只有两个时间事件。

redis的启动过程

(1)初始化服务器状态结构

新创建一个struct redisServer类型的实例变量作为服务器的状态,记录着整个服务器的状态,并为结构中的各个属性设置默认值,例如:服务器的运行ID、默认配置文件路径、默认端口等等,同时创建Redis命令表。

(2)载入配置选项

载入用户指定的配置参数和配置文件,并根据用户设定的配置,对服务器状态变量的相关属性进行修改。

(3)初始化服务器数据结构

这一步主要是为服务器状态中的一些数据结构分配内存,例如:

“clients“:链表,保存所有与服务器连接的客户端的状态结构。

”db“:字典保存服务器的所有数据库。

”lua“:用于执行Lua脚本的Lua环境。

”slowlog“:用于保存慢查询日志。

除此之外,还会进行一些非常重要的设置操作,例如:

为服务器设置进程信号处理器。

创建共享对象,例如经常经常用到的“OK”回复字符串对象,1到10000的字符串对象等等。

为serverCron函数创建时间事件。

如果AOF持久化功能已经打开,则打开现有的AOF文件,若AOF文件不存在,则创建并打开一个新的AOF文件,为AOF写入做好准备。

初始化服务器的后台I/O模块,为将来的I/O操作做好准备。

(4)还原数据库状态

若服务器启用了AOF持久化功能,则载入AOF文件,否则载入RDB文件,根据AOF文件或RDB文件记录的内容还原数据库状态,同时在日志文件中打印出载入文件并还原数据库状态所耗费的时长。

(5)执行事件循环

一切准备就绪,开始执行服务器的事件循环,开始接受客户端的连接请求,处理客户端发送的命令请求。

来源:oschina

链接:https://my.oschina.net/u/4332949/blog/3449911

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/506215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

datalist可以放div吗?_混凝土中能放竹子吗?可以代替钢筋吗?为何打地坪混凝土放竹子?...

大家好,我是专注家居和装修知识分享的家居杂坛。喜欢的就点击一下关注吧!对于在地面上所浇筑的混凝土,常规有两种做法。例如,在混凝土中铺设钢筋,打成钢筋混凝土的地面,又或者还有一些朋友在钢混凝土中放入…

snmp协议_软件评测师写作专栏之OSI七层模型及其常见的协议11

各位学员大家好,大家在学习计算机网络的时候,OSI七层模型及其常见的协议是必考的内容。为了让大家快速掌握这方面的知识点,接下来就带领大家一起来学习一下!例题:下面的协议中属于应用层协议的是( 1 ),该协…

nginx文件服务器密码登录,风的方向

说明很多时候我们服务器上的页面或者服务可能没有安全配置,使得服务开放的暴露在互联网中,很不安全。nginx可以给我们提供密码配置,来保护我们的服务器上的服务的安全性。配置nginx配置文件在需要配置密码的服务的相关nginx配置文件中的locat…

selenium python下载_使用Selenium、Chrome和Python下载PDF

我试着按照前面关于这个主题的文章来写,比如这些(post 1,post 2),但是我还是被卡住了。我的脚本必须使用一组凭据登录到站点,然后通过一些下拉菜单导航以选择报表。选择报表后,将弹出一个新窗口,在该窗口中…

劲乐团u显示服务器维护,劲乐团9YOU原版服务端架设教程

我来做一个o2jam的服务端架设教程,希望新手能有点帮助相信你已经全的数据库文件了,其实只要里面的三个就可以了test2...o2jamtrade---onlinereport那么GO了.首先确定你已经安装好了MSSQL.如果没有.........那就先安装下......企业版安装在SQL服务器的安装盘中找到MS…

linux部署tomcat项目404_一个tomcat下部署多个项目或一个服务器部署多个tomcat

点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐]♪ 点击上方绿标 收听一个tomcat下部署多个项目或一个服务器部署多个tomcat最近需要把两个项目同时部署到服务器上,于是研究了一下,页借鉴了很多别人的方法,把过程记录下来,以…

科学计数法_第一章 科学计数法与近似数

生活中,我们常常遇到一些较大的数,如10000000、3450000000等.利用科学计数法表示某些较大的数可以免去一些不必要的麻烦,尤其是遇到一些乘法运算时,如20000000245000000.科学记数法表示数时,不改变数的符号&#xff0c…

python调用浏览器打开网页_python调用浏览器,实现刷网页浏览小程序!

Python 和放大镜的二进制代码私信小编007即可自动获取大量Python视频教程以及各类PDF!python 打开浏览器,可以做简单的刷网页的小程序 and 其他有想象力的程序。不过仅供学习,勿用非法用途。python的webbrowser模块支持对浏览器进行一些操作主…

# 傅立叶变换 画曲线_让你永远忘不了的傅立叶变换解析

使用联想链条和几何直观,辅以从实际需求衍生概念的思考模式,详解什么是傅立叶变换,为什么要做傅立叶变换等,帮助记忆和理解,目的当然是标题所说:让你永远忘不了傅立叶变换这个公式。另,这篇博客…

bat批处理执行python_通过批处理来运行python程序

》准备》》在所用的python源程序最前面指定该源程序要用那种可执行程序去运行它》》例如:#!/bin/sh shell脚本#!/usr/bin/perl perl脚本#!/usr/bin/python python脚本#!/usr/bin/python3 python3脚本#!/usr/bin/python2 python2脚本》》我的程序使用的解释器》》》#…

messagehub讲解_艾舜杰SAP Data Hub 数据服务总线技术深度讲解

原标题:艾舜杰SAP Data Hub 数据服务总线技术深度讲解艾舜杰SAP Data Hub 是一个多方面的数据编排解决方案, 旨在解决在不断增长的分布式数据环境中的挑战。它的关键功能包括:数据管道、治理和架构管理。解决方案可弹性扩展, 可编排并自动化处理不同数据…

select报错 spark_spark-sql master on yarn 模式运行 select count(*) 报错日志

启动hive --service metastore启动 dfs yarn[rootbigdatastorm bin]# ./spark-sql --master yarn --deploy-mode client --driver-memory 512m --executor-memory 512m --total-executor-cores 1spark-sql>select count(*) ;LogSLF4J: Class path contains multiple SLF4J …

python字符串填充_填充函数(Python)字符串.zfi

我想更改下面的Python函数,以涵盖我的business_代码需要填充的所有情况。string.zfillPython函数处理此异常,将填充到左侧直到达到给定的宽度,但我以前从未使用过它。在#function for formating business codesdef formatBusinessCodes(code)…

找不到天隆虚拟机_玩转虚拟机,教你如何装系统

最近小白系统收到很多小伙伴的私信想要知道虚拟机如何安装系统,那么今天小白系统整理了下虚拟机安装系统的教程,下面一起看下吧。虚拟机安装系统适合什么人群呢?1、如果你新买的电脑不支持安装Win7系统,那么装个虚拟机吧&#xff…

ios 主题切换 思路_IOS主题切换ThemeManager

#import "ThemeManager.h"#define kDefaultThemeName "默认主题"#define kThemeName "kThemeName"implementation ThemeManagerstatic ThemeManager *instance nil;(ThemeManager *)shareInstance{static dispatch_once_t onceToken…

从数据类型 nvarchar 转换为 numeric 时出错_JS入门篇(三):javascript的数据类型详解...

JavaScript的数据类型分为两大类,基本数据类型和复杂数据类型。基本数据类型:Undefined、Null、Boolean、Number、String。复杂数据类型:Object。(1)Undefined类型Undefined 类型只有一个值,即特殊的 undefined。在使用 var 声明变…

下载keep运动软件_Keep运动软件官网下载_Keep运动最新官网下载_18183软件下载

Keep运动官网下载怎么样?不妨来18183下载试试!1.8亿运动爱好者都在Keep体验健身、跑步、骑行、计步功能,ta就是移动健身教练和饮食指导老师。Keep帮助人们随时随地练就完美身材,开启健康生活,就从Keep开始。18183软件下…

python 小程序搜索排名优化_python3 搜索关键字小程序

#!/usr/bin/python3#luckimport sysfilename input(‘请输入您要搜索的路径及文档名称:‘)if len(filename) 0:sys.exit(‘不能为空!‘)while True:mubiao input(‘请输入您要搜索的关键词:‘)if mubiao ‘exit‘:sys.exit(‘欢迎使用搜索系统!‘)if len(mubiao) 0:contin…

idea添加scala环境_idea怎么在线安装scala并且启动'

一.环境配置:1.1 安装JDK,配置环境变量。1.2下载Scala,并配置环境变量1.3安装playframe2框架:下载play并配置环境变量或者点击browse all versions选择更多版本,我安装的是play2.2.4。查看运行是否安装成功&#xff0c…

linux下anjuta_[分享] Linux下用Anjuta写个Hello World 的C++程序竟如此简单!

在IRC中常见人问起,学C/C,在Linux下用什么工具好。有推荐vi/vim和emacs的,个人认为,那太难为像我们这样的初学者了。印象中,KDE中的KDeveloper非常的不错,简直就跟VC是一样的强大和方便。几年没用过了&…