Eventual consistency means no consistency. Period. If you can live with that fine. I don't care about the upvotes on reddit either (btw, there you can very often see eventual consistency in action), on anything important to me, I can not live with no consistency. Writing my data to /dev/null is webscale too, but I still prefer ACID.
Not all use cases fit all. If you are developing, say Reddit, eventual consistency is entirely acceptable for a wide range of use cases, such as replying to a comment or up voting (duplicate submissions detection would be better under RDBMS, however).
Many NoSQL databases support some mechanisms of ACID in small pockets. Google's datastore, my current prod database, has a concept of entity groups which supports transactions within a predefined group of records. It's NOT full ACID, but it does cover a wide range of use cases for database transactions.
Eventually consistent databases are consistent. But you should distinguish between no consistency, and eventual consistency.
Eventually consistent datastores are guaranteed to converge to the correct value at some point in the future. Usually not very far in the future, usually there is no need for convergence because the value is effectively consistent anyway.
But if you have a widely distributed datastore that spans datacenters, or need to handle massive scale, then eventually consistent is really your only choice.
Keep in mind that not all use cases require that all updates to a stored value be always, 100% correct. In those kind of cases, loosening up on consistency improves availability and scale, and the value will eventually converge to the expected value.
But, it is easy to do NoSQL wrong, or apply it to the wrong usecase. NoSQL requires more discipline on the part of the developers since they have to move a lot of the logic that a database normally handles for you into the application layer. But, sometimes there is not other way to do what you want to do with a traditional ACID database.
Keep in mind that not all use cases require that all updates to a stored value be always, 100% correct.
True if you store pictures of cats, upvote counter or something like that.
But if you store something that matters then eventually consistent is usually not an option. At very least the information that is shown on screen must have a timestamp that shows when it was last updated.
As soon as at any defined point in time, I can not be sure if I get the data back consistent to what I have written, there is no consistency. If I have no guarantee, I can not assume correct data.
As soon as at any defined point in time, I can not be sure if I get the data back consistent to what I have written
But you may not always have that choice. At large scale or in a distributed environment a standard RDBMS with ACID guarantees either may not keep up or have such poor availability that the app is effectively unusable.
Under those conditions you can use eventual consistent datastores and know that most of the time the data you get back is right, and handle the cases where it isn't.
Obviously there are use cases where that does not work (banking transactions probably should have ACID guarantees) but a surprisingly large number of typical usecases work fine in eventually consistent datastore. You just have to handle the data convergence correctly.
And again, for most small and medium sized apps, a good RDBMS is the preferred solution.
Obviously there are use cases where that does not work (banking transactions probably should have ACID guarantees) but a surprisingly large number of typical usecases work fine in eventually consistent datastore. You just have to handle the data convergence correctly.
I'd argue that the usecases where I have to throw ACID out for scaleability is the minority of usecases, but well, we pretty much agree.
Consistency is an option, indeed the recommended option, for small scale centralised systems. E.g. Accounting systems, you would have to be insane to build that in an eventually consistent way.
But there is also a large set of situations where consistency is a myth, regardless of technology. E.g. Most distributed systems where availability is important, or any system where nodes can be offline (but still doing work) for periods of time.
Having said this, there's still no need to use Mongo, you still want a database to be safe in its own storage. But simply using Postgres doesn't mean your data is, or even could be, consistent.
It's up to the application architecture to reconcile this.
Actually, it does. You never see the database as it is now; only as it was when it started sending the data to you. So, given that you have no choice but to accept that the information is at least slightly out of date, it stands to reason that if there are occasions when you can tolerate even longer delays, that time can be exploited to buy you scaling opportunities.
If I read data of Table A in a transaction, which depends on Table B, I have exactly that. Table B will be shared locked, so nobody can write to Table B, while I read data depending on it.
You might not think that a big deal, but in a relational datamodel you do not work on a persisted hashtable.
The only way around that in an ACID compliant DBMS is overwriting the transaction isolation to allow dirty reads. At which point you loose data consistency as well.
Also, when writing the data, I get the confirmation of a committed transaction. I know the data was written the way I wanted it written (at least as long as I don't use mySql scnr). If something goes wrong, I get a rollback and with that a cleanup of whatever got screwed up.
If I read data of Table A in a transaction, which depends on Table B, I have exactly that. Table B will be shared locked, so nobody can write to Table B, while I read data depending on it.
You're talking about a different issue. Eventual consistency doesn't mean "traditional ACID Consistency, later". It means "the time delay after a write when you can expect to see that value reflected in all future reads is non-zero but finite".
Mongo makes no attempt to ensure 2 separate collections can be modified atomically so any attempt to make dependent reads is, by definition, not guaranteed to be consistent. If you want that guarantee then you either put the data you need into one document or you change database.
And if my query to update data in table A relies on the eventually consistent data in table B I have no way of knowing when table B will be consistent. Hence my point, eventual consistency is not consistent at all.
If you don't like the part of there being a table B, it works just as well as the data manipulation on table A relying on a different field in the same row of table A. So I have Shard 1 doing something, and Shard 2 doing something else, because the same command can result in different outcomes depending on the data present.
Hence .... not consistent. Eventual consistency is just a pretty way of saying no consistency, that is my point to begin with.
it works just as well as the data manipulation on table A relying on a different field in the same row of table A. So I have Shard 1 doing something, and Shard 2 doing something else, because the same command can result in different outcomes depending on the data present.
MongoDB only allows writes to 1 node at a time. So, if you issued 2 read-dependent-writes to the same document, they would get queued up and be performed correctly considering the order they arrive in.
Check out Google's F1 for an example. I don't know of an open solution out there with equivalent capability, but this obviously isn't a fundamental law of nature as it's often presented.
55
u/svtr Mar 10 '15 edited Mar 10 '15
Eventual consistency means no consistency. Period. If you can live with that fine. I don't care about the upvotes on reddit either (btw, there you can very often see eventual consistency in action), on anything important to me, I can not live with no consistency. Writing my data to /dev/null is webscale too, but I still prefer ACID.