Blog Post

Couchbase 101-102-103 (Series 1)

Jasdeep Jaitla of Couchbase Published

We recently started an online webinar series to cover the core components of Couchbase Server from installation through getting set up for development and understanding indexing. A number of questions came up during the webinars and I am posting a written Q & A here.

My Ruby based load generator can be downloaded here: https://github.com/scalabl3/ruby-couchbase-loadgen

Couchbase 101 - Installation and Configuration

Q: When you add a server is it sharding?

A: Yes, we use "Hash Sharding" for all data, that means that for every key-value pair, we hash the string key to get the partition number (a logical container) it should live in. We look up the partition number in the cluster map to see where that partition is located in the Couchbase cluster, and then do CRUD directly with that Couchbase node responsible for that partition. When you add a new server (or more than one), we are simply redistributing the partitions evenly across the new number of nodes. 

Q: Do we have to add servers for replica alone?

A: Replicas, for effectiveness in a failover situation, need to be located on different nodes so that nodes can be "failed over". For one replica, there needs to be at least two Couchbase nodes. For two replicas there needs to be at least three Couchbase nodes, and for three replicas there needs to be at least four Couchbase nodes. Of course increasing the number of replicas also increases the need for bigger resources for optimal performance.

Q: Are all the docs with the same hash value stored on the same partition?

A: Yes, our Hash function is simply turning a string key into a number from [0...1023], all keys that hash to the number 2 will live within the partition container #2. That partition will reside on a particular node of Couchbase in the cluster, if you add more servers and rebalance, that partition may be moved to another server, but there is only ever one node that is the "master" for that partition. The "replica" for that partition will of course live on a separate node.

Q: In your horizontal scale example, the total partitions are always 1024.  Is 1024 the max partitions in a cluster?

A: When first learning about our sharding and distribution scheme, many developers look at this number as a knob to tweak, naturally, since we are all tinkerers. However, the number of partitions doesn't change performance characteristics. We feel 1024 is a good number of partitions for even distribution of data, it's not really something that needs changing, and is not a configuration parameter. The number very easily could be 10,000 or 990, and it wouldn't change the architecture of how we distribute data (it would just increase or reduce the number of data files).

Q: How Many Buckets can be installed on a single virtual machine?

A: This is a difficult question to give a rule of thumb, because the resources allocated to that virtual machine can vary greatly, but generally for a sizable machine of 8+ cores, about 10-12 Buckets is feasible. For each Bucket we allocate resources to manage and monitor, so having huge numbers of buckets increases CPU overhead and is generally not recommended.

Q: Does rebalancing of the nodes has any effect on the efficiency of the Couchbase?

A: We prioritize primary operations over rebalancing operations in Couchbase, but with that said, there is an increase of CPU and network traffic between Couchbase nodes during a rebalance. It's recommended to do rebalancing in off-peak usage times of course, the same goes for doing backups, just like any other system. Doing a rebalance at peak usage times will certainly slow down the rebalance timing if peak usage is very heavy.

Q: When you rebalance are partitions actually moved to another node or are they duplicated?

A: They are copied until the rebalance is complete, in case there is a failure during rebalance. The original master node remains the master node until rebalance finishes completely. Upon rebalance completion, the new master node for that partition becomes the master and the old one removes its data, and the cluster maps are updated accordingly across the cluster, and then the client sdk's.

Q: What tools are available for backup/restore and to help with disaster recovery?

A: We have cbbackup and cbrestore command line tools just for this purpose, you can read about them here: http://www.couchbase.com/docs//couchbase-manual-2.0/couchbase-backup-restore-backup-cbbackup.html

Couchbase 102 - Development

Q: What happens when are storing pictures in Couchbase? 

A: You can store pictures in two different ways with Couchbase, one is to store straight binary data as a Document value. The second option is to store it as pre-encoded bases64 within a JSON document, so then it's a standard JSON document with one or more images encoded as JSON values (with JSON keys). The advantage of storing images in Couchbase is that it will be served from RAM instead of disk so it will be very performant. Couple this with XDCR (Cross Data Center Replication) and you can create your own CDN for images!

Q: How do you modify/update multiple docs and rollback if an error occurs on one of them?

A: In Couchbase you can very easily use Optimistic (CAS) or Pessimistic (Lock) Concurrency for transactions on single documents, but for multiple documents in a single "transaction", you will need to use what is called a Two-Phase Commit. You can read more about it here: http://www.couchbase.com/docs/couchbase-devguide-2.0/two-phase-commits.html

Q: Is there a possibility for transactions in Couchbase?

A: Like the previous question, you can easily do single document transactions using Optimistic Concurrency with (CAS - Compare and Swap), or Get and Lock. 

Q: Is there a batch insert/update operation that would callback with a list of failed inserts/updates after the write to primary disk?

A: In some SDK's (Python for instance) they do have multi-set type operations (all of them have multi-get operations), but I don't believe we support multi-set AND observe type operations. 

Q: How can I make a query with multiple parameters to pass, like name, date, anda status; something like a "where" in SQL?

A: You do this with our Views (Indexes), querying multiple parameters might require either a) querying separate views and doing an intersection within your applicaiton, or being creative with your index key's so that you can range query. There are a number of different strategies for this, and it will be particular to a use case and document design to be able to answer it succinctly.

Q: Do you support other languages like Go or Clojure?

A: Yes! We have community editions for Go (https://github.com/dustin/go-couchbase), you can see all the community clients on our All Clients page on couchbsae.com: http://www.couchbase.com/communities/all-client-libraries Community client libraries aren't officially supported by our support contracts, but you can easily find help from our engineers via IRC or twitter.

Q: Are Key Patterns faster than Views?

A: In most cases where you can actually use Key Patterns, yes because they are binary operations coming out of RAM cache, but not everything can be modeled using Key Patterns. In those cases, that's where our Views (Indexes) are useful and also our Elastic Search integration as well.

Couchbase 103 - Views, Indexing and Querying

Q: Are the indexes held in memory?

A: No, all Indexes (much like other Indexing systems in other databases), are created on and queried from disk. The operating system will utilize RAM for filesystem cache which will improve performance on Index querying considerably. This is why we leave a good portion of RAM for the OS to do so (40% available RAM).

Q: Are the indexes automatically distributed across multiple nodes? Can you place indexes only on certain nodes for performance reasons. For example if you had a heavy query/index operation you did not want to affect multiple nodes.  

A: Every node of Couchbase maintains indexes for the master/active partitions that reside on it (that it's the "master" for). Because data is evenly distributed because of our Hash sharding of keys to partitions, you won't be able to have indexes only on certain nodes without an incomplete index. However, that being said, you could employ a different strategy of having a separate entire cluster that is on the receiving end of a one-way XDCR (Cross Data Center Replication) that is receiving documents from your primary data store (only receiving, not used for data creation or updates) which can then be used for heavy indexing and querying and completely optimized for that purpose.

Q: Can you hide the meta.id for a particular view at the interface level? Do you just eliminate it from the map function parameters? When you are using a website for example and a customer is querying the database..and you do not want to show the meta.id?

A: No, all document key's (id's) are included with the result set in JSON for the document that generated that result "row" (actually an array item in the array of results). Leaving it out of the map function doesn't change that. What you can do to solve the second case would be to not have your web page javascript query Couchbase directly (which I wouldn't recommend anyway as it means your Couchbase server is exposed, much like any database you typically don't expose it to the public). Instead, you can run the query through your own API and filter out the result set to not have document id's (meta.id). 

Q: When querying a view with skip, the response time seems proportional to the skip size. Is that expected?

A: It's better to actually use a pair of parameters instead of using skip, the startkey and startkey_docid to page through. Results are sorted by startkey first (your index-key) and then if there are multiple identical index-keys in the result set it's sorted then by startkey_docid. The reason for using this method instead is two-fold, one is that it avoids the response time problem, which also gets worse as you grow your cluster because the scatter-gather will all be affected by the skip -- the more nodes, the more time it takes to skip on each node since queries are scattered across the cluster. Secondly your result set will change when the Index gets updated, so then "skip" won't skip exactly the same after the first time you query.

Thanks for reading!

Jasdeep Jaitla
jasdeep@couchbase.com
@scalabl3