News for hackers. Stuff that matters.
Re:Jepsen: Dgraph 1.1.1 by wpietri on Friday May 01, 2020 @12:51PM (#23044005)
There's a part I don't get here: "To store large datasets Dgraph shards the set of triples by attribute, breaks attributes into one or more tablets, and assigns each tablet to a group of nodes." But earlier, it says, "For convenience, Dgraph can also represent all triples associated with a given entity as a JSON object mapping attributes to values—where values are other entities, that entity’s attributes and values are embedded as an object, recursively."

I know almost nothing about graph databases, so presumably this is just my ignorance. But if entity-focused retrieval is an important use case, isn't clustering by attribute going to kill performance? Naively, I'd think that one would cluster by entity and what an entity is connected to.

Re:Jepsen: Dgraph 1.1.1 by aphyr on Friday May 01, 2020 @04:10PM (#23046029)
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. :)

Re:Jepsen: Dgraph 1.1.1 by mrjn on Friday May 01, 2020 @04:37PM (#23046220)
> 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. In other terms, the number of network calls required (in a sufficiently distributed cluster, where each predicate/attribute is on a different server), is proportional to the number of attributes asked for in the query, not the number of results (at any step in graph traversal).

And that's the big part of the design. By constraining the number of network calls to very few machines, while doing traversals, which would lead to millions of results in the intermediate steps -- Dgraph can deal with high fan-out queries (with lots of node results) much better.

Alternative would be to shard by nodes (entities) -- in which case, if the intermediate steps have millions of results, they could end up broadcasting to the entire cluster to execute a single query. That'd kill latency.

So, the problem is not how many attributes a query is asking for -- that's generally bounded. The problem is how many nodes you end up with as you traverse the graph, those could be in millions.

That's why many graph layer systems suck at doing anything deeper than 1 or 2 level traversals / joins.

Re:Jepsen: Dgraph 1.1.1 by aphyr on Friday May 01, 2020 @06:07PM (#23047036)
>> 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. :)

Re:Jepsen: Dgraph 1.1.1 by wpietri on Friday May 01, 2020 @05:56PM (#23046949)
Thanks! That's exactly what I was looking to know. And it couldn't come from a more trusted source.
Re:Jepsen: Dgraph 1.1.1 by micheldiz on Friday May 01, 2020 @01:13PM (#23044249)
I think the other way around. Dgraph was thought to be distributed. It cannot be "atomically" distributed based on entities. But in smaller parts of an entity. If each instance of Dgraph takes care of a small part of that entity, it becomes virtually more performatic.

Imagine, in an abstract way, that it is a hashing process. Where the attributes are spread over several instances in the cluster and Dgraph just "decodes" it for you quickly because it already has the key.

Could it be based on entities? yes, but I don't think it would bring any benefit. Imagine that you have 10 instances, and you have 10 entities. You have 3 entities with many edges (values and outgoing edges) and 8 "light" entities, without much information. Well, you will leave 3 entities in high usesage of resources while 8 entities are idle because they do not have much information to deliver to all query and mutation requests in the Cluster.

A system based on attributes in a distributed way is much more performance tho.

Re:Jepsen: Dgraph 1.1.1 by mrjn on Friday May 01, 2020 @02:21PM (#23044977)
I think the Jepsen comment might be confusing. The point is that Dgraph can ingest data in either a Triple format, or a JSON format. Internally, Dgraph stores it in its own binary format. See [1] for more details.

> Naively, I'd think that one would cluster by entity and what an entity is connected to

In a distributed system, that approach leads high-fanout and network broadcasts, which kills query latency. Ideally, you want to do a traversal / join in one network call (max), not more. Because of this design, Dgraph can execute arbitrary depth queries in a much faster way. More details are in [1].

[1]: https://dgraph.io/paper