当前位置: 首页 > wzjs >正文

做网站广告的点怎么做文化传媒公司网站

做网站广告的点,怎么做文化传媒公司网站,免费一天赚500元游戏,网站建设代理成本Debezium日常分享系列之:提升Debezium性能测试环境搭建PostgreSQL运行测试分析结果提出修复方案JMH基准测试在测试应用中进行验证结论定期评估整个项目(或至少其关键部分)的性能表现十分必要,尤其是在新增功能或进行重大代码重构时…

Debezium日常分享系列之:提升Debezium性能

  • 测试环境搭建
  • PostgreSQL
  • 运行测试
  • 分析结果
  • 提出修复方案
  • JMH基准测试
  • 在测试应用中进行验证
  • 结论

定期评估整个项目(或至少其关键部分)的性能表现十分必要,尤其是在新增功能或进行重大代码重构时。不过,性能检查也可以临时开展,或更理想地——形成定期机制。

本文将通过一个案例,演示如何快速识别和分析Debezium中的特定性能问题。内容涵盖完整闭环:搭建轻量级性能测试、分析结果、提出优化方案并验证效果。

建立完善的性能测试通常充满挑战,许多细节可能导致结果失真。本文介绍的方法旨在快速暴露潜在瓶颈——通常是那些通过简单测试就能发现的"低垂果实"。当然,这并不意味着常规性能测试不重要。恰恰相反,全面且周期性的测试(尤其是使用高级负载生成工具的端到端测试)至关重要,许多性能问题只有在复杂环境中才会显现。

测试环境搭建

Debezium应用程序

我们首先基于Debezium嵌入式引擎和PostgreSQL连接器创建一个简单应用。该应用采用极简配置,主要依赖默认设置。特别说明的是,它使用decoderbufs插件从PostgreSQL数据库获取数据。

应用本身不处理获取的数据——这是为了刻意避免任何记录后处理(例如单消息转换)。这种设计确保应用耗时集中在核心数据获取路径上,而非外部处理逻辑。换言之,我们的重点是评估通过decoderbufs插件从PostgreSQL检索数据的效率,并定位该路径中的潜在性能瓶颈。

public class DebeziumEngniePostgres {public static void main(String[] args) {final Properties props = new Properties();props.setProperty("name", "engine");props.setProperty("connector.class", "io.debezium.connector.postgresql.PostgresConnector");props.setProperty("database.hostname", "127.0.0.1");props.setProperty("database.port", "5432");props.setProperty("database.user", "postgres");props.setProperty("database.password", "postgres");props.setProperty("database.dbname", "postgres");props.setProperty("topic.prefix", "perf");props.setProperty("table.include.list", "public.pgbench_.*");props.setProperty("snapshot.mode", "no_data");props.setProperty("offset.storage", "org.apache.kafka.connect.storage.FileOffsetBackingStore");props.setProperty("offset.storage.file.filename", "./data/offsets.dat");props.setProperty("offset.flush.interval.ms", "60000");props.setProperty("schema.history.internal", "io.debezium.storage.file.history.FileSchemaHistory");props.setProperty("schema.history.internal.file.filename", "./data/schemahistory.dat");try (DebeziumEngine<ChangeEvent<SourceRecord, SourceRecord>> engine = DebeziumEngine.create(Connect.class).using(props).notifying(record -> {}).build()) {ExecutorService executor = Executors.newSingleThreadExecutor();executor.execute(engine);System.out.println("Debezium started");Thread.sleep(600000);}catch (IOException|InterruptedException e) {System.out.println("Failed with " + e);}System.out.println("Debezium stopped");}
}

源码仓库地址

您可以像往常一样使用Maven构建和运行应用程序。只需首先创建数据目录,因为Debezium引擎会尝试将偏移量和模式历史文件存储在那里。

PostgreSQL

由于我们在这个示例中选择了PostgreSQL连接器,因此需要设置一个测试用的PostgreSQL数据库。为了简化操作,我们可以使用Debezium项目提供的容器镜像——它已经包含了所有必要的数据库配置,开箱即用:

