Skip to content
This repository has been archived by the owner on Jan 31, 2024. It is now read-only.

Initialize migration tool #1

Merged
merged 16 commits into from
Mar 25, 2019
Merged

Initialize migration tool #1

merged 16 commits into from
Mar 25, 2019

Conversation

kvch
Copy link
Contributor

@kvch kvch commented Jan 29, 2019

THIS IS WORK IN PROGRESS

This tool migrates .management-beats index the following way:

  1. Backups the existing .management-beats index as .management-beats-backup. The backup is then aliased as .management-beats.
  2. A new temporary index is created named .management-beats-new. The new index mapping of 6.7 is PUT to ES.
  3. Reindexes documents from .management-beats-backup which does not require any transformation: beat, enrollment_token.
  4. Queries all tags from .management-beats-backup. These are transformed into new tag documents. Also, configuration_block documents are created for each config element of a tag.
  5. Finalizes the migration by deleting the alias .management-beats. .management-beats-new is reindexed, and the backup is deleted.

If something goes wrong along the process, everything is rolled back.

TODO

  • fix broken rollback functionality
  • add missing Aliases to elasticsearch.Client
  • add more documentation Add more detailed README #4
  • add missing unit testing vendored lib

Possible enhancements

  • index new documents in bulk

migration.go Outdated Show resolved Hide resolved
@ph ph requested review from ph and mattapperson January 29, 2019 21:10
@ph
Copy link

ph commented Jan 29, 2019

@kvch Can you vendor libbeat and make a PR with just that? That will make this PR a lot smaller.

@kvch kvch force-pushed the initialize-migration-tool branch from 952afc2 to 951ee23 Compare January 30, 2019 12:25
@kvch
Copy link
Contributor Author

kvch commented Jan 30, 2019

@ph This commit includes all files which are not "vendored": 951ee23

migration.go Outdated
_, _, err := client.Reindex(managementIndexName, backupManagementIndexName, nil)
if err != nil {
return fmt.Errorf("error while backup up old .management-beats index: %+v", err)
}
Copy link

Choose a reason for hiding this comment

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

When reindexing we create a very new index. Are there any index settings to apply before/when we create the backup index? E.g. set number of shards to 1?

E.g.

  1. load index mapping from existing .management-beats index
  2. create target backup index with index mapping (and other settings?)
  3. reindex into backup index

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As it is a temporary index, I found it unnecessary to setup such things. Why do you think it is necessary?

migration.go Outdated Show resolved Hide resolved
migration.go Outdated Show resolved Hide resolved
migration.go Outdated Show resolved Hide resolved
migration.go Outdated Show resolved Hide resolved
migration.go Outdated Show resolved Hide resolved
migration.go Outdated
}
log.Println("Alias .management-beats is removed")

_, _, err = client.Reindex(newManagementIndexName, managementIndexName, nil)
Copy link

Choose a reason for hiding this comment

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

I think managementIndexName does not exist anymore when we are here. We should create the index and establish the mapping before reindexing into the index to be created.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed, I need to put the same mapping and settings as it is done for newManagmentIndexName.

migration.go Outdated
return nil
}

func rollback(client *elasticsearch.Client) error {
Copy link

Choose a reason for hiding this comment

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

what if rollback itself fails. Can we continue from the last ok step if the user runs the script again?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's my plan, but the rollback functionality is a bit fragile right now. But the architecture you've proposed above will be able to achieve this. I could add a flag to set where to start the migration when running the script.

@kvch kvch force-pushed the initialize-migration-tool branch 2 times, most recently from 15043ac to ca0495b Compare February 7, 2019 12:11
@kvch kvch force-pushed the initialize-migration-tool branch from 07a4df6 to 7560f2c Compare February 7, 2019 20:10
@mattapperson
Copy link

Functionally LGTM. Worth noting that when migrating a very large deployment it did hang for a while. But I doubt anyone will be doing that (10k beats, 6 tags per beat, 500 configs per tag)

@kvch
Copy link
Contributor Author

kvch commented Feb 21, 2019

@mattapperson I have done some refactoring to use the Bulk API of Elasticsearch to index new documents. Do you mind running another stress test to see if the script still hangs?

step.go Outdated

func (s steps) Undo(client *elasticsearch.Client) error {
i := len(s)
for i <= 0 {
Copy link

Choose a reason for hiding this comment

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

for i:=len(s)-1; i >= 0; i-- {
  ...
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤦‍♂️

migration.go Outdated
for i := step; i < uint(len(migrationSteps)); i++ {
err = migrationSteps[i].Do(client)
if err != nil {
undoErr := stepsToUndo.Undo(client)
Copy link

Choose a reason for hiding this comment

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

Where do you add a step to the undo list?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nowhere, but fixed.

step.go Outdated
if err != nil {
return fmt.Errorf("error while backup up old .management-beats index: %+v", err)
}
log.Println("Old .management-beats index is reindexed into .management-beats-backup")
Copy link

Choose a reason for hiding this comment

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

Better use log.Printf with predefine index name variables.

step.go Outdated Show resolved Hide resolved
@kvch kvch force-pushed the initialize-migration-tool branch from 8a751d0 to 0911757 Compare February 25, 2019 16:21
@kvch
Copy link
Contributor Author

kvch commented Feb 25, 2019

I still need to do a bit more testing so I can remove the ugly "WIP" "sign" from the PR.

"log"
"time"

//"gopkg.in/yaml.v2"
Copy link

Choose a reason for hiding this comment

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

not needed?

@ph
Copy link

ph commented Feb 27, 2019

@kvch code look good, have you tested it with CM 6.x to 6.7 with real data?

@kvch
Copy link
Contributor Author

kvch commented Mar 4, 2019

Yes, before the refactoring. Now I have tested it again, and added a few fixes. But I am facing a weird bug now, so I need a bit more time to find the problem.

@kvch kvch force-pushed the initialize-migration-tool branch from 8a90d95 to 92dd275 Compare March 8, 2019 09:13
@kvch
Copy link
Contributor Author

kvch commented Mar 8, 2019

@ph @mattapperson I have found the issue in the code. Now it is ready to be tested.

@kvch kvch removed the in progress label Mar 25, 2019
@kvch
Copy link
Contributor Author

kvch commented Mar 25, 2019

Merging to prepare first release.

@kvch kvch merged commit 4e23a04 into master Mar 25, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants