精华内容
下载资源
问答
  • 摘要: 阿里系统软件是如何应对“双11”流量峰值的呢?以下为大家一一揭晓! 作者|阿里资源管理技术专家杨仪 刚刚过去的 2018 年天猫“双11”,创下了全天 2135 亿 GMV 的数字奇迹,零点交易峰值比往年提升 50%,...

    摘要: 阿里系统软件是如何应对“双11”流量峰值的呢?以下为大家一一揭晓!

    作者|阿里资源管理技术专家杨仪

    刚刚过去的 2018 年天猫“双11”,创下了全天 2135 亿 GMV 的数字奇迹,零点交易峰值比往年提升 50%,各项指标均创下历史新高。

    2018 年是“双11”的第十年,也是阿里系统软件事业部参与的第二个“双11”,系统软件是介于业务应用和 IDC、网络、服务器之间的核心关键层,为阿里巴巴集团在线业务提供基础的操作系统、资源调度、SRE、JVM 等领域重要的基础设施。

    经过两年“双11”的精心淬炼,系统软件事业部与其他兄弟 BU 并肩作战,逐步提升了阿里巴巴在基础软件领域的技术深度。阿里系统软件是如何应对“双11”流量峰值的呢?以下为大家一一揭晓。

    “双11”面临的挑战

    双11的核心是稳定压倒一切,如何确保各个系统在峰值流量下的稳定性成为重中之重,系统软件作为阿里巴巴的基础设施底盘,今年主要面临如下挑战:

    • 在去年双11的完美表现的基础上,今年双11的稳定性不容有失,从内核到业务层保障,所有基础设施必须保障绝对稳定;
    • 大量新技术如规模化混部演进给集团带来技术进步的同时,给系统和业务带来不确定的技术风险;
    • 如何在保障业务稳定性的同时,确保成本最低,是业务给系统软件提出的更高要求;

    系统软件双11备战回顾

    双11备战之资源交付

    面向终态的站点交付

    众所周知,阿里巴巴的交易系统采用了异地多活的灾容架构,当大促来临前,需要在多个地域快速交付多个站点,通过全链路压测平台进行站点能力验证。借助于阿里巴巴资源快速弹性的能力,从交付使用到站点压测,需要在短短10多天时间内完成多个站点的快速交付,无疑是一个巨大的挑战。

    为了提升整体建站的效率,确保站点高质量交付,系统软件建站团队对建站链路进行了全面的方案优化和升级如下:

    • 全生命周期业务集群管控

      包括 0->1(建站)、1->N/N->1(弹性伸缩/快上快下)、1->0(站点下线);弹性伸缩范围包括接入层、中间件、Tair 及应用全链路。
    • 无缝对接容量模型

      单元化应用分组自动识别,应用弹性结合预算产出容量模型,对接中间件等容量模型,交易笔数->建站范围及资源需求。
    • 规模化资源编排
      
基于 Sigma 的规模化场景资源编排,最小化资源碎片,节省资源,通过实际验证,资源分配率达到 98%。
    • 自动化业务回归
      各 BU 自动化业务回归,例如基于天启/doom、全链路压测、军刀等。

    资源运营降低大促成本

    根据准确测算,2018年大促每万笔交易成本比去年下降20%;这里面除了混部技术的大规模运用、云化等因素外,还需要在资源运营层面进行一系列优化,其中的重点就是打造一套资源全生命周期管理的资源运营平台,实现资源快速交付和资源最大化利用。

    • 资源交付体系建设
      在资源交付链路上,资源运营团队对额度系统进行重构升级,将面向时间的额度系统升级为面向当前账户的额度体系,应用负责人可以自由地在应用之间进行额度转移,极大地提升了资源交付效率;此外,我们基于一系列的容量规划和算法预测,实现了大量业务的分时复用,将大量不参与大促的业务的资源提前释放,用于支撑大促需求。

    基于系统化的资源运营方式,集团资源运营的效率和利用率大幅提升,有效地防止了资源泄露和资源闲置,真正实现了大促成本不增加,为阿里集团节省了亿级别采购成本。

    双11备战之调度备战

    大规模混部技术应用

    2017年双11,阿里巴巴的混部技术在大促零点成功得到验证,今年双11混部的量级扩大到去年的3倍;在这个大目标下,混部团队对现有架构进行了升级,在离线调度器伏羲和在线调度器sigma之上演化出一个总体的资源协调者0层,主要承载离线和在线资源记账、区分优先级的资源分配和总体协调的作用,可以把它形象的看成是一个大的账本,上面的每一条记录便是某台机器上cpu/mem/io资源如何划分给在线和离线业务,从而解决混部环境在线和离混资源的资源分配问题。

    在混部业务稳定性保障方面,通过对两类资源(CPU和MEM)按优先级划分的策略进行使用,其中以CPU资源为例划分为三个级别,分别为金牌,CPU采用绑核模式具有最高优调度抢占优先级;银牌,在线和离线高优先级任务使用,离线银牌资源不会被在线任务驱赶,保障调度优先级和稳定性;铜牌,离线大部分worker申请铜牌资源使用。在线S10和S20需要使用CPU时可以驱赶离线铜牌对CPU核的占用,实现资源充足时离线成分用满,资源紧张时在线能及时抢占的效果。

    得益于前文所述的新混部调度框架,0层和1层调度间的资源配合有了一个明显提升,去年的混部方案中,0层只保留静态的集群或单机资源配比,并且比例生效都是通过外部人为设置,而今年0层精细化单机账本之后,每台单机的配比则交给fuxi和sigma自动调整,按照容器所需资源比例进行设置。借助于资源配比的按需调整功能,快上快下也实现了完全自动化的流程驱动。

    混部快上快下是指在大促过程中,离线快速地资源释放给在线或在线快速给归还资源给离线的过程;自动化流程完美的实现了规模化混部目标,通过完整链路优化,最终实现了快上2小时,快下1小时的时间目标,也正是如此快速的资源伸缩操作保障了离线业务在资源相对紧缺的情况下安全顺滑支持规模性压测及双11大促的完整支持。
    image.png

    今年双11,有超过50%的流量运行在混部集群;其中离在线混部(即离线提供资源给在线交易使用)支撑了40%的交易流量;在离线混部(即在线出让部分资源用于离线任务运行)一共部署约了数千台机器资源,为离线业务团队减少数千台机器采购。

    Sigma调度能力升级

    sigma是阿里巴巴自研的资源调度器,调度引擎是Sigma调度的核心,调度引擎的优劣,直接决定了其调度的业务的稳定性。今年调度能力升级主要做了以下几方面工作:

    • 业务运行时保障
      今年调度引擎团队首次提出了资源确定性的SLO目标,将业务方关心的资源争抢、超卖、CPU核重叠等容器运行时的稳定作为第一优先级任务解决,在确保核心应用CPU逻辑核不堆叠的前提下,满足了同应用不同容器和同容器对端核争抢的需求,从而提升了资源稳定性。
    • 引擎升级
      新版Sigma 调度器在原有基础上进行了重新设计和架构升级,兼容开源kubernetes框架,在数万笔交易容量集群上得到了大规模验证。
    • Pouch容器
      今年双11,超过10%的物理机上线了pouch开源回迁版本,为探索阿里内外使用同一个容器打下基础。同时,容器团队还在Containerd-1.0 方面做了大量的性能优化/锁优化/定时任务CPU优化,确保容器运行时稳定。
    • CpuShare精细化资源分配
      CpuShare是一种基于linux cgroup对应用的cpu和内存进行精细化的控制和使用的技术,双11前在线资源池整体share容器数占比10%,其中核⼼应⽤5%,次核⼼应⽤10%,非核⼼应⽤20%+。

    大促云化

    大促云化是指大促时通过短时间使用阿里云的计算能力,大促峰值过后将资源释放归还给公共云继续售卖的一种资源使用方式。

    大促云化的本质是资源的云化,包括计算资源、网络、IDC、服务器全部基于阿里云的底层技术,从2014年提出大促云化后,大促云化方案经过了多次升级改进,通过vpc网络打通云上云下互访,实现大促过后直接释放资源即可直接售卖,从而减少资源占用时长和改造成本。

    • 全量使用公共云方案,网络层通过VPC方案实现公共云环境与弹内环境互通;通过使用阿里云的ECS buffer,减少交易的资源采购;
    • 计算存储分离,使用阿里云的盘古做为远程盘存储,大大减小物理机本盘,降低了大促资源成本;
    • 此外,在应用、中间件、数据库层面大规模部署神龙云服务器,总体效果良好。

    大规模计算存储分离

    2018年是计算存储分离破局之年,基于盘古远程盘,部署了数千台在线宿主机,超过50%的集群使用了存储计算分离技术,这项技术有望大幅减少未来阿里集团在服务器SSD盘的硬件成本投入。

    双11备战之内核备战

    内核是系统运行的基础,今年内核团队的备战主要集中在以下两个方面:

    • 4.9 版本内核部署
      Linus Torvalds在2016年12月11日发布了Linux内核4.9的正式版本,由于4.9新内核修复了大量老内核已知bug,4.9版本的操作系统比目前版本相比稳定性更高,宕机率也有明显下降;目前装机量达到数十万台级别,双11交易集群约90%的交易部署在4.9内核环境,未来将继续扩大新内核的升级。
    • 混部环境内核调优
      离线和在线混部的集群中,由于宿主机整体资源有限,如何避免离线任务的运行对在线任务造成影响,成为业界难题;今年混部实施以来,发现混部任务调度到在线宿主机后在线业务频繁反馈容器及宿主机load高或CPU sys高的情况;经过内核团队介入排查,发布宿主机内存文件缓存过大,申请新内存时触发整机内存直接回收,导致系统开销大;优化思路:调整整机内存后台回收值(调整内存水线,提高内存Normal Zone的LOW/HIGH水线),提前回收文件缓存页面,避免内核进入直接回收流程。

    补丁前:MIN=8G, LOW=10G, HIGH=12G,LOW与MIN之间只有2G,当应用分配大量内存时,kswap还没来得及后台回收,系统内存就低于8G,这时应用只能进入direct reclaim,直接去回收。

    image.png

    补丁后:MIN=8G,LOW=25G,HIGH=27G
    image.png

    双11备战之JVM备战

    JVM协程(wisp)

    JVM协程今年部署范围交易核心应用扩大到导购,大促期间整体某导购核心应用水位从去年30%提升到今年的60%,业务没有新增机器。

    ZenGC

    • TenureAlloc

    部分核心应用默认开启ZenGC,GC暂停改善50%;

    • GCIH2.0

    核心应用部署GCIH2.0,在安全性和性能上进行了改进,GC暂停时间最多改进20+%。
    image.png

    • ElasticHeap动态堆内存

    双十一0点之前低流量时降低Java进程内存20%+,双十一0点迅速恢复Java堆全量使用,峰值过后,继续缩小Java堆,减少进程内存20%+,99%和最大暂停大幅好于CMS,CMS为G1的150%~5X。

    • EarlyOldScavenge

    在Lindorm Velocity证,大幅减少Concurrent GC从1天30+次,减少为1天1次,推算堆增长率减少95%以上。

    未来展望

    系统软件为打造阿里巴巴高性能、低成本的基础设施,在赋能业务发展、降低阿里巴巴资源运行成本方面实现了初步的技术积累,展望未来,系统软件仍有巨大的发展空间,欢迎各路技术牛人加入系统软件,一起打造阿里巴巴商业操作系统的核心软件。

    展开全文
  • 简介:2020 年双十一交易峰值达到 58.3 W 笔/秒,消息中间件 RocketMQ 继续数年 0 故障丝般顺滑地完美支持了整个集团大促的各类业务平稳。作者 | 愈安来源 | 阿里巴巴云原生公众号2020 年双十一交易峰值达到 58.3 W ...
    简介:2020 年双十一交易峰值达到 58.3 W 笔/秒,消息中间件 RocketMQ 继续数年 0 故障丝般顺滑地完美支持了整个集团大促的各类业务平稳。

    头图.png

    作者 | 愈安
    来源 | 阿里巴巴云原生公众号

    2020 年双十一交易峰值达到 58.3 W 笔/秒,消息中间件 RocketMQ 继续数年 0 故障丝般顺滑地完美支持了整个集团大促的各类业务平稳。2020 年双十一大促中,消息中间件 RocketMQ 发生了以下几个方面的变化:

    • 云原生化实践:完成运维层面的云原生化改造,实现 Kubernetes 化。
    • 性能优化:消息过滤优化交易集群性能提升 30%。
    • 全新的消费模型:对于延迟敏感业务提供新的消费模式,降低因发布、重启等场景下导致的消费延迟。

    云原生化实践

    1. 背景

    Kubernetes 作为目前云原生化技术栈实践中重要的一环,其生态已经逐步建立并日益丰富。目前,服务于集团内部的 RocketMQ 集群拥有巨大的规模以及各种历史因素,因此在运维方面存在相当一部分痛点,我们希望能够通过云原生技术栈来尝试找到对应解决方案,并同时实现降本提效,达到无人值守的自动化运维。

    消息中间件早在 2016 年,通过内部团队提供的中间件部署平台实现了容器化和自动化发布,整体的运维比 2016 年前已经有了很大的提高,但是作为一个有状态的服务,在运维层面仍然存在较多的问题。

    中间件部署平台帮我们完成了资源的申请,容器的创建、初始化、镜像安装等一系列的基础工作,但是因为中间件各个产品都有自己不同的部署逻辑,所以在应用的发布上,就是各应用自己的定制化了。中间件部署平台的开发也不完全了解集团内 RocketMQ 的部署过程是怎样的。

    因此在 2016 年的时候,部署平台需要我们去亲自实现消息中间件的应用发布代码。虽然部署平台大大提升了我们的运维效率,甚至还能实现一键发布,但是这样的方案也有不少的问题。比较明显的就是,当我们的发布逻辑有变化的时候,还需要去修改部署平台对应的代码,需要部署平台升级来支持我们,用最近比较流行的一个说法,就是相当不云原生。

    同样在故障机替换、集群缩容等操作中,存在部分人工参与的工作,如切流,堆积数据的确认等。我们尝试过在部署平台中集成更多消息中间件自己的运维逻辑,不过在其他团队的工程里写自己的业务代码,确实也是一个不太友好的实现方案,因此我们希望通过 Kubernetes 来实现消息中间件自己的 operator 。我们同样希望利用云化后云盘的多副本能力来降低我们的机器成本并降低主备运维的复杂程度。

    经过一段时间的跟进与探讨,最终再次由内部团队承担了建设云原生应用运维平台的任务,并依托于中间件部署平台的经验,借助云原生技术栈,实现对有状态应用自动化运维的突破。

    2. 实现

    1.png

    整体的实现方案如上图所示,通过自定义的 CRD 对消息中间件的业务模型进行抽象,将原有的在中间件部署平台的业务发布部署逻辑下沉到消息中间件自己的 operator 中,托管在内部 Kubernetes 平台上。该平台负责所有的容器生产、初始化以及集团内一切线上环境的基线部署,屏蔽掉 IaaS 层的所有细节。

    Operator 承担了所有的新建集群、扩容、缩容、迁移的全部逻辑,包括每个 pod 对应的 brokerName 自动生成、配置文件,根据集群不同功能而配置的各种开关,元数据的同步复制等等。同时之前一些人工的相关操作,比如切流时候的流量观察,下线前的堆积数据观察等也全部集成到了 operator 中。当我们有需求重新修改各种运维逻辑的时候,也再也不用去依赖通用的具体实现,修改自己的 operator 即可。

    最后线上的实际部署情况去掉了图中的所有的 replica 备机。在 Kubernetes 的理念中,一个集群中每个实例的状态是一致的,没有依赖关系,而如果按照消息中间件原有的主备成对部署的方案,主备之间是有严格的对应关系,并且在上下线发布过程中有严格的顺序要求,这种部署模式在 Kubernetes 的体系下是并不提倡的。若依然采用以上老的架构方式,会导致实例控制的复杂性和不可控性,同时我们也希望能更多的遵循 Kubernetes 的运维理念。

    云化后的 ECS 使用的是高速云盘,底层将对数据做了多备份,因此数据的可用性得到了保障。并且高速云盘在性能上完全满足 MQ 同步刷盘,因此,此时就可以把之前的异步刷盘改为同步,保证消息写入时的不丢失问题。云原生模式下,所有的实例环境均是一致性的,依托容器技术和 Kubernetes 的技术,可实现任何实例挂掉(包含宕机引起的挂掉),都能自动自愈,快速恢复。

    解决了数据的可靠性和服务的可用性后,整个云原生化后的架构可以变得更加简单,只有 broker 的概念,再无主备之分。

    3. 大促验证

    2.png

    上图是 Kubernetes 上线后双十一大促当天的发送 RT 统计,可见大促期间的发送 RT 较为平稳,整体符合预期,云原生化实践完成了关键性的里程碑。

    性能优化

    1. 背景

    RocketMQ 至今已经连续七年 0 故障支持集团的双十一大促。自从 RocketMQ 诞生以来,为了能够完全承载包括集团业务中台交易消息等核心链路在内的各类关键业务,复用了原有的上层协议逻辑,使得各类业务方完全无感知的切换到 RocketMQ 上,并同时充分享受了更为稳定和强大的 RocketMQ 消息中间件的各类特性。

    当前,申请订阅业务中台的核心交易消息的业务方一直都在不断持续增加,并且随着各类业务复杂度提升,业务方的消息订阅配置也变得更加复杂繁琐,从而使得交易集群的进行过滤的计算逻辑也变得更为复杂。这些业务方部分沿用旧的协议逻辑(Header 过滤),部分使用 RocketMQ 特有的 SQL 过滤。

    2. 主要成本

    目前集团内部 RocketMQ 的大促机器成本绝大部分都是交易消息相关的集群,在双十一零点峰值期间,交易集群的峰值和交易峰值成正比,叠加每年新增的复杂订阅带来了额外 CPU 过滤计算逻辑,交易集群都是大促中机器成本增长最大的地方。

    3. 优化过程

    由于历史原因,大部分的业务方主要还是使用 Header 过滤,内部实现其实是aviator 表达式。仔细观察交易消息集群的业务方过滤表达式,可以发现绝大部分都指定类似MessageType == xxxx这样的条件。翻看 aviator 的源码可以发现这样的条件最终会调用 Java 的字符串比较String.compareTo()。

    由于交易消息包括大量不同业务的 MessageType,光是有记录的起码有几千个,随着交易业务流程复杂化,MessageType 的增长更是繁多。随着交易峰值的提高,交易消息峰值正比增长,叠加这部分更加复杂的过滤,持续增长的将来,交易集群的成本极可能和交易峰值指数增长,因此决心对这部分进行优化。

    原有的过滤流程如下,每个交易消息需要逐个匹配不同 group 的订阅关系表达式,如果符合表达式,则选取对应的 group 的机器进行投递。如下图所示:

    3.png

    对此流程进行优化的思路需要一定的灵感,在这里借助数据库索引的思路:原有流程可以把所有订阅方的过滤表达式看作数据库的记录,每次消息过滤就相当于一个带有特定条件的数据库查询,把所有匹配查询(消息)的记录(过滤表达式)选取出来作为结果。为了加快查询结果,可以选择 MessageType 作为一个索引字段进行索引化,每次查询变为先匹配 MessageType 主索引,然后把匹配上主索引的记录再进行其它条件(如下图的 sellerId 和 testA )匹配,优化流程如下图所示:

    4.png

    以上优化流程确定后,要关注的技术点有两个:

    • 如何抽取每个表达式中的 MessageType 字段?
    • 如何对 MessageType 字段进行索引化?

    对于技术点 1 ,需要针对 aviator 的编译流程进行 hook ,深入 aviator 源码后,可以发现 aviator 的编译是典型的Recursive descent,同时需要考虑到提取后父表达式的短路问题。

    在编译过程中针对 messageType==XXX 这种类型进行提取后,把原有的 message==XXX 转变为 true/false 两种情况,然后针对 true、false 进行表达式的短路即可得出表达式优化提取后的情况。例如:

    表达式:
    messageType=='200-trade-paid-done' && buyerId==123456
    提取为两个子表达式:
    子表达式1(messageType==200-trade-paid-done):buyerId==123456 
    子表达式2(messageType!=200-trade-paid-done):false
    • 具体到 aviator 的实现里,表达式编译会把每个 token 构建一个 List ,类似如下图所示(为方便理解,绿色方框的是 token ,其它框表示表达式的具体条件组合):

    5.png

    提取了 messageType ,有两种情况:

    • 情况一:messageType == '200-trade-paid-done',则把之前 token 的位置合并成true,然后进行表达式短路计算,最后优化成 buyerId==123456 ,具体如下:

    6.png

    • 情况二:messageType != '200-trade-paid-done',则把之前 token 的位置合并成 false ,表达式短路计算后,最后优化成 false ,具体如下:

    7.png

    这样就完成 messageType 的提取。这里可能有人就有一个疑问,为什么要考虑到上面的情况二,messageType != '200-trade-paid-done',这是因为必须要考虑到多个条件的时候,比如:

    (messageType=='200-trade-paid-done' && buyerId==123456) || (messageType=='200-trade-success' && buyerId==3333)

    就必须考虑到不等于的情况了。同理,如果考虑到多个表达式嵌套,需要逐步进行短路计算。但整体逻辑是类似的,这里就不再赘述。

    说完技术点 1,我们继续关注技术点 2,考虑到高效过滤,直接使用 HashMap 结构进行索引化即可,即把 messageType 的值作为 HashMap 的 key ,把提取后的子表达式作为 HashMap 的 value ,这样每次过滤直接通过一次 hash 计算即可过滤掉绝大部分不适合的表达式,大大提高了过滤效率。

    3. 优化效果

    该优化最主要降低了 CPU 计算逻辑,根据优化前后的性能情况对比,我们发现不同的交易集群中的订阅方订阅表达式复杂度越高,优化效果越好,这个是符合我们的预期的,其中最大的 CPU 优化有32%的提升,大大降低了本年度 RocketMQ 的部署机器成本。

    全新的消费模型 —— POP 消费

    1. 背景

    RocketMQ 的 PULL 消费对于机器异常 hang 时并不十分友好。如果遇到客户端机器 hang 住,但处于半死不活的状态,与 broker 的心跳没有断掉的时候,客户端 rebalance 依然会分配消费队列到 hang 机器上,并且 hang 机器消费速度很慢甚至无法消费的时候,这样会导致消费堆积。另外类似还有服务端 Broker 发布时,也会由于客户端多次 rebalance 导致消费延迟影响等无法避免的问题。如下图所示:

    8.png

    当 Pull Client 2 发生 hang 机器的时候,它所分配到的三个 Broker 上的 Q2 都出现严重的红色堆积。对于此,我们增加了一种新的消费模型 —— POP 消费,能够解决此类稳定性问题。如下图所示:

    9.png

    POP 消费中,三个客户端并不需要 rebalance 去分配消费队列,取而代之的是,它们都会使用 POP 请求所有的 broker 获取消息进行消费。broker 内部会把自身的三个队列的消息根据一定的算法分配给请求的 POP Client。即使 Pop Client 2 出现 hang,但内部队列的消息也会让 Pop Client1 和 Pop Client2 进行消费。这样就 hang 机器造成的避免了消费堆积。

    2. 实现

    POP 消费和原来 PULL 消费对比,最大的一点就是弱化了队列这个概念,PULL 消费需要客户端通过 rebalance 把 broker 的队列分配好,从而去消费分配到自己专属的队列,新的 POP 消费中,客户端的机器会直接到每个 broker 的队列进行请求消费, broker 会把消息分配返回给等待的机器。随后客户端消费结束后返回对应的 Ack 结果通知 broker,broker 再标记消息消费结果,如果超时没响应或者消费失败,再会进行重试。

    10.png

    POP 消费的架构图如上图所示。Broker 对于每次 POP 的请求,都会有以下三个操作:

    • 对应的队列进行加锁,然后从 store 层获取该队列的消息;
    • 然后写入 CK 消息,表明获取的消息要被 POP 消费;
    • 最后提交当前位点,并释放锁。

    CK 消息实际上是记录了 POP 消息具体位点的定时消息,当客户端超时没响应的时候,CK 消息就会重新被 broker 消费,然后把 CK 消息的位点的消息写入重试队列。如果 broker 收到客户端的消费结果的 Ack ,删除对应的 CK 消息,然后根据具体结果判断是否需要重试。

    从整体流程可见,POP 消费并不需要 reblance ,可以避免 rebalance 带来的消费延时,同时客户端可以消费 broker 的所有队列,这样就可以避免机器 hang 而导致堆积的问题。

    11.png

    原文链接:https://developer.aliyun.com/article/783358?

    版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
    展开全文
  • 简介:2020 年双十一交易峰值达到 58.3 W 笔/秒,消息中间件 RocketMQ 继续数年 0 故障丝般顺滑地完美支持了整个集团大促的各类业务平稳。 作者 | 愈安 来源 |阿里巴巴云原生公众号 2020 年双十一交易峰值达到 ...

    简介: 2020 年双十一交易峰值达到 58.3 W 笔/秒,消息中间件 RocketMQ 继续数年 0 故障丝般顺滑地完美支持了整个集团大促的各类业务平稳。

    头图.png

    作者 | 愈安
    来源 | 阿里巴巴云原生公众号

    2020 年双十一交易峰值达到 58.3 W 笔/秒,消息中间件 RocketMQ 继续数年 0 故障丝般顺滑地完美支持了整个集团大促的各类业务平稳。2020 年双十一大促中,消息中间件 RocketMQ 发生了以下几个方面的变化:

    • 云原生化实践:完成运维层面的云原生化改造,实现 Kubernetes 化。
    • 性能优化:消息过滤优化交易集群性能提升 30%。
    • 全新的消费模型:对于延迟敏感业务提供新的消费模式,降低因发布、重启等场景下导致的消费延迟。

    云原生化实践

    1. 背景

    Kubernetes 作为目前云原生化技术栈实践中重要的一环,其生态已经逐步建立并日益丰富。目前,服务于集团内部的 RocketMQ 集群拥有巨大的规模以及各种历史因素,因此在运维方面存在相当一部分痛点,我们希望能够通过云原生技术栈来尝试找到对应解决方案,并同时实现降本提效,达到无人值守的自动化运维。

    消息中间件早在 2016 年,通过内部团队提供的中间件部署平台实现了容器化和自动化发布,整体的运维比 2016 年前已经有了很大的提高,但是作为一个有状态的服务,在运维层面仍然存在较多的问题。

    中间件部署平台帮我们完成了资源的申请,容器的创建、初始化、镜像安装等一系列的基础工作,但是因为中间件各个产品都有自己不同的部署逻辑,所以在应用的发布上,就是各应用自己的定制化了。中间件部署平台的开发也不完全了解集团内 RocketMQ 的部署过程是怎样的。

    因此在 2016 年的时候,部署平台需要我们去亲自实现消息中间件的应用发布代码。虽然部署平台大大提升了我们的运维效率,甚至还能实现一键发布,但是这样的方案也有不少的问题。比较明显的就是,当我们的发布逻辑有变化的时候,还需要去修改部署平台对应的代码,需要部署平台升级来支持我们,用最近比较流行的一个说法,就是相当不云原生。

    同样在故障机替换、集群缩容等操作中,存在部分人工参与的工作,如切流,堆积数据的确认等。我们尝试过在部署平台中集成更多消息中间件自己的运维逻辑,不过在其他团队的工程里写自己的业务代码,确实也是一个不太友好的实现方案,因此我们希望通过 Kubernetes 来实现消息中间件自己的 operator 。我们同样希望利用云化后云盘的多副本能力来降低我们的机器成本并降低主备运维的复杂程度。

    经过一段时间的跟进与探讨,最终再次由内部团队承担了建设云原生应用运维平台的任务,并依托于中间件部署平台的经验,借助云原生技术栈,实现对有状态应用自动化运维的突破。

    2. 实现

    1.png

    整体的实现方案如上图所示,通过自定义的 CRD 对消息中间件的业务模型进行抽象,将原有的在中间件部署平台的业务发布部署逻辑下沉到消息中间件自己的 operator 中,托管在内部 Kubernetes 平台上。该平台负责所有的容器生产、初始化以及集团内一切线上环境的基线部署,屏蔽掉 IaaS 层的所有细节。

    Operator 承担了所有的新建集群、扩容、缩容、迁移的全部逻辑,包括每个 pod 对应的 brokerName 自动生成、配置文件,根据集群不同功能而配置的各种开关,元数据的同步复制等等。同时之前一些人工的相关操作,比如切流时候的流量观察,下线前的堆积数据观察等也全部集成到了 operator 中。当我们有需求重新修改各种运维逻辑的时候,也再也不用去依赖通用的具体实现,修改自己的 operator 即可。

    最后线上的实际部署情况去掉了图中的所有的 replica 备机。在 Kubernetes 的理念中,一个集群中每个实例的状态是一致的,没有依赖关系,而如果按照消息中间件原有的主备成对部署的方案,主备之间是有严格的对应关系,并且在上下线发布过程中有严格的顺序要求,这种部署模式在 Kubernetes 的体系下是并不提倡的。若依然采用以上老的架构方式,会导致实例控制的复杂性和不可控性,同时我们也希望能更多的遵循 Kubernetes 的运维理念。

    云化后的 ECS 使用的是高速云盘,底层将对数据做了多备份,因此数据的可用性得到了保障。并且高速云盘在性能上完全满足 MQ 同步刷盘,因此,此时就可以把之前的异步刷盘改为同步,保证消息写入时的不丢失问题。云原生模式下,所有的实例环境均是一致性的,依托容器技术和 Kubernetes 的技术,可实现任何实例挂掉(包含宕机引起的挂掉),都能自动自愈,快速恢复。

    解决了数据的可靠性和服务的可用性后,整个云原生化后的架构可以变得更加简单,只有 broker 的概念,再无主备之分。

    3. 大促验证

    2.png

    上图是 Kubernetes 上线后双十一大促当天的发送 RT 统计,可见大促期间的发送 RT 较为平稳,整体符合预期,云原生化实践完成了关键性的里程碑。

    性能优化

    1. 背景

    RocketMQ 至今已经连续七年 0 故障支持集团的双十一大促。自从 RocketMQ 诞生以来,为了能够完全承载包括集团业务中台交易消息等核心链路在内的各类关键业务,复用了原有的上层协议逻辑,使得各类业务方完全无感知的切换到 RocketMQ 上,并同时充分享受了更为稳定和强大的 RocketMQ 消息中间件的各类特性。

    当前,申请订阅业务中台的核心交易消息的业务方一直都在不断持续增加,并且随着各类业务复杂度提升,业务方的消息订阅配置也变得更加复杂繁琐,从而使得交易集群的进行过滤的计算逻辑也变得更为复杂。这些业务方部分沿用旧的协议逻辑(Header 过滤),部分使用 RocketMQ 特有的 SQL 过滤。

    2. 主要成本

    目前集团内部 RocketMQ 的大促机器成本绝大部分都是交易消息相关的集群,在双十一零点峰值期间,交易集群的峰值和交易峰值成正比,叠加每年新增的复杂订阅带来了额外 CPU 过滤计算逻辑,交易集群都是大促中机器成本增长最大的地方。

    3. 优化过程

    由于历史原因,大部分的业务方主要还是使用 Header 过滤,内部实现其实是aviator 表达式。仔细观察交易消息集群的业务方过滤表达式,可以发现绝大部分都指定类似MessageType == xxxx这样的条件。翻看 aviator 的源码可以发现这样的条件最终会调用 Java 的字符串比较String.compareTo()。

    由于交易消息包括大量不同业务的 MessageType,光是有记录的起码有几千个,随着交易业务流程复杂化,MessageType 的增长更是繁多。随着交易峰值的提高,交易消息峰值正比增长,叠加这部分更加复杂的过滤,持续增长的将来,交易集群的成本极可能和交易峰值指数增长,因此决心对这部分进行优化。

    原有的过滤流程如下,每个交易消息需要逐个匹配不同 group 的订阅关系表达式,如果符合表达式,则选取对应的 group 的机器进行投递。如下图所示:

    3.png

    对此流程进行优化的思路需要一定的灵感,在这里借助数据库索引的思路:原有流程可以把所有订阅方的过滤表达式看作数据库的记录,每次消息过滤就相当于一个带有特定条件的数据库查询,把所有匹配查询(消息)的记录(过滤表达式)选取出来作为结果。为了加快查询结果,可以选择 MessageType 作为一个索引字段进行索引化,每次查询变为先匹配 MessageType 主索引,然后把匹配上主索引的记录再进行其它条件(如下图的 sellerId 和 testA )匹配,优化流程如下图所示:

    4.png

    以上优化流程确定后,要关注的技术点有两个:

    • 如何抽取每个表达式中的 MessageType 字段?
    • 如何对 MessageType 字段进行索引化?

    对于技术点 1 ,需要针对 aviator 的编译流程进行 hook ,深入 aviator 源码后,可以发现 aviator 的编译是典型的Recursive descent,同时需要考虑到提取后父表达式的短路问题。

    在编译过程中针对 messageType==XXX 这种类型进行提取后,把原有的 message==XXX 转变为 true/false 两种情况,然后针对 true、false 进行表达式的短路即可得出表达式优化提取后的情况。例如:

    表达式:
    messageType=='200-trade-paid-done' && buyerId==123456
    提取为两个子表达式:
    子表达式1(messageType==200-trade-paid-done):buyerId==123456 
    子表达式2(messageType!=200-trade-paid-done):false
    • 具体到 aviator 的实现里,表达式编译会把每个 token 构建一个 List ,类似如下图所示(为方便理解,绿色方框的是 token ,其它框表示表达式的具体条件组合):

    5.png

    提取了 messageType ,有两种情况:

    • 情况一:messageType == '200-trade-paid-done',则把之前 token 的位置合并成true,然后进行表达式短路计算,最后优化成 buyerId==123456 ,具体如下:

    6.png

    • 情况二:messageType != '200-trade-paid-done',则把之前 token 的位置合并成 false ,表达式短路计算后,最后优化成 false ,具体如下:

    7.png

    这样就完成 messageType 的提取。这里可能有人就有一个疑问,为什么要考虑到上面的情况二,messageType != '200-trade-paid-done',这是因为必须要考虑到多个条件的时候,比如:

    (messageType=='200-trade-paid-done' && buyerId==123456) || (messageType=='200-trade-success' && buyerId==3333)

    就必须考虑到不等于的情况了。同理,如果考虑到多个表达式嵌套,需要逐步进行短路计算。但整体逻辑是类似的,这里就不再赘述。

    说完技术点 1,我们继续关注技术点 2,考虑到高效过滤,直接使用 HashMap 结构进行索引化即可,即把 messageType 的值作为 HashMap 的 key ,把提取后的子表达式作为 HashMap 的 value ,这样每次过滤直接通过一次 hash 计算即可过滤掉绝大部分不适合的表达式,大大提高了过滤效率。

    3. 优化效果

    该优化最主要降低了 CPU 计算逻辑,根据优化前后的性能情况对比,我们发现不同的交易集群中的订阅方订阅表达式复杂度越高,优化效果越好,这个是符合我们的预期的,其中最大的 CPU 优化有32%的提升,大大降低了本年度 RocketMQ 的部署机器成本。

    全新的消费模型 —— POP 消费

    1. 背景

    RocketMQ 的 PULL 消费对于机器异常 hang 时并不十分友好。如果遇到客户端机器 hang 住,但处于半死不活的状态,与 broker 的心跳没有断掉的时候,客户端 rebalance 依然会分配消费队列到 hang 机器上,并且 hang 机器消费速度很慢甚至无法消费的时候,这样会导致消费堆积。另外类似还有服务端 Broker 发布时,也会由于客户端多次 rebalance 导致消费延迟影响等无法避免的问题。如下图所示:

    8.png

    当 Pull Client 2 发生 hang 机器的时候,它所分配到的三个 Broker 上的 Q2 都出现严重的红色堆积。对于此,我们增加了一种新的消费模型 —— POP 消费,能够解决此类稳定性问题。如下图所示:

    9.png

    POP 消费中,三个客户端并不需要 rebalance 去分配消费队列,取而代之的是,它们都会使用 POP 请求所有的 broker 获取消息进行消费。broker 内部会把自身的三个队列的消息根据一定的算法分配给请求的 POP Client。即使 Pop Client 2 出现 hang,但内部队列的消息也会让 Pop Client1 和 Pop Client2 进行消费。这样就 hang 机器造成的避免了消费堆积。

    2. 实现

    POP 消费和原来 PULL 消费对比,最大的一点就是弱化了队列这个概念,PULL 消费需要客户端通过 rebalance 把 broker 的队列分配好,从而去消费分配到自己专属的队列,新的 POP 消费中,客户端的机器会直接到每个 broker 的队列进行请求消费, broker 会把消息分配返回给等待的机器。随后客户端消费结束后返回对应的 Ack 结果通知 broker,broker 再标记消息消费结果,如果超时没响应或者消费失败,再会进行重试。

    10.png

    POP 消费的架构图如上图所示。Broker 对于每次 POP 的请求,都会有以下三个操作:

    • 对应的队列进行加锁,然后从 store 层获取该队列的消息;
    • 然后写入 CK 消息,表明获取的消息要被 POP 消费;
    • 最后提交当前位点,并释放锁。

    CK 消息实际上是记录了 POP 消息具体位点的定时消息,当客户端超时没响应的时候,CK 消息就会重新被 broker 消费,然后把 CK 消息的位点的消息写入重试队列。如果 broker 收到客户端的消费结果的 Ack ,删除对应的 CK 消息,然后根据具体结果判断是否需要重试。

    从整体流程可见,POP 消费并不需要 reblance ,可以避免 rebalance 带来的消费延时,同时客户端可以消费 broker 的所有队列,这样就可以避免机器 hang 而导致堆积的问题。

    原文链接

    本文为阿里云原创内容,未经允许不得转载。

    展开全文
  • 作者|愈安来源 |阿里巴巴中间件头图|下载于视觉中国2020 年的双十一交易峰值达到 58.3 W笔/秒,消息中间件 RocketMQ 继续数年 0 故障丝般顺滑地完美支持了整...

    作者 | 愈安

    来源 | 阿里巴巴中间件

    头图 | 下载于视觉中国

    2020 年的双十一交易峰值达到 58.3 W笔/秒,消息中间件 RocketMQ 继续数年 0 故障丝般顺滑地完美支持了整个集团大促的各类业务平稳。相比往年,消息中间件 RocketMQ 发生了以下几个方面的变化:

    • 云原生化实践。完成运维层面的云原生化改造,实现 Kubernetes 化。

    • 性能优化。消息过滤优化交易集群性能提升 30%。

    • 全新的消费模型。对于延迟敏感业务提供新的消费模式,降低因发布、重启等场景下导致的消费延迟。

    云原生化实践

      背景 

    Kubernetes 作为目前云原生化技术栈实践中重要的一环,其生态已经逐步建立并日益丰富。目前,服务于集团内部的 RocketMQ 集群拥有巨大的规模以及各种历史因素,因此在运维方面存在相当一部分痛点,我们希望能够通过云原生技术栈来尝试找到对应解决方案,并同时实现降本提效,达到无人值守的自动化运维。

    消息中间件早在 2016 年,通过内部团队提供的中间件部署平台实现了容器化和自动化发布,整体的运维比 2016 年前已经有了很大的提高,但是作为一个有状态的服务,在运维层面仍然存在较多的问题。

    中间件部署平台帮我们完成了资源的申请,容器的创建、初始化、镜像安装等一系列的基础工作,但是因为中间件各个产品都有自己不同的部署逻辑,所以在应用的发布上,就是各应用自己的定制化了。中间件部署平台的开发也不完全了解集团内 RocketMQ 的部署过程是怎样的。

    因此在 2016 年的时候,部署平台需要我们去亲自实现消息中间件的应用发布代码。虽然部署平台大大提升了我们的运维效率,甚至还能实现一键发布,但是这样的方案也有不少的问题。比较明显的就是,当我们的发布逻辑有变化的时候,还需要去修改部署平台对应的代码,需要部署平台升级来支持我们,用最近比较流行的一个说法,就是相当不云原生。

    同样在故障机替换、集群缩容等操作中,存在部分人工参与的工作,如切流,堆积数据的确认等。我们尝试过在部署平台中集成更多消息中间件自己的运维逻辑,不过在其他团队的工程里写自己的业务代码,确实也是一个不太友好的实现方案,因此我们希望通过 Kubernetes 来实现消息中间件自己的 operator 。我们同样希望利用云化后云盘的多副本能力来降低我们的机器成本并降低主备运维的复杂程度。

    经过一段时间的跟进与探讨,最终再次由内部团队承担了建设云原生应用运维平台的任务,并依托于中间件部署平台的经验,借助云原生技术栈,实现对有状态应用自动化运维的突破。

      实现

    整体的实现方案如上图所示,通过自定义的 CRD 对消息中间件的业务模型进行抽象,将原有的在中间件部署平台的业务发布部署逻辑下沉到消息中间件自己的 operator 中,托管在内部 Kubernetes 平台上。该平台负责所有的容器生产、初始化以及集团内一切线上环境的基线部署,屏蔽掉 IaaS 层的所有细节。

    Operator 承担了所有的新建集群、扩容、缩容、迁移的全部逻辑,包括每个 pod 对应的 brokerName 自动生成、配置文件,根据集群不同功能而配置的各种开关,元数据的同步复制等等。同时之前一些人工的相关操作,比如切流时候的流量观察,下线前的堆积数据观察等也全部集成到了 operator 中。当我们有需求重新修改各种运维逻辑的时候,也再也不用去依赖通用的具体实现,修改自己的 operator 即可。

    最后线上的实际部署情况去掉了图中的所有的 replica 备机。在 Kubernetes 的理念中,一个集群中每个实例的状态是一致的,没有依赖关系,而如果按照消息中间件原有的主备成对部署的方案,主备之间是有严格的对应关系,并且在上下线发布过程中有严格的顺序要求,这种部署模式在 Kubernetes 的体系下是并不提倡的。若依然采用以上老的架构方式,会导致实例控制的复杂性和不可控性,同时我们也希望能更多的遵循 Kubernetes 的运维理念。

    云化后的 ECS 使用的是高速云盘,底层将对数据做了多备份,因此数据的可用性得到了保障。并且高速云盘在性能上完全满足 MQ 同步刷盘,因此,此时就可以把之前的异步刷盘改为同步,保证消息写入时的不丢失问题。云原生模式下,所有的实例环境均是一致性的,依托容器技术和 Kubernetes 的技术,可实现任何实例挂掉(包含宕机引起的挂掉),都能自动自愈,快速恢复。

    解决了数据的可靠性和服务的可用性后,整个云原生化后的架构可以变得更加简单,只有 broker 的概念,再无主备之分。

      大促验证

    上图是 Kubernetes 上线后双十一大促当天的发送 RT 统计,可见大促期间的发送 RT 较为平稳,整体符合预期,云原生化实践完成了关键性的里程碑。

    性能优化

      背景

    RocketMQ 至今已经连续七年 0 故障支持集团的双十一大促。自从 RocketMQ 诞生以来,为了能够完全承载包括集团业务中台交易消息等核心链路在内的各类关键业务,复用了原有的上层协议逻辑,使得各类业务方完全无感知的切换到 RocketMQ 上,并同时充分享受了更为稳定和强大的 RocketMQ 消息中间件的各类特性。

    当前,申请订阅业务中台的核心交易消息的业务方一直都在不断持续增加,并且随着各类业务复杂度提升,业务方的消息订阅配置也变得更加复杂繁琐,从而使得交易集群的进行过滤的计算逻辑也变得更为复杂。这些业务方部分沿用旧的协议逻辑(Header过滤),部分使用 RocketMQ 特有的 SQL 过滤。

      主要成本

    目前集团内部 RocketMQ 的大促机器成本绝大部分都是交易消息相关的集群,在双十一零点峰值期间,交易集群的峰值和交易峰值成正比,叠加每年新增的复杂订阅带来了额外 CPU 过滤计算逻辑,交易集群都是大促中机器成本增长最大的地方。

      优化过程

    由于历史原因,大部分的业务方主要还是使用Header过滤,内部实现其实是aviator表达式( https://github.com/killme2008/aviatorscript )。仔细观察交易消息集群的业务方过滤表达式,可以发现绝大部分都指定类似 MessageType == xxxx 这样的条件。翻看aviator的源码可以发现这样的条件最终会调用Java的字符串比较 String.compareTo()。

    由于交易消息包括大量不同业务的MessageType,光是有记录的起码有几千个,随着交易业务流程复杂化,MessageType的增长更是繁多。随着交易峰值的提高,交易消息峰值正比增长,叠加这部分更加复杂的过滤,持续增长的将来,交易集群的成本极可能和交易峰值指数增长,因此决心对这部分进行优化。

    原有的过滤流程如下,每个交易消息需要逐个匹配不同group的订阅关系表达式,如果符合表达式,则选取对应的group的机器进行投递。如下图所示:

    对此流程进行优化的思路需要一定的灵感,在这里借助数据库索引的思路:原有流程可以把所有订阅方的过滤表达式看作数据库的记录,每次消息过滤就相当于一个带有特定条件的数据库查询,把所有匹配查询(消息)的记录(过滤表达式)选取出来作为结果。为了加快查询结果,可以选择 MessageType 作为一个索引字段进行索引化,每次查询变为先匹配 MessageType 主索引,然后把匹配上主索引的记录再进行其它条件(如下图的 sellerId 和 testA )匹配,优化流程如下图所示:

    以上优化流程确定后,要关注的技术点有两个:

    1. 如何抽取每个表达式中的 MessageType 字段?

    2. 如何对 MessageType 字段进行索引化?

    对于技术点 1 ,需要针对 aviator 的编译流程进行 hook ,深入 aviator 源码后,可以发现 aviator 的编译是典型的 Recursive descent :

     http://en.wikipedia.org/wiki/Recursive_descent_parser 

    同时需要考虑到提取后父表达式的短路问题。

    在编译过程中针对 messageType==XXX 这种类型进行提取后,把原有的 message==XXX 转变为 true/false 两种情况,然后针对 true、false 进行表达式的短路即可得出表达式优化提取后的情况。例如:

    表达式:messageType=='200-trade-paid-done' && buyerId==123456提取为两个子表达式:子表达式1(messageType==200-trade-paid-done):buyerId==123456 子表达式2(messageType!=200-trade-paid-done):false
    
    
    • 具体到 aviator 的实现里,表达式编译会把每个 token 构建一个 List ,类似如下图所示(为方便理解,绿色方框的是 token ,其它框表示表达式的具体条件组合):

    提取了 messageType ,有两种情况:

    • 情况一:messageType == '200-trade-paid-done',则把之前 token 的位置合并成true,然后进行表达式短路计算,最后优化成 buyerId==123456 ,具体如下:

    • 情况二:messageType != '200-trade-paid-done',则把之前 token 的位置合并成 false ,表达式短路计算后,最后优化成 false ,具体如下:

    这样就完成 messageType 的提取。这里可能有人就有一个疑问,为什么要考虑到上面的情况二,messageType != '200-trade-paid-done',这是因为必须要考虑到多个条件的时候,比如:

    (messageType=='200-trade-paid-done' && buyerId==123456) || (messageType=='200-trade-success' && buyerId==3333)

    就必须考虑到不等于的情况了。同理,如果考虑到多个表达式嵌套,需要逐步进行短路计算。但整体逻辑是类似的,这里就不再赘述。

    说完技术点1,我们继续关注技术点2,考虑到高效过滤,直接使用 HashMap 结构进行索引化即可,即把 messageType 的值作为 HashMap 的 key ,把提取后的子表达式作为 HashMap 的 value ,这样每次过滤直接通过一次 hash 计算即可过滤掉绝大部分不适合的表达式,大大提高了过滤效率。

      优化效果

    该优化最主要降低了 CPU 计算逻辑,根据优化前后的性能情况对比,我们发现不同的交易集群中的订阅方订阅表达式复杂度越高,优化效果越好,这个是符合我们的预期的,其中最大的 CPU 优化有 32% 的提升,大大降低了本年度 RocketMQ 的部署机器成本。

    全新的消费模型 —— POP 消费

      背景

    RocketMQ的PULL消费对于机器异常hang时并不十分友好。如果遇到客户端机器hang住,但处于半死不活的状态,与broker的心跳没有断掉的时候,客户端rebalance依然会分配消费队列到hang机器上,并且hang机器消费速度很慢甚至无法消费的时候,这样会导致消费堆积。另外类似还有服务端Broker发布时,也会由于客户端多次rebalance导致消费延迟影响等无法避免的问题。如下图所示:

    当Pull Client 2发生hang机器的时候,它所分配到的三个Broker上的Q2都出现严重的红色堆积。对于此,我们增加了一种新的消费模型——POP消费,能够解决此类稳定性问题。如下图所示:

    POP消费中,三个客户端并不需要rebalance去分配消费队列,取而代之的是,它们都会使用POP请求所有的broker获取消息进行消费。broker内部会把自身的三个队列的消息根据一定的算法分配给请求的POP Client。即使Pop Client 2出现hang,但内部队列的消息也会让Pop Client1 和Pop Client2进行消费。这样就hang机器造成的避免了消费堆积。

      实现

    POP 消费和原来 PULL 消费对比,最大的一点就是弱化了队列这个概念,PULL 消费需要客户端通过 rebalance 把 broker 的队列分配好,从而去消费分配到自己专属的队列,新的 POP 消费中,客户端的机器会直接到每个 broker 的队列进行请求消费, broker 会把消息分配返回给等待的机器。随后客户端消费结束后返回对应的 Ack 结果通知 broker,broker 再标记消息消费结果,如果超时没响应或者消费失败,再会进行重试。

    POP 消费的架构图如上图所示。Broker 对于每次 POP 的请求,都会有以下三个操作:

    1. 对应的队列进行加锁,然后从 store 层获取该队列的消息;

    2. 然后写入 CK 消息,表明获取的消息要被 POP 消费;

    3. 最后提交当前位点,并释放锁。

    CK 消息实际上是记录了 POP 消息具体位点的定时消息,当客户端超时没响应的时候,CK 消息就会重新被 broker 消费,然后把 CK 消息的位点的消息写入重试队列。如果 broker 收到客户端的消费结果的 Ack ,删除对应的 CK 消息,然后根据具体结果判断是否需要重试。

    从整体流程可见,POP 消费并不需要 reblance ,可以避免 rebalance 带来的消费延时,同时客户端可以消费 broker 的所有队列,这样就可以避免机器 hang 而导致堆积的问题。

    更多阅读推荐

    展开全文
  • 阿里双十一的四种应用场景 MDB 典型应用场景 用于缓存,降低对后端数据库的访问压力。 临时数据存储,部分数据丢失不会对业务产生较大影响。 读多写少,读qps达到万级别以上。 FastDump 典型应用场景 周期性地...
  • 首先说一个众所周知的数据:2017年双十一天猫成交...1、全网热度分析:双十一活动在全网的热度变化趋势、关注来源、媒体来源以及关联词分析。 2、各平台对比分析:针对“天猫”“京东”“苏宁”等一些电商平台的销...
  • 双十一流量洪峰将至,身为大数据工程师的你,还在苦学Spark、Hadoop、Storm,却还没搞过Flink?去年双十一,阿里在Flink实时计算技术的驱动下全程保持了“如丝般顺滑...
  • 2684亿!双十一背后的技术

    千次阅读 2019-11-11 20:52:47
    2019年阿里巴巴双十一交易额:2684亿 作为技术行业者的你,是否对这数据背后的技术更感兴趣? 这千亿级的交易量,业务平台是如何支撑的呢?!作为技术小白的我,按个人的经验和所了解的一些技术,对双十一的技术栈...
  • 双十一限制退款说起 每年的电商大促活动,规模最大的就是双十一促销,双十一已经从光棍节,演变成了国内最大的电商促销活动。每年的双十一,我都会买一些打折力度比较大的商品,特别是数码产品,比如相机、键盘等...
  • 今年双十一,当高并发、维稳已经不再那么让阿里人「如临大敌」之时,阿里技术体系又发生了哪些重要变化?
  • 女朋友问阿里双十一实时大屏如何实现,不懂技术的她居然好奇问这个,身为程序员的我只能用毕生所学开始跟她讲大数据技术。 全网最详细的大数据文章系列,强烈建议收藏加关注! 目录 历史文章 前言 阿里双十一...
  • 最近听了公司内部对“双十一”期间为了应对大流量访问而采取的策略的分享,这里做下记录。主要有以下几个方面, 1.限流 流量入口通过Nginx来进行限流,对接redis,如果秒访问量超过系统能处理的阈值,则直接给用户...
  • 刚刚过去的 2018 年天猫“双11”,创下了全天 2135 亿 GMV 的数字奇迹,零点交易峰值比往年提升 50%,各项指标均创下历史新高。 2018 年是“双11”的第十年,也是阿里系统软件事业部参与的第二个“双11”,系统软件...
  • 在整个交易的链路上,账单业务是一个重要的环节,尤其对商家系统来说,需要定期对账,账单子系统出现一点点问题都会影响商家的运营,2018的双十一,承载账单的消息系统把全网卖家账单系统60%的流量托付给了阿里...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,259
精华内容 1,303
关键字:

双十一峰值流量