·Redis缺省的数据库数目,单纯的string类型数据一

2020-05-02 17:57 来源:未知

本文将通过分析代码来介绍Redis的启动过程,通过查看Redis 的启动脚本,得知Redis的启动时从Redis.c的main方法开始的。Redis启动可以分为以下几个步骤:

背景

  公司一年的部分业务数据放在redis服务器上,但数据量比较大,单纯的string类型数据一年就将近32G,而且是经过压缩后的。

  所以我在想能否通过获取string数据的时间改为保存list数据类型,或者将数据持久化到硬盘上,或者放在不同库上,解决未来数据过大导致down机的问题。

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

相关知识点

 

  • string数据类型

 

  • 数据持久化
  • 数据加载

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

Redis的字符串(string)的实现原理

Redis是由C语言编写的,以高效和轻量著称。

比如一个简单的字符串”hello world”,其实是一个如下的字符的数组:

[‘h’, ‘e’, ‘l’, ‘l’, ‘o’, ‘ ‘, ‘w’, ‘o’, ‘r’, ‘l’, ‘d’, ‘’]

最后的一个’’是空字符,表示字符串的结尾。

Redis由于各种原因,并没有直接使用了C语言的字符串结构,而是对其做了一些封装,得到了自己的简单动态字符串(simple dynamic string, SDS)的抽象类型

Redis中,默认以SDS作为自己的字符串表示。只有在一些字符串不可能出现变化的地方使用C字符串。

SDS定义中有三个参数:

  buf是一块可用的内存空间,通常大小会大于等于需要存储的字符串的大小

  len表示字符串的长度,也表示buf中已经被使用的空间的大小

  free表示buf中没有被使用的空间的大小。

要注意的是,buf的大小等于len+free+1,其中多余的1个字节是用来存储’’的

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

那么这么封装到底有什么好处呢?

二,加载配置文件:

  1.常数复杂度获取字符串长度

在C语言中的字符串只是简单的字符的数组,当使用strlen获取字符串长度的时候,C语言内部其实是直接顺序遍历数组的内容,找到对应的’’对应的字符,从而计算出字符串的长度。显然这个算法复杂度和字符串的长度成正比,即O(N)。而对于SDS来说,只需要访问SDS的len属性就能得到字符串的长度,复杂度为O(1)。这样,获取字符串长度的操作就不会成为Redis的瓶颈。

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

  2.杜绝缓冲区溢出

C++里面的字符串使用了STL的string类型,我们开发者不太需要关注内存的分配和释放的过程。但是Redis是C语言编写的,并没有这么方便的数据类型。对于字符串的拼接、复制等操作,C语言开发者必须确保目标字符串的空间足够大,不然就会出现溢出的情况。

  char a[10]="hello";

  strcar(a,"world");

  strcpy(a,"hello world");

上面的三句代码,就是C语言的字符串拼接和复制的使用,但是明显出现了缓冲区溢出的问题。字符数组a的长度是10,而”hello world”字符串的长度为11,则需要12个字节的空间来存储(不要忘记了’’)。

然而当使用SDS的API对字符串进行修改的时候,API内部第一步会检测字符串的大小是否满足。

如果空间已经满足要求,那么就像C语言一样操作即可。

如果不满足,则拓展buf的空间,使得满足操作的需求,之后再进行操作。

每次操作之后,len和free的值会做相应的修改。

这就是SDS的全部的高明之处了吗?当然不!

当API发现SDS的buf的容量不够的时候,并不是简单申请正好适合的大小,而是额外申请了一倍的空间!我们以sds的API sdscat函数为例,该函数实现了sds的拼接的功能。

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

  3.减少修改字符串时带来的内存重新分配次数

c语言底层是一个N+1长的字符数组,长度的变化都会引起内存的重新分配。而对于SDS则通过一些策略去解决这些问题:

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

空间预分配

这种方式用于处理字符串长度增加的问题。

如果对字符串的修改使得字符串的长度增加,API首先会判断buf的空间大小是否满足,如果满足则直接操作,如果不满足,则进行如下操作:

如果对SDS进行修改之后的,SDS的长度(即len的值)小于1MB。程序将额外分配和len一样大小的未使用空间。以上面的”hello”

  • ” world”的操作为例。

在这个例子中”hello”的len是5(不考虑’′),修改之后的字符串”hello world”长度为11,那么新的SDS的buf的容量就是11*2+1。其中len和free都是11,多余的1字节用来存储’www.129028.com,0’。

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

惰性空间释放

当执行字符串长度缩短的操作的时候,SDS并不直接重新分配多出来的字节,而是修改len和free的值(len相应减小,free相应增大,buf的空间大小不变化)。通过惰性空间释放,可以很好的避免缩短字符串需要的内存重分配的情况。而且多余的空间也可以为将来可能有的字符串增长的操作做优化。

当然,SDS也提供直接释放未使用空间的API,在需要的时候,也能真正的释放掉多余的空间。

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

数据持久化

  • filesnapshotting(快照) 
  • Append-only(aof)
TAG标签:
版权声明:本文由www.129028.com-澳门金沙唯一官网www129028com发布于编程新闻,转载请注明出处:·Redis缺省的数据库数目,单纯的string类型数据一