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

[Bug] During heavy indexing load it's possible for lazy rollover to trigger multiple rollovers #109636

Merged

Conversation

gmarouli
Copy link
Contributor

@gmarouli gmarouli commented Jun 12, 2024

Let’s say we have my-metrics data stream which is receiving a lot of indexing requests. The following scenario can result in multiple unnecessary rollovers:

  1. We update the mapping and mark it to be lazy rolled over
  2. We receive 5 bulk index requests that all contain a write request for this data stream.
  3. Each of these requests are being picked up “at the same time”, they see that the data stream needs to be rolled over and they issue a lazy rollover request.
  4. Currently, data stream my-metrics has 5 tasks executing an unconditional rollover.
  5. The data stream gets rolled over 5 times instead of one.

This scenario is captured in the LazyRolloverDuringDisruptionIT.

We have witnessed this also in the wild, where a data stream was rolled over 281 times extra resulting in 281 empty indices.

This PR proposes:

  • To create a new task queue with a more efficient executor that further batches/deduplicates the requests.
  • We add two safe guards, the first to ensure we will not enqueue the rollover task if we see that a rollover has occurred already. The second safe guard is during task execution, if we see that the data stream does not have the rolloverOnWrite flag set to true we skip the rollover.
  • When we skip the rollover we return the following response:
{
  "acknowledged": true,
  "shards_acknowledged": true,
  "old_index": ".ds-my-data-stream-2099.05.07-000002",
  "new_index": ".ds-my-data-stream-2099.05.07-000002",
  "rolled_over": false,
  "dry_run": false,
  "lazy": false,
}

@elasticsearchmachine
Copy link
Collaborator

Hi @gmarouli, I've created a changelog YAML for you.

@gmarouli gmarouli requested a review from dakrone June 13, 2024 09:14
@gmarouli gmarouli marked this pull request as ready for review June 13, 2024 09:26
@elasticsearchmachine elasticsearchmachine added the Team:Data Management Meta label for data/management team label Jun 13, 2024
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-data-management (Team:Data Management)

@gmarouli gmarouli added v8.14.2 and removed v8.14.1 labels Jun 13, 2024
@gmarouli
Copy link
Contributor Author

@elasticmachine update branch

// We use high priority to not block writes for too long
this.lazyRolloverTaskQueue = clusterService.createTaskQueue(
"lazy-rollover",
Priority.HIGH,
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure about the HIGH priority for this, I think it'd be good to have someone on the distributed side weigh in about potential side-effects.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Discussed with distributed, we do not have enough evidence that this was an issue and this is quite a drastic change, so they recommended to not do this. I have reverted this.

Co-authored-by: Lee Hinman <[email protected]>
@gmarouli
Copy link
Contributor Author

@elasticmachine update branch

Copy link
Contributor

@nielsbauman nielsbauman left a comment

Choose a reason for hiding this comment

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

I think this LGTM. I'd like to give it a second round of thought to ensure I'm not missing anything. Added some comments in the meantime.

@gmarouli
Copy link
Contributor Author

gmarouli commented Jun 19, 2024

Update:" Ignore this, it was not applicable and it has been reverted.

@nielsbauman & @dakrone I realised today that we need a node feature since we are introducing a new task.

Initially, I thought it wasn't necessary because this is a master node action, but if there is a master failover from an newer node to the older node, we might end up with an older node needing to deal with the lazy rollover task which is effectively an unknown task.

The latest commit is fixing this, would you mind taking one more look on this change as well, also do you agree with this?

@gmarouli
Copy link
Contributor Author

@elasticmachine update branch

Copy link
Contributor

@nielsbauman nielsbauman left a comment

Choose a reason for hiding this comment

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

One more approval for the sake of completeness :)

@gmarouli gmarouli added auto-merge Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) auto-backport Automatically create backport pull requests when merged labels Jun 20, 2024
@gmarouli
Copy link
Contributor Author

@elasticmachine update branch

@gmarouli
Copy link
Contributor Author

@elasticmachine update branch

@gmarouli
Copy link
Contributor Author

@elasticmachine update branch

@gmarouli
Copy link
Contributor Author

@elasticmachine update branch

@elasticsearchmachine elasticsearchmachine merged commit c370d27 into elastic:main Jun 21, 2024
15 checks passed
@gmarouli gmarouli deleted the fix-multiple-lazy-rollovers branch June 21, 2024 07:15
@elasticsearchmachine
Copy link
Collaborator

💔 Backport failed

Status Branch Result
8.14 Commit could not be cherrypicked due to conflicts

You can use sqren/backport to manually backport by running backport --upstream elastic/elasticsearch --pr 109636

javanna pushed a commit to javanna/elasticsearch that referenced this pull request Jun 21, 2024
…rigger multiple rollovers (elastic#109636)

Let’s say we have `my-metrics`  data stream which is receiving a lot of
indexing requests. The following scenario can result in multiple
unnecessary rollovers:

1. We update the mapping and mark it to be lazy rolled over
2. We receive 5 bulk index requests that all contain a write request for this data stream.
3. Each of these requests are being picked up “at the same time”, they see that the data stream needs to be rolled over and they issue a lazy rollover request.
4. Currently, data stream my-metrics  has 5 tasks executing an unconditional rollover.
5. The data stream gets rolled over 5 times instead of one.

This scenario is captured in the `LazyRolloverDuringDisruptionIT`.

We have witnessed this also in the wild, where a data stream was rolled
over 281 times extra resulting in 281 empty indices.

This PR proposes:

- To create a new task queue with a more efficient executor that further batches/deduplicates the requests.
- We add two safe guards, the first to ensure we will not enqueue the rollover task if we see that a rollover has occurred already. The second safe guard is during task execution, if we see that the data stream does not have the `rolloverOnWrite` flag set to `true` we skip the rollover. 
- When we skip the rollover we return the following response:

```
{
  "acknowledged": true,
  "shards_acknowledged": true,
  "old_index": ".ds-my-data-stream-2099.05.07-000002",
  "new_index": ".ds-my-data-stream-2099.05.07-000002",
  "rolled_over": false,
  "dry_run": false,
  "lazy": false,
}
```
@gmarouli
Copy link
Contributor Author

💚 All backports created successfully

Status Branch Result
8.14

Questions ?

Please refer to the Backport tool documentation

gmarouli added a commit to gmarouli/elasticsearch that referenced this pull request Jun 21, 2024
…rigger multiple rollovers (elastic#109636)

Let’s say we have `my-metrics`  data stream which is receiving a lot of
indexing requests. The following scenario can result in multiple
unnecessary rollovers:

1. We update the mapping and mark it to be lazy rolled over
2. We receive 5 bulk index requests that all contain a write request for this data stream.
3. Each of these requests are being picked up “at the same time”, they see that the data stream needs to be rolled over and they issue a lazy rollover request.
4. Currently, data stream my-metrics  has 5 tasks executing an unconditional rollover.
5. The data stream gets rolled over 5 times instead of one.

This scenario is captured in the `LazyRolloverDuringDisruptionIT`.

We have witnessed this also in the wild, where a data stream was rolled
over 281 times extra resulting in 281 empty indices.

This PR proposes:

- To create a new task queue with a more efficient executor that further batches/deduplicates the requests.
- We add two safe guards, the first to ensure we will not enqueue the rollover task if we see that a rollover has occurred already. The second safe guard is during task execution, if we see that the data stream does not have the `rolloverOnWrite` flag set to `true` we skip the rollover.
- When we skip the rollover we return the following response:

```
{
  "acknowledged": true,
  "shards_acknowledged": true,
  "old_index": ".ds-my-data-stream-2099.05.07-000002",
  "new_index": ".ds-my-data-stream-2099.05.07-000002",
  "rolled_over": false,
  "dry_run": false,
  "lazy": false,
}
```
gmarouli added a commit that referenced this pull request Jun 21, 2024
…rigger multiple rollovers (#109636) (#110031)

Let’s say we have `my-metrics`  data stream which is receiving a lot of
indexing requests. The following scenario can result in multiple
unnecessary rollovers:

1. We update the mapping and mark it to be lazy rolled over
2. We receive 5 bulk index requests that all contain a write request for this data stream.
3. Each of these requests are being picked up “at the same time”, they see that the data stream needs to be rolled over and they issue a lazy rollover request.
4. Currently, data stream my-metrics  has 5 tasks executing an unconditional rollover.
5. The data stream gets rolled over 5 times instead of one.

This scenario is captured in the `LazyRolloverDuringDisruptionIT`.

We have witnessed this also in the wild, where a data stream was rolled
over 281 times extra resulting in 281 empty indices.

This PR proposes:

- To create a new task queue with a more efficient executor that further batches/deduplicates the requests.
- We add two safe guards, the first to ensure we will not enqueue the rollover task if we see that a rollover has occurred already. The second safe guard is during task execution, if we see that the data stream does not have the `rolloverOnWrite` flag set to `true` we skip the rollover.
- When we skip the rollover we return the following response:

```
{
  "acknowledged": true,
  "shards_acknowledged": true,
  "old_index": ".ds-my-data-stream-2099.05.07-000002",
  "new_index": ".ds-my-data-stream-2099.05.07-000002",
  "rolled_over": false,
  "dry_run": false,
  "lazy": false,
}
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport Automatically create backport pull requests when merged auto-merge Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) backport pending >bug :Data Management/Data streams Data streams and their lifecycles Team:Data Management Meta label for data/management team v8.14.2 v8.15.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants