4 ms·
Regarding microservices. They sound nice in theory, and certainly work for some cases. But what is the common pattern to handle a situation like this (in a perf
by kisstheblade 11y ago
Regarding microservices. They sound nice in theory, and certainly work for some cases. But what is the common pattern to handle a situation like this (in a performant and "scalable" way).
Say you have two (completely separate micro-) services:
- Order service
- Customer service
Now when a customer buys something, it is stored in the order service. But how is the customer information referenced in the order service? Do you store just some "customer id" and let the clients of this service worry about what it means? Or do you store some customer information also in the order service (in memory cache or in the services own datastore, both solutions which then need to synchronize this data somehow)?
Eg. how about a situation where you want to display a sortable list of orders, and it includes the columns for the customers first and last names. How can you sort on these columns if the order service doesn't know anything about the customer other than some "identifier"? Especially if the list is paged so you can't look up all the needed customer's information.
Just thought about this because this article (and many others) tout microservices as some kind of silver bullet.
- lotyrin 11y agoThe cross-service join problem is definitely a weak point of microservices. Generally you'd try to avoid designing service boundaries that you plan to do joins or transactions, etc. across. If you do need joins/transactions though, it's not impossible to coordinate them across services. Your reporting feature that wants to provide a sortable list of orders+customer information, whether it lives in the order or customer services or in its own, would have to collect order information including customer ids, then use those ids to collect customer information, join these together in a working area of some kind if they're large (in-memory cache as you've mentioned is a decent candidate) and sort/filter that as needed. A cache + invalidation strategy appropriate to the application could definitely be needed for acceptable performance. Depending on the characteristics of the team: size, planning style, communication style, etc. the cost of having to solve cases like these can be well worth paying to have smaller projects which can be reviewed easier with clearer ownership responsibility etc. Sometimes the tradeoff is a dramatic win and these are where the microservices advocates come from. Everything is trade-offs. With billions of humans, the worst design pattern/methodology/technology you can think of still probably has an appropriate application somewhere.
- kisstheblade 11y agoAgreed. Usually it's always the "user" object which cuts across services. Was wondering if there is some common pattern for handling this. For the scenario I outlined here some kind of "third service" / aggregated view of the data could also be a solution. Ie. store the data needed for queries in some queryable datastore (nosql, sql; pull the info from the needed services and refresh the view when needed)
- perlgeek 11y agoDenormalization is often a practical answer; the order service keeps an (immutable) copy of the customer's name and delivery address. If the customer changes the address, it will only matter for new orders. One can argue that this is actually a sensible behavior, because there's a point after which you can't change the delivery address anyway (once it has been handed over to the delivery service, for example), and this behavior of copying the address just moves the point a bit. Likewise, when a customer buys a product, a copy of the product description and price is included in the order; if the price changes between the checkout and the delivery, it's good if that isn't reflect in the amount that is invoiced. After all, the checkout established a contract that cannot be easily changed retroactively.
- kisstheblade 11y agoGood point. In this case at least it is actually preferable to copy the customer data over to the order.
- Terr_ 11y agoRight, I think this is an example of the importance of good requirements and scenarios before coding. While programmers may prefer to create denormalized "model of everything at once", some business processes require copies and snapshots. Not as implementation details, but directly.
- deleted 11y ago[deleted]
- deleted 11y ago[deleted]
- jtmarmon 11y agoYou can do a cross service join in a single request. Combine that with good caching and a normalized architecture is (almost) as performant as a demoralized one. Check out https://github.com/facebook/dataloader https://github.com/facebook/dataloader We use it to do cross service joins in the form of bulk requests in a very transparent way.