HNHacker News
TopNewBestAskShowJobs

aphyr

9,565 karma · joined January 15, 2010

https://aphyr.com

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

submissionscomments
aphyr··on Jepsen: Redpanda 21.10.1
> When choosing a distributed database you are in a way already by definition giving up a chunk of of the C, Consistency.

Er, I don't think that's right. Distributed systems (even those running in asynchronous networks) can and often do satisfy linearizability. Gilbert & Lynch's proof of the CAP theorem just says that if you do choose linearizability (C) in an asynchronous network (P), you can't also guarantee total availabilility (A)--under some network faults, some operations may not complete. https://users.ece.cmu.edu/~adrian/731-sp04/readings/GL-cap.p...

aphyr··on Jepsen: Redpanda 21.10.1
There's been a lot of interest in this, and I keep meaning to put together an open-to-the-public class when I'm less swamped! Might get a chance to do this shortly--I'll post on https://groups.google.com/a/jepsen.io/g/announce when it happens.
aphyr··on Jepsen: Radix DLT 1.0-Beta.35.1
If you find out, let me know! Folks are always asking me "What database is best?" and I'm just shuffling my feet and going "Uhhhh, well, systems are really hard to build correctly, there's lots of tradeoffs, you probably want something with a proven replication model under the hood but so much depends on workload and operational characteristics beyond just safety... If you find a database you love please tell me about it because I like hearing people's stories..."

FWIW, I think you're raising really good questions in this thread. Qualitative safety is highly contextual, depending on fault model, significance of individual operations, concurrency, throughput, latency demands, operational characteristics, data volume, etc etc., and I try to touch on that in the "Toward a Culture of Safety" section in this report. Hopefully that resonated for you.

aphyr··on Jepsen: Radix DLT 1.0-Beta.35.1
You understand incorrectly.
aphyr··on Jepsen: Radix DLT 1.0-Beta.35.1
The core ledger system lost committed transactions by choosing not to write them to disk before acknowledgement.
aphyr··on A History of Leather at Pride: 1965-1995
For cishet folks on HN: this writing isn't about or for you. I've seen a lot of this community's homophobia, misogyny, transphobia, and generally reactionary political drift over the last 12 years--including replies to my technical writing. I know exactly how this conversation is going to go if it happens here. I'm asking y'all not to have it.

I'm returning a 403 on HN referrals to aphyr.com as a mild discouragement. I hope you'll respect this.

aphyr··on The largest study to date on the genetic basis of sexuality (2019)
As a gay person who periodically wades past the dialectical peat bog that is Hacker News, I am begging you to stop digging. I cannot tell you how disheartening it is to find comments like this at the top of a thread, let alone anywhere. Perceived mutability is one aspect that affects perceptions of marginalized groups. Neither perceived nor actual mutability justifies discrimination.

A world in which gender transition were a trivial weekend occurrence would not excuse the gender wage gap. If conversion therapy were effective, it would still not be moral to imprison people for being gay. Being able to lighten one's skin does not, and should not, excuse the shooting of Black people at traffic stops.

For some of this, this isn't an armchair "design space". Some of us still have people shouting "faggot" at us from passing cars. Some of us have strangers threatening to kill us in the supermarket. Some of us have been fired when our old names were found out. Some of us are trying to figure out how to tell our children how not to be murdered. These kinds of discrimination are not "perfectly legitimate" social choices. They have impact on actual human beings.

aphyr··on Clojure, Faster
So clojure's type specialized function manages to be 300 times slower than the generic version in freaking python. In fairness "count" is better if still terrible (4x slower than python).

Er, to be clear, Clojure's `alength` is a generic function--you're not measuring type-specialized behavior. The type-specialized `alength` call clocks in at around ~4 ns/call, as the article notes.

aphyr··on Clojure, Faster
In short: it's slow because there isn't just one kind of Java array, and if you don't say which one you mean, Clojure has to do reflection to figure it out.

Inside the JVM, there are several different types of arrays: bytes, floats, objects, etc. Clojure.lang.RT includes methods for getting the length of all of these types--for instance, here's the method for the length of arrays of longs:

https://github.com/clojure/clojure/blob/master/src/jvm/cloju...

The clojure.core/alength function calls clojure.lang.RT/alength, but that callsite is polymorphic: the Clojure compiler doesn't know which of the RT functions to emit a call for, because it needs the type signature. If the type is unavailable at compile time, the Clojure compiler emits reflective code which inspects the type of the reference, determines which specific clojure.lang.RT/alength implementation to dispatch to, then executes that call dynamically. That's the slow part!

https://github.com/clojure/clojure/blob/clojure-1.10.1/src/c...

Just like the article says, if you include a type hint, the compiler can emit an invokestatic call directly to, say, clojure.lang.RT.alength(long[]), and skip all the reflection.

aphyr··on Clojure, Faster
Criterium (the benchmarking library used here) uses multiple runs to obtain tighter bounds on amortized performance, as well as techniques to account for the effects of garbage collection and JIT compilation. See https://github.com/hugoduncan/criterium for a brief overview, as well as links to the pitfalls and statistical techniques involved in JVM benchmarking.
aphyr··on Jepsen: Scylla 4.2-rc3
> However, either they do not scale or even when they do (newsql), they are 10x slower and handle less volume, etc.

There's something to be said about CQL specifically here, because its transactional model is an odd duck, and not always for scalability reasons. Scylla and Cassandra could offer richer transactions without significant performance penalties--indeed, which would significantly speed up some types of transactional workloads, but instead there are, as the grandparent poster notes, strange edge cases.

For instance, you can't select multiple CQL rows where the select would cover a column backed by a CQL collection. That's been fixed in Cassandra, but is still present in Scylla, and limited the kinds of tests we could write for Scylla.

You also can't perform an LWT write without a guard clause: linearizable upserts in the Jepsen tests require the presence of an always-null field in every row whose only purpose is to convince Scylla that yes, we really would like to use Paxos for this write.

Likewise, there's no logical notion of a batch combining reads and writes, or, for that matter, a batch of reads. If you want those sorts of things in C* or Scylla, I imagine one winds up stringing together reads and CaS statements in retry loops, or something to that effect. We were trying to hack together a batch read via a no-op write, except that it's actually impossible to do that robustly--you can only "read" values involving guard clauses, and there's no guard which will pass on all values. It's just... awkward.

This isn't a scalability thing--all three of these cases could be executed in a single Paxos round, scoped to a single partition. It's just... weird API design.

aphyr··on Jepsen: Scylla 4.2-rc3
You can imagine that Jepsen could run against filesystems itself. Basic JVM IO would be fairly easy to get going, and the POSIX APIs could be tested by having Jepsen call (maybe via IPC?) a small C/whatever binary. I don't know what fault injection would look like though: presumably you'd want to do something down in the kernel/device drivers/hw, and that land is largely a mystery to me.

Tangentially, I would love to have a FUSE filesystem with a.) minimal build dependencies, b.) some sort of CLI interface, and c.) the ability to, say, forget to flush un-fsynced data to "disk", allowing us to simulate a power failure. There have been a bunch of research projects on this front, and they find bugs spectacularly. I bet this approach would also find errors in distributed systems, but I've yet to find one that really has the right shape for use with Jepsen.

aphyr··on About Google's approach to research publication – Jeff Dean
Dean writes:

Our aim is to rival peer-reviewed journals in terms of the rigor and thoughtfulness in how we review research before publication.

But Gebru writes that HR and her management chain delivered her feedback in a surprise meeting where she was not allowed to read the actual feedback, understand the process which generated it, or engage in a dialogue about it:

Have you ever heard of someone getting “feedback” on a paper through a privileged and confidential document to HR?

A week before you go out on vacation, you see a meeting pop up at 4:30pm PST on your calendar (this popped up at around 2pm). No one would tell you what the meeting was about in advance. Then in that meeting your manager’s manager tells you “it has been decided” that you need to retract this paper by next week...

And you are told after a while, that your manager can read you a privileged and confidential document and you’re not supposed to even know who contributed to this document, who wrote this feedback, what process was followed or anything. You write a detailed document discussing whatever pieces of feedback you can find, asking for questions and clarifications, and it is completely ignored.

(from https://www.platformer.news/p/the-withering-email-that-got-a...)

I've been through the peer review process at Physical Review Letters, SIGMOD, and VLDB. You get a document containing all the reviewer's comments, plus a metareviewer's take on the overall decision and what has to change. You can engage in dialogue with the metareviewer, including a detailed response letter justifying your choices, highlighting things the reviewers may have missed, and explaining where you plan to make changes. You get additional rounds of comments from the reviewers in light of that letter on later drafts.

I'm not a Googler, and I have no idea what the standard review process looks like there, but what Gebru describes does not sound at all like peer review. I also note that Dean does not contradict Gebru's account of the meeting or feedback process. If I had a paper rejected in this fashion, I would also demand to know what the hell was going on and who was responsible.

This feels off.

aphyr··on Unifying the Technical Interview
This is an excellent observation--and indeed, one of the things about implementing (so, so many versions of) microKanren is that I've learned the paper version relies heavily on magic. It is very easy to get a microKanren that works sometimes, but explodes in some conditions, because of the subtle ways that the paper relies on the behavior of improper lists (raw cons pairs) vs proper lists, and because many recursive cases which would normally be explicitly enumerated (or handled via polymorphic dispatch) just happen to work correctly thanks to the way they encode bindings, substitutions, etc as lists. In particular, there are many places where it looks like a `map` might make things simpler, but will subtly break things, thanks to the need to recurse into improper lists. The mplus/bind control flow graph is also... extremely tricky if you aren't precise about null/empty/car/cdr.

If you take a look at the "full" version of this program, which uses more struct types, it involves a good deal more explicit recursion: https://gist.github.com/aphyr/4d41e7655b10a68e753f729bdc1c5a...

her kanren can't really solve "inside" of the structs that she asked to be provided.

Ahhhh, so this is true, and actually a feature: uKanren exploits scheme vectors as lvars, and initially my language was just lists. I wound up adding structs precisely so that I'd have an analogous non-list compound type!

aphyr··on Unifying the Technical Interview
I can't speak for anyone else, but it's my favorite comment so far. :-)
aphyr··on Rewriting the Technical Interview
Funny story--I am also a (recovering) Mathematica programmer! I'm not sure it's quite as good of a fit, for a few reasons.

One is that Mathematica's syntax is, in a lot of ways, already pretty C-like. It uses mutable assignment `x = y`, function-arglist syntax `Fun[arg1, arg2]` instead of a Lisp-style `(f arg1 arg2)`, commas for list separators (in Clojure, they're whitespace), braces `{a, b, c}` are a sequential construct, rather than a map, and semicolons `first ; second ; third` denote sequential expressions (in Clojure, ; is an end-of-line comment).

The second reason is that Mathematica, in my understanding, doesn't treat parentheses as first-class syntactic elements: they're used to control interpretation of the parse tree, but they transparently collapse, instead of being accessible as a reified type. (Are they? I know Mathematica is sort of an endless coal-mine of a language, and it's entirely possible I'm just not experienced enough to know about this!) If this constraint is true, I'm not sure how you would parse `func(arg1, arg2)` vs `func((arg1, arg2))`. Maybe it's inferrable from any symbol followed by a list, since `(arg1, arg2)` gives you a bounded context for the arglist, even if the parens disappear--and we can give up on having `(a,b)` for tuples or `()` as a unit syntax. It might also be inferrable from context, depending on what types of infix operators you allow, and how ; works as a separator. My license is long-since expired, so I can't test right now--perhaps you can give it a shot and show it off here!

I wound up cutting this from the post, but... the full version of this rewriter provides a Java-style OO syntax with property accessors and chainable method calls. A tricky thing in Mathematica might be disambiguating `obj.property` from `obj.method()`, if the `()` isn't reified. For that matter, what do you do about `fun` vs `fun()`...

One possible workaround might be to exploit (as I've done to hack around Clojure's insistence that "map keys be unique" and "maps have even numbers of elements") lesser-used Unicode codepoints, only this time, using alternatives for `(` and `)`, and to roll your own stack parser for arglist parsing... ideas, ideas. :)

aphyr··on Jepsen: Redis-Raft 1b3fbf6
So many people were very upset about the barbies. Now that they're gone, I get complaints! Folks are never satisfied. :/
aphyr··on Jepsen: Redis-Raft 1b3fbf6
> Letting a follower forward request to leader on client's behalf is not easy to implement correctly, that's why most popular raft based software (hashicorp stack) doesn't do that. Not worth it.

I'm honestly surprised by this comment! I've written multiple Raft implementations, and request proxying was one of the easiest things to get right--it doesn't have to touch the Raft subsystem at all. Could you talk a little more about this?

aphyr··on Jepsen: Redis-Raft 1b3fbf6
Part of this is release timing--the Dgraph and Redis analyses were mainly done in Q1 of this year, and I was able to write and release the Mongo & PostgreSQL reports on my own schedule. Wish I were that productive! ;-)
aphyr··on Jepsen: Redis-Raft 1b3fbf6
> It's clear this project did not start with exhaustive unit tests.

I can't speak to "exhaustive", but Redis-Raft did have an extant unit and integration test suite prior to our collaboration. Here's what they looked like: https://github.com/RedisLabs/redisraft/tree/ff9fb28c74db880c...