podman run --rm --name postgres -it -e POSTGRES_PASSWORD=postgres -p 5432:5432 quay.io/debezium/example-postgres:3.2

接下来,我们需要一个工具在测试期间为数据库生成负载。PostgreSQL自带这样的工具:pgbench。在大多数Linux发行版中,它与核心数据库软件包是分开提供的。例如在Fedora系统上,您需要额外安装postgresql-contrib包。

建立常规性能测试时,关键环节之一是选择合适的负载生成工具。像pgbench这类工具可能存在诸如协调遗漏问题等缺陷,导致生成的数据不真实,或引入其他偏差从而产生误导性结果。如前所述,本文暂不探讨这些复杂问题——这是本示例中采用的简化处理方式之一,特此说明。

在使用pgbench之前,需要先初始化它将操作的测试表:

PGPASSWORD=postgres pgbench -h 127.0.0.1 -U postgres -i postgres --scale=10

该命令会在数据库中创建若干以pgbench_开头的表。您可能已经注意到,我们的应用程序已配置为捕获这些pgbench_*表的变更。

运行测试

现在一切准备就绪,让我们使用pgbench对数据库施加负载:

PGPASSWORD=postgres pgbench -h 127.0.0.1 -U postgres --scale=10 -b simple-update --jobs=20 --client=20 -T 120 postgres

同时,我们将运行启用 Java Flight Recorder 的测试应用程序:

java -XX:+FlightRecorder -XX:StartFlightRecording=delay=30s,duration=60s,filename=dbz-flight.jfr,settings=profile -jar dbz-app/target/debezium-quick-perf-1.0-SNAPSHOT.jar

要捕获Flight Recorder事件,请确保在启动应用程序时包含-XX:+FlightRecorder参数。您可以通过性能分析工具手动开始记录,或通过命令行参数配置延迟时间、持续时间、输出文件和性能分析设置:-XX:StartFlightRecording=delay=30s,duration=60s,filename=dbz-flight.jfr,settings=profile.

当记录完成后,您可以同时停止应用程序和pgbench(如果它仍在运行)。也可以停止并删除数据库容器。

如需重复测试,建议从干净的数据库开始,并删除数据目录中的offset文件以重置连接器的读取位置。

分析结果

获取Flight Recorder文件后,我们可以用任何支持Java Flight Recorder (JFR)的工具打开它。这可以是您的IDE,但我更推荐使用专用工具:Java Mission Control (JMC)。

不过需要注意,JMC对Wayland的支持存在缺陷。这可能导致某些关键视图(如我们需要的火焰图)显示为空。详情可参阅JMC-8247问题记录。

火焰图能直观展示应用程序的时间消耗分布:
在这里插入图片描述

有一件事立即引人注目,那就是在 schemaChanged() 方法中花费了大量的时间,特别是在正则表达式匹配中:
在这里插入图片描述
同样的问题在方法分析视图中也很明显:
在这里插入图片描述
这里,正则表达式匹配是最耗时的操作之一。您还可以检查采样事件的调用堆栈,精确定位这个计算的来源。

问题的根源在于PostgreSQL不会发出专门的模式变更事件。相反,模式元数据被嵌入到第一个使用更新后模式的记录中。因此,Debezium必须几乎在处理的每条记录中检查可能的模式变更。具体实现取决于所使用的插件。对于默认的decoderbufs插件,Debezium会将记录的类型和其他修饰符与已有的信息进行比较。这些类型修饰符以字符串形式提供,并且每条记录都需要使用正则表达式进行解析。随着时间的推移,这会累积成很大的开销。

既然我们已经发现了一个潜在的性能瓶颈,最好将我们的发现报告给开发团队。针对这个具体问题,我提交了DBZ-9093。

提出修复方案

