Skip to content

HDDS-15562. EventNotification: persistence strategy for consumer checkpoint (via distributed RocksDB update)#10689

Open
gardenia wants to merge 1 commit into
apache:HDDS-13513_Event_Notification_FeatureBranchfrom
gardenia:HDDS-15562-DB-Checkpoint
Open

HDDS-15562. EventNotification: persistence strategy for consumer checkpoint (via distributed RocksDB update)#10689
gardenia wants to merge 1 commit into
apache:HDDS-13513_Event_Notification_FeatureBranchfrom
gardenia:HDDS-15562-DB-Checkpoint

Conversation

@gardenia

@gardenia gardenia commented Jul 8, 2026

Copy link
Copy Markdown

Please describe your PR in detail:

Persist the checkpoint within the OM RocksDB metadata table using a distributed Ratis update message so that another OM can pick up if the leader changes.

Technical Solution:

  • Update the RocksDB metadata table (OMSetEventNotificationCheckpointRequest) and distribute this to other OMs via Ratis (SetEventNotificationCheckpointRequest)

Checkpoint Throttling:

  • We update our local progress in-memory on every transaction batch, but throttle the persistent Ratis writes (configurable via OZONE_OM_PLUGIN_CHECKPOINT_SAVE_INTERVAL, defaulting to every 100 transactions).
  • The intent is to prevent saturating the Ratis log or causing write storms on RocksDB while maintain our at-least-once delivery guarantee.
  • If a Ratis write fails, throttling is bypassed to ensure the next update cycle retries immediately.

Error Handling:

  • Both loading and saving failures are non-blocking for background polling progress
  • On load failures, we log a warning and fallback to starting from transaction 0/null.
  • On save failures, we log a warning but always advance progress in-memory to ensure progress but conform to at-least-once event delivery.

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-15562

How was this patch tested?

Unit tests

@gardenia gardenia changed the base branch from master to HDDS-13513_Event_Notification_FeatureBranch July 8, 2026 08:34
@gardenia

gardenia commented Jul 8, 2026

Copy link
Copy Markdown
Author

