[HN Gopher] How to get transactions between almost any data stores
___________________________________________________________________
How to get transactions between almost any data stores
Author : KraftyOne
Score : 95 points
Date : 2023-08-30 14:13 UTC (8 hours ago)
(HTM) web link (petereliaskraft.net)
(TXT) w3m dump (petereliaskraft.net)
| tabeth wrote:
| An interesting idea, but if I'm understanding the problem trying
| to be solved - might be better suited by durable execution (two
| examples being Azure's durable functions, and Temporal.io).
|
| In practice transactions between arbitrary data stores would
| result in potentially boundless and widely unpredictable latency,
| no?
|
| Also, is Postgres strongly consistent and linearizable)? One
| alternative would be using a database with stronger consistency
| guarantees (Spanner is but not open source, FoundationDB is but
| has limitations on transactions unless you implement mvcc
| yourself, which to be fair you are).
| jeremyjh wrote:
| Consistency is a property of distributed databases. Stock
| Postgres is not distributed, and thus gets strong consistency
| for free.
|
| There is still a concept of (transaction) isolation levels, and
| the ANSI SQL standard defines a transaction mode READ
| UNCOMMITTED that could give you inconsistent results, but
| Postgres ignores that and treats it as READ COMMITTED.
| tabeth wrote:
| Yeah you are right - I thought the primary in this case was
| distributed since most of the shims were (CouchDB, Mongo,
| etc).
| banq wrote:
| The Saga is Antipattern https://sergiy-
| yevtushenko.medium.com/the-saga-is-antipatter...
|
| Microservices distributed transactions are an anti pattern
| [deleted]
| hakunin wrote:
| In most cases microservices are an anti-pattern, because they
| are trying to solve problems that can be solved without
| incurring their complexity and sacrifices.
|
| However, I remember Sagas originally applied to dealing with
| multiple 3rd party API, the example was "book flight, hotel,
| rental car". If you're dealing with necessarily separate
| systems, then there's probably a place for sagas.
| samsquire wrote:
| Thank you for submitting this and thank you to the authors.
|
| I am curious how this kind of thing can scale. What I'm inspired
| by this article is the idea of applying multiversion semantics to
| datastores that aren't multiversioned.
|
| Sounds like if you have a transactionally sound store of
| "versions" and a way to query every datastore with a version
| field, you could implement point in time consistency, because the
| current version would only change when all datastores are
| updated. You still have to wait for all datastores to be updated,
| so that part is similar to 2 phase commit.
|
| My understanding is that two phase commit does not scale and is
| slow because of all the round trips, but we still want
| linearizability and strong consistency in systems.
|
| I tried to implement an asynchronously replicating data protocol
| but it is eventually consistent, not linearizable (it fails the
| Jepsen linearizability test)
|
| https://github.com/samsquire/eventually-consistent-mesh
|
| I'm a beginner in this area but I have a toy multiversion
| concurrency control implementation that uses Java threads. (See
| MVCC.java and TransactionC.java) the key statements of code is in
| commit() and shouldRestart().
|
| https://github.com/samsquire/multiversion-concurrency-contro...
|
| Dropbox does something 2 phase commit with their cross shard
| replication which is interesting
| https://dropbox.tech/infrastructure/cross-shard-transactions...
| KraftyOne wrote:
| While we haven't tested this, I suspect the main scaling
| bottleneck in practice is the primary database, as every Epoxy
| transaction goes through it. If you wanted to run Epoxy at
| large scale, you'd need a primary that supports very high
| transaction throughput.
| dang wrote:
| Paper: http://petereliaskraft.net/res/p2732-kraft.pdf
| FrameworkFred wrote:
| I think I followed that pretty well (I'll maybe need to read it
| again to be sure)...very nice, well done!
| jiaaro wrote:
| Does Epoxy use postgres' own transaction ids across datastores?
| If not, does it implement its own "transaction id horizon" like
| postgres has so that you can assume all transactions before a
| certain counter are committed?
| KraftyOne wrote:
| Yeah, our implementation uses Postgres transaction IDs across
| data stores.
| PaulHoule wrote:
| Distributed transactions have been around for a while.
| kerblang wrote:
| The author already acknowledged that there are other ways to do
| distributed transactions
|
| > The traditional solution is to use two-phase commit through a
| protocol like X/Open XA. However, while XA is supported by most
| big relational databases like Postgres and MySQL, it's not
| supported by popular newer data stores like MongoDB, Cassandra,
| or Elasticsearch
| AtlasBarfed wrote:
| Inaccurate:
|
| Cassandra has a distributed transaction based on paxos, and I
| think a raft version is in the works.
|
| I admittedly skimmed the article, but the notion of a central
| coordinator for the transaction isn't really a scalable
| solution. In the stated use case, heterogeneous stores, it's
| kind of what you're stuck with to some degree.
|
| But... why not use a purely distributed central store like
| Cassandra or Zookeeper (I think zoo is masterless?) rather
| than Postgres?
|
| IMO this doesn't have a chance of standing up to a network
| partition like Aphyr would throw at it, but then again I
| didn't graduate from Stanford.
| rubiquity wrote:
| The author is specifically talking about XA.
| cratermoon wrote:
| across heterogeneous data stores?
| PaulHoule wrote:
| Yep.
|
| https://en.wikipedia.org/wiki/Distributed_transaction
| [deleted]
| gregw2 wrote:
| How heterogeneous do you mean? But basically, "yes".
|
| IBM had CICS transactions back in the day for some definition
| of heterogeneity. Tuxedo did this in the 80s across broader
| platforms. In the 90s (when I heard of it) there was an open
| standard created for it:
| https://en.wikipedia.org/wiki/X/Open_XA so that Unix-y type
| systems had some agreement on how to do it without buying
| mainframe/tuxedo-y type components. And around or a bit after
| then, Microsoft created its own "Distributed Transaction
| Coordinator". This is not my area of expertise but I've heard
| about it throughout the last 30 years.
|
| The NoSQL side of heterogeneous is newer than the 90s but
| even there, I found in 2 minutes a paper from 2006, 17 years
| ago, on the topic: https://www.researchgate.net/profile/Akon-
| Dey/publication/28...
|
| This is definitely a wheel that gets reinvented.
| jimbokun wrote:
| Does this mean Epoxy must execute all the calls to the underlying
| services? If so, how is the data to be stored in each db
| communicated to Epoxy?
| amelius wrote:
| The way it should probably work is through hooks that you can
| implement yourself.
| jiaaro wrote:
| Based on the paper Dang linked, it appears that epoxy is
| involved in all queries to all data stores it coordinates
| zabzonk wrote:
| use a tp monitor? such things have been around for a very long
| time. i remember writing code to interface with one in the 90s,
| and a bit later. but things like cics and tuxedo were there long
| before that.
| [deleted]
| numbsafari wrote:
| Again with the straw man example of a bank transfer.
|
| Another article you didn't need to read because it talks about a
| problem you likely don't have because the author can't be
| bothered to come up with actual, real world examples.
| koromak wrote:
| Fine. I've got a Document database for user data, AWS Cognito
| for user ID's and authentication, Stripe for payments, and
| Postgres for a subset of user profile data that interacts with
| application data.
|
| Common actions like Create, Delete, and some Updates touch all
| of these services. Automatic transactions between these would
| be fantastic. Especially on the billing side, some billing
| flows involve multiple trips between Stripe and our DB,
| batching the whole process inside a guaranteed reversable
| transaction would be lovely.
|
| Of course we're not going to get that with Stripe and Cognito
| as they expose bespoke API's, but the idea still holds.
| numbsafari wrote:
| Except it doesn't, really. You don't usually want your user
| sitting around waiting for all those services to talk to each
| other before they a notification that the process is complete
| or not.
|
| Further, those complex interactions between those various
| services will be much hard to debug and tweak when trying to
| provide support to end users. Can't pay your bill because
| Cognito is down? Can't grant access because Stripe is down?
| The data warehouse is doing an index build so you can't do
| any transactions? Guess we should turn off the website
| between 2AM and 4AM ET to allow for data warehouse rebuilds.
|
| There's a reason we don't do things this way.
| marktani wrote:
| can you share a more helpful real world example?
|
| as someone who hasn't implemented transactions in microservices
| before, I have only seen the bank transfer example and it seems
| adequate and easy to understand - I wouldn't know what
| limitations it has
| numbsafari wrote:
| It doesn't exist. This isn't how banks transfer funds between
| accounts.
|
| It's fake. As a result, you can't actually evaluate the
| engineering trade offs of the proposed solution.
|
| Here's the thing: do you even need transactions (in the sense
| of ACID transactions that are resolved heuristically, as
| described in this article) between your microservices? Likely
| not.
|
| And what are the implications of having to wait around for
| PGSQL and Mongo negotiate a transaction between a third data
| store? Probably blocking and latency and all the associated
| problems which will lead to ... not use transaction across
| service boundaries.
| jeremyjh wrote:
| People who have a use for this technology don't need a real
| world example, they already know where they would apply it. A
| bank transfer is a good example because it is easy to
| understand, regardless of your background.
___________________________________________________________________
(page generated 2023-08-30 23:00 UTC)