The purpose of this spike was to to explore different ways of running a data migration on a Mongo database with no downtime (or as little as possible).
The code in the repository can be split into 3-strands of work
This spike demonstrates a migration on the PersonalDetails object where the name field is removed and two new fields: firstName and lastName are introduced. For example, the object is changed from:
{
"personalDetailsId": "12345",
"name": "Bob Builder",
"dateOfBirth": "19700101"
}To:
{
"personalDetailsId": "12345",
"firstName": "Bob",
"lastName": "Builder",
"dateOfBirth": "19700101"
}Two core types of Migration:
Data is written back to the original collection, the data written must be backwards compatible
Data is read from the original collection, migrated and written to a new collection. If the migration fails for any reason then the new collection can simply be dropped.
The High Level Migration Process consists of two parts:
- Obtain a lock on the source collection
- Read the documents from the source collection using MongoDocumentSelector
- For each document:
- Migrate the document (if required) using an implementation of DocumentMigrator
- Write the document to the new collection using MongoDocumentWriter
KafkaMessageListener listens to topic and consumes records related to CRUD operations on the source collection. Each operation is processed by a MongoOperationProcessor corresponding to the type of operation (e.g. Insert, Update, Delete)
A simple Spring Boot Application that exposes the following CRUD operations via REST over HTTP:
GET /personal-details/{personalDetailsId}POST /personal-detailsPUT /personal-detailsDELETE /personal-details/{personalDetailsId}
For for more details on the operations see the PersonalDetailsClient
A basic client Application which hits each of the HTTP endpoints of [Personal Details Server](#Personal Details Server) at the following intervals:
- Create - every 2 seconds
- Read - every 1 second
- Update - every 3 seconds
- Delete - every 5 seconds
This project uses:
- Buck as the main build tool. Please refer to the Getting Started Guide for installation and usage of Buck.
This build has been tested using
v2017.10.01.01of Buck. - Docker to package up and run both the application and associated infrastructure.
To build the personal-details-server and personal-details-client applications execute the following commands:
./start-mongo.sh dev
buck build //...This will generate two Docker images:
personal-details-client:${version}personal-details-server:${version}
Where ${version} is:
The docker images can be seen by running the following command:
docker imagesTo execute the demo you will need the following running:
- Mongo
- Kafka
- Personal Details Server
- Personal Details Client Application
Start a Docker container running an authenticated Mongo instance.
./start-mongo.sh demoConnecting to the mongo instance from the host OS
mongo -username=admin -password=Passw0rd -authenticationDatabase=admin localhost:28018/admin./start-kafka.sh./start-haproxy.shStart the Personal Details Microservice running in a Docker container
./start-personal-details.shIf you want to connect to the Docker container execute the following command:
docker exec -it personal-details-server-v1 /bin/bashStart an example client which will start making HTTP requests to the personal-details-server
./start-personal-details-client.sh
