samedi 27 octobre 2018

How to reconcile microservice "share nothing" principle with "independence"

Let's say my entire domain has entities like

[
   {
      id: 1,
      name: "Joe",
      age: 16,
      hometown: "Los Angeles",
      friends: [2]
   },
   {
      id: 2,
      name: "Jack",
      age: 83,
      hometown: "Phily",
      friends: [1, 3]
   },
   {
      id: 3,
      name: "Susy",
      age: 50,
      hometown: "Dayton",
      friends: [2]
   }
]

and I decide to have 2 separate services

  1. Person Info Manager
  2. Friend Manager

to deal with these entities. The way I would literally interpret "share nothing" would be have that each service has storage like

[
   {
      id: 1,
      name: "Joe",
      age: 16,
      hometown: "Los Angeles"
   },
   {
      id: 2,
      name: "Jack",
      age: 83,
      hometown: "Phily"
   },
   {
      id: 3,
      name: "Susy",
      age: 50,
      hometown: "Dayton"
   }
]

for 1. and

{
    1: [2],
    2: [1, 3],
    3: [2]
}

for 2. So basically the overall information has been partitioned into being stored in 2 places (except the ids which I guess are shared).

Here are some potential problems that I see with this:

  • In the case of the Friend Manager service, since all you have is ids, there is probably nothing useful that can be done in overall system without combing information from this service with information from Person Info Manager service.
  • To follow the previous point, let's say that we want a UI where users can manage friend ships. Then we will need to query the Friend Manager Service to get this information and perform "joins" by id. This means that Friend Manager Service has a dependency on Person Info Manager service, or there is some third service that has a dependency on both.

To remedy those potential problems (I'm not sure they are real problems; that's why I am asking S.O.) we could have that they share more data. Let's say that you need at minimum to know a person's name in order to manage friendships. Then we could have

{
    info: {
        1: {
          name: "Joe"
        },
        2: {
          name: "Jack"
        },
        3: {
          name: "Susy"
        }
    },
    friendships: {
        1: [2],
        2: [1, 3],
        3: [2]
    }
}

so that now the Friend Manager service can work independently. Some potential downsides with this are

  • Extra storage cost from duplicate data
  • The names in in Friend Manager service could be stale because of lag in receiving updates from the Person Info Manager service or because of error. Whereas if the Friend Manager service were to query Person Info Manager service for names whenever needed, then it would always have the up-to-date info (the query could also account for persons who have been removed).

Aucun commentaire:

Enregistrer un commentaire