源码分析 RocketMQ DLedger 多副本即主从切换实现原理

11 RocketMQ主从原理、读写分离与故障转移 前面已经了解过的内容如下: 集群中的每个Master Broker只存储一部分消息,通过主从保证高可用; 所有Brokerdou 阅读详情

原文:https://juejin.im/post/5db837186fb9a0204c5c36bb

DLedger 基于 raft 协议,故天然支持主从切换,即主节点(Leader)发生故障,会重新触发选主,在集群内再选举出新的主节点。

RocketMQ 中主从同步,从节点不仅会从主节点同步数据,也会同步元数据,包含 topic 路由信息、消费进度、延迟队列处理队列、消费组订阅配置等信息。那主从切换后元数据如何同步呢?特别是主从切换过程中,对消息消费有多大的影响,会丢失消息吗?

温馨提示:本文假设大家已经对 RocketMQ4.5 版本之前的主从同步实现有一定的了解,这部分内容在《RocketMQ技术内幕》一书中有详细的介绍,大家也可以参考如下两篇文章: 1、 RocketMQ HA机制(主从同步) 。 2、RocketMQ 整合 DLedger(多副本)即主从切换实现平滑升级的设计技巧

1、BrokerController 中与主从相关的方法详解

本节先对 BrokerController 中与主从切换相关的方法。

1.1 startProcessorByHa

BrokerController#startProcessorByHa

private void startProcessorByHa(BrokerRole role) {
    if (BrokerRole.SLAVE != role) {
        if (this.transactionalMessageCheckService != null) {
            this.transactionalMessageCheckService.start();
        }
    }
}
复制代码

感觉该方法的取名较为随意,该方法的作用是开启事务状态回查处理器,即当节点为主节点时,开启对应的事务状态回查处理器,对PREPARE状态的消息发起事务状态回查请求。

1.2 shutdownProcessorByHa

BrokerController#shutdownProcessorByHa

private void shutdownProcessorByHa() {
    if (this.transactionalMessageCheckService != null) {
        this.transactionalMessageCheckService.shutdown(true);
    }
}
复制代码

关闭事务状态回查处理器,当节点从主节点变更为从节点后,该方法被调用。

1.3 handleSlaveSynchronize

BrokerController#handleSlaveSynchronize

private void handleSlaveSynchronize(BrokerRole role) {
    if (role == BrokerRole.SLAVE) {   // @1
        if (null != slaveSyncFuture) {   
            slaveSyncFuture.cancel(false);
        }
        this.slaveSynchronize.setMasterAddr(null);   // 
        slaveSyncFuture = this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try {
                    BrokerController.this.slaveSynchronize.syncAll();
                } catch (Throwable e) {
                    log.error("ScheduledTask SlaveSynchronize syncAll error.", e);
                }
            }
        }, 1000 * 3, 1000 * 10, TimeUnit.MILLISECONDS);
    } else {  // @2
        //handle the slave synchronise
        if (null != slaveSyncFuture) {
            slaveSyncFuture.cancel(false);
        }
        this.slaveSynchronize.setMasterAddr(null);
    }
}
复制代码

该方法的主要作用是处理从节点的元数据同步,即从节点向主节点主动同步 topic 的路由信息、消费进度、延迟队列处理队列、消费组订阅配置等信息。

代码@1:如果当前节点的角色为从节点:

  • 如果上次同步的 future 不为空,则首先先取消。
  • 然后设置 slaveSynchronize 的 master 地址为空。不知大家是否与笔者一样,有一个疑问,从节点的时候,如果将 master 地址设置为空,那如何同步元数据,那这个值会在什么时候设置呢?
  • 开启定时同步任务,每 10s 从主节点同步一次元数据。

代码@2:如果当前节点的角色为主节点,则取消定时同步任务并设置 master 的地址为空。

1.4 changeToSlave

BrokerController#changeToSlave

