Repository navigation
Address wrap-up items for Iceberg side input table cache - #40222
jrmccluskey merged 7 commits into
Conversation
- Bind historical sort orders unchecked via SortOrderParser.fromJson(schema, node, getOrderId()) in SerializableTableSpec. - Expose Hadoop Configuration via IcebergCatalogConfig.getHadoopConfiguration() and propagate to SerializableTableSpec.getFileIO(conf) through SideInputTable in write transforms. - Add worker-local transient Guava cache to ExtractTableIdsDoFn to eliminate hot-key shuffle bottlenecks on streaming writes. - Add comprehensive unit and integration tests.
…tion in tests - Ensure TableMetadataDriver passes its Clock to ExtractTableIdsDoFn so virtual-time advancement in tests (e.g. testUnusedTablesEvictedFromStreamingCache) correctly expires worker-local table ID caches instead of using wall-clock time. - Fixes testUnusedTablesEvictedFromStreamingCache flakiness on CI environments with limited concurrency.
… cache TTL - Advance ControllableTestClock on trigger rows in testMetadataRefreshedAcrossIntervals, testMetadataRefreshedAcrossIntervalsAsSideInput, and testMetadataRefreshedAcrossIntervalsAsSideInputWithMultipleTables so worker-local table ID caches expire as intended across virtual intervals. - In testStreamingSpecEvolutionWithoutPipelineRestart, wait for the worker-local cache TTL (500ms) to elapse after spec evolution before emitting the second element.
- Add library.java.jackson_databind to dependencies in sdks/java/io/iceberg/build.gradle to resolve usedUndeclaredArtifacts dependency analysis warning caused by JsonNode usage in SerializableTableSpec.
|
|
||
| @VisibleForTesting | ||
| public abstract @Nullable Clock getClock(); | ||
|
|
There was a problem hiding this comment.
nit: make this and setClock package private
| ValueInSingleWindow.of(element, timestamp, window, paneInfo)); | ||
| if (tableIdentifier != null && !tableIdentifier.trim().isEmpty()) { | ||
| out.output(tableIdentifier.trim()); | ||
| String canonicalId = tableIdentifier.trim(); |
There was a problem hiding this comment.
readability nit: I don't think we need the outer if (tableIdentifier != null && !tableIdentifier.trim().isEmpty()) check.
Also let's work directly with tableIdentifier instead of trimming it into a "canonical" version
| String canonicalId = tableIdentifier.trim(); | ||
| if (localTableIdCache == null && refreshInterval != null) { | ||
| initCache(); | ||
| } |
There was a problem hiding this comment.
readability nit: Do we need this if we're already calling it in setup()?
There was a problem hiding this comment.
removed, was a codegen add-in because a unit test directly called ProcessElement() without calling setup() first and the obvious "fix" was to check that the cache was initialized in ProcessElement()
| table.updateSpec().addField("city").commit(); | ||
| // Ensure worker-local table ID cache TTL (interval / 2 = 500ms) has elapsed | ||
| try { | ||
| Thread.sleep(600); |
There was a problem hiding this comment.
give this a little extra time to avoid potential flakes?
| private final @Nullable Clock clock; | ||
| private transient @Nullable Ticker ticker; | ||
| private transient @Nullable Cache<String, Boolean> localTableIdCache; |
There was a problem hiding this comment.
Lots of complexity here. I feel like we can simplify with just a simple LinkedHashMap<String, Long> LRU that tracks tableIds and the last emitted millis. So only emit when (now - lastEmitted) > refreshInterval and update lastEmitted=now.
Both ways probably work though so will leave it up to you
There was a problem hiding this comment.
Let's go with the simpler implementation
|
Assigning reviewers: R: @ahmedabu98 for label java. Note: If you would like to opt out of this review, comment Available commands:
The PR bot will only process comments in the main thread (not review comments). |
…p LRU - Replace Guava Cache, CacheBuilder, and Ticker in ExtractTableIdsDoFn with a standard LinkedHashMap-based LRU cache capped at 10,000 entries. - Track lastEmitted timestamp per table identifier and emit when (now - lastEmitted) >= refreshInterval / 2. - Remove getClock() and setClock() from TableMetadataDriver and its Builder to keep the AutoValue API clean and free of testing methods. - Provide testing hooks via static globalTestClock and instance setClock on ExtractTableIdsDoFn.
|
Test failure was a PubSubToKafkaE2E test flake, merging |
…#40248) * Expose Public API for Iceberg Side Input Cache (#40140) * Expose Public API for Iceberg Side Input Cache * Update sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/IcebergIO.java Co-authored-by: Ahmed Abualsaud <65791736+ahmedabu98@users.noreply.github.com> * Streamline API, remove redundant checks * Check polled table metric * Evolve Iceberg schema mid-execution in streaming side input cache test * Throw if sub-options are enabled without side input cache enabled * test with partition spec evolution --------- Co-authored-by: Ahmed Abualsaud <65791736+ahmedabu98@users.noreply.github.com> * Address wrap-up items for Iceberg side input table cache (#40222) * Address wrap-up items for Iceberg side input table cache - Bind historical sort orders unchecked via SortOrderParser.fromJson(schema, node, getOrderId()) in SerializableTableSpec. - Expose Hadoop Configuration via IcebergCatalogConfig.getHadoopConfiguration() and propagate to SerializableTableSpec.getFileIO(conf) through SideInputTable in write transforms. - Add worker-local transient Guava cache to ExtractTableIdsDoFn to eliminate hot-key shuffle bottlenecks on streaming writes. - Add comprehensive unit and integration tests. * Propagate Clock to ExtractTableIdsDoFn for deterministic cache expiration in tests - Ensure TableMetadataDriver passes its Clock to ExtractTableIdsDoFn so virtual-time advancement in tests (e.g. testUnusedTablesEvictedFromStreamingCache) correctly expires worker-local table ID caches instead of using wall-clock time. - Fixes testUnusedTablesEvictedFromStreamingCache flakiness on CI environments with limited concurrency. * Make streaming refresh and spec evolution tests robust against worker cache TTL - Advance ControllableTestClock on trigger rows in testMetadataRefreshedAcrossIntervals, testMetadataRefreshedAcrossIntervalsAsSideInput, and testMetadataRefreshedAcrossIntervalsAsSideInputWithMultipleTables so worker-local table ID caches expire as intended across virtual intervals. - In testStreamingSpecEvolutionWithoutPipelineRestart, wait for the worker-local cache TTL (500ms) to elapse after spec evolution before emitting the second element. * Declare jackson-databind dependency in Iceberg IO module - Add library.java.jackson_databind to dependencies in sdks/java/io/iceberg/build.gradle to resolve usedUndeclaredArtifacts dependency analysis warning caused by JsonNode usage in SerializableTableSpec. * Avoid potential flakes in EvolveSpec DoFn, address nits * Simplify worker-local cache in TableMetadataDriver using LinkedHashMap LRU - Replace Guava Cache, CacheBuilder, and Ticker in ExtractTableIdsDoFn with a standard LinkedHashMap-based LRU cache capped at 10,000 entries. - Track lastEmitted timestamp per table identifier and emit when (now - lastEmitted) >= refreshInterval / 2. - Remove getClock() and setClock() from TableMetadataDriver and its Builder to keep the AutoValue API clean and free of testing methods. - Provide testing hooks via static globalTestClock and instance setClock on ExtractTableIdsDoFn. * simplify dofn + fix unit test --------- Co-authored-by: Ahmed Abualsaud <65791736+ahmedabu98@users.noreply.github.com>
Completes a handful of cleanup tasks for the side input cache:
Fixes #39723
Thank you for your contribution! Follow this checklist to help us incorporate your contribution quickly and easily:
addresses #123), if applicable. This will automatically add a link to the pull request in the issue. If you would like the issue to automatically close on merging the pull request, commentfixes #<ISSUE NUMBER>instead.CHANGES.mdwith noteworthy changes.See the Contributor Guide for more tips on how to make review process smoother.
To check the build health, please visit https://github.com/apache/beam/blob/master/.test-infra/BUILD_STATUS.md
GitHub Actions Tests Status (on master branch)
See CI.md for more information about GitHub Actions CI or the workflows README to see a list of phrases to trigger workflows.