一、前言
因为近期项目中开始使用Redis,为了更好的理解Redis并应用在适合的业务场景,需要对Redis设计与实现深入的理解。
我分析流程是按照从main进入,逐步深入分析Redis的启动流程。同时根据Redis初始化的流程,理解Redis各个模块的功能及原理。
二、redis启动流程
1.初始化server变量,设置redis相关的默认值
2.读入配置文件,同时接收命令行中传入的参数,替换服务器设置的默认值
3.初始化服务器功能模块。在这一步初始化了包括进程信号处理、客户端链表、共享对象、初始化数据、初始化网络连接等
4.从RDB或AOF重载数据
5.网络监听服务启动前的准备工作
6.开启事件监听,开始接受客户端的请求
启动的部分过程通过查看下图,会更直观。
下面是针对启动过程中,对各个模块的详细理解。(目前只分析了后台线程系统与慢查询日志系统)
rdbSave负责将内存中的数据库数据以RDB格式保存到磁盘中,如果RDB文件已经存在将会替换已有的RDB文件。保存RDB文件期间会阻塞主进程,这段时间期间将不能处理新的客户端请求,直到保存完成为止。为避免主进程阻塞,Redis提供了rdbSaveBackground函数。在新建的子进程中调用rdbSave,保存完成后会向主进程发送信号,同时主进程可以继续处理新的客户端请求。
b)读取(rdbLoad)
当Redis启动时,会根据配置的持久化模式,决定是否读取RDB文件,并将其中的对象保存到内存中。载入RDB过程中,每载入1000个键就处理一次已经等待处理的客户端请求,但是目前仅处理订阅功能的命令(PUBLISH 、 SUBSCRIBE 、 PSUBSCRIBE 、 UNSUBSCRIBE 、 PUNSUBSCRIBE),其他一律返回错误信息。因为发布订阅功能是不写入数据库的,也就是不保存在Redis数据库的。RDB的缺点:再说RDB缺点时,需要提到的是RDB有保存点的概念。在默认的redis.conf中可以看到这样的默认配置:意思是当满足上面任意一个条件时,将会进行快照保存。为了保证IO读写性能不会成为Redis的瓶颈,一般都会创建一个比较大的值来作为保存点。1.此时如果保存点设置过大,就会导致宕机丢失的数据过多。保存点设置过小,又会造成IO瓶颈2.当对数据进行保存时,可能会由于数据集过大导致操作耗时,这会导致Redis可能在短时间内无法处理客户端请求。
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:每执行一个命令都保存一次这种模式下,可以保证每一条客户端指令都被保存,保证数据不会丢失。但缺点就是性能大大下降,因为每一次操作都是独占性的,需要阻塞主进程。
b)读取
AOF保存的是数据协议格式的数据,所以只要将AOF中的数据转换为命令,模拟客户端重新执行一遍,就可以还原所有数据库状态。读取的过程是:1.创建模拟的客户端2.读取AOF保存的文本,还原数据为原命令和原参数。然后使用模拟的客户端发出这个命令请求。3.继续执行第二步,直到读取完AOF文件AOF需要将所有的命令都保存到磁盘,那么这个文件会随着时间变得越来越大。读取也会变得很慢。Redis提供了AOF的重写机制,帮助减少文件的大小。实现的思路是:最初保存到AOF文件的将会是四条指令。但经过AOF重写后,会变成一条指令:同时,考虑到为了在AOF重写时,不影响AOF的写入增加了AOF重写缓存的概念。也就是说Redis在开启AOF时,除了将命令格式数据写入到AOF文件,同时也会写入到AOF重写缓存。这样AOF的写入、重写就做到了隔离,保证了重写时不会阻塞写入。
c)AOF重写流程
1.AOF重写完成会向主进程发送一个完成的信号2.会将AOF重写缓存中的数据全部写入到文件中3.用新的AOF文件,覆盖原有的AOF文件。
d)AOF缺点
1.AOF文件通常会大于相同数据集的RDB文件2.AOF模式下性能与RDB模式下性能高低,主要取决于AOF选用的fsync模式
下面给出客户端请求RedisServer时,server端持久化的部分操作图解。
四、Redis数据库的实现
Redis是一个键值对数据库,称为键空间。实现这种KV形式的存储,Redis使用了两种数据结构类型:1、字典
Redis字典使用的是哈希表实现,原本不准备详细介绍Redis哈希表的实现。但发现Redis在实现哈希表时,
提供了一个很好的rehash方案,这个方案思路很好,甚至可以衍生到其他各个应用中使用,方案的名称叫“渐进式Rehash”。
实现哈希表的方法大同小异,但为何各个开源软件总是去开发自己独有的哈希数据结构呢?
从研究PHP内核的哈希实现与Redis哈希实现,发现应用场景决定了必须定制才能更好的发挥性能。(关于PHP哈希实现可以参看:PHP内核中的神器之HashTable)
a)PHP主要应用于WEB场景,在WEB场景针对单次请求数据之间是隔离的,并且哈希的数量是有限的,那么进行一次rehash也是很快的。
所以PHP内核使用阻塞形式rehash,即rehash进行中将不能对当前哈希表进行任何操作。
b)在来看Redis,常驻进程,接收客户端请求处理各项事务,并且操作的数据是相关且数据量较大的,如果使用PHP内核的那种方式就会出现:
对哈希表进行rehash时,此时将阻塞所有客户端请求,并发性能会大大下降。
Redis字典使用的是哈希表实现,原本不准备详细介绍Redis哈希表的实现。但发现Redis在实现哈希表时,
提供了一个很好的rehash方案,这个方案思路很好,甚至可以衍生到其他各个应用中使用,方案的名称叫“渐进式Rehash”。
实现哈希表的方法大同小异,但为何各个开源软件总是去开发自己独有的哈希数据结构呢?
从研究PHP内核的哈希实现与Redis哈希实现,发现应用场景决定了必须定制才能更好的发挥性能。(关于PHP哈希实现可以参看:PHP内核中的神器之HashTable)
a)PHP主要应用于WEB场景,在WEB场景针对单次请求数据之间是隔离的,并且哈希的数量是有限的,那么进行一次rehash也是很快的。
所以PHP内核使用阻塞形式rehash,即rehash进行中将不能对当前哈希表进行任何操作。
b)在来看Redis,常驻进程,接收客户端请求处理各项事务,并且操作的数据是相关且数据量较大的,如果使用PHP内核的那种方式就会出现:
对哈希表进行rehash时,此时将阻塞所有客户端请求,并发性能会大大下降。
初始化字典图解:
新增字典元素图解:
Rehash执行流程:
相关推荐
### Redis架构设计分析 #### 一、前言 在项目的实际应用中,Redis因其高性能、低延迟等特点成为了不可或缺的一部分。为了更好地理解和应用Redis,在合适的业务场景中发挥其最大效能,有必要深入了解Redis的设计与...
### Redis架构设计与实现 #### 一、内部数据结构 Redis 的内部数据结构是其能够高效存储和处理数据的关键所在。这些数据结构不仅为 Redis 提供了基础支持,还允许它实现了复杂的数据类型如字符串(String)、列表...
redis架构与设计.xmind
在构建一个基于SpringMVC、MongoDB和Redis的初步架构设计时,我们需要深入了解这三大技术以及它们如何协同工作。SpringMVC是Spring框架的一部分,主要用于处理Web应用的模型-视图-控制器(MVC)结构。MongoDB是一个...
综上所述,Redis的架构设计注重性能和数据安全的平衡。启动流程确保了服务的稳定启动,而数据持久化方案RDB和AOF则提供了灵活的备份和恢复策略。根据业务需求和对数据完整性的要求,可以选择适合的持久化策略,以...
因为近期项目中开始使用Redis,为了更好的理解Redis并应用在适合的业务场景,需要对Redis 设计与实现深入的理解。 我分析流程是按照从main进入,逐步深入分析Redis的启动流程。同时根据Redis初始化的流程,理解Redis...
因为近期项目中开始使用Redis,为了更好的理解Redis并应用在适合的业务场景,需要对Redis设计与实现深入的理解。 本文档分析流程是按照从main进入,逐步深入分析Redis的启动流程。同时根据Redis初始化的流程,理解...
同时,也会讲解如何在分布式系统中整合Redis,如在微服务架构中使用Redis进行服务发现和负载均衡。 除此之外,Redis还提供了事务(Transactions)、管道(Pipelining)和Lua脚本等高级特性,以增强其功能和灵活性。...
1. **写入端设计**:采用一级Twemproxy架构,一个Twemproxy实例管理多个Redis实例,写入数据通过一致性Hash算法(如fnv1a-64和ketama)分片到不同的Redis节点,确保数据的均匀分布。 2. **读取端设计**:为避免读取...
本文将详细介绍如何在基于ARM架构的银河麒麟桌面版操作系统上进行Redis 3+的离线安装。 **一、Redis简介** Redis是一款开源的、基于键值对的数据存储系统,它通常作为数据库、缓存和消息中间件使用。Redis 3+版本...
【高可用Redis服务架构设计】 Redis作为一种高性能的内存数据库,广泛应用于web开发中的session存储、热数据缓存、消息队列以及订阅发布系统等场景。然而,为了保证服务的稳定性和可靠性,构建高可用的Redis服务是...
Redis的架构原理包括内存模型和数据存储方式。内存模型方面,Redis提供了一些命令用于查看内存统计,例如`used_memory`显示Redis分配的总内存,`used_memory_rss`则表示Redis占用的实际物理内存。内存碎片比`mem_...
Redis是一种开源的高性能...而James老师作为资深系统架构师、项目经理,具备丰富的Java开发经验以及在高并发、高性能服务方面的深刻见解,他的课程能够从实际工程应用和架构设计的高度,为学员提供实战指导和经验分享。
阿里云Redis技术架构是针对企业级应用而设计的高性能、高可用的数据存储解决方案。该架构主要分为单机、集群、容灾和多活四种模式,分别适用于不同的业务场景。 单机模式适合对协议敏感且对性能有较高要求的场景,...
Java架构设计示例文档涉及的知识点众多,通常它旨在为读者提供一个关于如何设计高效、可扩展和可维护的Java应用架构的参考。文档可能包含以下几个核心部分:需求分析、系统设计、技术选型、模块划分、接口设计、安全...
本文深度剖析了Redis作为一种高效、灵活且广泛应用的日志型、内存持久化的Key-Value数据库的技术特点,涵盖其基础架构、数据类型、快速响应原因以及布隆过滤器等扩展技术,并详述了其在缓存、排名统计、数据记录、...
个人redis设计规范整理总结,简单易用。祝大家善于总结归纳,讲网上复杂的资料简单化