Databases Reference
In-Depth Information
Separate read traffic from write traffic
Given the recommendation to direct the majority of write traffic to the master, we should
consider clearly separating read requests from write requests. We should configure our
load balancer to direct write traffic to the master, while balancing the read traffic across
the entire cluster.
In a web-based application, the HTTP method is often sufficient to distinguish a request
with a significant side effect—a write—from one that has no significant side effect on
the server: POST, PUT, and DELETE can modify server-side resources, whereas GET
is side-effect free.
When using server extensions, it's important to distinguish read and write operations
using @GET and @POST annotations. If our application depends solely on server exten‐
sions, this will suffice to separate the two. If we're using the REST API to submit Cypher
queries to the database, however, the situation is not so straightforward. The REST API
uses POST as a general “process this” semantic for requests whose contents can include
Cypher statements that modify the database. To separate read and write requests in this
scenario, we introduce a pair of load balancers: a write load balancer that always directs
requests to the master, and a read load balancer that balances requests across the entire
cluster. In our application logic, where we know whether the operation is a read or a
write, we will then have to decide which of the two addresses we should use for any
particular request, as illustrated in Figure 4-9 .
When running in server mode, Neo4j exposes a URI that indicates whether that instance
is currently the master, and if it isn't, which is. Load balancers can poll this URI at
intervals to determine where to route traffic.
Cache sharding
Queries run fastest when the portions of the graph needed to satisfy them reside in main
memory (that is, in the filesystem cache and the object cache). A single graph database
instance today can hold many billions of nodes, relationships, and properties, meaning
that some graphs will be just too big to fit into main memory. Partitioning or sharding
a graph is a difficult problem to solve (see “The Holy Grail of Graph Scalability” on page
162 ). How, then, can we provide for high-performance queries over a very large graph?
One solution is to use a technique called cache sharding ( Figure 4-10 ), which consists
of routing each request to a database instance in an HA cluster where the portion of the
graph necessary to satisfy that request is likely already in main memory (remember:
every instance in the cluster will contain a full copy of the data). If the majority of an
application's queries are graph-local queries, meaning they start from one or more spe‐
cific points in the graph, and traverse the surrounding subgraphs, then a mechanism
that consistently routes queries beginning from the same set of start points to the same
database instance will increase the likelihood of each query hitting a warm cache.
Search WWH ::




Custom Search