public void changeToSlave(int brokerId) {
    log.info("Begin to change to slave brokerName={} brokerId={}", brokerConfig.getBrokerName(), brokerId);
    //change the role
    brokerConfig.setBrokerId(brokerId == 0 ? 1 : brokerId); //TO DO check       // @1
    messageStoreConfig.setBrokerRole(BrokerRole.SLAVE);                            // @2
    //handle the scheduled service
    try {
        this.messageStore.handleScheduleMessageService(BrokerRole.SLAVE);    //  @3
    } catch (Throwable t) {
        log.error("[MONITOR] handleScheduleMessageService failed when changing to slave", t);
    }
    //handle the transactional service
    try {
        this.shutdownProcessorByHa();                                                                    //  @4
    } catch (Throwable t) {
        log.error("[MONITOR] shutdownProcessorByHa failed when changing to slave", t);
    }
    //handle the slave synchronise
    handleSlaveSynchronize(BrokerRole.SLAVE);                                               // @5
    try {
        this.registerBrokerAll(true, true, brokerConfig.isForceRegister());              // @6
    } catch (Throwable ignored) {
    }
    log.info("Finish to change to slave brokerName={} brokerId={}", brokerConfig.getBrokerName(), brokerId);
}
复制代码

Broker 状态变更为从节点。其关键实现如下:

  • 设置 brokerId,如果broker的id为0,则设置为1,这里在使用的时候,注意规划好集群内节点的 brokerId。
  • 设置 broker 的状态为 BrokerRole.SLAVE。
  • 如果是从节点,则关闭定时调度线程(处理 RocketMQ 延迟队列),如果是主节点,则启动该线程。
  • 关闭事务状态回查处理器。
  • 从节点需要启动元数据同步处理器,即启动 SlaveSynchronize 定时从主服务器同步元数据。
  • 立即向集群内所有的 nameserver 告知 broker 信息状态的变更。

1.5 changeToMaster

BrokerController#changeToMaster

public void changeToMaster(BrokerRole role) {
    if (role == BrokerRole.SLAVE) {
        return;
    }
    log.info("Begin to change to master brokerName={}", brokerConfig.getBrokerName());
    //handle the slave synchronise
    handleSlaveSynchronize(role);   // @1
    //handle the scheduled service
    try {
        this.messageStore.handleScheduleMessageService(role);      // @2
    } catch (Throwable t) {
        log.error("[MONITOR] handleScheduleMessageService failed when changing to master", t);
    }
    //handle the transactional service
    try {
        this.startProcessorByHa(BrokerRole.SYNC_MASTER);         // @3
    } catch (Throwable t) {
        log.error("[MONITOR] startProcessorByHa failed when changing to master", t);
    }
    //if the operations above are totally successful, we change to master
    brokerConfig.setBrokerId(0); //TO DO check                              // @4
    messageStoreConfig.setBrokerRole(role);                               
    try {
        this.registerBrokerAll(true, true, brokerConfig.isForceRegister()); // @5
    } catch (Throwable ignored) {
    }
    log.info("Finish to change to master brokerName={}", brokerConfig.getBrokerName());
}
复制代码

该方法是 Broker 角色从从节点变更为主节点的处理逻辑,其实现要点如下:

  • 关闭元数据同步器,因为主节点无需同步。
  • 开启定时任务处理线程。
  • 开启事务状态回查处理线程。
  • 设置 brokerId 为 0。
  • 向 nameserver 立即发送心跳包以便告知 broker 服务器当前最新的状态。

主从节点状态变更的核心方法就介绍到这里了,接下来看看如何触发主从切换。

2、如何触发主从切换

从前面的文章我们可以得知,RocketMQ DLedger 是基于 raft 协议实现的,在该协议中就实现了主节点的选举与主节点失效后集群会自动进行重新选举,经过协商投票产生新的主节点,从而实现高可用。

BrokerController#initialize

if (messageStoreConfig.isEnableDLegerCommitLog()) {
    DLedgerRoleChangeHandler roleChangeHandler = new DLedgerRoleChangeHandler(this, (DefaultMessageStore) messageStore);
    ((DLedgerCommitLog)((DefaultMessageStore) messageStore).getCommitLog()).getdLedgerServer().getdLedgerLeaderElector().addRoleChangeHandler(roleChangeHandler);
}
复制代码

