Spring XD 基准测试 第 1 部分

工程 | Glenn Renfro | 2015 年 6 月 17 日 | ...

#简介#

在开发流式应用程序时,一个常见的问题是:“每秒可以处理多少个事件?”。这篇博文的首要目的是回答这个问题,同时避免陷入基准测试的经典难题,即基准测试与“营销测试”的区别。消息中间件供应商提供的“原生”基准测试应用程序的常见方法是专注于原始数据传输速度,而不考虑消息数据的序列化或反序列化,也不进行任何数据处理。在本系列的第 1 部分中,我们将采用这种方法。

我们的测试在 Spring XD 中使用了直接绑定(内存中)和 Apache KafkaⓇ 传输,场景是生产者和消费者同时运行。此测试场景模拟实时流处理,而不是仅使用生产者或仅使用消费者的测试套件。测试场景对直接绑定使用单个容器,对 Kafka 传输使用多个容器。每个测试都改变事件(消息)的大小,结果以每秒消耗的总消息数和 MB 数显示。在 Kafka 传输测试的情况下,我们使用了 Kafka 提供的性能工具来为我们提供已配置基础设施的基准测试。##什么是 Spring XD?## Spring XD 是一个统一的、分布式的、可扩展的系统,用于数据摄取、实时分析、批处理和数据导出。该项目的目的是简化大数据或企业流/批处理应用程序的开发。有关 XD 的更多信息,请参见此处。##架构## 所有测试均使用 RackSpace OnMetal 服务器运行,以保证所有服务的网络速度,并为基于 Kafka 的测试提供适当的磁盘写入速度。有关此选择的更多详细信息,请参见下文。所用服务器的规格如下:###服务器实例类型###

  • 用于 Spring XD 的 OnMetal 计算实例
    • Intel® Xeon® E5-2680 v2 2.8Ghz
    • 1x10 核
    • 32GB RAM
    • 启动设备(32GB SATADOM)
  • 用于 Kafka 的 OnMetal IO 实例
    • Intel® Xeon® E5-2680 v2 2.8Ghz
    • 1x10 核
    • 128 GB RAM
    • 启动设备(32GB SATADOM)
    • 双 1.6 TB PCIe 闪存卡(数据磁盘)
  • 用于 Zookeeper 的 Rackspace 计算 V1(使用了较小的实例类型,因为 Zookeeper 的占用空间不大)
    • 2 个 vCPU
    • 3.75GB RAM
    • 启动设备(50 GB 高性能 SSD)

###网络:### 所有测试都在 10 千兆位网络上运行 Spring XD,平均速度为 1117 MB/s 或 8.936 Gbps。我们使用 iperf 确定网络性能,客户端使用以下命令: iperf -c -f Mbytes,服务器使用命令:iperf -s。###磁盘:### 所有需要高性能磁盘写入的测试都实现在 OnMetal IO 数据磁盘上。这些设备的平均磁盘写入速度约为 ~934 MB/s。用于验证磁盘写入速度的命令为: dd if=/dev/zero of=/data1/largefile bs=1M count=10000 conv=fdatasync。dd 命令上的 fdatasync 要求在退出之前进行完全“同步”,从而验证数据完全写入磁盘而不是缓存。##工具## 用于测试传输的两个主要工具是负载生成器 源模块和吞吐量 接收器模块,它们可以在 github 上的spring-xd-modules 项目中找到。负载生成器源模块在内存中生成数据,并且可以配置为发送特定数量的特定大小的消息。吞吐量模块是一个接收器,它计算接收到的消息,并定期将观察到的吞吐量报告到日志中。

#传输测试# ##直接绑定传输## 为了消除网络延迟,有时希望允许位于同一位置的连续模块直接通信,而不是使用配置的远程传输。Spring XD 默认情况下仅在生产者和消费者(绑定在管道两侧的模块)的每个“对”都保证位于同一 JVM 中时才创建直接绑定。此基准测试的目的是显示使用直接绑定单个 XD 容器的消息吞吐量。在此场景中,我们在单个容器中发送和消费了 5 亿条消息。以下流定义用于捕获 1000 字节消息测试的结果:stream create directBindingTest --definition "load-generator --messageCount=500000000 --messageSize=1000 | throughput" stream deploy directBindingTest --properties module.*.count=0 下图显示了消息大小为 100、1000、10000 和 100000 字节时的每秒消息/MB 数:###每秒消息数### 直接绑定每秒消息数 ###每秒兆字节数### 直接绑定每秒兆字节数

消息大小 每秒消息数 XD 每秒兆字节数 XD
100 12,919,560 1,232
1,000 5,126,920 4,893
10,000 1,121,921 10,699
100,000 152,364 14,530

图表显示,随着消息大小的增加,速率会下降,但总体数据吞吐量会增加。对于 100 到 1000 字节范围内的典型大小有效负载,我们能够使用单个线程每秒推送 500 万到 1200 万个事件。在此规模下执行小型操作(例如访问哈希表中的数据)的成本意味着任何数据处理都会显着降低速率。

##Kafka 传输## ###测试拓扑###

对于使用 Kafka 进行测试,我们创建了以下拓扑

![拓扑](https://github.com/markpollack/spring-xd-images/blob/master/xdkafkadeployment.jpg?raw=true)
使用 Spring XD 和 Kafka 的测试拓扑

在三个 OnMetal I/O 实例上设置了一个三节点 Kafka 集群。每个 Kafka 实例有两个 SSD,没有 RAID。一个 Zookeeper 实例在 Kafka 代理和 XD 之间共享,并部署在 Compute v1 Rackspace 实例上。XD 集群部署在 2 个 OnMetal 计算实例上。RS(RackSpace)实例一托管一个 XD-Admin、一个 HSQLDB 和一个 xd 容器。RS(RackSpace)实例二托管一个 xd 容器。

####实例类型选择#### 实例类型是根据处理器速度、磁盘写入速度和能够处理大量数据的网络选择的。最初,测试计划在 EC2 上进行,但我们发现临时磁盘写入速度太慢(约 ~75 MB/s),无法让 Kafka 达到峰值性能。我们计划在新的发布的 D2 实例类型上重新运行测试。我们决定使用 Rackspace OnMetal I/O 来利用高性能 SSD(约 ~934 MB/s)。####测试#### 此基准测试的目的是显示在使用 Kafka 作为传输的情况下,在不同机器上的两个不同 XD 容器上运行的源(发布者)和接收器(消费者)的消息吞吐量。此基准测试的目标是捕获 Kafka 自身测试工具的原生统计信息,并将它们与同一组测试的 Spring XD 结果进行比较。这种比较很重要,因为 XD 不使用标准的 Kafka Consumer API,而是使用Spring Integration Kafka 适配器,该适配器增加了其他功能,例如控制从哪个偏移量消费以及从主题中消费哪些分区。在每种情况下,都会创建一个具有六个分区和三个副本因子的主题。生产者将放置在 RS 实例一上,消费者将放置在 RS 实例二上。所有这些测试的有效负载仅使用字节数组数据进行操作。因此,对于这些测试,Spring XD 将 Kafka 传输模式设置为原始。原始模式表示 Spring XD 不会嵌入标头,并将序列化处理留给用户。

Kafka 原生测试

使用 Kafka 的性能工具,方法与基准测试 Apache Kafka:每秒 200 万次写入 中演示的方法相同,我们希望确定 Kafka 集群的基本速度。在下面的示例中,以下生产者/消费者命令用于获取 1000 字节消息测试的这些结果

生产者: ./bin/kafka-topics.sh --zookeeper :2181 --create --topic $1 --partitions 6 --replication-factor 3 ./bin/kafka-run-class.sh org.apache.kafka.clients.tools.ProducerPerformance $1 300000000 1000 -1 acks=1 bootstrap.servers=:9092,:9092,1:9092 batch.size=128000 消费者: ./bin/kafka-run-class.sh ./bin/kafka-consumer-perf-test.sh --zookeeper :2181 --messages 300000000 --topic $1 --threads 1

使用 Kafka 作为传输的 XD 测试

Spring XD 1.2 使用新的Spring Integration Kafka 适配器,它提供了比标准 Kafka 客户端库更丰富的功能集。XD 的配置开箱即用,除了我们在 servers.yml 中设置了以下配置以匹配原生测试中使用的配置

  1. xd.transport 为 kafka
  2. xd.messagebus.kafka.zkAddress 为共享的 ZooKeeper URL
  3. xd.messagebus.kafka.brokers 为 kafka 代理 URL
  4. xd.messagebus.kafka.mode 为 raw,因为我们正在传输原始数据
  5. xd.messagebus.kafka.batchSize 为 128000
  6. xd.messagebus.kafka.default.minPartitionCount 为 6
  7. xd.messagebus.kafka.default.replicationFactor 为 3
  8. zk.client.connect 为共享的 ZooKeeper URL

要详细了解这些配置,请查看我们位于此处的文档。

以下结果是在1000字节消息测试中使用的流: stream create myTest --definition "load-generator --messageCount=300000000 --messageSize=1000 | throughput" stream deploy myTest ####吞吐量#### #####每秒消息数##### KafkaMsgsPerSecond

消息大小 每秒消息数 Kafka 客户端 每秒消息数 XD
100 2,567,657 2,348,289
1,000 592,881 562,113
10,000 64,806 61,985
100,000 6,505 6,341
#####每秒消息数#####

KafkaMbPerSecond

消息大小 每秒兆字节 Kafka 客户端 每秒兆字节 XD
100 245 224
1,000 565 536
10,000 618 591
100,000 611 605

与直接绑定基准测试一样,图表显示随着消息大小的增加,速率下降,但总体数据吞吐量增加。对于100到1000字节范围内的典型大小有效负载,我们能够使用单个线程每秒推送600K到约200万个事件。需要注意的是,Spring XD的基准测试(基于功能更丰富的消费者库)与Kafka原生客户端API的基准测试相差在8%以内。另请注意,在1000到10000字节的消息大小之间,单个生产者可以达到约10Gb网络容量的一半。在未来的测试中,我们将展示多个生产者和消费者的基准测试,以展示XD如何扩展以及诸如批处理大小等其他调整参数如何影响性能。

#结论# 上述基准测试表明Spring XD可以满足高性能流式用例的需求。它们还表明,使用Spring Integration Kafka (SIK)客户端库的Spring XD与原生的Kafka高级消费者库相比,引入的开销非常小,同时提供了诸如控制偏移量和分区等附加功能。因此,您可以利用Spring XD编程模型以及SIK消费者API中的功能,而对性能的影响最小。
#后续步骤# 虽然有一些用例主要以数据直通为主,但大多数用例将涉及有效负载的某些处理。此外,我们只使用了单个处理线程。在未来的博文中,我们将展示XD如何通过更多容器实例进行扩展,如何影响使用流行库反序列化/序列化对象时的消息速率,以及多线程和反应式编程如何帮助提高每个JVM进程的速率。敬请关注!

编者注:©2015 Pivotal Software, Inc. 保留所有权利。Apache和Apache Kafka是Apache软件基金会在美国和/或其他国家/地区的注册商标或商标。

获取Spring时事通讯

与Spring时事通讯保持联系

订阅

领先一步

VMware提供培训和认证,以加速您的进步。

了解更多

获取支持

Tanzu Spring在一个简单的订阅中提供OpenJDK™、Spring和Apache Tomcat®的支持和二进制文件。

了解更多

即将举行的活动

查看Spring社区中所有即将举行的活动。

查看全部