HNHacker News
TopNewBestAskShowJobs

aphyr

9,731 karma · joined January 15, 2010

https://aphyr.com

Hacker, physics geek, clojurer, rubyist, aikidoist, photographer.

submissionscomments
aphyr··on Jepsen: MongoDB 4.2.6
I like to keep in mind that MongoDB's existing feature set is maturing--occasional regressions may happen, but by and large they're making progress. The problems in this analysis were in a transaction system that's only been around for a couple years, so it's had less time to have rough edges sanded off.
aphyr··on Jepsen: MongoDB 4.2.6
It's been on my list for a long time, but I've also struggled to find out like... what, exactly, is the right way to do postgres replication? Every time I go into the docs I wind up with a laundry list of different mechanisms for replication and failover, and no idea which one would be most appropriate for a test. I gotta get on this!
aphyr··on Jepsen: MongoDB 4.2.6
That is, a table on the jepsen.io frontpage, or at least on each product's review page, with database products and configuration on rows and consistency properties on columns, and a nice "Yay!" or "Nope!" mark in the cell, plus links on how to achieve the database configurations in the table (esp. how to configure each database to have the most guarantees).

This is a wonderful idea, and I've got no idea how to actually do it in a standardized, rigorous way. Vendor claims are often contradictory, it's hard to get a good idea of anomaly frequency, availability is... a rabbithole, and it's hard to come up with a standard taxonomy of anomalies--most of the analyses I do wind up finding something I've never really seen before, haha. With that in mind, I've wound up letting the reports speak for themselves.

Also, ideally the analyses should be rerun automatically (or possibly after being paid, but making it easy for the company to do so) every time a new major release happens rather than being done once and then being stale.

I don't know a good way to do this either. Each report is typically the product of months of experimental work; it's not like Jepsen is a pass-fail test suite that gives immediately accurate results. There is, unfortunately, a lot of subtle interpretive work that goes into figuring out if a test is doing something meaningful, and a lot of that work needs to be repeated on each test run. Think, like... staring at the logs and noticing that a certain class of exception is being caught more often than you might have expected, and realizing that a certain type of transaction now triggers a new conflict detection mechanism which causes higher probabilities of aborts; those aborts reduce the frequency with which you can observe database state, allowing a race condition to go un-noticed. That kinda thing.

If I'm lucky and the API/setup process haven't changed, I can re-run an analysis in about a week or so. If I'm unlucky, there's been drift in the OS, setup process, APIs, client libraries, error handling, etc. It's not uncommon for a repeat analysis to take months. :-(

aphyr··on Jepsen: MongoDB 4.2.6
Have you ever tried distributed transactions with relational databases?

I am delighted to say that yes: checking safety properties of distributed systems, including those of relational databases, is literally my job. See https://jepsen.io/analyses for a comprehensive list of prior work, or http://jepsen.io/analyses/tidb-2.1.7, http://jepsen.io/analyses/yugabyte-db-1.1.9, http://jepsen.io/analyses/yugabyte-db-1.3.1, or http://jepsen.io/analyses/voltdb-6-3 for recent examples of Jepsen analyses on relational databases.

aphyr··on Jepsen: MongoDB 4.2.6
Chief, it does not have to be this hard. 3.4 clearly states:

This anomaly occurred even with read concern snapshot and write concern majority

3.5: In this case, a test running with read concern snapshot and write concern majority executed a trio of transactions with the following dependency graph

3.6: Worse yet, transactions running with the strongest isolation levels can exhibit G1c: cyclic information flow.

3.7: It’s even possible for a single transaction to observe its own future effects. In this test run, four transactions, all executed at read concern snapshot and write concern majority, append 1, 2, 3, and 4 to key 586—but the transaction which wrote 1 observed [1 2 3 4] before it appended 1.

Like... if you had read any of these sections--or even their very first sentences--you wouldn't be in this position. They're also summarized both in the abstract and discussion sections, in case you skipped the results.

