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 retention lease syncing #37398

Merged
merged 35 commits into from
Jan 27, 2019

Conversation

jasontedor
Copy link
Member

This commit introduces retention lease syncing from the primary to its replicas when a new retention lease is added. A follow-up commit will add a background sync of the retention leases as well so that renewed retention leases are synced to replicas.

Relates #37165

This commit introduces retention lease syncing from the primary to its
replicas when a new retention lease is added. A follow-up commit will
add a background sync of the retention leases as well so that renewed
retention leases are synced to replicas.
@jasontedor jasontedor added >enhancement v7.0.0 :Distributed/Distributed A catch all label for anything in the Distributed Area. If you aren't sure, use this one. v6.7.0 labels Jan 14, 2019
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-distributed

@jasontedor jasontedor mentioned this pull request Jan 14, 2019
24 tasks
@jasontedor
Copy link
Member Author

There will be a few follow-ups to this PR:

  • background sync of replication leases to replicas
  • replicas will not expire retention leases, only the primary will do that

@jasontedor
Copy link
Member Author

@elasticmachine run gradle build tests 1

Copy link
Member

@dnhatn dnhatn left a comment

Choose a reason for hiding this comment

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

I left two comments but this looks really good.

}

@Override
protected ReplicaResult shardOperationOnReplica(final Request request, final IndexShard replica) throws Exception {
Copy link
Member

Choose a reason for hiding this comment

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

I think we should handle BWC where old replicas don't have this action yet. Maybe add an upgrade test as a follow-up?

Copy link
Contributor

@bleskes bleskes left a comment

Choose a reason for hiding this comment

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

I did a high level pass. Things looks good but I wanted to raise points for discussion.

* master: (28 commits)
  Introduce retention lease serialization (elastic#37447)
  Update Delete Watch to allow unknown fields (elastic#37435)
  Make finalize step of recovery source non-blocking (elastic#37388)
  Update the default for include_type_name to false. (elastic#37285)
  Security: remove SSL settings fallback (elastic#36846)
  Adding mapping for hostname field (elastic#37288)
  Relax assertSameDocIdsOnShards assertion
  Reduce recovery time with compress or secure transport (elastic#36981)
  Implement ccr file restore (elastic#37130)
  Fix Eclipse specific compilation issue (elastic#37419)
  Performance fix. Reduce deprecation calls for the same bulk request (elastic#37415)
  [ML] Use String rep of Version in map for serialisation (elastic#37416)
  Cleanup Deadcode in Rest Tests (elastic#37418)
  Mute IndexShardRetentionLeaseTests.testCommit elastic#37420
  unmuted test
  Remove unused index store in directory service
  Improve CloseWhileRelocatingShardsIT (elastic#37348)
  Fix ClusterBlock serialization and Close Index API logic after backport to 6.x (elastic#37360)
  Update the scroll example in the docs (elastic#37394)
  Update analysis.asciidoc (elastic#37404)
  ...
* master:
  Add simple method to write collection of writeables (elastic#37448)
  Fix retention lease commit test
* master:
  Reformat some classes in the index universe
  [DOCS] Add watcher context examples (elastic#36565)
* master:
  Add run under primary permit method (elastic#37440)
@jasontedor
Copy link
Member Author

@dnhatn This is ready for another round. I will open follow-ups for:

  • syncing of retention leases on expiration
  • periodic syncing of retention leases
  • periodic flushing of retention leases

I am ready to open these in rapid succession. 😇

* elastic/master: (68 commits)
  Fix potential IllegalCapacityException in LLRC when selecting nodes (elastic#37821)
  Mute CcrRepositoryIT#testFollowerMappingIsUpdated
  Fix S3 Repository ITs When Docker is not Available (elastic#37878)
  Pass distribution type through to docs tests (elastic#37885)
  Mute SharedClusterSnapshotRestoreIT#testSnapshotCanceledOnRemovedShard
  SQL: Fix casting from date to numeric type to use millis (elastic#37869)
  Migrate o.e.i.r.RecoveryState to Writeable (elastic#37380)
  ML: removing unnecessary upgrade code (elastic#37879)
  Relax cluster metadata version check (elastic#37834)
  Mute TransformIntegrationTests#testSearchTransform
  Refactored GeoHashGrid unit tests (elastic#37832)
  Fixes for a few randomized agg tests that fail hasValue() checks
  Geo: replace intermediate geo objects with libs/geo (elastic#37721)
  Remove NOREPLACE for /etc/elasticsearch in rpm and deb (elastic#37839)
  Remove "reinstall" packaging tests (elastic#37851)
  Add unit tests for ShardStateAction's ShardStartedClusterStateTaskExecutor (elastic#37756)
  Exit batch files explictly using ERRORLEVEL (elastic#29583)
  TransportUnfollowAction should increase settings version (elastic#37859)
  AsyncTwoPhaseIndexerTests race condition fixed (elastic#37830)
  Do not allow negative variances (elastic#37384)
  ...
@jasontedor
Copy link
Member Author

@elasticmachine run elasticsearch-ci/2
@elasticmachine run elasticsearch-ci/default-distro

@jasontedor
Copy link
Member Author

@elasticmachine run elasticsearch-ci/2

Copy link
Member

@dnhatn dnhatn left a comment

Choose a reason for hiding this comment

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

I left a minor comment and two points to discuss. LGTM. Thanks @jasontedor.

Objects.requireNonNull(replica);
replica.updateRetentionLeasesOnReplica(request.getRetentionLeases());
// we flush to ensure that retention leases are committed
flush(replica);
Copy link
Member

Choose a reason for hiding this comment

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

We may need to deal with the fact that a sequence-based or file-based recovery with a synced-flush does not propagate the retention leases to a recovering replica.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, and also hand-off on relocation. I intend to address these later.

Objects.requireNonNull(request);
Objects.requireNonNull(primary);
// we flush to ensure that retention leases are committed
flush(primary);
Copy link
Member

Choose a reason for hiding this comment

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

If the primary recovers from the safe commit, we will lose the committed retention leases. Should we copy them in Store#trimUnsafeCommits ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good call. Let us get that in a follow-up.

@dnhatn
Copy link
Member

dnhatn commented Jan 26, 2019

I am not sure, but maybe we should revisit Yannick's idea which stores the retention leases in the cluster state? Handling the retention leases for an intermediate cluster of a chain replication with a remote recovery might be tricky.

@jasontedor jasontedor merged commit 5fddb63 into elastic:master Jan 27, 2019
jasontedor added a commit that referenced this pull request Jan 27, 2019
When adding a retention lease, we make a reference copy of the retention
leases under lock and then make a copy of that collection outside of the
lock. However, since we merely copied a reference to the retention
leases, after leaving a lock the underlying collection could change on
us. Rather, we want to copy these under lock. This commit adds a
dedicated method for doing this, asserts that we hold a lock when we use
this method, and changes adding a retention lease to use this method.

This commit was intended to be included with #37398 but was pushed to
the wrong branch.
jasontedor added a commit that referenced this pull request Jan 27, 2019
This commit introduces retention lease syncing from the primary to its
replicas when a new retention lease is added. A follow-up commit will
add a background sync of the retention leases as well so that renewed
retention leases are synced to replicas.
jasontedor added a commit that referenced this pull request Jan 27, 2019
When adding a retention lease, we make a reference copy of the retention
leases under lock and then make a copy of that collection outside of the
lock. However, since we merely copied a reference to the retention
leases, after leaving a lock the underlying collection could change on
us. Rather, we want to copy these under lock. This commit adds a
dedicated method for doing this, asserts that we hold a lock when we use
this method, and changes adding a retention lease to use this method.

This commit was intended to be included with #37398 but was pushed to
the wrong branch.
@jasontedor jasontedor deleted the sync-retention-leases branch January 27, 2019 13:28
assert primaryMode;
retentionLeases.put(id, new RetentionLease(id, retainingSequenceNumber, currentTimeMillisSupplier.getAsLong(), source));
if (retentionLeases.containsKey(id) == false) {
throw new IllegalArgumentException("retention lease with ID [" + id + "] does not exist");
Copy link
Contributor

Choose a reason for hiding this comment

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

I have a concern about the strictness introduced here. I think clients of this API are generally going to be trying to ensure that there is a retention lease in place, and I worry about a situation where, for example, the system clock were to jump forward far enough for all existing leases to expire. I think it would be good in that case if clients were to re-establish these expired leases, but today they would be rejected by this method which means that clients will generally have to be prepared to call addRetentionLease if they discover that their lease has expired. I think it'd be better if we implemented that fall-back behaviour here where clients can't forget to call it (and where it can be correctly synchronised).

Copy link
Member Author

Choose a reason for hiding this comment

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

I think this concern is a good one and worth discussing in a larger group. You can see what it presents for consumers in the current integration of CCR with shard history retention leases (WIP branch on my fork).

That said, I am not sure how much to worry about this in practice. In most cases, the life of a retention lease should be significantly longer than the renewal period (e.g., default retention of twelve hours versus renewal frequencies of at most sixty seconds in the case of a CCR follower). And also longer than what most clocks jump by (e.g., for daylight savings time) except when they are completely misconfigured and then we have no guarantees.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Distributed/Distributed A catch all label for anything in the Distributed Area. If you aren't sure, use this one. >enhancement v6.7.0 v7.0.0-beta1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants