RocketMQ 消息可靠性原理深度解析
RocketMQ 消息可靠原理一、链路上的可靠性保障1. 消息持久化基础介绍分布式队列因为有高可靠性的要求,所以数据要进行持久化存储。 MQ收到一条消息后,需要向生产者返回一个ACK响应,并将消息存储起来。(告诉生产者已经将消息进行存储) MQ Push一条消息给消费者后,等待消费者的ACK响应,需要将消息标记为已消费。如果没有标记为已消费,MQ会不断的尝试往消费者推送这条消息。 MQ需要定期删除一些过期的消息,这样才能保证服务一直可用。 RocketMQ采用直接用磁盘文件来保存消息,而不需要借助MySQL这一类索引工具。rocketmq默认文件–commitLog。 abort文件: 这个文件是RocketMQ用来判断程序是否正常关闭的一个标识文件。正常情况下,会在启动时创建,而关闭服务时删除。但是如果遇到一些服务器宕机,或者kill -9这样一些非正常关闭服务的情况,这个abort文件就不会删除,因此RocketMQ就可以判断上一次服务是非正常关闭的,后续就会做一些数据恢复的操作。 CommitLogCommitLog:存储消息的元数据。所有消息都会顺序存入到Commit...
RocketMQ 架构设计深度解析
RocketMQ 架构设计一、基础架构RocketMQ主要由NameServer、Broker、Producer以及Consumer四部分构成。 1. NameServer主要负责对于源数据的管理,包括了对于Topic和路由信息的管理。NameServer是一个功能齐全的服务器,其角色类似Dubbo中的Zookeeper,但NameServer与Zookeeper相比更轻量。主要是因为每个NameServer节点互相之间是独立的,没有任何信息交互。也就是去中心化,NameServer 之间不通信。 2. Producer消息生产者,负责产生消息,一般由业务系统负责产生消息。Producer 由用户进行分布式部署,消息由Producer通过多种负载均衡模式发送到Broker集群路由解耦,发送低延时,支持快速失败。 3. Broker消息中转角色,负责存储消息,转发消息。Broker是具体提供业务的服务器,单个Broker节点与所有的NameServer节点保持长连接及心跳,并会定时将Topic信息注册到NameServer,也就是服务注册,顺带一提底层的通信和连接都是基于Netty...
Redis 其他知识点汇总
Redis 其他知识点一、事务(待补充内容) 二、多线程2.1 多线程 I/O 的引入因为 Redis 的性能瓶颈有时会出现在网络 I/O 的处理上,为了提高网络 I/O 的并行度,采用多个 I/O 线程来处理网络请求。但是对于命令的执行,Redis 仍然使用单线程来处理,引入了多线程 I/O 之后,Redis 的性能至少提升了一倍以上。 2.2 多线程配置不过默认的多线程 I/O 只针对发送响应数据(write client socket),并不会以多线程的方式去处理读请求(read client socket)。 若要开启多线程处理客户端读请求,就需要把 Redis.conf 配置文件中的 io-threads-do-reads 配置项设为 yes,当然还有 IO 多线程个数的配置项。 注意: 主线程也算是一个 I/O 线程。 1io-threads N 2.3 线程模型在 Redis 6.0 版本之后,Redis 在启动的时候,默认会额外创建 4 个 IO 线程。 Redis-server 是 Red...
Redis 缓存应用深度解析
Redis 缓存一、淘汰策略1.1 基本介绍Redis 4.0 之前一共实现了 6 种内存淘汰策略,在 4.0 之后,又增加了 2 种策略。我们可以按照是否会进行数据淘汰把它们分成两类: 不进行数据淘汰的策略:只有 noeviction 这一种 会进行淘汰的 7 种其他策略 会进行淘汰的 7 种策略,我们可以再进一步根据淘汰候选数据集的范围把它们分成两类: 在设置了过期时间的数据中进行淘汰:包括 volatile-random、volatile-ttl、volatile-lru、volatile-lfu(Redis 4.0 后新增)四种 在所有数据范围内进行淘汰:包括 allkeys-lru、allkeys-random、allkeys-lfu(Redis 4.0 后新增)三种 默认情况下,Redis 在使用的内存空间超过 maxmemory 值时,并不会淘汰数据,也就是设定的 noeviction 策略。对应到 Redis 缓存,也就是指,一旦缓存被写满了,再有写请求来时,Redis 不再提供服务,而是直接返回错误。Redis 用作缓存时,实际的数据集通常都是大于缓存容...
Redis 并发控制深度解析
Redis 并发控制一、原子操作为了实现并发控制要求的临界区代码互斥执行,Redis 的原子操作采用了两种方法: 把多个操作在 Redis 中实现成一个操作,也就是单命令操作 把多个操作写到一个 Lua 脚本中,以原子性方式执行单个 Lua 脚本 1.1 单命令操作Redis 是使用单线程来串行处理客户端的请求操作命令的,所以,当 Redis 执行某个命令操作时,其他命令是无法执行的,这相当于命令操作是互斥执行的。当然,Redis 的快照生成、AOF 重写这些操作,可以使用后台线程或者是子进程执行,也就是和主线程的操作并行执行。不过,这些操作只是读取数据,不会修改数据,所以,我们并不需要对它们做并发控制。 虽然 Redis 的单个命令操作可以原子性地执行,但是在实际应用中,数据修改时可能包含多个操作,至少包括读数据、数据增减、写回数据三个操作,这显然就不是单个命令操作了。Redis 提供了 INCR/DECR 命令,把这三个操作转变为一个原子操作。INCR/DECR 命令可以对数据进行增值/减值操作,而且它们本身就是单个命令操作,Redis 在执行它们时,本身就具有...
Redis 持久化策略深度解析
Redis 持久化策略一、AOF(Append Only File)1.1 AOF 的写后日志机制说到日志,我们比较熟悉的是数据库的写前日志(Write Ahead Log, WAL),也就是说,在实际写数据前,先把修改的数据记到日志文件中,以便故障时进行恢复。不过,AOF 日志正好相反,它是写后日志,”写后”的意思是 Redis 是先执行命令,把数据写入内存,然后才记录日志。 1.1.1 为什么采用写后日志为了避免额外的检查开销,Redis 在向 AOF 里面记录日志的时候,并不会先去对这些命令进行语法检查。所以,如果先记日志再执行命令的话,日志中就有可能记录了错误的命令,Redis 在使用日志恢复数据时,就可能会出错。 而写后日志这种方式,就是先让系统执行命令,只有命令能执行成功,才会被记录到日志中,否则,系统就会直接向客户端报错。所以,Redis 使用写后日志这一方式的一大好处是,可以避免出现记录错误命令的情况。 除此之外,AOF 还有一个好处:它是在命令执行后才记录日志,所以不会阻塞当前的写操作。 1.1.2 AOF 的潜在风险AOF 也有两个潜在的风险: 风险一:数据丢...
Redis 高可用方案深度解析
Redis 高可用一、主从复制1.1 主从复制概述主从复制是 Redis 高可用服务最基础的保证,实现方案就选择一个服务器作为 master,其他的服务器作为 slaver,一主多从,读写分离。这里注意一下,主从服务器之间的命令复制是异步进行的,不会等到从服务器都同步完才向客户端返回结果。所以,无法实现强一致性(数据时时刻刻都是一致的),只能达到最终一致性。 实际上,Redis 提供了主从库模式,以保证数据副本的一致,主从库之间采用的是读写分离的方式: 读操作:主库、从库都可以接收 写操作:首先到主库执行,然后,主库将写操作同步给从库 1.2 主从库第一次同步先来看看主从库间的第一次同步是如何进行的,这也是 Redis 实例建立主从库模式后的规定动作。当我们启动多个 Redis 实例的时候,它们相互之间就可以通过 replicaof(Redis 5.0 之前使用 slaveof)命令形成主库和从库的关系,之后会按照三个阶段完成数据的第一次同步。 例如,现在有实例 1(ip:172.16.19.3)和实例 2(ip:172.16.19.5),我们在实例 2 上执行以下这个命令:...
Redis 核心数据结构深度解析
Redis 核心数据结构一、全局 Hash 表1.1 全局 Hash 表概述为了实现从键到值的快速访问,Redis 使用了一个哈希表来保存所有键值对。一个哈希表,其实就是一个数组,数组的每个元素称为一个哈希桶。所以,我们常说,一个哈希表是由多个哈希桶组成的,每个哈希桶中保存了键值对数据。 如果值是集合类型的话,作为数组元素的哈希桶怎么来保存呢?其实,哈希桶中的元素保存的并不是值本身,而是指向具体值的指针。这也就是说,不管值是 String,还是集合类型,哈希桶中的元素都是指向它们的指针。 可以看到,哈希桶中的 entry 元素中保存了 *key 和 *value 指针,分别指向了实际的键和值,这样一来,即使值是一个集合,也可以通过 *value 指针被查找到。 因为这个哈希表保存了所有的键值对,所以,我也把它称为全局哈希表。哈希表的最大好处很明显,就是让我们可以用 O(1) 的时间复杂度来快速查找到键值对——我们只需要计算键的哈希值,就可以知道它所对应的哈希桶位置,然后就可以访问相应的 entry 元素。 你看,这个查找过程主要依赖于哈希计算,和数据量的多少并没有直接关系。也就是...
MySQL 事务深度解析
MySQL 事务深度解析一、事务 ACID1.1 简单介绍原子性(Atomicity) 也就是说这一串指令要么全部成功 要么全部失败 这点通过 begin 事务 commit 提交 rollback 回滚实现 其实就是 undo log 实现的 一致性(Consistency) 事务操作前后,数据满足一致性的约束,不会出现中间数据的情况 通过锁来实现,是在其他三个性质之上保证的 隔离性(Isolation) 多个事务执行时不会互相干扰 通过 MVCC 机制实现的 持久性(Durability) 事务处理之后,是要落盘的,而且即使系统故障数据也不会丢失 这点通过 log 日志实现 而且还是 redo log 1.2 总结 原子性通过 Undo Log 实现,保证事务要么全部成功要么全部回滚 隔离性通过 MVCC 和锁机制实现,保证并发事务互不干扰 持久性通过 Redo Log 和 WAL 机制保证,确保事务提交后即使宕机也不会丢失 一致性是事务执行前后数据库满足业务和约束规则的最终状态,它依赖于原子性、隔离性、持久性以及应用层的正确逻辑共同保证 二、SQL 的隔...
MySQL SQL 优化深度解析
MySQL SQL 优化一、执行流程1.1 SELECT 语句内部的执行步骤一条完整的 SELECT 语句内部的执行顺序是这样的: FROM 子句组装数据(包括通过 ON 进行连接) WHERE 子句进行条件筛选 GROUP BY 分组 使用聚集函数进行计算 HAVING 筛选分组 计算所有的表达式 SELECT 的字段 ORDER BY 排序 LIMIT 筛选 二、关键字的底层实现2.1 JOIN 的实现方式2.1.1 Index Nested-Loop Join(索引嵌套循环连接)(待补充内容) 优化方式: MRR(Multi-Range Read)优化 (待补充内容) 2.1.2 Simple Nested-Loop Join(简单嵌套循环连接)(待补充内容) 2.1.3 Block Nested-Loop Join(块嵌套循环连接)(待补充内容) 优化方式: (待补充内容) 2.1.4 Hash Join(哈希连接)(待补充内容) 2.2 ORDER BY 的实现方式2.2.1 全字段排序(待补充内容) 2.2.2 rowid 排序(待补充内容) 2.2...