4.0: Finally, even with the strongest levels of read and write concern for both single-document and transactional operations, we observed cases of G-single (read skew), G1c (cyclic information flow), duplicated writes, and a sort of retrocausal internal consistency anomaly: within a single transaction, reads could observe that transaction’s own writes from the future. MongoDB appears to allow transactions to both observe and not observe prior transactions, and to observe one another’s writes. A single write could be applied multiple times, suggesting an error in MongoDB’s automatic retry mechanism. All of these behaviors are incompatible with MongoDB’s claims of snapshot isolation.

It's OK to stop digging now!

aphyr··on Jepsen: MongoDB 4.2.6
> I did not find any proof of this in the rest of the report.

May I suggest sections 3.4, 3.5, 3.6, 3.7, 4.0, and 4.1?

aphyr··on Jepsen: MongoDB 4.2.6
Possibly! You're right that path dependence played a role in safety issues: the problems we found in 3.4.0-rc3 were related to grafting the new v1 replication protocol onto a system which made assumptions about how v0 behaved. That said, I don't want to discount that MongoDB has made significant improvements over the years. Single-document linearizability was a long time in the works, and that's nothing to sneeze at!

http://jepsen.io/analyses/mongodb-3-4-0-rc3

aphyr··on Jepsen: MongoDB 4.2.6
No, I haven't! You can see a full list of analyses here: http://jepsen.io/analyses
aphyr··on Jepsen: MongoDB 4.2.6
I was lucky to have a good education: my B.A. involved courses in contemporary experimental physics and independent research in nonlinear quantum dynamics (esp. proofs, experimental design, writing), cognitive and social psychology (more experiment design and stats), math structures (proof techniques), philosophy (metaphysics, philosophy of science), and English (rhetoric). All of those helped give me a foundation for doing this kind of experimental work and communicating it to others.

Jepsen draws inspiration from a long line of work on property-based testing, especially Quickcheck & co. It also draws on roughly 10 years of experience building & running distributed systems in production. A lot of Jepsen I invented from whole cloth, but some of the checkers in Jepsen are derived from specific research papers, like work by Wing, Gong, and Howe on linearizability checking.

Then it's just... a lot of thinking, experimenting, and writing. Jepsen's the product of ~6 years of full-time work. Elle, the system which detected the anomalies in this report, was a research project I've been puzzling over for roughly two years.

I write the Jepsen series, and open-source all of the code for these tests, partly as a resource so that other people can learn to do this same kind of work. :-)

aphyr··on Jepsen: MongoDB 4.2.6
You just can't test lower levels of guarantees and then complain you did not get what higher levels of guarantees were designed to provide.

Gently, may I suggest that you read the report, or at least the abstract? This is addressed in the second sentence. :-)

aphyr··on Jepsen: MongoDB 4.2.6
Calvin and CRDTs aren't new, but I still think they're dramatically underappreciated! Heidi Howard's recent work on generalizing Paxos quorums is super intriguing, and from some discussion with her, I think there are open possibilities in making leaderless single-round-trip consensus systems for log-oriented FSMs, which is what pretty much everyone WANTS.

I'm also excited about my own research with Elle, but we're still working on getting that through peer review, haha. ;-)

aphyr··on Jepsen: MongoDB 4.2.6
There's a few things at play here. One is talking only about the positive results from the previous Jepsen analysis, while not discussing the negative ones. Vendors often try to represent findings in the most positive light, but this was a particularly extreme case. Not discussing default behavior is a significant oversight, and it's especially important given ~80% of people run with default write concern, and 99% run with default read concern.

The middle part of the report talks about unexpected but (almost all) documented behavior around read and write concern for transactions. I don't want to conjecture too much about motivations here, but based on my professional experience with a few dozen databases, and surveys of colleagues, I termed it "surprising". The fact that there's explicit documentation for what I'd consider Counterintuitive API Design suggests that this is something MongoDB engineers considered, and possibly debated, internally.

The final part of the report talks about what I'm pretty sure are bugs. I'm strongly suspicious of the retry mechanism: it's possible that an idempotency token doesn't exist, isn't properly used, or that MongoDB's client or server layers are improperly interpreting an indeterminate failure as a determinate one. It seems possible that all 4 phenomena we observed stem from the retry mechanism, but as discussed in the report, it's not entirely clear that's the case.

aphyr··on Jepsen: MongoDB 4.2.6
Aw shucks, thank you! <3
aphyr··on Jepsen: MongoDB 4.2.6
Latency is a big one--you've got to wait an extra round-trip for secondaries to acknowledge primary writes, and primaries (assuming you don't have reliable clocks) need to check in with secondaries to confirm they have the most recent picture of things if you want to do a linearizable read. Snapshot isolated reads shouldn't require that, at least in theory--it's legal to read state from the past under SI, so there's no need to establish present leadership. That's why I'm surprised that MongoDB requires snapshot reads to go through write concern majority--it doesn't seem like it'd be necessary. Might have something to do with sharding--maybe establishing a consistent cut across shards requires a round of coordination. Even then I feel like that's a cost you should be able to pay only at write time, making reads fast, but... apparently not! I'm sure the MongoDB engineers who designed this system have good reasons; they're smart folks and understand the replication protocol much better than I do.

MongoDB's also published a writeup (which is cited a few times in the Jepsen report!) talking about the impact of stronger safety settings and why they choose weak defaults: http://www.vldb.org/pvldb/vol12/p2071-schultz.pdf

aphyr··on Jepsen: MongoDB 4.2.6
Yeah, there's no workaround that I can find for 3.4 (duplicate effects), 3.5 (read skew), 3.6 (cyclic information flow), or 3.7 (read own future writes). I've arranged those in "increasingly worrying order"--duplicating writes doesn't feel as bad as allowing transactions to mutually observe each other's effects, for example. The fact that you can't even rely on a single transactions' operations taking place (or, more precisely, appearing to take place) in the order they're written is especially worrying. All of these behaviors occurred with read and write concerns set to snapshot/majority.

That's not to say that workarounds don't exist, just that I didn't find any in the documentation or by twiddling config flags in the ~2 weeks I was working on this report. :)

aphyr··on Jepsen: MongoDB 4.2.6
Hi folks! Author of the report here. If anyone has questions about detecting transactional anomalies, what those anomalies are in the first place, snapshot isolation, etc., I'm happy to answer as best I can.
aphyr··on Jepsen: MongoDB 4.2.6
Nope! Something weird happened to that post; it got a lot of upvotes and some comments, but never made it to frontpage. After the InfoQ article took off yesterday, an HN mod got in touch and asked if I'd like to resubmit it.
aphyr··on Jepsen Disputes MongoDB's Data Consistency Claims
It looks like relatively few people clicked through to read the analysis itself, so @dang's kindly offered to repost it. You can find the analysis here:

https://jepsen.io/analyses/mongodb-4.2.6

... and the corresponding HN thread here:

https://news.ycombinator.com/item?id=23290844

aphyr··on Jepsen: Dgraph 1.1.1
It sounds like you're asking for contract work; you're welcome to email me at aphyr@jepsen.io.
aphyr··on Jepsen: Dgraph 1.1.1
Sure, I could run Jepsen against anything I can talk to over the network, but a.) it might be painful or impossible to get a fresh, healthy cluster for each test run (It's... fairly common that databases stop being databases during a test) and b.) doing fault injection means I need a way to, well, inject faults. That's why Jepsen tests almost always involve Jepsen controlling the cluster.
aphyr··on Jepsen: Dgraph 1.1.1
>> graph traversal across different attributes might pay a higher latency cost

> Those can be done concurrently if at the same query level, so not necessarily any slower.

An important clarification, yes! I should have made that more explicit. :)

aphyr··on Jepsen: Dgraph 1.1.1
Kinda depends on what you're doing, how much of Jepsen you're using, and how complex the system-specific code is. You can write a minimal Jepsen test in ~100 lines of code, if that's helpful. Jepsen and its main supporting libraries (Elle and Knossos) clock in at about 19K lines of code; a little over six years of full-time work.

For simulation testing, I'd suggest looking at Maelstrom, which uses Jepsen to provide a sort of workbench for writing toy Raft implementations in any language. You give it a binary which takes messages as JSON on STDIN and emits messages to STDOUT; it spawns a bunch of "nodes" (local processes) of that binary, connects them via a simulated network, generates pathological network behavior, simulates client requests, and verifies the resulting histories with Jepsen.

