本文主要是介绍微信开源 PhxQueue:“三高“的分布式队列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
导语 本文首先介绍了微信开源分布式队列 PhxQueue 的诞生背景及架构设计,然后着重在设计、性能、存储层 Fail over 过程三方面与 Kafka 进行了对比。期望了解 PhxQueue 或 Kafka 的读者均能从中获益。
开源地址:https://git.code.oa.com/wxg-td/phxqueue
PhxQueue 是微信开源的一款基于 Paxos 协议实现的高可用、高吞吐和高可靠的分布式队列,保证At-Least-Once Delivery,在微信内部广泛支持微信支付、公众平台等多个重要业务。
消息队列概述
消息队列作为成熟的异步通信模式,对比常用的同步通信模式,有如下优势:
- 解耦:防止引入过多的 API 给系统的稳定性带来风险;调用方使用不当会给被调用方系统造成压力,被调用方处理不当会降低调用方系统的响应能力。
- 削峰和流控:消息生产者不会堵塞,突发消息缓存在队列中,消费者按照实际能力读取消息。
- 复用:一次发布多方订阅。
PhxQueue诞生背景
旧队列
微信初期使用的分布式队列(称为旧队列)是微信后台自研的重要组件,广泛应用在各种业务场景中,为业务提供解耦、缓存、异步化等能力。
旧队列以 Quorum NRW 作为同步机制,其中 N=3、W=R=2,刷盘方式采用异步刷盘,兼顾了性能和可用性。
新需求
随着业务发展,接入业务种类日益增多,旧队列逐渐显得力不从心,主要不足如下:
-
异步刷盘,数据可靠性堪忧
对于支付相关业务,保证数据可靠是首要需求。
目前大多数分布式队列方案是以同步复制+异步刷盘来保证数据可靠性的,但我们认为需要同步刷盘来进一步提高数据可靠性。 -
乱序问题
部分业务提出了绝对有序的需求,但 NRW 并不保证顺序性,无法满足需求。
另外旧队列还存在出队去重、负载均衡等其他方面的问题亟需改善。上述种种促使了我们考虑新的方案。
业界方案的不足
Kafka 是大数据领域常用的消息队列,最初由 LinkedIn 采用 Scala 语言开发,用作 LinkedIn 的活动流追踪和运营系统数据处理管道的基础。
其高吞吐、自动容灾、出入队有序等特性,吸引了众多公司使用,在数据采集、传输场景中发挥着重要作用,详见Powerd By Kafka。
但我们充分调研了 Kafka,认为其在注重数据可靠性的场景下,有如下不足:
Kafka 性能与同步刷盘的矛盾
Kafka 在开启配置 log.flush.interval.messages=1,打开同步刷盘特性后,吞吐会急剧下降。
该现象由如下因素导致:
- SSD 写放大
业务消息平均大小在数 1k 左右。
而 SSD 一次刷盘的最小单位为一个 page size,大小为 4k。
当 Kafka 对大小不足 4k 的消息进行刷盘时,实际写入的物理数据量是消息大小的数倍。导致硬盘写带宽资源被浪费。 - 业务场景下 Producer batch 效果不好
Kafka Producer batch,简单来说,就是把多个消息打包在一起发送到 Broker,广泛用于大数据场景。按道理,batch效果足够,是能抵消写放大的影响的。
但业务场景下的消息生产不同于大数据场景下的日志生产,每个需要入队的业务请求在业务系统中有独立的上下文,batch难度大。即使在业务和Broker之间加入代理层,将Producer转移到代理层内进行batch,也因代理层的节点数众多,batch效果难以提高,导致写放大无法抵消。
Kafka replica 同步设计上的不足
Kafka replica 同步设计概要:
Kafka Broker leader 会跟踪与其保持同步的 follower 列表,该列表称为ISR(即in-sync Replica)。如果一个 follower 宕机,或者落后太多,leader 将把它从ISR中移除。
该同步方式偏重于同步效率,但是在可用性方面表现略显不足:
- Broker fail over 过程成功率下降严重
在3 replicas的场景下,leader 均匀分布在各 Broker 上,一个Broker出现故障,就意味着1/3的 leader、follower 离线,这时读写成功率下降:- 对于 leader 离线的 partition,暂时无法读写,需要等待 Controller 选举出新的 leader 后才能恢复;
- 对于 follower 离线的 partition,也暂时无法读写,需要等待一定时长(取决于 replica.lag.time.max.ms,默认10s)后,leader 将故障 follower 从 ISR 中剔除才能恢复。
也就是说,任意一个 Broker 故障时,读写成功率会在一段时间内降为0。
- 同步延迟取决于最慢节点
在同步复制场景下,需要等待所有节点返回ack。
通过对比 Kafka replica 与 Paxos 的表现,我们认为在同步方式上 Paxos 是更好的选择:
对比项 | Kafka replica | Paxos | Paxos好处 |
---|---|---|---|
Broker fail over 过程成功率 | Leader或follower的离线均会造成短暂时间内无法读写 | 只有 leader 的离线会造成短暂时间内无法读写 | 单节点故障后的 fail over 过程中仍有过半成功率,对大多数不要求绝对有序的业务,换节点重试可避免失败 |
同步延迟 | 需要等待所有节点返回 ack,延迟取决于最慢节点 | 只需等待多数派节点返回 ack,最慢节点并不影响整体吞吐 | 前端等待耗时更短 |
所以,我们基于 Paxos 重新设计了一套分布式队列,并且进行了包括同步刷盘之内的多项优化,完成了 PhxQueue。
PhxQueue 介绍
PhxQueue 目前在微信内部广泛支持微信支付、公众平台等多个重要业务,日均入队达千亿,分钟入队峰值达一亿。
其设计出发点是高数据可靠性,且不失高可用和高吞吐,同时支持多种常见队列特性。
PhxQueue支持的特性如下:
- 同步刷盘,入队数据绝对不丢,自带内部实时对账
- 出入队严格有序
- 多订阅
- 出队限速
- 出队重放
- 所有模块均可平行扩展
- 存储层批量刷盘、同步,保证高吞吐
- 存储层支持同城多中心部署
- 存储层自动容灾/接入均衡
- 消费者自动容灾/负载均衡
PhxQueue 设计
整体架构
PhxQueue 由下列5个模块组成。
Store - 队列存储
Store 作为队列存储,引入了 PhxPaxos 库,以 Paxos 协议作副本同步。只要多数派节点正常工作及互联,即可提供线性一致性读写服务。
为了提高数据可靠性,同步刷盘作为默认开启特性,且性能不亚于异步刷盘。
在可用性方面,Store 内有多个独立的 paxos group,每个 paxos group 仅 master 提供读写服务,平时 master 动态均匀分布在 Store 内各节点,均衡接入压力,节点出灾时自动切换 master 到其它可用节点。
Producer - 生产者
Producer 作为消息生产者,根据 key 决定消息存储路由。相同 key 的消息默认路由到同一个队列中,保证出队顺序与入队顺序一致。
Consumer - 消费者
Consumer 作为消费者,以批量拉取的方式从 Store 拉消息,支持多协程方式批量处理消息。
Consumer 以服务框架的形式提供服务,使用者以实现回调的方式,根据不同主题(Topic),不同处理类型(Handler)定义具体的消息处理逻辑。
Scheduler - 消费者管理器(可选择部署)
Scheduler 的作用是,收集 Consumer 全局负载信息, 对 Consumer 做容灾和负载均衡。当使用者没有这方面的需求时,可以省略部署 Scheduler,此时各 Consumer 根据配置权重决定与队列的处理关系。
部署 Scheduler 后,Scheduler leader 与所有 Conusmer 维持心跳,在收集 Consumer 的负载信息的同时,反向调整 Consumer 与队列的处理关系。
当 Scheduler leader 宕机了后,Scheduler 依赖下述分布式锁服务选举出新 leader,不可用期间仅影响 Consumer 的容灾和负载均衡,不影响 Consumer 的正常消费。
Lock - 分布式锁(可选择部署)
Lock 是一个分布式锁,其接口设计非常通用化,使用者可以选择将 Lock 独立部署,提供通用分布式锁服务。
Lock 在 PhxQueue 中的作用有如下两点:
- 为 Scheduler 选举 leader;
- 防止多个 Consumer 同时处理一条队列。
Lock 同样也是可选择部署的模块:
- 若部署了 Scheduler,就必须部署 Lock 为 Scheduler 选举出 leader;
- 否则,若业务对重复消费不敏感,可选择不部署 Lock。
这里所指的重复消费场景是:若省略部署 Scheduler 的话,Consumer 需要通过读取配置得知可处理的队列集合;当队列有变更(如队列缩扩容)时,各 Consumer 机器上的配置改变有先有后,这时各 Consumer 在同一时间看到的配置状态可能不一样,导致一段时间内两个 Consumer 都认为自己该消费同一个队列,造成重复消费。Lock 的部署可以避免该场景下的重复消费。(注意,即使省略部署 Lock,该场景仅造成重复消费,而不会造成乱序消费)
Store 复制流程
PhxQueue Store 通过 PhxPaxos库 进行副本复制。
PhxPaxos 的工程实现方式分为三层:app 层负责处理业务请求,paxos 层执行 paxos同步过程,状态机层更新业务状态。
其中,app 层发起 paxos 提议,paxos 层各节点通过 paxos 协议共同完成一个 paxos log 的确认,之后状态机以 paxos log 作为的输入作状态转移,更新业务的状态,最后返回状态转移结果给 app 层。
一致的状态机层,加上来自 paxos 层的一致输入,就产生一致的状态转移,从而保证多个节点强一致。
这里我们要基于 PhxPaxos 在状态机层实现一个队列,就需要作如下概念映射:
队列概念 | PhxPaxos概念 | PhxPaxos概念解析 |
---|---|---|
队列数据 | paxos log | paxos 日志,其值由 paxos 算法确定,在各节点内强一致 |
队列偏移 | instance id | paxos 日志的唯一编号,严格递增 |
队列读偏移 | check point | 构成状态机镜像的最大 instance id,该 id 之前的 paxos 日志可删除 |
- 队列这种模型不涉及数据修改,是有序的数据集合,和 paxos log 的定义很像,所以可以让入队的数据直接作为 paxos log,而状态机只需要保存 paxos log 序列。
- instance id 的严格递增特性,使得它可以方便地作为队列偏移。
- 队列中读偏移之前的数据,认为是可以删除的数据,这点和 check point 的定义一致。
整体上队列状态机和 paxos 能很好地切合。
Store Group Commit - 高效刷盘及副本同步
未经优化的 Paxos 协议并未解决同步刷盘的写放大问题。而且,其副本同步效率不如 Kafka。
原因是,Kafka 的副本同步是流式批量的,而 Paxos 协议是以 paxos log 为单位串行同步,每个 paxos log 的同步开销是 1个RTT + 1次刷盘。
在多DC部署的场景下,ping 时延可达4ms,这样会导致单个 paxos group 的理论最高 TPS 仅250。
我们采用多 paxos group 部署 以及 Group Commit 的方式来同时解决同步刷盘的写放大问题以及Paxos吞吐问题。
如上图, 我们部署多个 paxos group,以 paxos group 作为 Group Commit 的单位,一个 paxos group 内对应多个 queue,将多个 queue 在一段时间内入队的数据合并在一起,当等待耗时或积累数据数目达到阀值,才会触发一次 Paxos 同步和同步刷盘,等待期间前端阻塞。
与 Kafka 的 Producer 批量逻辑相比,在存储层以 Group Commit 进行批量合并的好处如下:
- 业务层无需关注如何组织请求进行批量;
- 在存储层以 paxos group 为单位的聚合效果比上层聚合效果更好。
PhxQueue 与 Kafka 对比
下面分别从设计、性能、存储层 failover 过程三方面对比 PhxQueue 与 Kafka。
设计对比
PhxQueue 架构虽然与 Kafka 等常见分布式队列类似,但设计上仍有不少独特之处。为了能让对 Kafka 有一定了解的读者更方便地了解 PhxQueue,下面列出了两者的对比。
注:以下对比基于相同的数据可靠性场景:少数派节点失效,不会造成数据丢失,且整体依旧可用。
特性 | PhxQueue 设计 | Kafka 设计 | 总结 |
---|---|---|---|
水平扩展最小粒度 | queue | partition | 两者均以分区作为水平扩展的最小粒度,PhxQueue 定义为 queue,Kafka 定义为 partition。 |
物理文件存储粒度 | paxos group | partition | 存储所用的物理文件数,决定了磁盘写并发。一个 paxos group/partition 对应着一个物理文件。与 Kafka 不同的是,PhxQueue 有意区分 queue 和 paxos group 的概念。一个 queue 只属于一个 paxos group,一个 paxos group 内可包含多个 queue,从而避免逻辑水平扩展影响写盘并发。 |
存储层的可写角色 | master | leader | PhxQueue 与 Kafka 均只有 master/leader 可写。 |
存储层 master(leader) 分布 | 自动均匀分布到各节点 | 自动均匀分布到各节点 | PhxQueue 与 Kafka 均支持 master(leader) 自动均衡,分摊接入压力到各节点。 |
存储层 master(leader) 选举 | Store 自身依赖 Paxos 选举 master | Broker 依赖 Zookeeper 选举出 Controller,再由 Controller 选举出各分区的 leader | Kafka Broker 引入 Controller 解决了 Zookeeper 压力大的问题;PhxQueue Store 不依赖外部选举,每一组均能独立进行 Paxos 决议,分散了选举压力。 |
批量生产能力 | Producer、Store 均有独立的 batch 逻辑 | 仅 Producer 有 batch 逻辑 | batch 逻辑是提高吞吐的杀手锏。PhxQueue 为了应对高扇入场景下 Producer 端 batch 效果不好的情况,在 Store 中加入了 batch 逻辑。 |
生产确认 | Paxos 协议,多数派 accept 即完成同步 | 全同步协议,所有 ISR 返回 ack 后完成同步 | PhxQueue 只需多数派应答即可完成同步,Kafka 同步需要等待最慢节点。 |
存储层的组间容灾隔离 | 有 | 无 | 对于 PhxQueue,Paxos 只要求组内多数节点存活即可完成写入,所以单节点离线造成的失败,可以在组内换节点重试成功;对于 Kafka,单节点离线会造成整组暂时不可写,重试逻辑需要换组进行,相当于一个组的请求转移到了别的组,有可能压垮别的组,牺牲了组间容灾隔离。 |
存储层的服务发现 | 通过本地配置文件获取存储层信息 | 通过 Metadata RPC 获取存储层信息 | PhxQueue 通过配置文件做服务发现,使用者需维护各机器配置的一致性;Kafka 以 Zookeeper 作为配置管理中心,为了避免性能下降及提高稳定性,没有直接将 Zookeeper 暴露给使用方,而是使用 RPC 的方式返回信息。 |
消费隔离 | 以订阅(Sub)为单位 | 以消费分组(Consumer Group)为单位 | 两者均支持消费隔离。 |
消费管理 | 各 Consumer 与 Schduler 维持心跳并上报负载,Schduler 根据负载调整各 Consumer 的消费权重,Consumer 再根据消费权重决定要处理的队列 | 由 Coordinator 对每个 Consumer Group 选举出一个 Consumer 作为 leader,决定该 Consumer Group 内的队列分配 | 为了适应混合部署的场景,PhxQueue 新增了负载均衡功能,当某 Consumer 负载过高时,可自动调整分配;Kafka并无该功能。 |
性能对比
测试环境
CPU: 64 x Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz
Memory: 64 GB
Network: 10 Gigabit Ethernet
Disk: SSD Raid 10
Cluster Nodes: 3
Ping: 1ms
测试基准及配置
基准描述 | 基准要求 | PhxQueue | Kafka | 备注 |
---|---|---|---|---|
刷盘并发 | 100并发 | 100 queues, 100 paxos group | 100 partitions | 测试环境硬盘为 SSD,高并发能获得高吞吐 |
副本同步方式 | 3 replicas | 3 Stores | replication.factor=3;min.insync.replicas=2;request.required.acks=-1 | 3 replicas 部署;要求一个 replica 不可用时,整体仍可用,且数据不丢 |
入队数据大小 | 10字节 | 10字节 | 无 |
测试结果
开启 Producer Batch:
入队 QPS(w/s) | 平均耗时(ms) | |
---|---|---|
PhxQueue(同步刷盘) | 18 | 90 |
Kafka(异步刷盘) | 18 | 120 |
Kafka(同步刷盘) | 9 | 290 |
以上场景,PhxQueue 瓶颈在 cpu,使用率达70% ~ 80%。
小结
- PhxQueue 性能与 Kafka 持平;
- 相同 QPS 下,由于不用等最慢节点返回,PhxQueue 平均耗时比 Kafka 稍优;
- 关闭 Producer Batch 后,在同步刷盘场景下,PhxQueue 性能可达 Kafka 的2倍,原因是,PhxQueue 存储层在写盘前做了 batch,而 Kafka 没有,所以后者会有写放大。
存储层 failover 过程对比
主要对比杀死存储层的一个节点后,对整体吞吐的影响。
Kafka
表现:
- Failover 期间,在不同阶段程度不同,入队成功率在0% ~ 33%;
- Failover 持续时间由租约决定,租约时长默认10s。
测试过程:
将 replica.lag.time.max.ms 从 10s 调整为 60s(延长时间方便观察),然后 kill Broker 0,挑选3个 partition,观察 ISR 变化如下:
第一阶段(未 kill Broker 0):Topic: test-dis-p100 Partition: 96 Leader: 0 Replicas: 0,1,2 Isr: 1,0,2Topic: test-dis-p100 Partition: 97 Leader: 1 Replicas: 1,2,0 Isr: 1,0,2Topic: test-dis-p100 Partition: 98 Leader: 2 Replicas: 2,0,1 Isr: 1,0,2
第二阶段(kill Broker 0 后持续8s):Topic: test-dis-p100 Partition: 96 Leader: 0 Replicas: 0,1,2 Isr: 1,0,2Topic: test-dis-p100 Partition: 97 Leader: 1 Replicas: 1,2,0 Isr: 1,0,2Topic: test-dis-p100 Partition: 98 Leader: 2 Replicas: 2,0,1 Isr: 1,0,2
第三阶段(持续1分钟左右):- List itemTopic: test-dis-p100 Partition: 96 Leader: 1 Replicas: 0,1,2 Isr: 2,1Topic: test-dis-p100 Partition: 97 Leader: 1 Replicas: 1,2,0 Isr: 2,1,0Topic: test-dis-p100 Partition: 98 Leader: 2 Replicas: 2,0,1 Isr: 2,1,0
第四阶段(至此入队成功率完全恢复):Topic: test-dis-p100 Partition: 96 Leader: 1 Replicas: 0,1,2 Isr: 2,1Topic: test-dis-p100 Partition: 97 Leader: 1 Replicas: 1,2,0 Isr: 2,1Topic: test-dis-p100 Partition: 98 Leader: 2 Replicas: 2,0,1 Isr: 2,1
其中,第二/三阶段入队成功率受损:
- 第二阶段期间,Partition 96/97/98 均无法写入,入队成功率成功率下降至0%。
- 第三阶段期间,Partition 96 可继续写入,但 Partition 97/98 无法写入,因为写入要等 Broker 0 回 ack,但 Broker 0 已 kill,入队成功率下降至33%。
而实际观察,第二/三阶段期间完全没吞吐,原因是压测工具不断报连接失败,停止了写入。
压测工具输出:
30551 records sent, 6107.8 records/sec (0.06 MB/sec), 1733.9 ms avg latency, 5042.0 max latency.
30620 records sent, 6117.9 records/sec (0.06 MB/sec), 1771.9 ms avg latency, 5076.0 max latency.
30723 records sent, 6123.8 records/sec (0.06 MB/sec), 1745.4 ms avg latency, 5009.0 max latency.
30716 records sent, 6127.3 records/sec (0.06 MB/sec), 1841.1 ms avg latency, 5299.0 max latency.
30674 records sent, 6133.6 records/sec (0.06 MB/sec), 1621.3 ms avg latency, 4644.0 max latency.
>>>>>>>>>> kill Broker 0 here (入队成功率受损)>>>>>>>>>>
10580 records sent, 123.4 records/sec (0.00 MB/sec), 1537.1 ms avg latency, 84236.0 max latency. <<-----吞吐下降严重
11362 records sent, 132.3 records/sec (0.00 MB/sec), 1658.3 ms avg latency, 84232.0 max latency.
11367 records sent, 132.3 records/sec (0.00 MB/sec), 1582.4 ms avg latency, 84228.0 max latency.
11236 records sent, 130.9 records/sec (0.00 MB/sec), 1694.2 ms avg latency, 84240.0 max latency.
11406 records sent, 132.8 records/sec (0.00 MB/sec), 1650.5 ms avg latency, 84233.0 max latency.
压测工具连接Broker失败日志:
[2017-08-16 15:38:22,844] WARN Connection to node 0 could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient)
[2017-08-16 15:38:22,859] WARN Connection to node 0 could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient)
[2017-08-16 15:38:22,865] WARN Connection to node 0 could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient)
[2017-08-16 15:38:22,868] WARN Connection to node 0 could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient)
原因分析:
Kafka Broker leader 是通过 Controller 选举出来的,ISR 列表是 leader 维护的。
前者的的租约是 Controller 定义的,后者的租约是 Broker 配置 replica.lag.time.max.ms 指定的。
所以,第二阶段持续时间较短,是 Controller 的租约时间决定的,第三阶段持续时间较长,是 replica.lag.time.max.ms 决定的。
当 Broker 0 被 kill 时,前者影响本来 Broker 0 是 leader 的 1/3 partitions 的入队成功率,后者影响 Broker 0 作为 follower 的 2/3 partitions 的入队成功率。
PhxQueue
表现:
- Failover 期间,入队成功率仅下降至66%;
- Failover 持续时间由租约决定,租约时长默认5s。
- 开启 换队列重试特性(适合没有绝对顺序性要求的业务提高可用性)后,Failover 期间仍有90+%入队成功率。
测试过程:
将 Store master 租约时长从10s调整为60s(延长时间方便观察),然后kill store 0,观察某 Producer 入队成功率:
关闭换队列重试特性:
>>>>>>>>>> kill store 0 here (入队成功率受损)>>>>>>>>>>-------------------------------------------
-- total: 192323
-- time(ms): 10015
-- qps: 19203.49
-- routine_sleep: 73.88%
-- retcode cnt percent
-- -1 22097 11.49 <<---------------------- 失败:连接失败
-- 0 125905 65.47 <<---------------------- 成功:仍有66%成功率
-- 10102 44321 23.05 <<---------------------- 失败:提示需要重定向到 master
-- usetime(ms) cnt percent
-- < 1 0 0.00
-- < 2 0 0.00
-- < 5 610 0.32
-- < 10 7344 3.82
-- < 20 18937 9.85
-- < 50 36067 18.75
-- < 100 6971 3.62
-- < 200 20239 10.52
-- < 500 59059 30.71
-- < 1000 30601 15.91
-- >= 1000 12495 6.50>>>>>>>>>> (入队成功率完全恢复)>>>>>>>>>>-------------------------------------------
-- total: 198955
-- time(ms): 10001
-- qps: 19893.51
-- routine_sleep: 98.00%
-- retcode cnt percent
-- 0 198955 100.00 <<---------------------- 成功:100%成功率
-- usetime(ms) cnt percent
-- < 1 0 0.00
-- < 2 2 0.00
-- < 5 5895 2.96
-- < 10 30830 15.50
-- < 20 65887 33.12
-- < 50 95403 47.95
-- < 100 753 0.38
-- < 200 185 0.09
-- < 500 0 0.00
-- < 1000 0 0.00
-- >= 1000 0 0.00
开启换队列重试特性:
>>>>>>>>>> kill store 0 here (入队成功率受损)>>>>>>>>>>-------------------------------------------
-- total: 134752
-- time(ms): 10001
-- qps: 13473.85
-- routine_sleep: 77.43%
-- retcode cnt percent
-- -202 14 0.01 <<---------------------- 失败:超时
-- -1 2712 2.01 <<---------------------- 失败:连接失败
-- 0 127427 94.56 <<------------------------- 成功:仍有94%成功率
-- 10102 4572 3.39 <<---------------------- 失败:提示需要重定向到 master
-- 10105 27 0.02 <<---------------------- 失败:master 未选举出来
-- usetime(ms) cnt percent
-- < 1 0 0.00
-- < 2 4 0.00
-- < 5 3284 2.44
-- < 10 10704 7.94
-- < 20 22109 16.41
-- < 50 32752 24.31
-- < 100 4541 3.37
-- < 200 4331 3.21
-- < 500 11265 8.36
-- < 1000 19706 14.62
-- >= 1000 26056 19.34>>>>>>>>>> (入队成功率完全恢复)>>>>>>>>>>-------------------------------------------
-- total: 198234
-- time(ms): 10014
-- qps: 19795.69
-- routine_sleep: 94.36%
-- retcode cnt percent
-- 0 198234 100.00 <<---------------------- 成功:100%成功率
-- usetime(ms) cnt percent
-- < 1 0 0.00
-- < 2 0 0.00
-- < 5 3875 1.95
-- < 10 22978 11.59
-- < 20 53000 26.74
-- < 50 87575 44.18
-- < 100 6204 3.13
-- < 200 6468 3.26
-- < 500 11963 6.03
-- < 1000 5637 2.84
-- >= 1000 534 0.27
小结
- 在存储层 failover 过程中,PhxQueue 和 Kafka 的入队成功率均有一定时长的下降,PhxQueue 的入队成功率在66% ~ 100%,Kafka 的入队成功率在0% ~ 33%;
- PhxQueue 开启换队列重试特性后,failover 过程中入队成功率保持在90+%。
- PhxQueue 和 Kafka 均能自动切换 master,最终入队成功率完全恢复。
总结
PhxQueue 在存储层做了很多的努力:实现了 master 自动切换,且仍然保证线性一致,切换期间仍然高可用;保证了同步刷盘的吞吐,其性能不亚于异步刷盘。
另外实现了大部分队列实用特性,例如出入队顺序一致、多订阅、限速、消息重放等,适用于各种业务场景。
目前 PhxQueue 已在微信内部大规模使用,也正式开源。
我们将保持 PhxQueue 开源版本与内部版本的一致,欢迎读者试用并反馈意见。
开源地址:https://github.com/Tencent/phxqueue
这篇关于微信开源 PhxQueue:“三高“的分布式队列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!