`

Notify、MetaQ、Kafka、ActiveMQ

 
阅读更多
1 Notify

Notify是淘宝自主研发的一套消息服务引擎,是支撑双11最为核心的系统之一,在淘宝和支付宝的核心交易场景中都有大量使用。消息系统的核心作用就是三点:解耦,异步和并行。下面让我以一个实际的例子来说明一下解耦异步和并行分别所代表的具体意义吧:

假设我们有这么一个应用场景,为了完成一个用户注册淘宝的操作,可能需要将用户信息写入到用户库中,然后通知给红包中心给用户发新手红包,然后还需要通知支付宝给用户准备对应的支付宝账号,进行合法性验证,告知sns系统给用户导入新的用户等10步操作。
那么针对这个场景,一个最简单的设计方法就是串行的执行整个流程

这种方式的最大问题是,随着后端流程越来越多,每步流程都需要额外的耗费很多时间,从而会导致用户更长的等待延迟。自然的,我们可以采用并行的方式来完成业务,能够极大的减少延迟

但并行以后又会有一个新的问题出现了,在用户注册这一步,系统并行的发起了4个请求,那么这四个请求中,如果通知SNS这一步需要的时间很长,比如需要10秒钟的话,那么就算是发新手包,准备支付宝账号,进行合法性验证这几个步骤的速度再快,用户也仍然需要等待10秒以后才能完成用户注册过程。因为只有当所有的后续操作全部完成的时候,用户的注册过程才算真正的“完成”了。用户的信息状态才是完整的。而如果这时候发生了更严重的事故,比如发新手红包的所有服务器因为业务逻辑bug导致down机,那么因为用户的注册过程还没有完全完成,业务流程也就是失败的了。这样明显是不符合实际的需要的,随着下游步骤的逐渐增多,那么用户等待的时间就会越来越长,并且更加严重的是,随着下游系统越来越多,整个系统出错的概率也就越来越大。

通过业务分析我们能够得知,用户的实际的核心流程其实只有一个,就是用户注册。而后续的准备支付宝,通知sns等操作虽然必须要完成,但却是不需要让用户等待的。
这种模式有个专业的名词,就叫最终一致。为了达到最终一致,我们引入了MQ系统。


核心原理

Notify在设计思路上与传统的MQ有一定的不同,他的核心设计理念是
1. 为了消息堆积而设计系统
2. 无单点,可自由扩展的设计

下面就请随我一起,进入到我们的消息系统内部来看看他设计的核心原理

    为了消息堆积而设计系统在市面上的大部分MQ产品,大部分的核心场景就是点对点的消息传输通道,然后非常激进的使用内存来提升整体的系统性能,这样做虽然标称的tps都能达到很高,但这种设计的思路是很难符合大规模分布式场景的实际需要的。
    在实际的分布式场景中,这样的系统会存在着较大的应用场景瓶颈,在后端有大量消费者的前提下,消费者出现问题是个非常常见的情况,而消息系统则必须能够在后端消费不稳定的情况下,仍然能够保证用户写入的正常并且TPS不降,是个非常考验消息系统能力的实际场景。
    也因为如此,在Notify的整体设计中,我们最优先考虑的就是消息堆积问题,在目前的设计中我们使用了持久化磁盘的方式,在每次用户发消息到Notify的时候都将消息先落盘,然后再异步的进行消息投递,而没有采用激进的使用内存的方案来加快投递速度。
    这种方式,虽然系统性能在峰值时比目前市面的MQ效率要差一些,但是作为整个业务逻辑的核心单元,稳定,安全可靠是系统的核心诉求。
    无单点,可自由扩展的设计


    发送消息的集群这主要是业务方的机器,这些APP的机器上是没有任何状态信息的,可以随着用户请求量的增加而随时增加或减少业务发送方的机器数量,从而扩大或缩小集群能力。
    配置服务器集群(Config server)这个集群的主要目的是动态的感知应用集群,消息集群机器上线与下线的过程,并及时广播给其他集群。如当业务接受消息的机器下线时,config server会感知到机器下线,从而将该机器从目标用户组内踢出,并通知给notify server,notify server 在获取通知后,就可以将已经下线的机器从自己的投递目标列表中删除,这样就可以实现机器的自动上下线扩容了。
    消息服务器(Notify Server)消息服务器,也就是真正承载消息发送与消息接收的服务器,也是一个集群,应用发送消息时可以随机选择一台机器进行消息发送,任意一台server 挂掉,系统都可以正常运行。当需要增加处理能力时,只需要简单地增加notify Server就可以了
    存储(Storage)Notify的存储集群有多种不同的实现方式,以满足不同应用的实际存储需求。针对消息安全性要求高的应用,我们会选择使用多份落盘的方式存储消息数据,而对于要求吞吐量而不要求消息安全的场景,我们则可以使用内存存储模型的存储。自然的,所有存储也被设计成了随机无状态写入存储模型以保障可以自由扩展。
    消息接收集群业务方用于处理消息的服务器组,上下线机器时候也能够动态的由config server 感知机器上下线的时机,从而可以实现机器自动扩展。

2、MetaQ

METAQ是一款完全的队列模型消息中间件,服务器使用Java语言编写,可在多种软硬件平台上部署。客户端支持Java、C++编程语言,已于2012年3月对外开源,开源地址是:http://metaq.taobao.org/。MetaQ大约经历了下面3个阶段

    在2011年1月份发布了MetaQ 1.0版本,从Apache Kafka衍生而来,在内部主要用于日志传输。
    在2012年9月份发布了MetaQ 2.0版本,解决了分区数受限问题,在数据库binlog同步方面得到了广泛的应用。
    在2013年7月份发布了MetaQ 3.0版本,MetaQ开始广泛应用于订单处理,cache同步、流计算、IM实时消息、binlog同步等领域。MetaQ3.0版本已经开源,参见这里

综上,MetaQ借鉴了Kafka的思想,并结合互联网应用场景对性能的要求,对数据的存储结构进行了全新设计。在功能层面,增加了更适合大型互联网特色的功能点。

MetaQ简介

图3-6-MetaQ整体结构

如图3-6所示,MetaQ对外提供的是一个队列服务,内部实现也是完全的队列模型,这里的队列是持久化的磁盘队列,具有非常高的可靠性,并且充分利用了操作系统cache来提高性能。

    是一个队列模型的消息中间件,具有高性能、高可靠、高实时、分布式特点。
    Producer、Consumer、队列都可以分布式。
    Producer向一些队列轮流发送消息,队列集合称为Topic,Consumer如果做广播消费,则一个consumer实例消费这个Topic对应的所有队列,如果做集群消费,则多个Consumer实例平均消费这个topic对应的队列集合。
    能够保证严格的消息顺序
    提供丰富的消息拉取模式
    高效的订阅者水平扩展能力
    实时的消息订阅机制
    亿级消息堆积能力

MetaQ存储结构

MetaQ的存储结构是根据阿里大规模互联网应用需求,完全重新设计的一套存储结构,使用这套存储结构可以支持上万的队列模型,并且可以支持消息查询、分布式事务、定时队列等功能,如图3-7所示。


MetaQ单机上万队列

MetaQ内部大部分功能都靠队列来驱动,那么必须支持足够多的队列,才能更好的满足业务需求,如图所示,MetaQ可以在单机支持上万队列,这里的队列全部为持久化磁盘方式,从而对IO性能提出了挑战。MetaQ是这样解决的

    Message全部写入到一个独立的队列,完全的顺序写
    Message在文件的位置信息写入到另外的文件,串行方式写。

通过以上方式,既做到数据可靠,又可以支持更多的队列,如图3-8所示。

MetaQ与Notify区别

    Notify侧重于交易消息,分布式事务消息方面。
    MetaQ侧重于顺序消息场景,例如binlog同步。以及主动拉消息场景,例如流计算等。

3 Apache Kafka

Kafka是分布式发布-订阅消息系统。它最初由LinkedIn公司开发,之后成为Apache项目的一部分。Kafka是一个分布式的,可划分的,冗余备份的持久性的日志服务。它主要用于处理活跃的流式数据。

在大数据系统中,常常会碰到一个问题,整个大数据是由各个子系统组成,数据需要在各个子系统中高性能,低延迟的不停流转。传统的企业消息系统并不是非常适合大规模的数据处理。为了已在同时搞定在线应用(消息)和离线应用(数据文件,日志)Kafka就出现了。Kafka可以起到两个作用:

    降低系统组网复杂度。
    降低编程复杂度,各个子系统不在是相互协商接口,各个子系统类似插口插在插座上,Kafka承担高速数据总线的作用。

Kafka主要特点:

    同时为发布和订阅提供高吞吐量。据了解,Kafka每秒可以生产约25万消息(50 MB),每秒处理55万消息(110 MB)。
    可进行持久化操作。将消息持久化到磁盘,因此可用于批量消费,例如ETL,以及实时应用程序。通过将数据持久化到硬盘以及replication防止数据丢失。
    分布式系统,易于向外扩展。所有的producer、broker和consumer都会有多个,均为分布式的。无需停机即可扩展机器。
    消息被处理的状态是在consumer端维护,而不是由server端维护。当失败时能自动平衡。
    支持online和offline的场景。

分享到:
评论

相关推荐

    kafka-notify-system:一个基于Kafka的演示通知系统,生产者将通知发布到Kafka,消费者订阅通知并发送给用户

    通知生产者该模块使用Apache Kafka客户端将通知发布到Kafka。 SimpleBatchProducer是一个单线程生成器,默认情况下发布通知分区程序(键:receiverId + serviceName)。 这样可以保证每个分区上消息的本地顺序。 ...

    activemq-cpp开发手册

    - **notify()**:唤醒等待线程。 - **notifyAll()**:唤醒所有等待线程。 以上内容涵盖了Activemq-cpp开发手册中的关键知识点,有助于开发者深入了解并掌握如何使用ActiveMQ C++ API进行高效的消息传递系统开发。

    十种MQ的技术选型详细对比.docx

    - **RocketMQ**的前身是MetaQ,最初可以看作是LinkedIn的Kafka(Scala版)的一个Java版本,并在此基础上增加了事务支持。 - **RocketMQ**相对于原生Kafka的特点在于除了基本的日志收集功能外,还支持高可用(HA)、...

    IPC的MessageQ与Notify例程

    标题中的“IPC的MessageQ与Notify例程”指的是在嵌入式系统开发中,特别是涉及到数字信号处理(DSP)领域的进程间通信(Inter-Process Communication, IPC)技术。IPC是多任务系统中不同进程间交换数据的重要手段。...

    MFC 全面解读WM_NOTIFY

    ### MFC全面解读WM_NOTIFY 在MFC(Microsoft Foundation Classes)框架中,`WM_NOTIFY`消息扮演着极其关键的角色,特别是在处理控件间通信时。本文将深入解析`WM_NOTIFY`消息的机制、应用场景以及其在MFC中的实现...

    淘宝消息中间件Notify

    Notify_1.4_truncate.docx Notify_1.7_client_design.doc Notify_1.7_client_develop_guide.docx ... ... Notify1.7_server_design.docx Notify1.7UserGuide.pptx Notify1.8_SEDA.docx Notify2010plan.pptx Notify...

    kafka-notify:Nuvla用户通知方法

    Nuvla特定的用于通知用户的脚本Kafka主题用作消息的来源。 消息可以发送到Slack或电子邮件。 请参阅下面的示例。 在适用的情况下,环境变量... notify-slack: image: nuvladev/kafka-notify:master networks: - test-...

    notify.js 好用的提示工具

    notify.js 好用的提示工具

    Java 同步方式 wait和notify/notifyall

    在Java中,`wait()`, `notify()`, 和 `notifyAll()` 是Java Object类的三个方法,它们在实现线程间通信和协作时扮演着关键角色。这些方法主要用于解决线程等待和唤醒的问题,是基于Java Monitor(监视器)模型的。 ...

    4.20170706_从机自动使能notify.zip

    "自动使能 notify" 是一种功能,它涉及自动化流程和通知机制。在20170706这个日期点,可能是一个系统或软件更新,或者一个特定项目的一部分,其中从机被配置为能够自动启用通知功能。这可能是为了提高效率,减少人工...

    Laravel开发-laravel-notify

    在Laravel框架中,`laravel-notify`是一个非常实用的扩展包,它为开发者提供了方便的通知接口,以便在Laravel4项目中实现各种通知功能。这个包的主要目的是简化通知的创建、管理和展示,使开发者可以更加专注于业务...

    wait和notify讲解

    wait和notify讲解

    java之wait,notify的用法([ 详解+实例 ])

    Java之wait和notify的用法详解 在Java多线程编程中,wait和notify是两个非常重要的方法,它们都是Object类的方法,用于线程之间的通信和同步。下面我们将详细解释wait和notify的用法。 wait方法 wait方法是Object...

    前端项目-notify.js.zip

    《前端项目:深入理解notify.js及其在Web通知API中的应用》 在当今的Web开发领域,用户交互体验的提升已经成为了一项重要的任务。为了更好地与用户进行实时沟通,前端开发者们利用了各种技术,其中就包括了Web ...

    Java多线程wait和notify

    在Java中,`wait()` 和 `notify()` 方法是实现线程间通信和协作的重要工具,它们属于 `java.lang.Object` 类,这意味着所有类都默认继承了这两个方法。本文将详细探讨如何使用 `wait()` 和 `notify()` 来控制子线程...

    BootstrapPlugin - notify 使用笔记

    BootstrapPlugin的notify功能是Bootstrap框架中的一个通知插件,它允许开发者轻松地在网页上创建各种类型的通知消息,提供了一种高效、灵活的方式来传递信息给用户。这个插件基于Bootstrap的CSS样式和JavaScript功能...

    Notify架构与原理.pdf

    4. **WHY NOT JMS**:尽管存在如ActiveMQ和HornetQ等成熟的JMS开源产品,但Notify针对大规模分布式系统的事务支持、订阅者集群和性能进行了优化。例如,它不支持两阶段提交协议,而是选择了更适应大规模分布式系统的...

    佳明手表(Garmin watch) Image Notify APP

    Image Notify APP是专为佳明手表设计的一款第三方应用程序,开发者出于对佳明手表的热爱,构建了这款软件,使其能够在Android手机上运行,提供更丰富的通知体验。 Image Notify的主要功能在于将手机接收到的通知以...

    WM_NOTIFY.zip_WM_NOTI_WM_NOTIFY

    在Windows编程领域,`WM_NOTIFY`消息是一个至关重要的部分,它是窗口间通信的重要机制,用于在父窗口和其子控件之间传递信息。这个压缩包文件`WM_NOTIFY.zip_WM_NOTI_WM_NOTIFY`包含了关于`WM_NOTIFY`消息的深入分析...

    主线程去控制子线程wait与notify

    在Java多线程编程中,`wait()`和`notify()`是两个非常重要的方法,它们用于线程间的协作和通信。这两个方法是Java语言中的Object类提供的,因此所有的对象都可以使用。在本文中,我们将深入探讨如何使用主线程来控制...

Global site tag (gtag.js) - Google Analytics