在上一步中,我们发现了PostgreSQL连接器在使用decoderbufs插件时存在的性能问题。幸运的是,当使用pgoutput插件时不存在这个问题。不过考虑到decoderbufs仍受支持且被设为默认选项,让我们探讨如何修复这个问题。

JMH基准测试

为了衡量修复效果,我们可以使用专为此目的设计的Java微基准测试工具(JMH)。一个简单的JMH基准测试示例如下:

@State(Scope.Benchmark)
public class PostgresTypeMetadataPerf {private static final int OP_COUNT = 10;private static final int MOD_COUNT = 10;private static final String[] MODIFIERS = {"text","character varying(255)","numeric(12,3)","geometry(MultiPolygon,4326)","timestamp (12) with time zone","int[]","myschema.geometry","float[10]","date","bytea"};private ReplicationMessage.Column[] columns = new ReplicationMessage.Column[OP_COUNT];private ReplicationMessage.Column createColumn (int modifierIndex) {String columnName = "test";PostgresType columnType = PostgresType.UNKNOWN;String typeWithModifiers = MODIFIERS[modifierIndex];boolean optional = true;return new AbstractReplicationMessageColumn(columnName, columnType, typeWithModifiers, optional) {@Overridepublic Object getValue(PostgresStreamingChangeEventSource.PgConnectionSupplier connection,boolean includeUnknownDatatypes) {return null;}};}@Setup(Level.Invocation)public void setup() {Random random = new Random(1234);for (int i = 0; i < OP_COUNT; i++) {columns[i] = createColumn(random.nextInt(MOD_COUNT));}}@Benchmark@BenchmarkMode(Mode.AverageTime)@OutputTimeUnit(TimeUnit.MICROSECONDS)@Fork(value = 1)@OperationsPerInvocation(OP_COUNT)public void columnMetadata(Blackhole bh) {for (int i = 0; i < OP_COUNT; i++) {bh.consume(columns[i].getTypeMetadata());}}
}

虽然 JMH 和微基准测试通常存在许多需要注意的事项,但这个基准测试至少为我们提供了一些基准。

以下是在我的机器上使用未打补丁的代码得出的结果:

Iteration   1: 0.768 us/op
Iteration   2: 0.761 us/op
Iteration   3: 0.780 us/op
Iteration   4: 0.780 us/op
Iteration   5: 0.750 us/opBenchmark                                Mode  Cnt  Score   Error  Units
PostgresTypeMetadataPerf.columnMetadata  avgt    5  0.768 ? 0.049  us/op

鉴于类型修饰符通常会被复用,一种简单的优化方法是将已解析的修饰符缓存到 map 中。实现此缓存逻辑后,JMH 基准测试给出了以下结果:

Iteration   1: 0.278 us/op
Iteration   2: 0.278 us/op
Iteration   3: 0.284 us/op
Iteration   4: 0.288 us/op
Iteration   5: 0.291 us/opBenchmark                                Mode  Cnt  Score   Error  Units
PostgresTypeMetadataPerf.columnMetadata  avgt    5  0.284 ? 0.023  us/op

虽然这是一个简单的基准测试(可能存在某些问题),但性能提升幅度已经足以表明实际应用中的收益。

在测试应用中进行验证

作为最终测试,我们可以重新运行简单的性能测试,检查schemaChanged()方法的时间消耗。从更新后的火焰图可以明显看出改进效果:
在这里插入图片描述
当您对修复方案有信心后,可以提交一个拉取请求——最好包含用于验证的JMH基准测试。

要高度确信该修复的有效性,需要建立完整的端到端性能测试流程。不过在如此复杂的环境中,实际效果可能微乎其微。与我们的受控测试或JMH基准测试不同,真实场景包含序列化、I/O开销等诸多因素,这些都可能稀释可见的收益。孤立测试中显著的性能提升,在整体上可能只带来微小改进——但积少成多总是好的。

结论

本文探索了一种轻量级方法来识别Debezium(使用PostgreSQL连接器的嵌入式引擎)中的性能瓶颈。通过简单的测试设置、Flight Recorder和火焰图分析,我们定位到了decoderbufs插件中正则表达式处理的高成本问题。

