Skip to content

Commit 86f1cef

Browse files
committed
Merge remote-tracking branch 'node_redis/master'
2 parents 6af4436 + 323d6a2 commit 86f1cef

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+5235
-2482
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
node_modules
22
.tern-port
3+
.nyc_output
4+
coverage

.npmignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
examples/
22
benches/
3-
test.js
3+
test/
44
diff_multi_bench_output.js
55
generate_commands.js
66
multi_bench.js

.travis.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
language: node_js
2+
sudo: true
3+
node_js:
4+
- "0.10"
5+
- "0.12"
6+
- "iojs-v2"
7+
after_success: npm run coverage

README.md

Lines changed: 118 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,17 @@
11
redis - a node.js redis client
22
===========================
33

4-
This is a complete Redis client for node.js. It supports all Redis commands, including many recently added commands like EVAL from
5-
experimental Redis server branches.
4+
[![Build Status](https://travis-ci.org/NodeRedis/node_redis.png)](https://travis-ci.org/NodeRedis/node_redis)
5+
[![Coverage Status](https://coveralls.io/repos/NodeRedis/node_redis/badge.svg?branch=)](https://coveralls.io/r/NodeRedis/node_redis?branch=)
66

7+
This is a complete Redis client for node.js. It supports all Redis commands,
8+
including many recently added commands like EVAL from experimental Redis server
9+
branches.
710

811
Install with:
912

1013
npm install redis
1114

12-
Pieter Noordhuis has provided a binding to the official `hiredis` C library, which is non-blocking and fast. To use `hiredis`, do:
13-
14-
npm install hiredis redis
15-
16-
If `hiredis` is installed, `node_redis` will use it by default. Otherwise, a pure JavaScript parser will be used.
17-
18-
If you use `hiredis`, be sure to rebuild it whenever you upgrade your version of node. There are mysterious failures that can
19-
happen between node and native code modules after a node upgrade.
20-
21-
2215
## Usage
2316

2417
Simple example, included as `examples/simple.js`:
@@ -57,34 +50,9 @@ This will display:
5750
1: hashtest 2
5851
mjr:~/work/node_redis (master)$
5952

60-
61-
## Performance
62-
63-
Here are typical results of `multi_bench.js` which is similar to `redis-benchmark` from the Redis distribution.
64-
It uses 50 concurrent connections with no pipelining.
65-
66-
JavaScript parser:
67-
68-
PING: 20000 ops 42283.30 ops/sec 0/5/1.182
69-
SET: 20000 ops 32948.93 ops/sec 1/7/1.515
70-
GET: 20000 ops 28694.40 ops/sec 0/9/1.740
71-
INCR: 20000 ops 39370.08 ops/sec 0/8/1.269
72-
LPUSH: 20000 ops 36429.87 ops/sec 0/8/1.370
73-
LRANGE (10 elements): 20000 ops 9891.20 ops/sec 1/9/5.048
74-
LRANGE (100 elements): 20000 ops 1384.56 ops/sec 10/91/36.072
75-
76-
hiredis parser:
77-
78-
PING: 20000 ops 46189.38 ops/sec 1/4/1.082
79-
SET: 20000 ops 41237.11 ops/sec 0/6/1.210
80-
GET: 20000 ops 39682.54 ops/sec 1/7/1.257
81-
INCR: 20000 ops 40080.16 ops/sec 0/8/1.242
82-
LPUSH: 20000 ops 41152.26 ops/sec 0/3/1.212
83-
LRANGE (10 elements): 20000 ops 36563.07 ops/sec 1/8/1.363
84-
LRANGE (100 elements): 20000 ops 21834.06 ops/sec 0/9/2.287
85-
86-
The performance of `node_redis` improves dramatically with pipelining, which happens automatically in most normal programs.
87-
53+
Note that the API is entire asynchronous. To get data back from the server,
54+
you'll need to use a callback. The return value from most of the API is a
55+
backpressure indicator.
8856

8957
### Sending Commands
9058

@@ -176,15 +144,16 @@ resume sending when you get `drain`.
176144
`client` will emit `idle` when there are no outstanding commands that are awaiting a response.
177145

178146
## redis.createClient()
147+
If you have `redis-server` running on the same computer as node, then the defaults for
148+
port and host are probably fine and you don't need to supply any arguments. `createClient()` returns a `RedisClient` object.
179149

180150
### overloading
181-
* redis.createClient() = redis.createClient(6379, '127.0.0.1', {})
182-
* redis.createClient(options) = redis.createClient(6379, '127.0.0.1', options)
183-
* redis.createClient(unix_socket, options)
184-
* redis.createClient(port, host, options)
151+
* `redis.createClient(port,host,options)`
152+
* `redis.createClient()` is equivalent to `redis.createClient(6379, '127.0.0.1', {})`
153+
* `redis.createClient(options)` is equivalent to `redis.createClient(6379, '127.0.0.1', options)`
154+
* `redis.createClient(unix_socket, options)`
185155

186-
If you have `redis-server` running on the same computer as node, then the defaults for
187-
port and host are probably fine. `options` in an object with the following possible properties:
156+
`options` is an object with the following possible properties:
188157

189158
* `parser`: which Redis protocol reply parser to use. Defaults to `hiredis` if that module is installed.
190159
This may also be set to `javascript`.
@@ -197,7 +166,7 @@ every command on a client.
197166
* `socket_nodelay`: defaults to `true`. Whether to call setNoDelay() on the TCP stream, which disables the
198167
Nagle algorithm on the underlying socket. Setting this option to `false` can result in additional throughput at the
199168
cost of more latency. Most applications will want this set to `true`.
200-
* `socket_keepalive` defaults to `true`. Whether the keep-alive functionality is enabled on the underlying socket.
169+
* `socket_keepalive` defaults to `true`. Whether the keep-alive functionality is enabled on the underlying socket.
201170
* `no_ready_check`: defaults to `false`. When a connection is established to the Redis server, the server might still
202171
be loading the database from disk. While loading, the server not respond to any commands. To work around this,
203172
`node_redis` has a "ready check" which sends the `INFO` command to the server. The response from the `INFO` command
@@ -216,8 +185,8 @@ limits total time for client to reconnect. Value is provided in milliseconds and
216185
* `max_attempts` defaults to `null`. By default client will try reconnecting until connected. Setting `max_attempts`
217186
limits total amount of reconnects.
218187
* `auth_pass` defaults to `null`. By default client will try connecting without auth. If set, client will run redis auth command on connect.
219-
* `family` defaults to `IPv4`. The client connects in IPv4 if not specified or if the DNS resolution returns an IPv4 address.
220-
You can force an IPv6 if you set the family to 'IPv6'. See nodejs net or dns modules how to use the family type.
188+
* `family` defaults to `IPv4`. The client connects in IPv4 if not specified or if the DNS resolution returns an IPv4 address.
189+
You can force an IPv6 if you set the family to 'IPv6'. See nodejs net or dns modules how to use the family type.
221190

222191
```js
223192
var redis = require("redis"),
@@ -237,7 +206,6 @@ You can force an IPv6 if you set the family to 'IPv6'. See nodejs net or dns mod
237206
client.end();
238207
```
239208

240-
`createClient()` returns a `RedisClient` object that is named `client` in all of the examples here.
241209

242210

243211
## client.auth(password, callback)
@@ -658,6 +626,105 @@ client.zadd(args, function (err, response) {
658626
});
659627
```
660628

629+
## Performance
630+
631+
Much effort has been spent to make `node_redis` as fast as possible for common
632+
operations. As pipelining happens naturally from shared connections, overall
633+
efficiency goes up.
634+
635+
Here are typical results of `multi_bench.js` which is similar to
636+
`redis-benchmark` from the Redis distribution. It uses 5 concurrent connections
637+
and shows the difference between pipelines of 1 and 50.
638+
639+
JavaScript parser:
640+
641+
Client count: 5, node version: 0.10.32, server version: 2.8.18, parser: javascript
642+
PING, 1/5 min/max/avg/p95: 0/ 3/ 0.05/ 1.00 1103ms total, 18132.37 ops/sec
643+
PING, 50/5 min/max/avg/p95: 0/ 4/ 0.81/ 2.00 327ms total, 61162.08 ops/sec
644+
SET 4B str, 1/5 min/max/avg/p95: 0/ 2/ 0.05/ 0.00 1104ms total, 18115.94 ops/sec
645+
SET 4B str, 50/5 min/max/avg/p95: 0/ 3/ 0.83/ 2.00 333ms total, 60060.06 ops/sec
646+
SET 4B buf, 1/5 min/max/avg/p95: 0/ 2/ 0.09/ 1.00 1876ms total, 10660.98 ops/sec
647+
SET 4B buf, 50/5 min/max/avg/p95: 0/ 11/ 2.55/ 4.00 1025ms total, 19512.20 ops/sec
648+
GET 4B str, 1/5 min/max/avg/p95: 0/ 1/ 0.05/ 1.00 1117ms total, 17905.10 ops/sec
649+
GET 4B str, 50/5 min/max/avg/p95: 0/ 3/ 0.87/ 2.00 347ms total, 57636.89 ops/sec
650+
GET 4B buf, 1/5 min/max/avg/p95: 0/ 1/ 0.05/ 1.00 1110ms total, 18018.02 ops/sec
651+
GET 4B buf, 50/5 min/max/avg/p95: 0/ 2/ 0.85/ 2.00 342ms total, 58479.53 ops/sec
652+
SET 4KiB str, 1/5 min/max/avg/p95: 0/ 1/ 0.05/ 1.00 1119ms total, 17873.10 ops/sec
653+
SET 4KiB str, 50/5 min/max/avg/p95: 0/ 3/ 0.89/ 2.00 358ms total, 55865.92 ops/sec
654+
SET 4KiB buf, 1/5 min/max/avg/p95: 0/ 1/ 0.09/ 1.00 1894ms total, 10559.66 ops/sec
655+
SET 4KiB buf, 50/5 min/max/avg/p95: 0/ 7/ 2.57/ 4.00 1031ms total, 19398.64 ops/sec
656+
GET 4KiB str, 1/5 min/max/avg/p95: 0/ 6/ 0.06/ 1.00 1248ms total, 16025.64 ops/sec
657+
GET 4KiB str, 50/5 min/max/avg/p95: 0/ 3/ 1.03/ 2.00 415ms total, 48192.77 ops/sec
658+
GET 4KiB buf, 1/5 min/max/avg/p95: 0/ 1/ 0.06/ 1.00 1177ms total, 16992.35 ops/sec
659+
GET 4KiB buf, 50/5 min/max/avg/p95: 0/ 10/ 1.02/ 2.00 409ms total, 48899.76 ops/sec
660+
INCR, 1/5 min/max/avg/p95: 0/ 2/ 0.05/ 0.55 1137ms total, 17590.15 ops/sec
661+
INCR, 50/5 min/max/avg/p95: 0/ 2/ 0.85/ 2.00 343ms total, 58309.04 ops/sec
662+
LPUSH, 1/5 min/max/avg/p95: 0/ 1/ 0.06/ 1.00 1143ms total, 17497.81 ops/sec
663+
LPUSH, 50/5 min/max/avg/p95: 0/ 3/ 0.87/ 2.00 350ms total, 57142.86 ops/sec
664+
LRANGE 10, 1/5 min/max/avg/p95: 0/ 2/ 0.06/ 1.00 1283ms total, 15588.46 ops/sec
665+
LRANGE 10, 50/5 min/max/avg/p95: 0/ 3/ 1.12/ 2.00 449ms total, 44543.43 ops/sec
666+
LRANGE 100, 1/5 min/max/avg/p95: 0/ 1/ 0.09/ 1.00 1932ms total, 10351.97 ops/sec
667+
LRANGE 100, 50/5 min/max/avg/p95: 0/ 5/ 2.46/ 4.00 985ms total, 20304.57 ops/sec
668+
SET 4MiB buf, 1/5 min/max/avg/p95: 1/ 4/ 1.37/ 2.00 691ms total, 723.59 ops/sec
669+
SET 4MiB buf, 50/5 min/max/avg/p95: 3/ 166/ 57.66/ 116.00 601ms total, 831.95 ops/sec
670+
GET 4MiB str, 1/5 min/max/avg/p95: 84/ 110/ 93.18/ 106.95 9320ms total, 10.73 ops/sec
671+
GET 4MiB str, 50/5 min/max/avg/p95: 156/7375/3400.10/6840.40 8928ms total, 11.20 ops/sec
672+
GET 4MiB buf, 1/5 min/max/avg/p95: 84/ 105/ 91.21/ 99.00 9129ms total, 10.95 ops/sec
673+
GET 4MiB buf, 50/5 min/max/avg/p95: 424/5704/3518.94/5626.65 9145ms total, 10.93 ops/sec
674+
675+
If you use very large responses in your application, the JavaScript parser
676+
performs badly. Until the JS parser is fixed, you can use the C-based `hiredis`
677+
parser bound to the official `hiredis` C library. To use `hiredis`, do:
678+
679+
npm install hiredis redis
680+
681+
If the `hiredis` npm module is installed, `node_redis` will use it by default.
682+
Otherwise, the pure JavaScript parser will be used.
683+
684+
If you use `hiredis`, be sure to rebuild it whenever you upgrade your version of
685+
node. There are mysterious failures that can happen between node and native
686+
code modules after a node upgrade.
687+
688+
Most users find that the JS parser is faster than the `hiredis` parser. Because
689+
of the pain associated with upgrading native code modules, you should only use
690+
`hiredis` if your application needs it.
691+
692+
hiredis parser:
693+
694+
Client count: 5, node version: 0.10.32, server version: 2.8.18, parser: hiredis
695+
PING, 1/5 min/max/avg/p95: 0/ 3/ 0.05/ 1.00 1092ms total, 18315.02 ops/sec
696+
PING, 50/5 min/max/avg/p95: 0/ 5/ 0.87/ 2.00 347ms total, 57636.89 ops/sec
697+
SET 4B str, 1/5 min/max/avg/p95: 0/ 2/ 0.06/ 1.00 1151ms total, 17376.19 ops/sec
698+
SET 4B str, 50/5 min/max/avg/p95: 0/ 3/ 0.83/ 2.00 334ms total, 59880.24 ops/sec
699+
SET 4B buf, 1/5 min/max/avg/p95: 0/ 3/ 0.09/ 1.00 1932ms total, 10351.97 ops/sec
700+
SET 4B buf, 50/5 min/max/avg/p95: 0/ 9/ 2.64/ 4.00 1059ms total, 18885.74 ops/sec
701+
GET 4B str, 1/5 min/max/avg/p95: 0/ 1/ 0.06/ 0.00 1185ms total, 16877.64 ops/sec
702+
GET 4B str, 50/5 min/max/avg/p95: 0/ 3/ 0.85/ 2.00 341ms total, 58651.03 ops/sec
703+
GET 4B buf, 1/5 min/max/avg/p95: 0/ 1/ 0.06/ 0.00 1179ms total, 16963.53 ops/sec
704+
GET 4B buf, 50/5 min/max/avg/p95: 0/ 3/ 0.85/ 2.00 340ms total, 58823.53 ops/sec
705+
SET 4KiB str, 1/5 min/max/avg/p95: 0/ 1/ 0.06/ 1.00 1210ms total, 16528.93 ops/sec
706+
SET 4KiB str, 50/5 min/max/avg/p95: 0/ 3/ 0.93/ 2.00 372ms total, 53763.44 ops/sec
707+
SET 4KiB buf, 1/5 min/max/avg/p95: 0/ 1/ 0.10/ 1.00 1967ms total, 10167.77 ops/sec
708+
SET 4KiB buf, 50/5 min/max/avg/p95: 0/ 6/ 2.63/ 4.00 1053ms total, 18993.35 ops/sec
709+
GET 4KiB str, 1/5 min/max/avg/p95: 0/ 6/ 0.06/ 1.00 1176ms total, 17006.80 ops/sec
710+
GET 4KiB str, 50/5 min/max/avg/p95: 0/ 4/ 1.00/ 2.00 399ms total, 50125.31 ops/sec
711+
GET 4KiB buf, 1/5 min/max/avg/p95: 0/ 1/ 0.06/ 1.00 1158ms total, 17271.16 ops/sec
712+
GET 4KiB buf, 50/5 min/max/avg/p95: 0/ 3/ 0.99/ 2.00 398ms total, 50251.26 ops/sec
713+
INCR, 1/5 min/max/avg/p95: 0/ 1/ 0.05/ 0.00 1112ms total, 17985.61 ops/sec
714+
INCR, 50/5 min/max/avg/p95: 0/ 3/ 0.84/ 2.00 339ms total, 58997.05 ops/sec
715+
LPUSH, 1/5 min/max/avg/p95: 0/ 1/ 0.05/ 1.00 1131ms total, 17683.47 ops/sec
716+
LPUSH, 50/5 min/max/avg/p95: 0/ 3/ 0.86/ 2.00 345ms total, 57971.01 ops/sec
717+
LRANGE 10, 1/5 min/max/avg/p95: 0/ 1/ 0.06/ 1.00 1228ms total, 16286.64 ops/sec
718+
LRANGE 10, 50/5 min/max/avg/p95: 0/ 3/ 0.95/ 2.00 382ms total, 52356.02 ops/sec
719+
LRANGE 100, 1/5 min/max/avg/p95: 0/ 1/ 0.08/ 1.00 1567ms total, 12763.24 ops/sec
720+
LRANGE 100, 50/5 min/max/avg/p95: 0/ 6/ 1.68/ 3.00 675ms total, 29629.63 ops/sec
721+
SET 4MiB buf, 1/5 min/max/avg/p95: 1/ 4/ 1.37/ 2.00 692ms total, 722.54 ops/sec
722+
SET 4MiB buf, 50/5 min/max/avg/p95: 3/ 183/ 57.79/ 125.00 605ms total, 826.45 ops/sec
723+
GET 4MiB str, 1/5 min/max/avg/p95: 5/ 16/ 8.14/ 12.95 816ms total, 122.55 ops/sec
724+
GET 4MiB str, 50/5 min/max/avg/p95: 24/ 323/ 202.98/ 309.00 519ms total, 192.68 ops/sec
725+
GET 4MiB buf, 1/5 min/max/avg/p95: 6/ 13/ 8.01/ 11.95 802ms total, 124.69 ops/sec
726+
GET 4MiB buf, 50/5 min/max/avg/p95: 16/ 480/ 203.85/ 435.70 531ms total, 188.32 ops/sec
727+
661728
## TODO
662729

663730
Better tests for auth, disconnect/reconnect, and all combinations thereof.
@@ -674,7 +741,7 @@ I think there are more performance improvements left in there for smaller values
674741
comment again with indignation!)
675742

676743
## Contributors
677-
Some people have have added features and fixed bugs in `node_redis` other than me.
744+
Many people have have added features and fixed bugs in `node_redis`.
678745

679746
Ordered by date of first contribution.
680747
[Auto-generated](http://github.com/dtrejo/node-authors) on Wed Jul 25 2012 19:14:59 GMT-0700 (PDT).
@@ -740,5 +807,3 @@ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
740807
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
741808
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
742809
OTHER DEALINGS IN THE SOFTWARE.
743-
744-
![spacer](http://ranney.com/1px.gif)

benches/buffer_bench.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
'use strict';
2+
13
var source = new Buffer(100),
24
dest = new Buffer(100), i, j, k, tmp, count = 1000000, bytes = 100;
3-
5+
46
for (i = 99 ; i >= 0 ; i--) {
57
source[i] = 120;
68
}

benches/hiredis_parser.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use strict';
2+
13
var Parser = require('../lib/parser/hiredis').Parser;
24
var assert = require('assert');
35

benches/re_sub_test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use strict';
2+
13
var client = require('../index').createClient()
24
, client2 = require('../index').createClient()
35
, assert = require('assert');

benches/reconnect_test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use strict';
2+
13
var redis = require("../index").createClient(null, null, {
24
// max_attempts: 4
35
});

benches/stress/codec.js

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,8 @@
1+
'use strict';
2+
13
var json = {
24
encode: JSON.stringify,
35
decode: JSON.parse
46
};
57

6-
var MsgPack = require('node-msgpack');
7-
msgpack = {
8-
encode: MsgPack.pack,
9-
decode: function(str) { return MsgPack.unpack(new Buffer(str)); }
10-
};
11-
12-
bison = require('bison');
13-
148
module.exports = json;
15-
//module.exports = msgpack;
16-
//module.exports = bison;

benches/stress/speed/speed.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use strict';
2+
13
var msgpack = require('node-msgpack');
24
var bison = require('bison');
35
var codec = {

0 commit comments

Comments
 (0)