【转】分析Redis架构设计
一、前言
我分析流程是按照从main进入,逐步深入分析Redis的启动流程。同时根据Redis初始化的流程,理解Redis各个模块的功能及原理。
二、redis启动流程

三、Redis数据持久化方案
1.RDB持久化方案
rdbSave负责将内存中的数据库数据以RDB格式保存到磁盘中,如果RDB文件已经存在将会替换已有的RDB文件。保存RDB文件期间会阻塞主进程,这段时间期间将不能处理新的客户端请求,直到保存完成为止。为避免主进程阻塞,Redis提供了rdbSaveBackground函数。在新建的子进程中调用rdbSave,保存完成后会向主进程发送信号,同时主进程可以继续处理新的客户端请求。
当Redis启动时,会根据配置的持久化模式,决定是否读取RDB文件,并将其中的对象保存到内存中。载入RDB过程中,每载入1000个键就处理一次已经等待处理的客户端请求,但是目前仅处理订阅功能的命令(PUBLISH 、 SUBSCRIBE 、 PSUBSCRIBE 、 UNSUBSCRIBE 、 PUNSUBSCRIBE),其他一律返回错误信息。因为发布订阅功能是不写入数据库的,也就是不保存在Redis数据库的。RDB的缺点:再说RDB缺点时,需要提到的是RDB有保存点的概念。在默认的redis.conf中可以看到这样的默认配置:[plain] view plaincopy
- #save <seconds> <changes>
[plain] view plaincopy
- save 900 1 #如果15分钟内,有1个键被修改
[plain] view plaincopy
- save 300 10 #如果6分钟内,有10个键被修改
[plain] view plaincopy
- save 60 10000 #如果60秒内有10000个键被修改
意思是当满足上面任意一个条件时,将会进行快照保存。为了保证IO读写性能不会成为Redis的瓶颈,一般都会创建一个比较大的值来作为保存点。1.此时如果保存点设置过大,就会导致宕机丢失的数据过多。保存点设置过小,又会造成IO瓶颈2.当对数据进行保存时,可能会由于数据集过大导致操作耗时,这会导致Redis可能在短时间内无法处理客户端请求。
2.AOF持久化方案
1.将客户端请求的命令转换为网络协议格式2.将协议内容字符串追加到变量server.aof_buf中3.当AOF系统达到设定的条件时,会调用aof_fsync(文件描述符号)将数据写入磁盘
其中第三步提到的设定条件,就是AOF性能的关键点。目前Redis支持三种保存条件机制:1.AOF_FSYNC_NO:不保存
此模式下,每执行一条客户端的命令,都会将协议字符串追加到server.aof_buf中,但不会执行写入磁盘。
写入只发生在:
1.Redis被正常关闭
2.Aof功能关闭
3.系统写缓存已满,或后台定时保存操作被执行
上面三种情况都会阻塞主进程,导致客户端请求失败。
2.AOF_FSYNC_EVERYSECS:每一秒保存一次
由后台子进程调用写入保存,不会阻塞主进程。如果发生宕机,那么最大丢失数据会在2s以内的数据。这也是默认的设置选项
3.AOF_FSYNC_ALWAYS:每执行一个命令都保存一次
这种模式下,可以保证每一条客户端指令都被保存,保证数据不会丢失。但缺点就是性能大大下降,因为每一次操作都是独占性的,需要阻塞主进程。
AOF保存的是数据协议格式的数据,所以只要将AOF中的数据转换为命令,模拟客户端重新执行一遍,就可以还原所有数据库状态。读取的过程是:1.创建模拟的客户端2.读取AOF保存的文本,还原数据为原命令和原参数。然后使用模拟的客户端发出这个命令请求。3.继续执行第二步,直到读取完AOF文件AOF需要将所有的命令都保存到磁盘,那么这个文件会随着时间变得越来越大。读取也会变得很慢。Redis提供了AOF的重写机制,帮助减少文件的大小。实现的思路是:[plain] view plaincopy
- LPUSH list 1 2 3 4 5
[plain] view plaincopy
- LPOP list
[plain] view plaincopy
- LPOP list
[plain] view plaincopy
- LPUSH list 1
最初保存到AOF文件的将会是四条指令。但经过AOF重写后,会变成一条指令:[plain] view plaincopy
- LPUSH list 1 3 4 5
同时,考虑到为了在AOF重写时,不影响AOF的写入增加了AOF重写缓存的概念。也就是说Redis在开启AOF时,除了将命令格式数据写入到AOF文件,同时也会写入到AOF重写缓存。这样AOF的写入、重写就做到了隔离,保证了重写时不会阻塞写入。
1.AOF重写完成会向主进程发送一个完成的信号2.会将AOF重写缓存中的数据全部写入到文件中3.用新的AOF文件,覆盖原有的AOF文件。
1.AOF文件通常会大于相同数据集的RDB文件2.AOF模式下性能与RDB模式下性能高低,主要取决于AOF选用的fsync模式

