4

I'm currently in a process of providing our applications of a high availability capability.

Our applications have an auto update feature (using Mongeez) that ensures that the structure of all databases/collections/documents are on correct format for that application version.

The problem is that I'm having a hard time, on how to resolve the replication and versioning problem.

I'll use the following example to better explain the problem.

Example

I need to update Application X to Application X2.0 on both servers without downtime, so I do the following:

  1. Stop Application XA
  2. Install the 2.0 version on Server A
  3. Launch Application X2.0A
  4. Application X2.0A automatically updates MongoDB to the 2.0 format
  5. Since we are using a MongoDB Replica Set, it automatically propagates the changes in all MongoDB instances
  6. PROBLEM!!!... Application XB is still running version 1.0 but it's using the 2.0 version of the databases/collections/documents structure

How can I solve this issue? What am I doing wrong in the previous "workflow"?

Gonçalo Cardoso
  • 2,253
  • 4
  • 34
  • 63

1 Answers1

0

Let's suppose:

  • F1: Format 1.0
  • F2: Format 2.0
  • XA: reads & writes F1
  • XB: new application, reads & writes F2 (document 2.0)

If F2 is compatible with F1, you can make XA & XB run together. It seems that this cause isn't what you described :)

If F2 is not compatible with F1, there is a lot of work to do.

=============== SIMPLE METHOD ==================

  1. add a version field to your document (or use a field to distinguish between F1 and F2)
  2. make you XB compatible with F1&F2: if it reads F1 then writes F1, if it reads F2 then writes F2
  3. upgrade all applications to XB (XA is not affected because there are no F2 at this moment)
  4. make XB only writes F2: if it reads F1 then writes F2, re-deploy XB.
  5. convert all F1 documents to F2

=============== COMMON BUT COMPLEX METHOD ==================

Let's define some concepts first:

  • C1: collection for F1
  • C2: collection for F2
  • XB: an application with a switch to control the reading: from C1 or C2. it uses XA's logic to read from C1.

Steps:

  1. XA running, reads & writes F1 in C1
  2. migrate all data from C1 to C2 (upgrade from F1 to F2)
  3. analyze and execute oplog to make sure all new modifications in C1 migrated to C2
  4. XB reads from C1, write to C1&C2 (IMPORTANT!)
  5. deploy XB step by step, XA is not affected because C1 is usable
  6. switch all XB to read from C2
  7. remove legacy code for F1 in XB

You need some programs(scripts) to do step2 & step3.

If you don't care about cold data, you can skip step2&step3, let XB run for some time to migrate hot data.

=============== another method ==================

  1. divide your server into to groups. eg: G1(XA1, XA2), G2(XA3, XA4)
  2. use nginx/haproxy to balance your requests
  3. make all requests sent to G1(XA1, XA2)
  4. deploy XB to G2, result: G2(XB3, XB4)
  5. make all requests sent to G2(XB3, XB4)
  6. deploy XB to G1, result: G1(XB1, XB2)
  7. make all requests sent to G1(XB1, XB2)/G2(XB3, XB4)
  8. convert all F1 documents to F2

there are risks:

  1. In step 3/step 5, your server load may exceed, so you need to do this in non-business time
  2. If you have bugs in XB, there is no way to rollback.
shawn
  • 4,305
  • 1
  • 17
  • 25
  • Both of you solutions aren't very practical since they would make mandatory for every version of the application to be able to read and write to all it's previous versions – Gonçalo Cardoso Apr 08 '15 at 08:45
  • every big company do this way. – shawn Apr 08 '15 at 09:01
  • You are telling me that every company as it's 9.9.9 version retro-compatible with version 0.0.1? – Gonçalo Cardoso Apr 08 '15 at 09:02
  • no, you only need make compatible between the latest version the previous version. when you have an application XC for F3, just forget F1, only need to be compatible with F2. your all F1 data should have been migrated after all XBs are online. – shawn Apr 08 '15 at 09:04
  • another simple way is to tolerate some downtime and/or some error ... we sometimes do this :) because we never say we provide 100% stability, we only provide 99.99% :D – shawn Apr 08 '15 at 09:04
  • The problem with being compatible with only the last version, is that we have a lot of clients that refuse to always have the latest version installed. And it's also very complicated for them in terms of logistic. – Gonçalo Cardoso Apr 08 '15 at 09:10
  • Your question is about your applications with MongoDB replset. So I think that all applications are under your control, you can use these methods to upgrade them in time. If your clients insist to use very old applications, there is no other way than keeping all applications compatible. If you look into the server-side of mobile applications, you will find many many codes for compatibility because there are always so many users refuse to upgrade their apps to the latest version. It's very very sad, but it's the truth. – shawn Apr 08 '15 at 09:16
  • Well, I edited my answer and add a method which I would not recommend to use. – shawn Apr 08 '15 at 09:27
  • I don't understand how the replication of the DB's would work on that new method? Do G1 use a separate replicaset of G2? If so how, how does the data from the G1 DB gets synchronized with the one from G2? – Gonçalo Cardoso Apr 08 '15 at 10:18
  • No matter what method you choose, when MongoDB works in replica set mode, you can treat them as one instance, the same databases, the same collections, the same documents. Just think about you have only one mongo instance. MongoDB replica set's major purpose is to provide backup, disaster recovery and read-write split. – shawn Apr 08 '15 at 10:42
  • I know that about replica set, but I don't understand what's the difference between this last method and the others... you just added 2 more servers... – Gonçalo Cardoso Apr 08 '15 at 13:43
  • In method 1&2, XA&XB have to serve at the same time for a while (no downtime, no risk). In method 3, XA stops serving, then XB starts to serve (no downtime, a little risky). – shawn Apr 08 '15 at 13:52
  • But I still have the problem with the data on 2 distinct versions on the database at the same time, and my application that need to be retrocompatible till version 0.0.0.1 – Gonçalo Cardoso Apr 08 '15 at 14:00
  • when all applications have been upgraded to XB, write some programs(usually scripts) to convert all F1 to F2. see method1-step5, method2-step2&3, method3-step8. this is my last comment. i have talked too much. – shawn Apr 08 '15 at 14:36
  • Thanks for all the comments, but none of your solutions are doable. – Gonçalo Cardoso Apr 08 '15 at 14:49