NOTE: this is a rework of the original implementation which used Ozone filesystem bucket property metadata to store the properties (PR and review comments from @ChenSammi can be found here #10515).

This approach of using a distributed write to the RocksDB metadata table for persisting the checkpoint was suggested by @ChenSammi in review comments you can find on the above PR.

Persist the checkpoint within the OM RocksDB metadata table using a distributed
Ratis update message so that another OM can pick up if the leader changes.

Technical Solution:
* Update the RocksDB metadata table (OMSetEventNotificationCheckpointRequest) and
distribute this to other OMs via Ratis (SetEventNotificationCheckpointRequest)

Checkpoint Throttling:
* We update our local progress in-memory on every transaction batch, but throttle
the persistent Ratis writes (configurable via OZONE_OM_PLUGIN_CHECKPOINT_SAVE_INTERVAL,
defaulting to every 100 transactions).
* The intent is to prevent saturating the Ratis log or causing write storms on RocksDB
while maintain our at-least-once delivery guarantee.
* If a Ratis write fails, throttling is bypassed to ensure the next
update cycle retries immediately.

Error Handling:
* Both loading and saving failures are non-blocking for background polling progress
* On load failures, we log a warning and fallback to starting from transaction 0/null.
* On save failures, we log a warning but always advance progress in-memory to ensure
progress but conform to at-least-once event delivery.

Detailed Changes:
- Protobuf:
  - Add SetEventNotificationCheckpoint type and request/response payloads to OmClientProtocol.proto.
- OmUtils & OzoneManagerRatisUtils:
  - Wire SetEventNotificationCheckpoint as a write request.
  - Route SetEventNotificationCheckpoint to its corresponding OMRequest class.
- Requests & Responses:
  - Create OMSetEventNotificationCheckpointRequest to write checkpoint values to metaTable.
  - Create OMSetEventNotificationCheckpointResponse to persist values in metaTable via addToDBBatch.
- Strategy:
  - Expose NotificationCheckpointStrategy interface with load, save, and reset.
  - Implement OzoneDbCheckpointStrategy to query and save checkpoints atomically via the new OM requests.
  - Added reset() call to durably clear checkpoints during self-healing.
- Plugin Context & Poller:
  - Wire the checkpoint strategy through OMEventListenerPluginContext and OMEventListenerPluginManager.
  - Integrate strategy into the poller and publisher. Both loading and saving failures are non-blocking,
  falling back to starting from 0/null on load failures and continuing in-memory progress on save failures.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a durable, HA-consistent persistence mechanism for the OM event-notification consumer checkpoint by storing it in the OM RocksDB metaTable and replicating updates via a new Ratis-distributed OMRequest. This enables another OM to continue from the last persisted checkpoint after leader changes, while throttling persistent writes to avoid Ratis/RocksDB write storms.

Changes:

  • Introduces a NotificationCheckpointStrategy abstraction and an OM-backed implementation (OzoneDbCheckpointStrategy) that persists checkpoints via a new SetEventNotificationCheckpoint OMRequest.
  • Wires checkpoint strategy into the plugin context and updates the Kafka publisher/poller seek position to load/save checkpoints non-blockingly.
  • Extends the OM protocol (proto + request factory + routing helpers) and adds unit tests covering request handling and strategy throttling/failure behavior.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/eventlistener/TestOMSetEventNotificationCheckpointRequest.java Adds UT for the new OM request caching/metaTable behavior.
hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/eventlistener/TestOzoneDbCheckpointStrategy.java Adds UTs for load/save throttling, failure recovery, and reset behavior.
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/eventlistener/package-info.java New response package documentation.
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/eventlistener/OMSetEventNotificationCheckpointResponse.java New response that batches metaTable checkpoint writes.
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/eventlistener/package-info.java New request package documentation.
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/eventlistener/OMSetEventNotificationCheckpointRequest.java New request that updates the metaTable cache for checkpoint persistence.
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/utils/OzoneManagerRatisUtils.java Registers the new request type in the request factory.
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/eventlistener/OzoneDbCheckpointStrategy.java Implements checkpoint persistence via Ratis-submitted OMRequest with throttling.
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/eventlistener/OMEventListenerPluginManager.java Creates and injects the checkpoint strategy into the plugin context.
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/eventlistener/OMEventListenerPluginContextImpl.java Exposes checkpoint strategy via the plugin context implementation.
hadoop-ozone/ozone-manager-plugins/src/test/java/org/apache/hadoop/ozone/om/eventlistener/TestOMEventListenerLedgerPollerRecovery.java Adds UTs ensuring load/save failures don’t block poller progress.
hadoop-ozone/ozone-manager-plugins/src/main/java/org/apache/hadoop/ozone/om/eventlistener/OMEventListenerLedgerPollerSeekPosition.java Loads/saves checkpoint via strategy with non-blocking failure handling and reset.
hadoop-ozone/ozone-manager-plugins/src/main/java/org/apache/hadoop/ozone/om/eventlistener/OMEventListenerKafkaPublisher.java Uses plugin-provided checkpoint strategy for seek position initialization.
hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto Adds new OMRequest/OMResponse types and messages for checkpoint updates.
hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java Classifies the new request as a write and leader-routed request.
hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/eventlistener/OMEventListenerPluginContext.java Adds an API to obtain the checkpoint strategy from plugin context.
hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/eventlistener/NotificationCheckpointStrategy.java Adds new strategy interface for checkpoint persistence.
hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java Adds a dedicated metaTable key prefix for event-notification checkpoints.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +54 to +62
final SetEventNotificationCheckpointRequest request =
getOmRequest().getSetEventNotificationCheckpointRequest();

final String checkpointKey = request.getCheckpointKey();
final String checkpointValue = request.getCheckpointValue();

// Store in metaTable using CacheKey with our specific checkpoint prefix
final String dbKey = OzoneConsts.EVENT_NOTIFICATION_CHECKPOINT_PREFIX + checkpointKey;

Comment on lines 34 to +37
List<OmCompletedRequestInfo> listCompletedRequestInfo(Long startKey, int maxResults) throws IOException;

NotificationCheckpointStrategy getNotificationCheckpointStrategy();

Comment on lines +133 to +135
submitRequest(omRequest);
LOG.info("Persisted {} = {} directly as metadata inside metaTable under key {}",
checkpointName, val, dbKey);
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.

2 participants