Microservices: how to handle foreign key relationships

前端 未结 4 2057
温柔的废话
温柔的废话 2021-01-29 20:14

Microservices architecture suggest that each service should handle it\'s own data. Hence any service (Service A) dependent on data owned by other service (service B) should acce

相关标签:
4条回答
  • 2021-01-29 20:55

    When distributing your code to achieve reduced coupling, you want to avoid resource sharing, and data is a resource you want to to avoid sharing.

    Another point is that only one component in your system owns the data (for state changing operations), other components can READ but NOT WRITE, they can have copies of the data or you can share a view model they can use to get the latest state of an object.

    Introducing referential integrity will reintroduce coupling, instead you want to use something like Guids for your primary keys, they will be created by the creator of the object, the rest is all about managing eventual consistency.

    Take a look at Udi Dahan's talk in NDC Oslo for a more details

    Hope this helps

    0 讨论(0)
  • 2021-01-29 20:58

    A 2020 update to this answer is to use a Change Data Capture tool like Debezium. Debezium will monitor your database tables for changes and stream them to Kafka/Pulsar (other pipes) and your subscribers can then capture the changes and synchronize them.

    0 讨论(0)
  • 2021-01-29 21:01

    first solution: API Composition

     Implement a query by defining an API Composer, which invoking the
     services that own the data and performs an in-memory join of the
     results
    

    second solution: CQRS

    Define a view database, which is a read-only replica that is designed to support that 
    query. The application keeps the replica up to data by subscribing to Domain events 
    published by the service that own the data.
    

    0 讨论(0)
  • 2021-01-29 21:04

    It is possible to use a shared database for multiple microservices. You can find the patterns for data management of microservices in this link: http://microservices.io/patterns/data/database-per-service.html. By the way, it is a very useful blog for microservices architecture.

    In your case, you prefer to use database per service pattern. This make microservices more autonomous. In this situation, you should duplicate some of your data among multiple microservices. You can share the data with api calls between microservices or you can share it with async messaging. It depends on your infrastructure and frequency of change of the data. If it is not changing often, you should duplicate the data with async events.

    In your example, Delivery service can duplicate delivery locations and product information. Product service manage the products and locations. Then the required data is copied to Delivery service's database with async messages (for example you can use rabbit mq or apache kafka). Delivery service does not change the product and location data but it uses the data when it is doing its job. If the part of the product data which is used by Delivery service is changing often, data duplication with async messaging will be very costly. In this case you should make api calls between Product and Delivery service. Delivery service asks Product service to check whether a product is deliverable to a specific location or not. Delivery service asks Products service with an identifier (name, id etc.) of a product and location. These identifiers can be taken from end user or it is shared between microservices. Because the databases of microservices are different here, we cannot define foreign keys between the data of these microservices.

    Api calls maybe easier to implement but network cost is higher in this option. Also your services are less autonomous when you are doing api calls. Because, in your example when Product service is down, Delivery service cannot do its job. If you duplicate the data with async messaging, the required data to make delivery is located in the database of Delivery microservice. When Product service is not working you will be able to make delivery.

    0 讨论(0)
提交回复
热议问题