半消息:是指暂时还不能被 Consumer 消费的消息,Producer 成功发送到 Broker 端的消息,但是此消息被标记为 “暂不可投递” 状态,只有等 Producer 端执行完本地事务后经过二次确认了之后,Consumer 才能消费此条消息。 依赖半消息,可以实现分布式消息事务,其中的关键在于二次确认以及消息回查:1、Producer 向 broker 发送半消息 2、Producer
死信队列用于处理无法被正常消费的消息,即死信消息。 当一条消息初次消费失败,消息队列 RocketMQ 会自动进行消息重试;达到最大重试次数后,若消费依然失败,则表明消费者在正常情况下无法正确地消费该消息,此时,消息队列 RocketMQ 不会立刻将消息丢弃,而是将其发送到该消费者对应的特殊队列中,该特殊队列称为死信队列。 死信消息的特点: 不会再被消费者正常消费。 有效期与正常消息相同,均为 3
题目请实现两个函数,分别用来序列化和反序列化二叉树,不对序列化之后的字符串进行约束,但要求能够根据序列化之后的字符串重新构造出一棵与原二叉树相同的树。二叉树的序列化(Serialize)是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树等遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过
题目给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出如下图所示。题解//利用中序遍历,根节点在中间的特性,递归解决 public class Solution { /** * 给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重
在操作系统中,使用传统的方式,数据需要经历几次拷贝,还要经历用户态/内核态切换。1. 从磁盘复制数据到内核态内存; 2. 从内核态内存复制到用户态内存; 3. 然后从用户态内存复制到网络驱动的内核态内存; 4. 最后是从网络驱动的内核态内存复制到网卡中进行传输。 所以,可以通过零拷贝的方式,减少用户态与内核态的上下文切换和内存拷贝的次数,用来提升I/O的性能。零拷贝比较常见的实现方式是mmap,这
在RocketMQ中,Consumer端的两种消费模式(Push/Pull)都是基于拉模式来获取消息的,而在Push模式只是对pull模式的一种封装,其本质实现为消息拉取线程在从服务器拉取到一批消息后,然后提交到消息消费线程池后,又“马不停蹄”的继续向服务器再次尝试拉取消息。如果未拉取到消息,则延迟一下又继续拉取。在两种基于拉模式的消费方式(Push/Pull)中,均需要Consumer端知道从B
领导者Sentinel节点选举Sentinel节点之间会做一个领导者选举的工作,选出一个Sentinel节点作为领导者进行故障转移的工作。Redis使用了Raft算法实现领导者选举。故障转移领导者选举出的Sentinel节点负责故障转移,过程如下:1. 在从节点列表中选出一个节点作为新的主节点,这一步是相对复杂一些的一 步 2. Sentinel领导者节点会对第一步选出来的从节点执行slaveof
哨兵模式是通过哨兵节点完成对数据节点的监控、下线、故障转移。定时监控Redis Sentinel通过三个定时监控任务完成对各个节点发现和监控: 1. 每隔10秒,每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构 2. 每隔2秒,每个Sentinel节点会向Redis数据节点的sentinel :hello 频道上发送该Sentinel节点对于主节点的判断以及当前Sent
主从复制存在一个问题,没法完成自动故障转移。所以我们需要一个方案来完成自动故障转移,它就是Redis Sentinel(哨兵)。Redis Sentinel ,它由两部分组成,哨兵节点和数据节点: 哨兵节点: 哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的 Redis 节点,不存储数据,对数据节点进行监控。 数据节点: 主节点和从节点都是数据节点; 在复制的基础上,哨兵实现了 自动化的故障恢复
主从复制虽好,但也存在一些问题: 一旦主节点出现故障,需要手动将一个从节点晋升为主节点,同时需要修改应用方的主节点地址,还需要命令其他从节点去复制新的主节点,整个过程都需要人工干预。 主节点的写能力受到单机的限制。 主节点的存储能力受到单机的限制。 第一个问题是Redis的高可用问题,第二、三个问题属于Redis的分布式问题。
部分复制主要是Redis针对全量复制的过高开销做出的一种优化措施, 使用 psync{runId}{offset}命令实现。当从节点(slave)正在复制主节点 (master)时,如果出现网络闪断或者命令丢失等异常情况时,从节点会向 主节点要求补发丢失的命令数据,如果主节点的复制积压缓冲区内存在这部分数据则直接发送给从节点,这 样就可以保持主从节点复制的一致性。1. 当主从节点之间网络出现中断时
Redis在2.8及以上版本使用psync命令完成主从数据同步,同步过程分为:全量复制和部分复制。全量复制一般用于初次复制场景,Redis早期支持的复制功能只有全量复制,它会把主节点全部数据一次性发送给从节点,当数据量较大时,会对主从节点和网络造成很大的开销。全量复制的完整运行流程如下: 1. 发送psync命令进行数据同步,由于是第一次进行复制,从节点没有复制偏移量 和主节点的运行ID,所以发送
Redis主从复制的工作流程大概可以分为如下几步: 1. 保存主节点(master)信息 这一步只是保存主节点信息,保存主节点的ip和port。 2. 主从建立连接 从节点(slave)发现新的主节点后,会尝试和主节点建立网络连接。 3. 发送ping命令 连接建立成功后从节点发送ping请求进行首次通信,主要是检测主从之间网络套 接字是否可用、主节点当前是否可接受处理命令。 4. 权限验证 如果
Redis的复制拓扑结构可以支持单层或多层复制关系,根据拓扑复杂性可以分为以下三种:一主一从、一主多从、树状主从结构。 1.一主一从结构 一主一从结构是最简单的复制拓扑结构,用于主节点出现宕机时从节点提供故障转移支持。2.一主多从结构一主多从结构(又称为星形拓扑结构)使得应用端可以利用多个从节点实现读写分离(见图)。对于读占比较大的场景,可以把读命令发送到从节点来分担主节点压力。3.树状主从结构
主从复制,是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器。前者称为 主节点(master),后者称为 从节点(slave)。且数据的复制是 单向 的,只能由主节点到从节点。Redis 主从复制支持 主从同步 和 从从同步 两种,后者是 Redis 后续版本新增的功能,以减轻主节点的同步负担。主从复制主要的作用?数据冗余: 主从复制实现了数据的热备份,是持久化之外的一种数据冗
重启 Redis 时,我们很少使用 RDB 来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 RDB 来说要慢很多,这样在Redis 实例很大的情况下,启动需要花费很长的时间。 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。将rdb 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,
RDB和AOF如何选择一般来说, 如果想达到足以媲美数据库的 数据安全性,应该 同时使用两种持 久化功能。在这种情况下,当 Redis 重启的时候会优先载入 AOF 文件来恢复原始的数据,因为在通常情况下 AOF 文件保存的数据集要比 RDB 文件保存的数据集要完整。 如果 可以接受数分钟以内的数据丢失,那么可以 只使用 RDB 持久化。 有很多用户都只使用 AOF 持久化,但并不推荐这种方式,因
RDB | 优点1. 只有一个紧凑的二进制文件 dump.rdb ,非常适合备份、全量复制的场景。 2. 容灾性好,可以把RDB文件拷贝道远程机器或者文件系统张,用于容灾恢复。 3. 恢复速度快,RDB恢复数据的速度远远快于AOF的方式 RDB | 缺点1. 实时性低,RDB 是间隔一段时间进行持久化,没法做到实时持久化/秒级持久化。如果在这一间隔事件发生故障,数据会丢失。2. 存在兼容问题,Re
Redis持久化⽅案分为RDB和AOF两种。RDBRDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发。 RDB⽂件是⼀个压缩的⼆进制⽂件,通过它可以还原某个时刻数据库的状态。由于RDB⽂件是保存在硬盘上的,所以即使Redis崩溃或者退出,只要RDB⽂件存在,就可以⽤它来恢复还原数据库的状态。 手动触发分别对应save和bgsave命令:save命令:阻
Redis不是说用单线程的吗?怎么6.0成了多线程的? Redis6.0的多线程是用多线程来处理数据的读写和协议解析,但是Redis执行命令还是单线程的。这样做的⽬的是因为Redis的性能瓶颈在于⽹络IO⽽⾮CPU,使⽤多线程能提升IO读写的效率,从⽽整体提⾼Redis的性能。为什么命令执行为什么不采用多线程?使用多线程会提升复杂度,对于 redis 这种内存数据库,代价太高一般情况下,redis
官方的解释:官方FAQ表示,因为Redis是基于内存的操作,CPU成为Redis的瓶颈的情况很少见,Redis的瓶颈最有可能是内存的大小或者网络限制。 如果想要最大程度利用CPU,可以在一台机器上启动多个Redis实例。 PS:网上有这样的回答,吐槽官方的解释有些敷衍,其实就是历史原因,开发者嫌多线程麻烦,后来这个CPU的利用问题就被抛给了使用者。 同时FAQ里还提到了, Redis 4.0 之后
Redis为什么快呢?Redis的速度⾮常的快,单机的Redis就可以⽀撑每秒十几万的并发,相对于MySQL来说,性能是MySQL的⼏⼗倍。速度快的原因主要有⼏点: 1. 完全基于内存操作 2. 使⽤单线程,避免了线程切换和竞态产生的消耗 3. 基于⾮阻塞的IO多路复⽤机制 4. C语⾔实现,优化过的数据结构,基于⼏种基础的数据结构,redis做了⼤量的优化,性能极⾼能说一下I/O多路复用吗?第一
Redis有五种基本数据结构。 string字符串最基础的数据结构。字符串类型的值实际可以是字符串(简单的字符串、复 杂的字符串(例如JSON、XML))、数字 (整数、浮点数),甚至是二进制(图 片、音频、视频),但是值最大不能超过512MB。 字符串主要有以下几个典型使用场景: 缓存功能 计数 共享Session 限速hash哈希类型是指键值本身又是一个键值对结构。 哈希主要有以下典型应用场景
什么是RedisRedis是一种基于键值对(key-value)的NoSQL数据库。比一般键值对数据库强大的地方,Redis中的value支持string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、HyperLogLog、GEO(地理信息定位)等多种数据结构,因此Redis可以满足很多的应用场景。而且因为Redis会将所有的数据都放
排查过程:(1)使用 top 命令观察,确定是 mysqld 导致还是其他原因。 (2)如果是 mysqld 导致的,show processlist,查看 session 情况,确定是不是有消耗资源的 sql 在运行。 (3)找出消耗高的 sql,看看执行计划是否准确, 索引是否缺失,数据量是否太大。 处理:(1)kill 掉这些线程 (同时观察 cpu 使用率是否下降), (2)进行相应的调整
百万级别以上的数据如何删除?关于索引:由于索引需要额外的维护成本,因为索引文件是单独存在的文件,所以当我们对数据的增加,修改,删除,都会产生额外的对索引文件的操作,这些操作需要消耗额外的IO,会降低增/改/删的执行效率。 所以,在我们删除数据库百万级别数据的时候,查询MySQL官方手册得知删除数据的速度和创建的索引数量是成正比的。 1. 所以我们想要删除百万数据的时候可以先删除索引 2. 然后删除
一、分库1.1 事务的问题使用关系型数据库,有很大一点在于它保证事务完整性。而分库之后单机事务就用不上了,必须使用分布式事务来解决。1.2 跨库 JOIN 问题在一个库中的时候我们还可以利用 JOIN 来连表查询,而跨库了之后就无法使用JOIN 了。此时的解决方案就是在业务代码中进行关联,也就是先把一个表的数据查出来,然后通过得到的结果再去查另一张表,然后利用代码来关联得到最终的结果。这种方式实现
实际上,不停机扩容,实操起来是个非常麻烦而且很有风险的操作一、第一阶段:在线双写,查询走老库1. 建立好新的库表结构,数据写入久库的同时,也写入拆分的新库 2. 数据迁移,使用数据迁移程序,将旧库中的历史数据迁移到新库 3. 使用定时任务,新旧库的数据对比,把差异补齐二、在线双写,查询走新库1. 完成了历史数据的同步和校验 2. 把对数据的读切换到新库 三、第三阶段:旧库下线旧库不再写入新的数据经
什么是路由?就是数据应该分到哪一张表。水平分表主要有三种路由方式:1、范围路由选取有序的数据列(例如:整形、时间戳等)作为路由的条件。不同分段分散到不同的数据库表中。我们可以观察一些支付系统,发现只能查一年范围内的支付记录,这个可能就是支付公司按照时间进行了分表。范围路由设计的复杂点主要体现在分段大小的选取上,分段太小会导致切分后子表数量过多,增加维护复杂度;分段太大可能会导致单表依然存在性能问题
一、怎么分库垂直分库以表为依据,按照业务归属不同,将不同的表拆分到不同的库中。水平分库以字段为依据,按照一定策略(hash、range 等),将一个库中的数据拆分到多个库中。二、怎么分表水平分表:以字段为依据,按照一定策略(hash、range 等),将一个表中的数据拆分到多个表中。 垂直分表:以字段为依据,按照字段的活跃性,将表中字段拆到不同的表(主表和扩展表)中。
Copyright © 2005-2024 51CTO.COM 版权所有 京ICP证060544号