World Wide Webber


My Books
REST in Practice: Hypermedia and Systems Architecture
Amazon:
US, UK
Developing Enterprise Web Services by Sandeep Chatterjee and Jim Webber
Amazon:
US, UK,
Also available: Korean Edition

My Bookshelf
RESTful Web Services Cookbook by Subbu Allamaraju
Programming Clojure by Stuart Halloway
RESTful Web Services by Leonard Richardson and Sam Ruby
Strategies for Scaling Neo4j
Posted: 22 March 2011 @ 00:34 UT from Seattle, US
Last updated: 22 March 2011 @ 01:07 UT

As I've discussed before, graph databases like Neo4j can be lack the same predictability in terms of scaling when compared to other kinds of NOSQL stores (that’s the cost of a rich data model). But with a little thought, we've seen how both cache-sharding and the application of domain-specific strategies can help to improve throughput and increase the dataset size that Neo4j can store and process.

Those blog posts triggered some very useful discussion on the Neo4j mailing list, with several community members adding their own thoughts and experiences. In particular Mark Harwood suggested a simple heuristic for deciding a scaling strategy, that I thought was so useful I'd share it (with his permission) here.

  1. Dataset size: Many tens of Gigabytes
    Strategy: Fill a single machine with RAM
    Reasoning: Modern racks contain a lot of RAM, of the order of 128GB typically for a typical machine. Since Neo4j likes to use RAM to cache data, where O(dataset) ≈ O(memory) we can keep all the data cached in-memory and operate on it at extremely high speed.
    Weaknesses: Still need to cluster for availability; write scalability limited by disk performance. 
  2. Dataset size: Many hundreds of Gigabytes
    Strategy:Cache sharding
    Reasoning: The dataset is too big to hold all in RAM on a single server but small enough to allow replicating it on disk across machines. Using cache sharding improves the likelihood of reaching a warm cache which maintains high performance. The cost of a cache miss is not catastrophic (a local disk read), and can be mitigated by replacing spinning disks with SSDs.
    Weaknesses: Consistent routing requires a router on top of the Neo4j infrastructure; write-master in the cluster is a limiting factor in write-scalability.
  3. Dataset size: Terabytes and above
    Strategy: Domain-specific sharding
    Reasoning: At this scale, the dataset is too big for a single memory space and it's too big to practically replicate across machines so sharding is the only viable alternative. However given there is no perfect algorithm (yet) for arbitrary sharding of graphs, we rely on domain-specific knowledge to be able to predict which nodes should be allocated to which machines.
    Weaknesses: Not all domains may be amenable to domain-specific sharding

As an architect, I really like this heuristic. It's easy to find where I am on the scale and plan a Neo4j deployment accordingly. It also provides quite an exciting pointer towards the future - while I think most enterprise-scale deployments are currently in the tens to hundreds of gigabytes range, there are clearly applications out there for connected data that do - or will - require more horsepower.

Neo4j 2.0 will address these challenges, it's going to be a fun ride. But until then, I hope you'll find this as helpful as heuristic as I did.

Comments:
#

Hi Jim, 

great insights as always. 

Regarding the second strategy, it's surely a good way to enhance local performance, but I couldn't say the same about scalability: writes are still bound by the single master, and even reads are difficult to scale unless you find a good domain-specific routing strategy to avoid excessive cache churning (which is indeed the number three strategy). 

Regarding the third strategy, domain-specific sharding could be coupled with master-master pairs (one pair for each shard) and eventually cache sharding too, to achieve HA and higher performance: you may want to explicitly mention this too. 

Finally, regarding Neo4j 2.0, do you already have any plans about how to solve the sharding problem? 

Thanks for sharing, 

Cheers! 

Sergio B.

#

Hey @Sergio, 

You're right about write throughput. In this case Nei4j is bounded by the same write-master/read-slave pattern that's common to MySQL. 

It still allows for substantial scaling, but isn't horizontally write-scalable like KV stores (e.g. Riak) are. 

I'm not sure what you mean about master-master pairs for domain-specific sharding. Do you just mean each shard is replicated? 

Jim

#

Thanks for your answer Jim. 

Yes, when talking about master-master pairs I'm referring to replication in each domain-specific shard: may seem obvious, but many just miss that. 

What about my comment on read scalability in case of cache sharding? Don't you think excessive cache churning (in case of "bad" routing) could hinder that too?

#

Hey Sergio, 

I like the master-master per shard notion, it's like having an option 2.5 between cache sharing and real sharding. Good call. 

With cache sharding and read scalability, if you pick a poor routing algorithm that doesn't match your domain then you will fail to hit warm caches. That will make read performance much lower.  

So there is a design challenge to get your consistent routing algorithm right. That's much easier to do (e.g. sticky sessions) than solving the graph sharding problem because we're only dealing with replicas, not dealing with partitioning the graph. 

Jim

Author Name:
Email:
Author URL:
Comment:
Antispam:
Please type the following string (note that if the strings don't match, your comment will be lost... sorry!): 'NHHB'.
 
Recent entries

Recent comments

Feeds:
RSS 2.0 Atom