
I want to share the work done on the performance of various libraries for working with memcached in Node.JS. For the study were selected 4 candidates.
Brief descriptions are taken directly from the sources and are given in the original. Here is the resulting list with versions and links.
- mc v1.0.6 - The Memcache Client for Node.js ( mc )
- node-memcache v0.3.0 - A pure-javascript memcached library for node. ( node-memcache )
- node-memcached v0.2.6 - Fully featured Memcached client for Node.js ( node-memcached )
- memjs v0.8.0 - MemJS is a pure Node.js client library for using memcache. ( memjs )
There are other libraries, but these four were chosen. The reason is simple: there was more information and mentions on the network than the rest.
They got out about a year ago, and they only got to the article just now. I would be glad if you point out a couple of worthy rivals. Be sure to lay out the tests and on them.
')
From prehistory
I started studying Node.JS, experimenting with it and actually writing on it relatively recently, about a year ago. The task was set quite interesting and in fact there were no requirements for the platform. It can be said, I personally chose Node.JS then, as an alternative “up and down” to the studied PHP and I don’t regret it at all. In other words, I am only happy with this choice. Now the second project is already launched and Node.JS justifies itself. To be honest, I got a lot of pleasure from learning deeper JavaScript. It immediately became clear to me that this was not at all the language that I seemed to know for a long time. And how amazed I was when I tried to write unit tests using nodeunit, as everything is elegant and concise, unlike PHP.
Slightly deviated from the topic. This, of course, undeniable merits, which are already described here more than once in Habré and on other resources. But this is not PHP, on which we have written a lot of internal libraries, and there is a mass of strangers for all occasions. After all, the experience of writing projects of varying complexity in PHP for more than 10 years. I again had to do everything from scratch. As once, when switching from C ++ to a pearl, and then from a pearl to PHP. Here I also took a new, unfamiliar tool and tried to somehow customize it for myself.
It was necessary to learn how to work with many systems, be it with mongoDb or with RabbitMQ, or even with the same Mysql. Virtually nothing standard, as in PHP was not here. It was necessary to choose from the mass of libraries the most suitable and block the objects with the functionality I needed. So, in steps, I explored various tools and libraries and at some point I got to memkes.
So let's get started
For the purity of the experiment, I wrapped a single interface with all these libraries, so that in the test script, just specify the desired option, and the actions themselves will be the same for all subjects.
The interface will consist of 4 methods:
Init (cb) - object initialization
Set (key, val, cb) - set value
Get (key, cb) - get values
End () - close all active connections
An example implementation of the interface for the mc library would look like this:
impl.mc = function(){}; impl.mc.prototype = { Init : function(cb) { var self = this; var Mc = require('mc'); self.mmc = new Mc.Client('<ip>:11211', Mc.Adapter.binary); self.mmc.connect(function() { cb(self); }); }, Set : function(key, val, cb) { this.mmc.set(key, val, {flags: 0, exptime : 100}, cb); }, Get : function(key, cb) { this.mmc.get(key, cb); }, End : function() { this.mmc.disconnect(); } };
We write the same implementations for the remaining 3 libraries and put them in the module impl.js. Immediately make a reservation, so as not to pile up and so not a small code, I did not add error handling to the examples. These are just tests and, naturally, in real library wrappers this is all taken into account.
How will the testing take place?
The first step is to write 1000 random integer values ​​with the names of the keys of the form:
__key_ [libName] _ [0 ... 999],
where libName is the name of one of the libraries under study (mc, memcached ...)
We measure time and count the number of records per second. The library name is added to the key so that they do not overlap between different implementations in the test.
The second step - after recorded, we begin to read. We read 100k times at random from the range, again, we note the time and count the number of readings per second.
And here is the code itself, which sequentially launches all the options. I tried to minimize the code to the maximum, well, that's how it happened.
var cacheImpl = require('./impl');
First of all, I was not interested in the absolute values ​​of the number of records and readings per second (although this too), but which library would be faster in general.
Tests were conducted on a working cluster, writing / reading was performed on memcached on a neighboring server. The servers are loaded with real traffic, so absolute values ​​can be paid little attention to. Relative values ​​are important.
Total, after running the script, we get the following result:
memcache Set qps: 8929
memcache Get qps: 19444
memcached Set qps: 6098
memcached Get qps: 8924
memjs Set qps: 8850
memjs Get qps: 12857
mc Set qps: 14286
mc Get qps: 23207
Immediately we see a clear leader, and both by writing and by reading, I will sign as a percentage of the leader.
Record rating:
1. mc 100.00%
2. memcache 62.50%
3. memjs 61.95%
4. memcached 42.69%
Reading rating:
1. mc 100.00%
2. memcache 83.79%
3. memjs 55.40%
4. memcached 38.45%

These are interesting results. Of course, libraries are distinguished by their functionality, convenience of working with them, the ability to work with a cluster of memkeys, a pool of connections, etc. I deliberately miss these moments and take the most common situation when there is one memkesha server. If one will work faster, then with several servers the relative result should not differ much.
Tests are quite synthetic, since only integers are written, reading is done only by existing keys (cases when there is no key is not taken into account), etc. But, nevertheless, all libraries are in equal conditions. Nevertheless, I hope that the results will be useful.
I would be glad if someone helped me decide on the choice of a library, or at least made me think that not all libraries are equally good in terms of performance.
I would like to hear constructive criticism of the work I have done: consistency, style of presentation, and everything that can help make the article better. We will study together.
Here is my "debut" in Habré. How successful he is is up to you.