https://github.com/jepsen-io/maelstrom

aphyr··on Jepsen: Dgraph 1.1.1
The first sentence is describing how Dgraph shards data for storage; the second sentence discusses how data can be represented in the query API. You're right that this could lead to broad fanout, if users typically retrieved all attributes for a given UID. It also impacts the performance of joins: graph traversal across a single attribute is much faster when all those edges are on the same node, but graph traversal across different attributes might pay a higher latency cost. This is a classic dilemma in distributed graph storage--does one shard by attribute? By entity? Each leads to distinct performance tradeoffs, and Dgraph happened to choose attribute sharding.

Also keep in mind that typical Dgraph workloads request specific attributes (think "SELECT NAME, AGE") rather than everything ("SELECT *"), which reduces the impact of fanout. :)

aphyr··on Jepsen: Dgraph 1.1.1
Yes: the library is prominently linked on the home page, and there are deep links to the Dgraph test suite code throughout the report. Pretty much all of my work is OSS, and public release of test harness for each report is explicitly part of the Jepsen ethics policy. :)

https://github.com/jepsen-io https://jepsen.io/ https://jepsen.io/ethics

aphyr··on Jepsen: Dgraph 1.1.1
Yep! Testing databases is my full time job. Vendors pay me for the work, and that means the Jepsen library, test harness for each database, and all the reports are free for everyone. :)
aphyr··on Elle: Inferring Isolation Anomalies from Experimental Observations
Ah, yes, thank you!
aphyr··on Elle: Inferring Isolation Anomalies from Experimental Observations
Good question!

Consider RandDB, a database which returns random values for reads. It is possible that with RandDB, we happen to get a history which looks, say, serializable. And indeed, the observed history might be equivalent to a serializable Adya history, even though the underlying system is clearly not. This is, however, an accident--and given sufficiently long histories, the probability that we fail to observe a violation decreases.

Another possibility is that a database can explode the state space by producing indeterminate results for transactions. Of course, a database that deliberately did this would be silly, because nobody wants (I assume!?) a database that throws errors constantly. But when indeterminacy does happen, it's possible that we might fail to resolve some underlying anomaly. For instance, say an indeterminate write transaction actually aborts internally, but we don't know it aborted. If a committed read sees that write, that's technically an aborted read, but Elle (or any external observer) wouldn't be able to tell, because we can't prove the original write transaction aborted.

Likewise, if a database happens to avoid returning reads for some writes, we can't say anything about what write orderings are illegal. In the case of list append, we have the nice property that any single read tells us the entire version history up to that read, so the fraction of the version order we can't infer is limited to some (hopefully) short series of writes in the last n seconds. If the database never returns a read, though, all bets are off!

aphyr··on Elle: Inferring Isolation Anomalies from Experimental Observations
Oh! I didn't expect this to show up here! Happy to answer questions, if folks have any.

While this is on frontpage, I'd like to ask: if anyone has experience with machine proofs, I'd appreciate your help in completing a formal proof of Elle's correctness. I've been teaching myself Isabelle/HOL in an attempt to formalize the proof sketch, and I have encoded most of the formalism and properties I care about, but actually proving lemmata has been... frustrating. Like, I burned hours one one lemma because it hinged on showing \forall x :: Nat, x \in N.

https://github.com/jepsen-io/elle/tree/master/proof

If you'd like to work on this, my email is aphyr@jepsen.io!

aphyr··on Jepsen: Etcd 3.4.3
Many do, and even large DBs can be accomodated by throwing terabytes of RAM at the problem, but etcd is fundamentally targeted at a different problem domain than a general-purpose database. Everything in etcd is represented by a single-threaded state machine, which is great for simplicity and correctness, but that comes with performance limitations.
aphyr··on Jepsen: Etcd 3.4.3
This is also one of the things I suggested that'd be nice to have in the etcd API, along with an AST for boolean operations over guard expressions, more flexible comparators etc. You can emulate these with a sequence of independent transactions, but it'd be nice if the micro-transaction system were a tad more general.
← PreviousPage 6 of 27Next →