Upgrade your elasticsearch 1.x cluster to 5.x
Today I was reading about breaking changes in the upcoming 5.0 release of elasticsearch. I read about indexes that are created in 1.x cannot be migrated to 5.x. Even if they were created in the 1.x, migrated to 2.x they cannot be run in 5.x. Luckily there is a migration plugin for 2.4.x. To be a little bit prepared, I wanted to try it out for myself.
Create a project setup
Create the project setup that makes it easy to create a cluster of different versions. First we need a number of different elasticseach versions. You can download them from the elastic website. I have three different versions 1.7.5, 2.4.1 and 5.0.0-rc1 running.
I want to put the data and the config in a separate location. That way I can switch easier between versions. As you can see the configuration for 1 and 2 is different from the one of 5. Therefore they have two different folders.
The test setup looks like this:
projects
upgrade
startNode.sh
config
elasticsearch.yml
logging.yml
config5
elasticsearch.yml
jvm.options (only for 5)
log4j2.properties (only for 5)
data
logs
elasticsearch-1.7.5
elasticsearch-2.4.1
elasticsearch-5.0.0-rc1
The most important file now is the startNode.sh script that can start the different versions of the elasticsearch cluster. The scripts looks like this:
#!/bin/bash
CURRENT_PROJECT=$(pwd)
CONFIG=$CURRENT_PROJECT/config
CONFIG5=$CURRENT_PROJECT/config5
DATA=$CURRENT_PROJECT/data
LOGS=$CURRENT_PROJECT/logs
# BASH_ES_OPTS="-Des.path.conf=$CONFIG -Des.path.data=$DATA -Des.path.logs=$LOGS"
BASH_ES_OPTS="-Epath.conf=$CONFIG5 -Epath.data=$DATA -Epath.logs=$LOGS"
# ELASTICSEARCH=$HOME/Development/elastic/elasticsearch/elasticsearch-1.7.5
# ELASTICSEARCH=$HOME/Development/elastic/elasticsearch/elasticsearch-2.4.1
ELASTICSEARCH=$HOME/Development/elastic/elasticsearch/elasticsearch-5.0.0-rc1
$ELASTICSEARCH/bin/elasticsearch $BASH_ES_OPTS
cluster.name: upgrade-cluster
node.name: "Node 1"
index.number_of_shards: 1
index.number_of_replicas: 0
curl -XPOST 'http://localhost:9200/mystore/product/_bulk' --data-binary "@mystore.bulk"
The file has the following format:
{ "index" : { "_id" : "1" }}
{"title":"PS4","category":"hardware","price":399.98,"stock":1}
{ "index" : { "_id" : "2" }}
{"title":"Xbox One","category":"hardware","price":449.00,"stock":100}
Using the very handy tool called httpie we can use the rest API of elastic. The following command returns the avialable indices.
http ':9200/_cat/indices?v' -b
With the following result
health status index pri rep docs.count docs.deleted store.size pri.store.size
green open mystore 1 0 10 0 5kb 5kb
Next step is bringing down the cluster and starting it with the 5.x software. When starting the cluster it fails with some nice stacktraces. If you check the root cause of the stacktrace, you can find the following lines:
Caused by: java.lang.IllegalStateException: unsupported compression: index was created before v2.0.0.beta1 and wasn't upgraded?
Not good right? So let us first try to start with version 2.4.1 software and see what happens. Everything starts up fine with version 2.4.1 software, so let us try version 5.x again. To bad, stacktraces all of the place, but a very informative message if you ask me.
4) Error injecting constructor, java.lang.IllegalStateException: The index [[mystore/hd77vX6dSRSt2dUz8LbZ4w]] was created before v2.0.0.beta1. It should be reindexed in Elasticsearch 2.x before upgrading to 5.0.0-rc1.
Time to install the migration plugin in the version 2.x cluster. More information can be found here. So I install the plugin, using the command from the plugin website. Restarting using the 2.4.x software seemed to have changed the name of the index and the logs contain messages about dangled indices. The output from the same http command as before now is:
health status index pri rep docs.count docs.deleted store.size pri.store.size
green open hd77vX6dSRSt2dUz8LbZ4w 1 0 10 0 5.1kb 5.1kb
red open mystore 1 0
This is not good, mystore index is red and we have an index with a strange name. I restore the old inde using the snapshot I created. Oh I did not create a snapshot. So I start over again with a clean index. First create the index in version 1 software of elasticsearch. Than restart with version 2 and the plugin enabled. As documented I now visit the following url: http://localhost:9200/_plugin/elasticsearch-migration/.
Since we have installed the plugin, I first run the cluster checker. The following image show the result. As you can see we have two problems. One we already mentioned, we cannot provide index settings in the config any longer. And the other is one we also found out the hard way, we need to upgrade the index. So we open up the reindex helper.
Push the button to re-index. The name of the index is now changed as you can see from the output of the http command.
health status index pri rep docs.count docs.deleted store.size pri.store.size
green open mystore-2.4.1 1 0 10 0 5.8kb 5.8kb
Now we can startup with version 5 software again. This time the cluster boots fine. The result for the same http command now is:
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open mystore-2.4.1 0M3rSt0hQPmX_hbIc5g37A 1 0 10 0 5.9kb 5.9kb