I spent last week trying to make Couchbase work as a replacement for Memcached for our cluster-hosted application. I'd used a previous incarnation of the product, called Membase back in the day, and had very good results with the product in terms as a drop-in replacement for Memcached.
The reasons why we were looking to make the switch were pretty light, I'll admit - we wanted full-on binary compatibility and persistence. Caching is pivotal in the application I've written - a back-end PHP-based framework that manages an AMQP cluster for communications with the front-end application servers. Frequently-accessed data is bundled into mongo-like structures culled from relational tables in MySql and linked-documents are fetched from mongo.
Since the application processes documents uploaded by the user base as one of it's primary requirements, our cache requirements are fairly large. Due to the sensitivity of these documents, there's layers of encryption and obfuscation wrapped around raw data being stored both in-memory and on-disk. As such, data which was already large to being with, is now substantial in terms of size. Some records can be as large as 16Mb.
Because these data-objects are frequently-accessed within a session, and will probably be accessed by different accounts within a very short duration, caching large data became feasible in terms of performance. Repeated hits to the databases to build these objects, while already optimal in terms of speed, will still impact the overall performance of the framework in both CPU utilization and networking bandwidth.
Within the cluster, we're using Memcached hosted on AWS' elasti-cache service. At zero-state, there's 3.2gb of cache available. Still, documents are branded with a relatively low expiry value. and our cache chunk sizes and growth-factors are tuned to support caching of large objects.
Couchbase divides storage into what they term: "buckets". At the top-level, buckets are configured to be either couchbase or memcached buckets. Couchbase buckets are basically nosql databases: they persist through disk i/o and have a formalized structure. Memcache buckets don't persist, and you can pretty much store anything you want without worrying about the internal structure.
As I delved deeper into Couchbase, I found that the idea of buckets quite attractive and quickly set-up multiple memcached buckets - one for cache shared between the back- and front-end, and one exclusive to the back-end.
I also like the Couchbase web-admin tool - unfortunately, the tool is representative of the product itself - it's very attractive but lacks deep functionality almost as if the admin tool was designed by Marketing and not Engineering.
Today, I de-installed Couchbase, reverted to my parent branch in the source, and restored memcached as the de-facto cache server. Here are the reasons why:
- Couchbase memcached buckets do not support retrieval of the key catalog.
This is, by far, the biggest reason I have for dropping the product. While not at all important in a production sense, we rely on an in-house utility to monitor cache which presents a list of all keys cached as click-able links allowing us to display the contents stored under that key. This has become an indispensable tool during development.
Searching the web for how-to retrieve key-catalogs revealed that you can write a view - supported only for couchbase-buckets, not memcache-buckets, or you can tap into the TAP - and internal server API not intended for customer use, or supported, or even promising to provide consistent returns.
- Lack of Documentation
Couchbase documentation is a lot like the Couchbase web-administration tool. It's nice to look at, and very functional in terms of delivering content to your screen.
However, most of the documentation provided is centered around explaining the engineering behind the product, not how to use the product features.
Try to find an example of using TAP. Or an explanation on CAS values. While there's plenty of documentation explaining what TAP and CAS are, there's virtually no (at least that I located) documentation on how to use these features of the product.
- Inconsistent Method Returns
After installing the PHP SDK, I began coding calls to the couchbase service. All calls need to be wrapped in exception handlers - no big deal - but the return codes are inconsistent for the various methods.
Some calls return the data being fetched on-success, and a boolean-false on failure.
The delete() call, for example, returns the CAS key on success. If you're not using the CAS key, it returns the default CAS key - which is zero (0).
Did you catch that? A successful delete operation returns a zero.
Further testing showed that, for the delete() method, you have to test the type of the returned data - if the delete succeeds, the method returns a string(0) while if the method fails, (key did not exist), it returns a boolean(0).
- Inability to Tune the Server
As stated earlier, we store large-data items in-cache. Under memcached, this wasn't a problem as we configured the max_item_size to support large objects. In testing, the front-end application immediately started reporting failures because it was unable to cache any document larger that 1mb in size.
According to the couchbase site, the size of a cached item is hard-coded in the couchbase source and is not tunable by the end-user (customer). Couchbase buckets are limited to 20mb if you need something larger or with persistence.
- Lack of Community Support
A few days into my porting-experiment, I registered on the Couchbase comunity forum for the PHP SDK API. I posted a question which basically encapsulated most of the issues I've enumerated here. A week later, I've yet to receive a reply. Of any type.
Most open-source and commercial products invest in their support communities. Agile development means that if an answer isn't quickly provided, your product risks being removed from the customer's application stack because engineers simply can't afford to wait days for solution to a problem.
- Not an AWS Service End-Point
Couchbase deployment in the cloud requires some additional configuration work to deploy as a scalable service in the cloud. It's currently not-supported by elasti-cache so you're forced to "roll you own" end-point service for auto-scaling and fail-over.
- Web Tool
The web-tool is beautiful to look at. Like the RabbitMQ console, it provides you with real-time graph images showing your cache activity. You can see your top keys and their stats.
You can't configure your server past the size of the buckets.
You can't view your key catalog nor can you view your key contents.
The question was asked, why don't you just use couchbase-buckets for your caching as they'd solve all your issues?
I already have mongo deployed in my application stack. If I'd wanted disk-based caching, I would have used my existing mongo deployment. I'm still toying with the idea of writing a broker service that would passively accept messages published from my memcached class so as to emulate persistence of non-expiring cached items.
Overall, there's things I like about Couchbase memcached service -- buckets are a great example. And, unfortunately, the only one I can think of as the cons far outweigh the pros of using Couchbase as a replacement service for memcached.
Sometimes, older is better.