Redis字典使用的是哈希表实现,原本不准备详细介绍Redis哈希表的实现。但发现Redis在实现哈希表时,
提供了一个很好的rehash方案,这个方案思路很好,甚至可以衍生到其他各个应用中使用,方案的名称叫“渐进式Rehash”。
实现哈希表的方法大同小异,但为何各个开源软件总是去开发自己独有的哈希数据结构呢?
从研究PHP内核的哈希实现与Redis哈希实现,发现应用场景决定了必须定制才能更好的发挥性能。(关于PHP哈希实现可以参看:PHP内核中的神器之HashTable)
a)PHP主要应用于WEB场景,在WEB场景针对单次请求数据之间是隔离的,并且哈希的数量是有限的,那么进行一次rehash也是很快的。
所以PHP内核使用阻塞形式rehash,即rehash进行中将不能对当前哈希表进行任何操作。
b)在来看Redis,常驻进程,接收客户端请求处理各项事务,并且操作的数据是相关且数据量较大的,如果使用PHP内核的那种方式就会出现:
对哈希表进行rehash时,此时将阻塞所有客户端请求,并发性能会大大下降。



【转】分析Redis架构设计的更多相关文章
- 分析Redis架构设计
http://blog.csdn.net/a600423444/article/details/8944601 一.前言 因为近期项目中开始使用Redis,为了更好的理解Redis并应用在适合的业务场 ...
- Redis --> Redis架构设计
Redis架构设计 一.前言 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 字符串(strings), 散列 ...
- 细说分布式Redis架构设计和踩过的那些坑
细说分布式Redis架构设计和踩过的那些坑_redis 分布式_ redis 分布式锁_分布式缓存redis 细说分布式Redis架构设计和踩过的那些坑
- Redis架构设计
高可用Redis服务架构分析与搭建 各种web开发业务中最为常用的key-value数据库了 应用: 在业务中用其存储用户登陆态(Session存储),加速一些热数据的查询(相比较mysql而言,速度 ...
- [转载] Codis作者黄东旭细说分布式Redis架构设计和踩过的那些坑们
原文: http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=208733458&idx=1&sn=691bfde670fb ...
- Discuz!NT中的Redis架构设计
在之前的Discuz!NT缓存的架构方案中,曾说过Discuz!NT采用了两级缓存方式,即本地缓存+memcached方式.在近半年多的实际运行环境下,该方案经受住了检验.现在为了提供多样式的解决方案 ...
- Redis 架构设计
1.设计层面 (1) 存储小而热的数据 (2) 结合业务数据特点,正确使用内存类型 (3) 冷.热数据分离 2.架构层面 (1) 提前做好容量(内存)规划 (2) 结合持久化模式优劣正确使用,一般建议 ...
- jquery源码分析(二)——架构设计
要学习一个库首先的理清它整体架构: 1.jQuery源码大致架构如下:(基于 jQuery 1.11 版本,共计8829行源码)(21,94) 定义了一些变量和函数jQu ...
- Redis架构设计--客户端请求RedisServer时,server端持久化的部分操作
随机推荐
- js 实现复制到剪切板 复制按钮兼容各大浏览器
zeroclipboard官网:https://github.com/zeroclipboard/ZeroClipboard 下载压缩包,得到两个“ZeroClipboard.js”和“ZeroCli ...
- web相关问题总结 - imsoft.cnblogs
1,问题:编辑好的web程序乱码,显示不正常 解决方法:在head中加入一下代码,设置网页使用的语言为中文. <meta http-equiv="Content-Type" ...
- JQuery中操作Css样式
//1.获取和设置样式 $("#tow").attr("class")获取ID为tow的class属性 $("#two").attr(&qu ...
- [转]CentOS6.3安装JDK和环境配置
转自:http://www.linuxidc.com/Linux/2012-09/70780.htm 1.CentOS默认情况下,会安装OpenOffice之类的软件,这些软件需要Java的支持,默认 ...
- DIV的圆角表现和TAB切换
内容大体是从网上找过来的,感觉那位哥们说的对,css还是比较靠谱的,当然有些高玩搞出来的东西本地 没有运行起来. 把自己的应用贴出来同大家分享 <html> <head> &l ...
- c#部分---一维数组、冒泡排序、foreach的用法
一维数组:2016-10-14 定义方式:{定义的时候,需要数据类型.长度!} 1.int []aa=new int [5]; 表示数组里面有5个字符: 2.int []aa=new int []{ ...
- python设置字体颜色
在开发项目过程中,为了方便调试代码,经常会向stdout中输出一些日志,默认的这些日志就直接显示在了终端中.而一般的应用服务器,第三方库,甚至服务器的一些通告也会在终端中显示,这样就搅乱了我们想要的信 ...
- c++时间处理
struct tm;这是一个结构体,包括了时间的各个属性年月日,时分秒 time(time_t * t);获取从1900年到现在经过的毫秒数,或者也可以这么用time_t t=time(NULL); ...
- JSBinding + SharpKit / 原理篇:内存管理与垃圾回收
C# 和 JS 都有垃圾回收机制,需要保证 2 者能够分工协作. 类对象 类在C#中是引用类型.我们在 C# 中维护了2个map,保存 C# 对象和 JS 对象的一一对应关系. 举一个例子,看以下代码 ...
- ob_start()失效与phpunit的非正常结束
在ob_clean();或ob_get_clean()之前有return或致命错误,从而结束了程序,会导致ob_start失效, 这和phpunit的非正常结束