Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Default Replication Worker Performance Test Harness #20956

Merged
merged 19 commits into from
Jan 5, 2023

Conversation

davinchia
Copy link
Contributor

@davinchia davinchia commented Jan 3, 2023

What

Introduce a performance test harness for the default replication worker to make it easy for devs to test effect of changes on platform throughput.

The current set up is designed to be run manually. In the future, we can look into integrating this report into our build pipelines. For now, this is good enough as I wanted to start somewhere.

How

  • Set up a source that spits out dynamic messages.
  • Set up a destination that does nothing to mimic the fastest destination.
  • Set up the ReplicationPerformanceClass with an E2E sync that has performs all the same steps as the current DefaultReplicationWorker.
  • Add Java Micro Benchmark as a simple test harness.

The general idea is to use JMH to run the test n number of times (currently 4 times). The dev can then look at logs to see throughput and how it varies.

As of this PR, we see general platform throughput of ~ 20 - 25 MB/s.

Recommended reading order

  1. ReplicationWorkerPerformanceTest.java
  2. Everything else.

🚨 User Impact 🚨

Are there any breaking changes? What is the end result perceived by the user? If yes, please merge this PR with the 🚨🚨 emoji so changelog authors can further highlight this if needed.

Pre-merge Checklist

Expand the relevant checklist and delete the others.

New Connector

Community member or Airbyter

  • Community member? Grant edit access to maintainers (instructions)
  • Secrets in the connector's spec are annotated with airbyte_secret
  • Unit & integration tests added and passing. Community members, please provide proof of success locally e.g: screenshot or copy-paste unit, integration, and acceptance test output. To run acceptance tests for a Python connector, follow instructions in the README. For java connectors run ./gradlew :airbyte-integrations:connectors:<name>:integrationTest.
  • Code reviews completed
  • Documentation updated
    • Connector's README.md
    • Connector's bootstrap.md. See description and examples
    • docs/integrations/<source or destination>/<name>.md including changelog. See changelog example
    • docs/integrations/README.md
    • airbyte-integrations/builds.md
  • PR name follows PR naming conventions

Airbyter

If this is a community PR, the Airbyte engineer reviewing this PR is responsible for the below items.

  • Create a non-forked branch based on this PR and test the below items on it
  • Build is successful
  • If new credentials are required for use in CI, add them to GSM. Instructions.
  • /test connector=connectors/<name> command is passing
  • New Connector version released on Dockerhub by running the /publish command described here
  • After the connector is published, connector added to connector index as described here
  • Seed specs have been re-generated by building the platform and committing the changes to the seed spec files, as described here
Updating a connector

Community member or Airbyter

  • Grant edit access to maintainers (instructions)
  • Secrets in the connector's spec are annotated with airbyte_secret
  • Unit & integration tests added and passing. Community members, please provide proof of success locally e.g: screenshot or copy-paste unit, integration, and acceptance test output. To run acceptance tests for a Python connector, follow instructions in the README. For java connectors run ./gradlew :airbyte-integrations:connectors:<name>:integrationTest.
  • Code reviews completed
  • Documentation updated
    • Connector's README.md
    • Connector's bootstrap.md. See description and examples
    • Changelog updated in docs/integrations/<source or destination>/<name>.md including changelog. See changelog example
  • PR name follows PR naming conventions

Airbyter

If this is a community PR, the Airbyte engineer reviewing this PR is responsible for the below items.

  • Create a non-forked branch based on this PR and test the below items on it
  • Build is successful
  • If new credentials are required for use in CI, add them to GSM. Instructions.
  • /test connector=connectors/<name> command is passing
  • New Connector version released on Dockerhub and connector version bumped by running the /publish command described here
Connector Generator
  • Issue acceptance criteria met
  • PR name follows PR naming conventions
  • If adding a new generator, add it to the list of scaffold modules being tested
  • The generator test modules (all connectors with -scaffold in their name) have been updated with the latest scaffold by running ./gradlew :airbyte-integrations:connector-templates:generator:testScaffoldTemplates then checking in your changes
  • Documentation which references the generator is updated as needed

Tests

Unit

Put your unit tests output here.

Integration

Put your integration tests output here.

Acceptance

Put your acceptance tests output here.

@octavia-squidington-iv octavia-squidington-iv added area/platform issues related to the platform area/server labels Jan 3, 2023
@davinchia davinchia temporarily deployed to more-secrets January 3, 2023 01:22 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 3, 2023 01:23 — with GitHub Actions Inactive
Comment on lines +51 to +52
workerThread.start();
workerThread.join();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this test in the same process, but using different threads? If that's the case, then this also bypasses the stdio streams as well, which also present their own bottlenecks (cc @colesnodgrass)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. Let me see if I can quickly work something up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does show that the core serialising isn't the bottleneck like we thought.

@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 02:17 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 02:17 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 03:20 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 03:20 — with GitHub Actions Inactive
@octavia-squidington-iv octavia-squidington-iv removed area/platform issues related to the platform area/server labels Jan 4, 2023
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 03:25 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 03:26 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 05:09 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 05:09 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 05:39 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 05:40 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 19:35 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 19:35 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 20:59 — with GitHub Actions Inactive
@davinchia davinchia marked this pull request as ready for review January 4, 2023 22:19
@davinchia davinchia requested a review from a team as a code owner January 4, 2023 22:19
@Benchmark
// SampleTime = the time taken to run the benchmarked method. Use this because we only care about
// the time taken to sync the entire dataset.
@BenchmarkMode(Mode.SampleTime)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colesnodgrass unfortunately because these annotations don't have the target annotation type, we cannot fold them into a meta annotation. I think this is fine for now.