上述代码片段截取自 BrokerController 的 initialize 方法,我们可以得知在 Broker 启动时,如果开启了 多副本机制,即 enableDLedgerCommitLog 参数设置为 true,会为 集群节点选主器添加 roleChangeHandler 事件处理器,即节点发送变更后的事件处理器。

接下来我们将重点探讨 DLedgerRoleChangeHandler 。

2.1 类图

在这里插入图片描述

DLedgerRoleChangeHandler 继承自 RoleChangeHandler,即节点状态发生变更后的事件处理器。上述的属性都很简单,在这里就重点介绍一下 ExecutorService executorService,事件处理线程池,但只会开启一个线程,故事件将一个一个按顺序执行。

接下来我们来重点看一下 handle 方法的执行。

2.2 handle 主从状态切换处理逻辑

DLedgerRoleChangeHandler#handle

public void handle(long term, MemberState.Role role) {
    Runnable runnable = new Runnable() {
        public void run() {
            long start = System.currentTimeMillis();
            try {
                boolean succ = true;
                log.info("Begin handling broker role change term={} role={} currStoreRole={}", term, role, messageStore.getMessageStoreConfig().getBrokerRole());
                switch (role) {
                    case CANDIDATE:    // @1
                        if (messageStore.getMessageStoreConfig().getBrokerRole() != BrokerRole.SLAVE) {
                            brokerController.changeToSlave(dLedgerCommitLog.getId());
                        }
                        break;
                    case FOLLOWER:         // @2
                        brokerController.changeToSlave(dLedgerCommitLog.getId());
                        break;
                    case LEADER:           // @3
                        while (true) {
                            if (!dLegerServer.getMemberState().isLeader()) {
                                succ = false;
                                break;
                            }
                            if (dLegerServer.getdLedgerStore().getLedgerEndIndex() == -1) {
                                break;
                            }
                            if (dLegerServer.getdLedgerStore().getLedgerEndIndex() == dLegerServer.getdLedgerStore().getCommittedIndex()
                                && messageStore.dispatchBehindBytes() == 0) {
                                break;
                            }
                            Thread.sleep(100);
                        }
                        if (succ) {
                            messageStore.recoverTopicQueueTable();
                            brokerController.changeToMaster(BrokerRole.SYNC_MASTER);
                        }
                        break;
                    default:
                        break;
                }
                log.info("Finish handling broker role change succ={} term={} role={} currStoreRole={} cost={}", succ, term, role, messageStore.getMessageStoreConfig().getBrokerRole(), DLedgerUtils.elapsed(start));
            } catch (Throwable t) {
                log.info("[MONITOR]Failed handling broker role change term={} role={} currStoreRole={} cost={}", term, role, messageStore.getMessageStoreConfig().getBrokerRole(), DLedgerUtils.elapsed(start), t);
            }
        }
    };
    executorService.submit(runnable);
}
复制代码

代码@1:如果当前节点状态机状态为 CANDIDATE,表示正在发起 Leader 节点,如果该服务器的角色不是 SLAVE 的话,需要将状态切换为 SLAVE。

代码@2:如果当前节点状态机状态为 FOLLOWER,broker 节点将转换为 从节点。

代码@3:如果当前节点状态机状态为 Leader,说明该节点被选举为 Leader,在切换到 Master 节点之前,首先需要等待当前节点追加的数据都已经被提交后才可以将状态变更为 Master,其关键实现如下:

  • 如果 ledgerEndIndex 为 -1,表示当前节点还未又数据转发,直接跳出循环,无需等待。
  • 如果 ledgerEndIndex 不为 -1 ,则必须等待数据都已提交,即 ledgerEndIndex 与 committedIndex 相等。
  • 并且需要等待 commitlog 日志全部已转发到 consumequeue中,即 ReputMessageService 中的 reputFromOffset 与 commitlog 的 maxOffset 相等。

等待上述条件满足后,即可以进行状态的变更,需要恢复 ConsumeQueue,维护每一个 queue 对应的 maxOffset,然后将 broker 角色转变为 master。

经过上面的步骤,就能实时完成 broker 主节点的自动切换。由于单从代码的角度来看主从切换不够直观,下面我将给出主从切换的流程图。

2.3 主从切换流程图

由于从源码的角度或许不够直观,故本节给出其流程图。

温馨提示:该流程图的前半部分在 源码分析 RocketMQ 整合 DLedger(多副本)实现平滑升级的设计技巧 该文中有所阐述。

在这里插入图片描述

3、主从切换若干问题思考

我相信经过上面的讲解,大家应该对主从切换的实现原理有了一个比较清晰的理解,我更相信读者朋友们会抛出一个疑问,主从切换会不会丢失消息,消息消费进度是否会丢失而导致重复消费呢?

3.1 消息消费进度是否存在丢失风险

首先,由于 RocketMQ 元数据,当然也包含消息消费进度的同步是采用的从服务器定时向主服务器拉取进行更新,存在时延,引入 DLedger 机制,也并不保证其一致性,DLedger 只保证 commitlog 文件的一致性。

当主节点宕机后,各个从节点并不会完成同步了消息消费进度,于此同时,消息消费继续,此时消费者会继续从从节点拉取消息进行消费,但汇报的从节点并不一定会成为新的主节点,故消费进度在 broker 端存在丢失的可能性。当然并不是一定会丢失,因为消息消费端只要不重启,消息消费进度会存储在内存中。

综合所述,消息消费进度在 broker 端会有丢失的可能性,存在重复消费的可能性,不过问题不大,因为 RocketMQ 本身也不承若不会重复消费。

3.2 消息是否存在丢失风险

消息会不会丢失的关键在于,日志复制进度较慢的从节点是否可以被选举为主节点,如果在一个集群中,从节点的复制进度落后与从主节点,但当主节点宕机后,如果该从节点被选举成为新的主节点,那这将是一个灾难,将会丢失数据。关于一个节点是否给另外一个节点投赞成票的逻辑在 源码分析 RocketMQ DLedger 多副本之 Leader 选主 的 2.4.2 handleVote 方法中已详细介绍,在这里我以截图的方式再展示其核心点:

在这里插入图片描述

在这里插入图片描述

从上面可以得知,如果发起投票节点的复制进度比自己小的话,会投拒绝票。其

在这里插入图片描述

在这里插入图片描述

必须得到集群内超过半数节点认可,即最终选举出来的主节点的当前复制进度一定是比绝大多数的从节点要大,并且也会等于承偌给客户端的已提交偏移量。故得出的结论是不会丢消息。

本文的介绍就到此为止了,最后抛出一个思考题与大家相互交流学习,也算是对 DLedger 多副本即主从切换一个总结回顾。答案我会以留言的方式或在下一篇文章中给出。

4、思考题

例如一个集群内有5个节点的 DLedgr 集群。 Leader Node: n0-broker-a folloer Node: n1-broker-a,n2-broker-a,n3-broker-a,n4-broker-a

从节点的复制进度可能不一致,例如: n1-broker-a复制进度为 100 n2-broker-a复制进度为 120 n3-broker-a复制进度为 90 n4-broker-a负载进度为 90

如果此时 n0-broker-a 节点宕机,触发选主,如果 n1率先发起投票,由于 n1,的复制进度大于 n3,n4,再加上自己一票,是有可能成为leader的,此时消息会丢失吗?为什么?

欢迎大家以留言的方式进行交流,也可以加我微信号 dingwpmz 与我进行探讨,最后如果这篇文章对大家有所帮助的话,麻烦点个赞,谢谢大家。


作者:中间件兴趣圈
链接:https://juejin.im/post/5db837186fb9a0204c5c36bb
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

rocketmq原理源码分析之dledger控制器模式-原理分析 RocketMQ 4.5 版本之前,RocketMQ 的broker是 Master/Slave部署架构,一组 broker 有一个 Master ,有0到若干Slave,Slave复制Master消息存储,随时替代下线的Master。Master/Slave部署架构提供一定的高可用性,但这样的部署架构,主节点下线需要手动进行重启或者手动切换,需要一个新的多副本架构,支持自动切换,解决方案基本可以分为两种:rocketmq选择 raft,目前有 dledger和jraft两个实现,本文分析dledger控制 阅读详情

相关推荐

【RocketMQ】【源码】DLedger选主源码分析

RocketMQ 4.5版本之前,可以采用主从架构进行集群部署,但是如果master节点挂掉,不能自动在集群中选举出新的Master节点,需要人工介入,在4.5版本之后提供了DLedger模式,使用Raft算法,如果Master节点出现故障,可以自动选举出新的Master进行切换。Raft是分布式系统中的一种共识算法,用于在集群中选举Leader管理集群。Raft协议中有以下角色:Leader(领导者):集群中的领导者,负责管理集群。

S-H_A-N 638

RocketMQ主从切换原理总结及源码解析

RocketMQ主从切换及恢复的源码解析及总结

点滴之积 2876

RocketMQ5.0主备自动切换模式Broker选主详解

RocketMQ5.0增加了主备自动切换模式,这个模式是基于新开发的模块DLedger Controller(基于Raft组件DLedger)。下面结合源码来分析一下RocketMQ主备自动切换模式下的选主的流程。转存失败重新上传取消Broker的选主发起主要有三种情况:通过admin命令人为主动发起重新选主命令发起具体参照 命令(运维命令由笔者开发完成),详细使用参照命令的说明RocketMQ集群刚搭建Broker启动注册Broker到DLedger Controller,DLedger Control

m0_71777195的博客 2455

从RocketMQ的Broker源码层面验证一下这两个点

本篇博客会从源码层面,验证在RocketMQ基础概念剖析,并分析一下Producer的底层源码中提到的结论,分别是: Broker在启动时,会将自己注册到所有的NameServer上 Broker在启动之后,会每隔30S向NameServer发送心跳 之前的文章中,我们知道了RocketMQ中的一些核心概念,例如Broker、NameServer、Topic和Tag等等。Producer从启动到发送消息的整个过程,从源码级别分析了Producer在发送消息到Broker的时候,是如何拿到Broker.

SH的全栈笔记 366

RocketMQ 多副本前置篇:深入了解 Raft 协议与 Java 基础知识图谱

日志复制(Log Replication):领导者接收到客户端的请求后,将该请求追加到自己的日志中,并向其他节点发送日志追加请求。其他节点在收到日志追加请求后,将该日志追加到自己的日志中,并向领导者发送追加成功的响应。Raft 协议的核心是通过选举机制选出一个唯一的领导者,领导者负责接收客户端请求并复制日志到其他节点。此外,为了确保系统的可靠性和性能,建议使用成熟的分布式系统框架或库来实现 Raft 协议,而不是自行编写。方法中,我们创建了一个节点对象,并按照选举、接收选票和日志复制的顺序调用相应的方法。

IiProlog的博客 294

RocketMQ - Broker的主从架构原理是什么

这个时候就对消息的写入和获取都有一定的影响了,但是其实本质上而言,Slave Broker也是跟Master Broker一样有一份数据在的,只不过Slave Broker上的数据可能有部分没来得及从Master Broker同步,但是此时RocketMQ可以实现直接自动将Slave Broker切换成Master Broker吗?因为消息写入全部是发送到Master Broker的,然后消息获取也可以从Master Broker获取,只不过有一些消息获取可能从Slave Broker去获取。

yang的博客 447

主从切换_源码分析 RocketMQ DLedger 多副本即主从切换实现原理

DLedger 基于 raft 协议,故天然支持主从切换,即主节点(Leader)发生故障,会重新触发选主,在集群内再选举出新的主节点。RocketMQ 中主从同步,从节点不仅会从主节点同步数据,也会同步元数据,包含 topic 路由信息、消费进度、延迟队列处理队列、消费组订阅配置等信息。那主从切换后元数据如何同步呢?特别是主从切换过程中,对消息消费有多大的影响,会丢失消息吗?温馨提示:...

weixin_34911749的博客 422

【Qt】Qt5.15在线安装避坑指南:从代理配置到组件选择的完整实践

本文详细介绍了Qt5.15在线安装的全流程避坑指南,包括代理配置、组件选择和常见问题解决方案。通过使用Fiddler工具和国内镜像源,可显著提升下载速度。文章还提供了组件选择的黄金法则和安装后的验证步骤,帮助开发者高效完成Qt5.15的安装与配置。

weixin_42550052的博客 270

源码分析 RocketMQ DLedger 多副本即主从切换实现原理,java开发数据库面试题

1、BrokerController 中与主从相关的方法详解 本节先对 BrokerController 中与主从切换相关的方法。 1.1 startProcessorByHa BrokerController#startProcessorByHa private void startProcessorByHa(BrokerRole role) { if (BrokerRole.SLAVE != role) { if (this.transactionalMessageCheckService != nu

m0_65485530的博客 469

ray.tune调参学习笔记0:调参基本流程

本篇总结python中使用tune调参的整体流程

Mr_111000的专栏 2622

用MSBlock重塑C2f,让你的模型又轻又强(参数量与精度的双重突破)

打开确保模型解析器能识别MSBlock模块。通过将MSBlock集成到YOLOv8的C2f模块中,我们实现了一个“轻量且多尺度感知”的目标检测模型。这个改进不仅在工程上能降低部署成本、提升推理速度,更在科研上提供了“多尺度+动态核”的创新思路——这种思路可以延伸到其他网络(如ResNet、MobileNet)的改进中,帮你在论文中打造独特的研究点。如果你在实现过程中遇到问题,比如代码报错、训练收敛异常,可以先检查模块集成的每一步是否到位,再尝试调整MSBlock的卷积核尺寸、动态权重的计算方式等超参数。

m0_71589036的博客 105

源码阅读技巧篇:RocketMQ DLedger 多副本即主从切换专栏回顾

源码阅读技巧篇,以笔者从零开始学习 rocketmq dledger 多副本即主从切换为例,展示笔者的阅读源码的方法。

中间件兴趣圈 1589

Windows11 - Ubuntu 双系统及 ROS、ROS2 安装

在本教程中,我们将使用 Ubuntu 20.04 版本,该版本使用了新的 Ubuntu 桌面安装程序,该程序将包含在今后发布的所有 Ubuntu 版本中。如果你选择了这个选项,你会看到一个简单的界面,允许你选择要安装Ubuntu的硬盘,并通过滑块来决定你希望Ubuntu使用的磁盘空间大小。如果你的电脑有多个硬盘驱动器,那么只要它们各自有自己的驱动器,这个选项就能让你在安装 Ubuntu 的同时安装现有的操作系统。在此屏幕上,系统会提示您输入您的姓名和您的计算机名称,以显示在网络上。

机器人控制与仿真应用 4508

RocketMQ 整合 DLedger(多副本)即主从切换实现平滑升级的设计技巧

源码分析 RocketMQ DLedger 多副本系列已经进行到第 8 篇了,前面的章节主要是介绍了基于 raft 协议的选主与日志复制,从本篇开始将开始关注如何将 DLedger 应用到 RocketMQ中。 摘要:详细分析了RocketMQ DLedger 多副本(主从切换) 是如何整合到 RocketMQ中,本文的行文思路首先结合已掌握的DLedger 多副本相关的知识初步思考其实现思路,...

中间件兴趣圈 7765

Apifox接口测试+自动化测试

Apifox 接口测试+自动化测试快速入门!

程序员小杨哥的博客 1万+

【碳排放数据集】全球近实时网格化二氧化碳排放数据集GRACED

【碳排放数据集】全球近实时网格化二氧化碳排放数据集GRACED