虽然这个设置有意简化了现实场景的许多方面,也存在其他潜在缺陷,但它对于发现容易解决的性能问题仍然有效。开发者可以直接在本地运行轻量级基准测试,有助于在开发早期发现并解决低效问题。这些优化能提升整体吞吐量并减少不必要的CPU使用,尤其在高吞吐场景中。虽然这种方法不能替代全面的端到端性能测试,但它提供了一种快速实用的方式,在开发过程中发现并解决性能退步或低效问题。在投入时间建立更复杂的基准测试流程之前,这也是一个很好的第一步。


文章转载自:

http://7dl7Pg4u.bgpch.cn
http://xF8CQdvq.bgpch.cn
http://ZzTYoX7H.bgpch.cn
http://HIY4J5yd.bgpch.cn
http://Jl2Fkvta.bgpch.cn
http://qY0E3gKd.bgpch.cn
http://7bX2pGfW.bgpch.cn
http://sIqmHcEn.bgpch.cn
http://vSynzT7k.bgpch.cn
http://aLAd4dRe.bgpch.cn
http://JPh6NwpZ.bgpch.cn
http://JFT3AVmR.bgpch.cn
http://MRveVSvo.bgpch.cn
http://03H7bXYy.bgpch.cn
http://imafYZM0.bgpch.cn
http://mCO8jjpz.bgpch.cn
http://E0QGNMzb.bgpch.cn
http://qiRdVi38.bgpch.cn
http://gbULhcJa.bgpch.cn
http://JAZzkokf.bgpch.cn
http://yLQjplSO.bgpch.cn
http://wuRiqn11.bgpch.cn
http://4peulPNh.bgpch.cn
http://PEzyGU4K.bgpch.cn
http://9colHRdg.bgpch.cn
http://k49OsDsj.bgpch.cn
http://Qju5XmN8.bgpch.cn
http://44PcEqI5.bgpch.cn
http://iMOmXia8.bgpch.cn
http://VOSlHsjk.bgpch.cn
http://www.dtcms.com/wzjs/671171.html

相关文章:

  • 建站公司经营校园网站建设硬件采购
  • 怎么做网站排名优化企业官网入口
  • 阿里云免费网站做官网网站哪家公司好
  • 外国网站 游戏设定图广州游戏软件开发公司
  • 济南 网站建设wordpress 主题 小说
  • 滨江区建设局网站网站建设的作用和意义
  • 整站排名手工企业网站模板
  • 东莞证券官网昆明seo排名外包
  • 做创意美食的视频网站大悟县建设局网站
  • 电子商务网站建设与管理心得网站建设一百万
  • 先做网站再付款幸福人寿保险公司官方网站
  • 外文网站开发二维码小程序制作
  • 信融营销型网站建设wordpress标签小工具数量
  • 长春网站建设多少钱北京软件开发培训学校
  • 周年庆网站要怎么做有人有免费的片资源吗
  • 网站建设模板公司设计网站都有什么作用是什么原因
  • 阮一峰的个人网站中山好的网站建设公司
  • 江苏省省建设厅网站江苏省建筑网监督信息平台
  • 零基础网站建设教学公司网上怎么推广公司产品
  • 网站界面设计用户体验wordpress文章自定义字段
  • 设计网站开发方案流程公司网站的重要性
  • 服务器重启 iis网站暂停建设网站开发的语言有哪些
  • 分类信息网站的建设维护市场调研app软件
  • 做网站开发的应选什么专业推荐网站制作公司
  • 上海优化网站关键词wordpress 翻译不起作用
  • 专业做网站咨询政协网站信息化建设的作用
  • 标准网站优势网络营销的支持条件是什么
  • 好看的网站颜色原江苏省建设厅网站
  • 微信网站怎么做的好名字流量推广是什么意思
  • 一般网站建设公司有哪些外贸自建站模板