Chapter 15
In This Chapter
Spreading your data across servers
Ensuring your data is kept safe
Making record versions consistent across your database cluster
If a database tells you that data is saved, then you’re likely to rely on that assurance. For mission-critical use cases this reliance is vital. Moreover, many industries don’t just want changes to their data to be accessible immediately after an update; they also want the indexes used to find the data kept up to date, too — reflecting the current state of the database.
Another issue is the distribution of data around a database cluster. By distributing data, you improve the speed of writes. Distributing data though also means that you may sacrifice the speed of read operations and also of queries. This is because queries need to be handled by many servers. Understanding the tradeoffs for each situation is important.
Document NoSQL databases differ from each other in how they provide the preceding features. They are key for enterprises that want to bet their business on new technology in order to gain competitive advantages.
In this chapter, I discuss the advantages and risks of each approach to consistency and distribution of data in a document oriented NoSQL database.
Remember, there’s no right or wrong way to do things; the “right” way simply depends on the situation.
If all your new data arrives on the last server in your cluster, write operations will suffer, and as the overloaded server struggles to keep up, read operations will also be affected. This is where sharding comes in.
Sharding is the process of ensuring that data is spread evenly across an entire cluster of servers. Shards can be set up at the time a cluster is implemented (MongoDB), they can be fixed into a number of buckets or partitions that can be moved later (Couchbase, Microsoft DocumentDB), or they can be managed automatically simply by moving a number of documents between servers to keep things balanced (MarkLogic Server).
In this section, I describe different approaches to document record sharding, and how you may apply them.
With key-based sharding, the key — the name, URI, or ID — of a document determines which server it’s placed on. Like key-value stores and Bigtable clones, some document NoSQL databases assign a range of key values to each server in a cluster. Based on the key of the record and the ranges assigned to each server, a client connector can determine exactly which server to communicate with in order to fetch a particular document. MongoDB and Couchbase database drivers use this approach to sharding.
Some document NoSQL databases, such as MongoDB, allow their replicas to be queried, rather than exist purely as a backup for a primary shard. This allows for greater read parallelization. This splits the document access load between both the primary shard and its replicas, increasing overall cluster query performance.
The flip side is that, if asynchronous replication is used, then replicas could “disagree” on the current value of a document. You need to carefully select the client driver and server replication settings to avoid this situation.
With automatic sharding, the database randomly assigns a new document to a server, which means the database’s developer doesn’t have to carefully select a key in order to ensure good write throughput.
Automatic sharding works well for a live cluster, but if you need to scale out or scale back during peak periods, you’ll need to rebalance your partitions. For example, a new server with little data will respond quicker than one of the existing servers with lots of data. Using automatic sharding rebalances document among the new (empty) and existing (crowded) servers, increasing average response times.
Rebalancing automatically, rather than based on key range for each server, is an easier operation — you simply move the individual documents you need in order to keep a balance, rather than move them around to maintain fixed range buckets on each server. This means fewer documents to move around, and means you simply move them to a less busy server.
However, no one approach to assigning documents is truly balanced. Some servers will, for reasons unknown to we mortals, perform slightly worse than others, causing partitions to become slightly weighted over time. Rebalancing fixes this problem.
In some databases this rebalancing, or fixed range repartitioning, has to be initiated manually (Couchbase). This then has a batch performance impact across a cluster. Some document databases, like MarkLogic Server, perform this rebalancing live as it needs to. This evens out rebalancing load over time, rather than having to impact cluster performance when manually forced in a short time window.
Durability relates to keeping data intact once it’s saved. Both ACID-compliant, fully consistent systems and non-ACID, eventually consistent systems are capable of being durable.
Durability is typically achieved either by
This impacts the performance of write operations.
A journal log entry is a small description of the change. It provides good performance while ensuring durability.
Not all databases guarantee durability by design. Couchbase, for example, only writes to RAM during a write operation. An asynchronous process later on writes the data to disk.
At the time of this writing, Couchbase 3.0 was in beta and about to be released. This version takes a different approach to durability. It still writes data to RAM, but a new approach — the Couchbase Database Change Protocol (DCP) — is used to stream these changes from RAM to other replicas. This can happen before the originating server saves the data to disk.
Most databases use a journal log as a good tradeoff between the performance of write operations and durability. MarkLogic Server and MongoDB both use journal files to ensure that data is durable. Microsoft DocumentDB, instead, applies the full change during a transaction, so a journal file isn’t needed.
Once the data is saved durably to a disk on a single server, what happens if that server fails? The data is safe, but inaccessible. In this situation, data replication within a cluster is useful.
Replication can either occur
Whichever method you use, once it’s complete, you’re guaranteed that another copy of the data is available elsewhere in the same cluster. If the originating server goes down, the data can still be returned in a query.
What if you’re really having a bad day, and someone digs up a network or power cable to your entire datacenter? This is where database replication comes in.
In database replication, the changes to an entire database across a cluster are streamed as they happen to one or more backup clusters in a remote datacenter(s). Because of the network latency involved, this process generally is done asynchronously as a tradeoff between the speed of write operations and the consistency of remote data.
Sometimes though you may have different needs for your other data center clusters. Perhaps you only want a partial set of information replicated to other live clusters, say for reference reasons.
A good example of this is a metadata catalog in which a description of the data each cluster holds is replicated to other sites, but not the data itself. This kind of catalog is useful for very large files that you don’t need to replicate to all sites. One non-replicated file store holds the files, while your NoSQL document database holds the metadata catalog.
It’s also possible that you do want all data replicated, but you must prioritize which data to replicate first. Perhaps a list of all the notes you’ve made on a device is replicated first, and the notes themselves are replicated later. This is common in certain scenarios:
You can run Couchbase Mobile on a phone to provide for such situations.
This type of replication is sometimes called mobile synchronization, or flexible replication, or Query Based Flexible Replication (QBFR). The phrase query based reflects that a search query is used to bound the data to be replicated, allowing several priority-ordered datasets to be replicated in a push or pull manner.
It’s perfectly acceptable in some applications to have a slight lag in the time it takes for data to become visible. Facebook posts don’t appear instantly to all users. You can also see on Twitter that someone new is following you before the total number of followers is updated. This lag is typically only a few seconds, and for social media that’s not a problem. However, the same isn’t true in situations such as in the following:
It’s important to understand the differences in approaches when considering a database for your application. Not all NoSQL databases support full ACID guarantees, unlike their relational database management systems counterparts.
With eventual consistency, a write operation is successful on the server that receives it but all replicas of that data aren’t updated at the same time. They are updated later based on system replication settings.
Some databases provide only eventual consistency (Couchbase), whereas others allow tuning of consistency on a per operation basis, depending on the settings of the originating client request (MongoDB, Microsoft DocumentDB).
Most social networks use this consistency model for new posts. This model gives you very fast write operations, because you don’t have to wait for all replicas to be updated in order for the write operation to be complete. Inconsistency tends to last only a few seconds while the replicas catch up.
ACID consistency is the gold standard of consistency guarantees. For a full definition of ACID consistency, refer to Chapter 2. An ACID-compliant database ensures that
Some ACID databases go further and allow several changes to be executed within the same transaction. These changes are applied in a single set, ensuring consistency for all documents affected.
Consistency is achieved by shipping all the changes you want applied from the server where a transaction is started, to each replica, then applying the changes, and if all is well the transaction completes. If any one action fails, the entire transaction of changes is rolled back on all replicas. Transaction roll back ensures the data is kept in a consistent state.
MarkLogic Server provides ACID transactions both on the server-side (when applying a set of changes in a single operation) and across several client requests in an application (when applying each change individually, then having a user select ‘apply’). Microsoft’s DocumentDB provides ACID transactions only on the server-side, when executing a JavaScript stored procedure.
18.224.60.220