I'm hesitant to draw too strong a conclusion here, and I can't speak for the Redis Labs team, but I do suspect that this is somewhere where... having an outside tester, like Jepsen (or a suitably adversarial QA team) can help detect missing-stairs sorts of problems. Coming from the perspective of a prospective operator (and having some experience with testing distributed systems), I immediately said "of course I want proxy mode by default", when this wasn't how the Redis-Raft designers necessarily intended things to be used--they intended smart clients to make it so that users wouldn't actually need proxy mode, so they hadn't focused on testing it that way.

aphyr··on Jepsen: Redis-Raft 1b3fbf6
No, we haven't talked yet, but I would like to someday. :)
aphyr··on Jepsen: Redis-Raft 1b3fbf6
There's a lot of research into this, actually! Folks have been working on ways to extract executable code from Alloy, TLA+, Isabelle/HoL, and Coq specifications. That doesn't help with implementations which don't use codegen though--and it doesn't help you with the parts of the program that aren't formalized.
aphyr··on Jepsen: Redis-Raft 1b3fbf6
Pre-existing! It's a fork of willamt's https://github.com/willemt/raft/, which has been around since 2013, and has property-based fuzz testing! It really does look like it's got its own extensive tests; I'm surprised we found issues.
aphyr··on Jepsen: Redis-Raft 1b3fbf6
One of the things that surprised me about this analysis was just how many bugs we found that had to do with the actual Raft implementation. Usually when I test Raft-based systems the bugs are at the edges--like the coupling of the system to the Raft library, treating it like an externally-queryable log rather than the driver of a state machine, and so on. We found integration bugs here too, but also a fair number of issues in the Raft library itself--and this is despite Redis-Raft having existing integration tests!

This stuff is hard!

aphyr··on Jepsen: PostgreSQL 12.3
It's not particularly surprising, but it is noteworthy. Other systems I've tested have offered serializability but not strict serializability: for instance, CockroachDB.
aphyr··on Jepsen: PostgreSQL 12.3
Familiar. If you've read any of the literature on snapshot isolation or isolation levels in general (Berenson, Bernstein, Gray, Melton, O'Neil, O'Neil, Adya, Liskov, Fekete, Cerone, Bailis, Alvisi, Clement, Crooks, Pu...) you would probably not expect to see SI treated as stronger than RR. The paper which first defined SI says it's not. Heck, Jim Melton, who wrote that part of the ANSI spec, is a co-author on that paper, which goes on to say the strict interpretation is incorrect and not what ANSI intended!
aphyr··on Jepsen: PostgreSQL 12.3
But in the meantime, given the choice of phantom reads or G2-item, I think I'd pick blocking phantom reads.

Well... it's not quite so straightforward. SI still allows some phantoms. It only prohibits some of them.

In PostgreSQL's case, if they somehow made repeatable read to prevent G2-item without sacrificing the phantom reads, would that mean repeatable read is then "serializable" according to the ANSI definition?

I'm not quite sure I follow--If you're asking whether snapshot isolation (Postgres "Repeatable Read") plus preventing G2-item is serializable, the answer is no--that model would still allow G2 in general--specifically, cycles involving non-adjacent rw dependencies with predicates.

aphyr··on Jepsen: PostgreSQL 12.3
No, Jepsen is over, sorry!

Jokes aside, Marklogic is welcome to pay me. Each one of these reports takes weeks to months of full-time work.

aphyr··on Jepsen: PostgreSQL 12.3
I hear occasional rumors, but nobody's published.
aphyr··on Jepsen: PostgreSQL 12.3
The report talks at length about this, but maybe it bears rephrasing!

The ANSI definitions are bad: they allow multiple interpretations with varying results. 25 years ago, Berenson, O'Neil, et al. published a paper showing the ANSI definitions had this ambiguity, and that what the spec meant to define should have been a broader class of anomalies. They literally say that the broad interpretation is the "correct" one, and the research community basically went "oh, yeah, you're right". Adya followed up with generalized isolation level definitions, and pretty much every paper I've read has gone with these versions since. That didn't make its way back into the SQL spec though: it's still ambiguous, which means you can interpret RR as allowing G2-item.

Why prevent G2-item in RR? Because then the difference between repeatable read and serializable is specifically phantoms, rather than phantoms plus... some other hard-to-describe anomalies. If you use the broad/generalized interpretation, you can trust that a program which only accesses data by primary key, running under repeatable read, is actually serializable. That's a powerful, intuitive constraint. If you use the strict interpretation, RR allows Other Weird Behaviors, and it's harder to prove an execution is correct.

For a very thorough discussion of this, see either Berenson or Adya's papers, linked throughout the report.

← PreviousPage 4 of 26Next →