WW、forever的博客 146

源码分析 RocketMQ DLedger 多副本之 Leader 选主

温馨提示:《RocketMQ技术内幕》作者倾力打造的全新专栏:RocketMQ 多副本(主从切换): 1、《RocketMQ 多副本前置篇:初探raft协议》 本文将按照《RocketMQ 多副本前置篇:初探raft协议》的思路来学习RocketMQ选主逻辑。首先先回顾一下关于Leader的一些思考: 节点状态 需要引入3中节点状态:Follower(跟随者)、Candidate(候选者),...

中间件兴趣圈 6495

基于DRU-HVDC的构网型海上风电场环流机理仿真复现

本文介绍了基于DRU-HVDC的构网型海上风电场环流机理仿真模型的构建方法。主要内容包括: 完整的Simulink模型结构,包含主模型文件GFM_DRU_Main.slx和配置脚本GFM_DRU_Setup.m 系统参数设置,包括基础频率(20Hz)、电压基准值(690V)、功率基准值(2MVA)等 四种仿真场景配置:电压不平衡、相位不平衡、阻抗不平衡和频率不平衡 风力发电机(WT)子系统的详细构建步骤,包含电压源、输出阻抗和测量模块 变压器和DRU整流器的参数设置 该模型可用于研究构网型风电场的环流机理。

huanghm88的专栏 262

主从切换_RocketMQ 整合 DLedger(多副本)即主从切换实现平滑升级的设计技巧

源码分析 RocketMQ DLedger 多副本即主从切换系列已经进行到第8篇了,前面的章节主要是介绍了基于 raft 协议的选主与日志复制,从本篇开始将开始关注如何将 DLedger 应用到 RocketMQ中。摘要:详细分析了RocketMQ DLedger 多副本(主从切换) 是如何整合到 RocketMQ中,本文的行文思路首先结合已掌握的DLedger 多副本相关的知识初步思...

weixin_30419031的博客 168

9.16华为OD机试真题 新系统 - 矩阵螺旋遍历 (Java/Py/C/C++/Js/Go)

9.16华为OD机试真题 新系统 - 矩阵螺旋遍历 (Java/Py/C/C++/Js/Go)

算法大师! 645

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

RocketMQ源码分析之Dledger模式

目录dledger集群搭建broker在启动的过程中如何触发选主流程dledger如何实现选主leader处理写请求及日志复制流程dledger commitlog与old commitlog数据格式对比dledger commitlog中如何构建consumequeue和index   RocketMQ集群部署可以分为两种方式master-slave和dledger,虽然master-slave方式提供了一定的高可用性,但是如果集群中的master节点挂了,这时需要运维人员手动进行重启或者切换操作,即不能

不爱学习的小妞博客 3505

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

从源码分析RocketMQ系列-RocketMQ5.0 自动主从切换设计详解

因此我们希望利用 DLedger 实现一个基于 Raft 的一致性模块(DLedger Controller),并当作一个可选的选主组件,支持独立部署,也可以嵌入在 Nameserver 中,Broker 通过与 Controller 的交互完成 Master 的选举,从而解决上述问题,我们将该新模式称为 Controller 模式。

初学者 2144

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

【RocketMQ】DLedger选主源码分析

MQ消息队列

weixin_52437323的博客 451

源码分析RocketMQ系列索引

1、RocketMQ源码分析之NameServer 2、RocketMQ源码分析之Broker概述与同步消息发送原理与高可用设计及思考 3、源码分析RocketMQ之CommitLog消息存储机制 4、源码分析RocketMQ之消息消费 5、源码分析RocketMQ消息消费机制----消费者拉取消息机制 6、 源码分析RocketMQ消...

qq_18846731的博客 261
上一篇: JAVA实现:一个数组有2n个元素,其中有n个奇数、n个偶数,数组无序,写一个算法使得奇数位置放置奇数,偶数位置放置偶数
下一篇: 分布式一致性
还不够
博客等级 码龄16年 113粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值