@davinchia
Copy link
Contributor Author

fyi @cgardens

@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 22:21 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 22:21 — with GitHub Actions Inactive
@davinchia
Copy link
Contributor Author

Sample logging output:

      "recordsCommitted" : 1000000
    }
  } ]
}
2023-01-04 22:25:31 INFO i.a.w.g.DefaultReplicationWorker(getReplicationOutput):436 - failures: [ ]
2023-01-04 22:25:31 INFO i.a.w.g.ReplicationWorkerPerformanceTest(executeOneSync):96 - MBs read: 178, Time taken sec: 8.312, MB/s: 21.414821944177096
2023-01-04 22:25:31 INFO i.a.c.i.LineGobbler(voidCall):114 - 
2023-01-04 22:25:31 INFO i.a.c.i.LineGobbler(voidCall):114 - ----- END REPLICATION -----
2023-01-04 22:25:31 INFO i.a.c.i.LineGobbler(voidCall):114 - 
8.493 s/op
                 executeOneSync·p0.00:   8.313 s/op
                 executeOneSync·p0.50:   8.493 s/op
                 executeOneSync·p0.90:   8.674 s/op
                 executeOneSync·p0.95:   8.674 s/op
                 executeOneSync·p0.99:   8.674 s/op
                 executeOneSync·p0.999:  8.674 s/op
                 executeOneSync·p0.9999: 8.674 s/op
                 executeOneSync·p1.00:   8.674 s/op



Result "io.airbyte.workers.general.ReplicationWorkerPerformanceTest.executeOneSync":
  N = 4
  mean =      8.831 ±(99.9%) 4.006 s/op

  Histogram, s/op:
    [ 8.000,  8.125) = 0 
    [ 8.125,  8.250) = 0 
    [ 8.250,  8.375) = 1 
    [ 8.375,  8.500) = 0 
    [ 8.500,  8.625) = 1 
    [ 8.625,  8.750) = 1 
    [ 8.750,  8.875) = 0 
    [ 8.875,  9.000) = 0 
    [ 9.000,  9.125) = 0 
    [ 9.125,  9.250) = 0 
    [ 9.250,  9.375) = 0 
    [ 9.375,  9.500) = 0 
    [ 9.500,  9.625) = 0 
    [ 9.625,  9.750) = 1 
    [ 9.750,  9.875) = 0 

  Percentiles, s/op:
      p(0.0000) =      8.313 s/op
     p(50.0000) =      8.640 s/op
     p(90.0000) =      9.731 s/op
     p(95.0000) =      9.731 s/op
     p(99.0000) =      9.731 s/op
     p(99.9000) =      9.731 s/op
     p(99.9900) =      9.731 s/op
     p(99.9990) =      9.731 s/op
     p(99.9999) =      9.731 s/op
    p(100.0000) =      9.731 s/op


# Run complete. Total time: 00:00:36

REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.

NOTE: Current JVM experimentally supports Compiler Blackholes, and they are in use. Please exercise
extra caution when trusting the results, look into the generated code to check the benchmark still
works, and factor in a small probability of new VM bugs. Additionally, while comparisons between
different JVMs are already problematic, the performance difference caused by different Blackhole
modes can be very significant. Please make sure you use the consistent Blackhole mode for comparisons.

Benchmark                                                                 Mode  Cnt  Score   Error  Units
ReplicationWorkerPerformanceTest.executeOneSync                         sample    4  8.831 ± 4.006   s/op
ReplicationWorkerPerformanceTest.executeOneSync:executeOneSync·p0.00    sample       8.313           s/op
ReplicationWorkerPerformanceTest.executeOneSync:executeOneSync·p0.50    sample       8.640           s/op
ReplicationWorkerPerformanceTest.executeOneSync:executeOneSync·p0.90    sample       9.731           s/op
ReplicationWorkerPerformanceTest.executeOneSync:executeOneSync·p0.95    sample       9.731           s/op
ReplicationWorkerPerformanceTest.executeOneSync:executeOneSync·p0.99    sample       9.731           s/op
ReplicationWorkerPerformanceTest.executeOneSync:executeOneSync·p0.999   sample       9.731           s/op
ReplicationWorkerPerformanceTest.executeOneSync:executeOneSync·p0.9999  sample       9.731           s/op
ReplicationWorkerPerformanceTest.executeOneSync:executeOneSync·p1.00    sample       9.731           s/op

@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 22:42 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 22:42 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 23:31 — with GitHub Actions Inactive
@davinchia davinchia temporarily deployed to more-secrets January 4, 2023 23:31 — with GitHub Actions Inactive
@davinchia
Copy link
Contributor Author

PTAL @colesnodgrass @jdpgrailsdev @evantahler @pmossman

Cole/Jonathan, one approval for either of you two is enough. Mainly tagging for awareness. Parker, same thing here. Want to make sure both platform teams are aware this is available.

Evan - you are already on the PR. Thought to tag you since you are also interested in this work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants