nutcracker 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +22 -0
- data/Rakefile +55 -0
- data/bin/nutcracker +2 -0
- data/ext/nutcracker/ChangeLog +66 -0
- data/ext/nutcracker/LICENSE +177 -0
- data/ext/nutcracker/Makefile.am +7 -0
- data/ext/nutcracker/Makefile.in +726 -0
- data/ext/nutcracker/NOTICE +124 -0
- data/ext/nutcracker/README.md +240 -0
- data/ext/nutcracker/aclocal.m4 +956 -0
- data/ext/nutcracker/conf/nutcracker.leaf.yml +10 -0
- data/ext/nutcracker/conf/nutcracker.root.yml +8 -0
- data/ext/nutcracker/conf/nutcracker.yml +67 -0
- data/ext/nutcracker/config.h.in +316 -0
- data/ext/nutcracker/config/config.guess +1561 -0
- data/ext/nutcracker/config/config.sub +1686 -0
- data/ext/nutcracker/config/depcomp +630 -0
- data/ext/nutcracker/config/install-sh +520 -0
- data/ext/nutcracker/config/ltmain.sh +8413 -0
- data/ext/nutcracker/config/missing +376 -0
- data/ext/nutcracker/configure +18862 -0
- data/ext/nutcracker/configure.ac +155 -0
- data/ext/nutcracker/contrib/Makefile.am +3 -0
- data/ext/nutcracker/contrib/Makefile.in +560 -0
- data/ext/nutcracker/contrib/yaml-0.1.4.tar.gz +0 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/LICENSE +19 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.am +20 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.in +736 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/README +27 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/aclocal.m4 +956 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config.h.in +80 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/config.guess +1561 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/config.sub +1686 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/depcomp +630 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/install-sh +520 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/ltmain.sh +8406 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/missing +376 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/configure +13085 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/configure.ac +75 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/doc/doxygen.cfg +222 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/include/yaml.h +1971 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/libtool.m4 +7357 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltoptions.m4 +368 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltsugar.m4 +123 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltversion.m4 +23 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/lt~obsolete.m4 +92 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.am +4 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.in +484 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/api.c +1392 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/dumper.c +394 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/emitter.c +2329 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/loader.c +432 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/parser.c +1374 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/reader.c +465 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/scanner.c +3570 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/writer.c +141 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/yaml_private.h +640 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.am +8 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.in +675 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor-alt.c +800 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor.c +1130 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter-alt.c +217 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter.c +202 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-dumper.c +311 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-emitter.c +327 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-loader.c +63 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-parser.c +63 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-scanner.c +63 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-reader.c +354 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-version.c +29 -0
- data/ext/nutcracker/extconf.rb +5 -0
- data/ext/nutcracker/m4/libtool.m4 +7376 -0
- data/ext/nutcracker/m4/ltoptions.m4 +368 -0
- data/ext/nutcracker/m4/ltsugar.m4 +123 -0
- data/ext/nutcracker/m4/ltversion.m4 +23 -0
- data/ext/nutcracker/m4/lt~obsolete.m4 +92 -0
- data/ext/nutcracker/notes/c-styleguide.txt +425 -0
- data/ext/nutcracker/notes/debug.txt +96 -0
- data/ext/nutcracker/notes/memcache.txt +123 -0
- data/ext/nutcracker/notes/recommendation.md +118 -0
- data/ext/nutcracker/notes/redis.md +415 -0
- data/ext/nutcracker/notes/socket.txt +131 -0
- data/ext/nutcracker/scripts/multi_get.sh +26 -0
- data/ext/nutcracker/scripts/nutcracker.init +73 -0
- data/ext/nutcracker/scripts/nutcracker.spec +52 -0
- data/ext/nutcracker/scripts/pipelined_read.sh +23 -0
- data/ext/nutcracker/scripts/pipelined_write.sh +29 -0
- data/ext/nutcracker/scripts/populate_memcached.sh +24 -0
- data/ext/nutcracker/scripts/redis-check.py +23 -0
- data/ext/nutcracker/scripts/redis-check.sh +564 -0
- data/ext/nutcracker/src/Makefile.am +46 -0
- data/ext/nutcracker/src/Makefile.in +726 -0
- data/ext/nutcracker/src/hashkit/Makefile.am +22 -0
- data/ext/nutcracker/src/hashkit/Makefile.in +501 -0
- data/ext/nutcracker/src/hashkit/nc_crc32.c +105 -0
- data/ext/nutcracker/src/hashkit/nc_fnv.c +82 -0
- data/ext/nutcracker/src/hashkit/nc_hashkit.h +74 -0
- data/ext/nutcracker/src/hashkit/nc_hsieh.c +93 -0
- data/ext/nutcracker/src/hashkit/nc_jenkins.c +230 -0
- data/ext/nutcracker/src/hashkit/nc_ketama.c +240 -0
- data/ext/nutcracker/src/hashkit/nc_md5.c +379 -0
- data/ext/nutcracker/src/hashkit/nc_modula.c +144 -0
- data/ext/nutcracker/src/hashkit/nc_murmur.c +99 -0
- data/ext/nutcracker/src/hashkit/nc_one_at_a_time.c +51 -0
- data/ext/nutcracker/src/hashkit/nc_random.c +146 -0
- data/ext/nutcracker/src/nc.c +573 -0
- data/ext/nutcracker/src/nc_array.c +204 -0
- data/ext/nutcracker/src/nc_array.h +73 -0
- data/ext/nutcracker/src/nc_client.c +189 -0
- data/ext/nutcracker/src/nc_client.h +28 -0
- data/ext/nutcracker/src/nc_conf.c +1766 -0
- data/ext/nutcracker/src/nc_conf.h +134 -0
- data/ext/nutcracker/src/nc_connection.c +392 -0
- data/ext/nutcracker/src/nc_connection.h +99 -0
- data/ext/nutcracker/src/nc_core.c +334 -0
- data/ext/nutcracker/src/nc_core.h +131 -0
- data/ext/nutcracker/src/nc_event.c +214 -0
- data/ext/nutcracker/src/nc_event.h +39 -0
- data/ext/nutcracker/src/nc_log.c +254 -0
- data/ext/nutcracker/src/nc_log.h +120 -0
- data/ext/nutcracker/src/nc_mbuf.c +285 -0
- data/ext/nutcracker/src/nc_mbuf.h +67 -0
- data/ext/nutcracker/src/nc_message.c +828 -0
- data/ext/nutcracker/src/nc_message.h +253 -0
- data/ext/nutcracker/src/nc_proxy.c +359 -0
- data/ext/nutcracker/src/nc_proxy.h +34 -0
- data/ext/nutcracker/src/nc_queue.h +788 -0
- data/ext/nutcracker/src/nc_rbtree.c +348 -0
- data/ext/nutcracker/src/nc_rbtree.h +47 -0
- data/ext/nutcracker/src/nc_request.c +588 -0
- data/ext/nutcracker/src/nc_response.c +332 -0
- data/ext/nutcracker/src/nc_server.c +841 -0
- data/ext/nutcracker/src/nc_server.h +143 -0
- data/ext/nutcracker/src/nc_signal.c +131 -0
- data/ext/nutcracker/src/nc_signal.h +34 -0
- data/ext/nutcracker/src/nc_stats.c +1188 -0
- data/ext/nutcracker/src/nc_stats.h +206 -0
- data/ext/nutcracker/src/nc_string.c +109 -0
- data/ext/nutcracker/src/nc_string.h +112 -0
- data/ext/nutcracker/src/nc_util.c +619 -0
- data/ext/nutcracker/src/nc_util.h +214 -0
- data/ext/nutcracker/src/proto/Makefile.am +14 -0
- data/ext/nutcracker/src/proto/Makefile.in +482 -0
- data/ext/nutcracker/src/proto/nc_memcache.c +1306 -0
- data/ext/nutcracker/src/proto/nc_proto.h +155 -0
- data/ext/nutcracker/src/proto/nc_redis.c +2102 -0
- data/lib/nutcracker.rb +7 -0
- data/lib/nutcracker/version.rb +3 -0
- metadata +194 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
- strace
|
2
|
+
strace -o strace.txt -ttT -s 1024 -p `pgrep nutcracker`
|
3
|
+
|
4
|
+
- epoll
|
5
|
+
|
6
|
+
EPOLLIN = 0x001,
|
7
|
+
EPOLLPRI = 0x002,
|
8
|
+
EPOLLOUT = 0x004,
|
9
|
+
EPOLLERR = 0x008,
|
10
|
+
EPOLLHUP = 0x010,
|
11
|
+
EPOLLRDNORM = 0x040,
|
12
|
+
EPOLLRDBAND = 0x080,
|
13
|
+
EPOLLWRNORM = 0x100,
|
14
|
+
EPOLLWRBAND = 0x200,
|
15
|
+
EPOLLMSG = 0x400,
|
16
|
+
EPOLLRDHUP = 0x2000,
|
17
|
+
EPOLLONESHOT = (1 << 30),
|
18
|
+
EPOLLET = (1 << 31)
|
19
|
+
|
20
|
+
- libyaml (yaml-0.1.4)
|
21
|
+
|
22
|
+
- yaml tokens:
|
23
|
+
|
24
|
+
0 YAML_NO_TOKEN,
|
25
|
+
1 YAML_STREAM_START_TOKEN,
|
26
|
+
2 YAML_STREAM_END_TOKEN,
|
27
|
+
3 YAML_VERSION_DIRECTIVE_TOKEN,
|
28
|
+
4 YAML_TAG_DIRECTIVE_TOKEN,
|
29
|
+
5 YAML_DOCUMENT_START_TOKEN,
|
30
|
+
6 YAML_DOCUMENT_END_TOKEN,
|
31
|
+
7 YAML_BLOCK_SEQUENCE_START_TOKEN,
|
32
|
+
8 YAML_BLOCK_MAPPING_START_TOKEN,
|
33
|
+
9 YAML_BLOCK_END_TOKEN,
|
34
|
+
10 YAML_FLOW_SEQUENCE_START_TOKEN,
|
35
|
+
11 YAML_FLOW_SEQUENCE_END_TOKEN,
|
36
|
+
12 YAML_FLOW_MAPPING_START_TOKEN,
|
37
|
+
13 YAML_FLOW_MAPPING_END_TOKEN,
|
38
|
+
14 YAML_BLOCK_ENTRY_TOKEN,
|
39
|
+
15 YAML_FLOW_ENTRY_TOKEN,
|
40
|
+
16 YAML_KEY_TOKEN,
|
41
|
+
17 YAML_VALUE_TOKEN,
|
42
|
+
18 YAML_ALIAS_TOKEN,
|
43
|
+
19 YAML_ANCHOR_TOKEN,
|
44
|
+
20 YAML_TAG_TOKEN,
|
45
|
+
21 YAML_SCALAR_TOKEN
|
46
|
+
|
47
|
+
- yaml events
|
48
|
+
|
49
|
+
0 YAML_NO_EVENT,
|
50
|
+
1 YAML_STREAM_START_EVENT,
|
51
|
+
2 YAML_STREAM_END_EVENT,
|
52
|
+
3 YAML_DOCUMENT_START_EVENT,
|
53
|
+
4 YAML_DOCUMENT_END_EVENT,
|
54
|
+
5 YAML_ALIAS_EVENT,
|
55
|
+
6 YAML_SCALAR_EVENT,
|
56
|
+
7 YAML_SEQUENCE_START_EVENT,
|
57
|
+
8 YAML_SEQUENCE_END_EVENT,
|
58
|
+
9 YAML_MAPPING_START_EVENT,
|
59
|
+
10 YAML_MAPPING_END_EVENT
|
60
|
+
|
61
|
+
- sys/queue.h
|
62
|
+
|
63
|
+
queue.h is a generic linked list library adapted from BSD. It has three
|
64
|
+
macro knobs that are useful for debugging:
|
65
|
+
|
66
|
+
- QUEUE_MACRO_SCRUB nullifies links (next and prev pointers) of deleted
|
67
|
+
elements and catches cases where we are attempting to do operations
|
68
|
+
on an element that has already been unlinked.
|
69
|
+
- QUEUE_MACRO_TRACE keeps track of __FILE__ and __LINE__ of last two
|
70
|
+
updates to the list data structure.
|
71
|
+
- QUEUE_MACRO_ASSERT verifies the sanity of list data structure on every
|
72
|
+
operation.
|
73
|
+
|
74
|
+
- valgrind
|
75
|
+
valgrind --tool=memcheck --leak-check=yes <program>
|
76
|
+
|
77
|
+
- Core dump
|
78
|
+
ulimit -c unlimited
|
79
|
+
|
80
|
+
- Generate ENOMEM to test "Out of Memory"
|
81
|
+
ulimit -m <size> # limit maximum memory size
|
82
|
+
ulimit -v <size> # limit virtual memory
|
83
|
+
|
84
|
+
- get nutcracker stats
|
85
|
+
printf "" | socat - TCP:localhost:22222 | tee stats.txt
|
86
|
+
printf "" | nc localhost 22222 | python -mjson.tool
|
87
|
+
|
88
|
+
- Signalling and Logging
|
89
|
+
SIGTTIN - To up the log level
|
90
|
+
SIGTTOU - To down the log level
|
91
|
+
SIGHUP - To reopen log file
|
92
|
+
|
93
|
+
- Error codes:
|
94
|
+
http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_2.html
|
95
|
+
/usr/include/asm-generic/errno-base.h
|
96
|
+
/usr/include/asm-generic/errno.h
|
@@ -0,0 +1,123 @@
|
|
1
|
+
- ascii:
|
2
|
+
|
3
|
+
- Storage Commands (set, add, replace, append, prepend, cas):
|
4
|
+
|
5
|
+
set <key> <flags> <expiry> <datalen> [noreply]\r\n<data>\r\n
|
6
|
+
add <key> <flags> <expiry> <datalen> [noreply]\r\n<data>\r\n
|
7
|
+
replace <key> <flags> <expiry> <datalen> [noreply]\r\n<data>\r\n
|
8
|
+
append <key> <flags> <expiry> <datalen> [noreply]\r\n<data>\r\n
|
9
|
+
prepend <key> <flags> <expiry> <datalen> [noreply]\r\n<data>\r\n
|
10
|
+
|
11
|
+
cas <key> <flags> <expiry> <datalen> <cas> [noreply]\r\n<data>\r\n
|
12
|
+
|
13
|
+
where,
|
14
|
+
<flags> - uint32_t : data specific client side flags
|
15
|
+
<expiry> - uint32_t : expiration time (in seconds)
|
16
|
+
<datalen> - uint32_t : size of the data (in bytes)
|
17
|
+
<data> - uint8_t[]: data block
|
18
|
+
<cas> - uint64_t
|
19
|
+
|
20
|
+
- Retrival Commands (get, gets):
|
21
|
+
|
22
|
+
get <key>\r\n
|
23
|
+
get <key> [<key>]+\r\n
|
24
|
+
|
25
|
+
gets <key>\r\n
|
26
|
+
gets <key> [<key>]+\r\n
|
27
|
+
|
28
|
+
- Delete Command (delete):
|
29
|
+
|
30
|
+
delete <key> [noreply]\r\n
|
31
|
+
|
32
|
+
- Arithmetic Commands (incr, decr):
|
33
|
+
|
34
|
+
incr <key> <value> [noreply]\r\n
|
35
|
+
decr <key> <value> [noreply]\r\n
|
36
|
+
|
37
|
+
where,
|
38
|
+
<value> - uint64_t
|
39
|
+
|
40
|
+
- Misc Commands (quit)
|
41
|
+
|
42
|
+
quit\r\n
|
43
|
+
flush_all [<delay>] [noreply]\r\n
|
44
|
+
version\r\n
|
45
|
+
verbosity <num> [noreply]\r\n
|
46
|
+
|
47
|
+
- Statistics Commands
|
48
|
+
|
49
|
+
stats\r\n
|
50
|
+
stats <args>\r\n
|
51
|
+
|
52
|
+
- Error Responses:
|
53
|
+
|
54
|
+
ERROR\r\n
|
55
|
+
CLIENT_ERROR [error]\r\n
|
56
|
+
SERVER_ERROR [error]\r\n
|
57
|
+
|
58
|
+
where,
|
59
|
+
ERROR means client sent a non-existent command name
|
60
|
+
CLIENT_ERROR means that command sent by the client does not conform to the protocol
|
61
|
+
SERVER_ERROR means that there was an error on the server side that made processing of the command impossible
|
62
|
+
|
63
|
+
- Storage Command Responses:
|
64
|
+
|
65
|
+
STORED\r\n
|
66
|
+
NOT_STORED\r\n
|
67
|
+
EXISTS\r\n
|
68
|
+
NOT_FOUND\r\n
|
69
|
+
|
70
|
+
where,
|
71
|
+
STORED indicates success.
|
72
|
+
NOT_STORED indicates the data was not stored because condition for an add or replace wasn't met.
|
73
|
+
EXISTS indicates that the item you are trying to store with a cas has been modified since you last fetched it.
|
74
|
+
NOT_FOUND indicates that the item you are trying to store with a cas does not exist.
|
75
|
+
|
76
|
+
- Delete Command Response:
|
77
|
+
|
78
|
+
NOT_FOUND\r\n
|
79
|
+
DELETED\r\n
|
80
|
+
|
81
|
+
- Retrival Responses:
|
82
|
+
|
83
|
+
END\r\n
|
84
|
+
VALUE <key> <flags> <datalen> [<cas>]\r\n<data>\r\nEND\r\n
|
85
|
+
VALUE <key> <flags> <datalen> [<cas>]\r\n<data>\r\n[VALUE <key> <flags> <datalen> [<cas>]\r\n<data>]+\r\nEND\r\n
|
86
|
+
|
87
|
+
- Arithmetic Responses:
|
88
|
+
|
89
|
+
NOT_FOUND\r\n
|
90
|
+
<value>\r\n
|
91
|
+
|
92
|
+
where,
|
93
|
+
<value> - uint64_t : new key value after incr or decr operation
|
94
|
+
|
95
|
+
- Statistics Response
|
96
|
+
[STAT <name> <value>\r\n]+END\r\n
|
97
|
+
|
98
|
+
- Misc Response
|
99
|
+
|
100
|
+
OK\r\n
|
101
|
+
VERSION <version>\r\n
|
102
|
+
|
103
|
+
- Notes:
|
104
|
+
- set always creates mapping irrespective of whether it is present on not.
|
105
|
+
- add, adds only if the mapping is not present
|
106
|
+
- replace, only replaces if the mapping is present
|
107
|
+
- append and prepend command ignore flags and expiry values
|
108
|
+
- noreply instructs the server to not send the reply even if there is an error.
|
109
|
+
- decr of 0 is 0, while incr of UINT64_MAX is 0
|
110
|
+
- maximum length of the key is 250 characters
|
111
|
+
- expiry of 0 means that item never expires, though it could be evicted from the cache
|
112
|
+
- non-zero expiry is either unix time (# seconds since 01/01/1970) or,
|
113
|
+
offset in seconds from the current time (< 60 x 60 x 24 x 30 seconds = 30 days)
|
114
|
+
- expiry time is with respect to the server (not client)
|
115
|
+
- <datalen> can be zero and when it is, the <data> block is empty.
|
116
|
+
|
117
|
+
- Thoughts:
|
118
|
+
- ascii protocol is easier to debug - think using strace or tcpdump to see
|
119
|
+
protocol on the wire, Or using telnet or netcat or socat to build memcache
|
120
|
+
requests and responses
|
121
|
+
http://stackoverflow.com/questions/2525188/are-binary-protocols-dead
|
122
|
+
|
123
|
+
- http://news.ycombinator.com/item?id=1712788
|
@@ -0,0 +1,118 @@
|
|
1
|
+
If you are deploying nutcracker in your production environment, here are a few recommendations that might be worth considering.
|
2
|
+
|
3
|
+
## Log Level
|
4
|
+
|
5
|
+
By default debug logging is disabled in nutcracker. However, it is worthwhile running nutcracker with debug logging enabled and verbosity level set to LOG_INFO (-v 6 or --verbosity=6). This in reality does not add much overhead as you only pay the cost of checking an if condition for every log line encountered during the run time.
|
6
|
+
|
7
|
+
At LOG_INFO level, nutcracker logs the life cycle of every client and server connection and important events like the server being ejected from the hash ring and so on. Eg.
|
8
|
+
|
9
|
+
[Thu Aug 2 00:03:09 2012] nc_proxy.c:336 accepted c 7 on p 6 from '127.0.0.1:54009'
|
10
|
+
[Thu Aug 2 00:03:09 2012] nc_server.c:528 connected on s 8 to server '127.0.0.1:11211:1'
|
11
|
+
[Thu Aug 2 00:03:09 2012] nc_core.c:270 req 1 on s 8 timedout
|
12
|
+
[Thu Aug 2 00:03:09 2012] nc_core.c:207 close s 8 '127.0.0.1:11211' on event 0004 eof 0 done 0 rb 0 sb 20: Connection timed out
|
13
|
+
[Thu Aug 2 00:03:09 2012] nc_server.c:406 close s 8 schedule error for req 1 len 20 type 5 from c 7: Connection timed out
|
14
|
+
[Thu Aug 2 00:03:09 2012] nc_server.c:281 update pool 0 'alpha' to delete server '127.0.0.1:11211:1' for next 2 secs
|
15
|
+
[Thu Aug 2 00:03:10 2012] nc_connection.c:314 recv on sd 7 eof rb 20 sb 35
|
16
|
+
[Thu Aug 2 00:03:10 2012] nc_request.c:334 c 7 is done
|
17
|
+
[Thu Aug 2 00:03:10 2012] nc_core.c:207 close c 7 '127.0.0.1:54009' on event 0001 eof 1 done 1 rb 20 sb 35
|
18
|
+
[Thu Aug 2 00:03:11 2012] nc_proxy.c:336 accepted c 7 on p 6 from '127.0.0.1:54011'
|
19
|
+
[Thu Aug 2 00:03:11 2012] nc_server.c:528 connected on s 8 to server '127.0.0.1:11212:1'
|
20
|
+
[Thu Aug 2 00:03:12 2012] nc_connection.c:314 recv on sd 7 eof rb 20 sb 8
|
21
|
+
[Thu Aug 2 00:03:12 2012] nc_request.c:334 c 7 is done
|
22
|
+
[Thu Aug 2 00:03:12 2012] nc_core.c:207 close c 7 '127.0.0.1:54011' on event 0001 eof 1 done 1 rb 20 sb 8
|
23
|
+
|
24
|
+
To enable debug logging, you have to compile nutcracker with logging enabled using --enable-debug=log configure option.
|
25
|
+
|
26
|
+
## Liveness
|
27
|
+
|
28
|
+
Failures are a fact of life, especially when things are distributed. To be resilient against failures, it is recommended that you configure the following keys for every server pool. Eg:
|
29
|
+
|
30
|
+
resilient_pool:
|
31
|
+
auto_eject_hosts: true
|
32
|
+
server_retry_timeout: 30000
|
33
|
+
server_failure_limit: 3
|
34
|
+
|
35
|
+
Enabling `auto_eject_hosts:` ensures that a dead server can be ejected out of the hash ring after `server_failure_limit:` consecutive failures have been encountered on that said server. A non-zero `server_retry_timeout:` ensures that we don't incorrectly mark a server as dead forever especially when the failures were really transient. The combination of `server_retry_timeout:` and `server_failure_limit:` controls the tradeoff between resiliency to permanent and transient failures.
|
36
|
+
|
37
|
+
To ensure that requests always succeed in the face of server ejections (`auto_eject_hosts:` is enabled), some form of retry must be implemented at the client layer since nutcracker itself does not retry a request. This client-side retry count must be greater than `server_failure_limit:` value, which ensures that the original request has a chance to make it to a live server.
|
38
|
+
|
39
|
+
## Timeout
|
40
|
+
|
41
|
+
It is always a good idea to configure nutcracker `timeout:` for every server pool, rather than purely relying on client-side timeouts. Eg:
|
42
|
+
|
43
|
+
resilient_pool_with_timeout:
|
44
|
+
auto_eject_hosts: true
|
45
|
+
server_retry_timeout: 30000
|
46
|
+
server_failure_limit: 3
|
47
|
+
timeout: 400
|
48
|
+
|
49
|
+
Relying only on client-side timeouts has the adverse effect of the original request having timedout on the client to proxy connection, but still pending and outstanding on the proxy to server connection. This further gets exacerbated when client retries the original request.
|
50
|
+
|
51
|
+
By default, nutcracker waits indefinitely for any request sent to the server. However, when `timeout:` key is configured, a requests for which no response is received from the server in `timeout:` msec is timedout and an error response `SERVER_ERROR Connection timed out\r\n` is sent back to the client.
|
52
|
+
|
53
|
+
## Error Response
|
54
|
+
|
55
|
+
Whenever a request encounters failure on a server we usually send to the client a response with the general form - `SERVER_ERROR <errno description>\r\n` (memcached) or `-ERR <errno description>` (redis).
|
56
|
+
|
57
|
+
For example, when a memcache server is down, this error response is usually:
|
58
|
+
|
59
|
+
+ `SERVER_ERROR Connection refused\r\n` or,
|
60
|
+
+ `SERVER_ERROR Connection reset by peer\r\n`
|
61
|
+
|
62
|
+
When the request timedout, the response is usually:
|
63
|
+
|
64
|
+
+ `SERVER_ERROR Connection timed out\r\n`
|
65
|
+
|
66
|
+
Seeing a `SERVER_ERROR` or `-ERR` response should be considered as a transient failure by a client which makes the original request an ideal candidate for a retry.
|
67
|
+
|
68
|
+
## read, writev and mbuf
|
69
|
+
|
70
|
+
All memory for incoming requests and outgoing responses is allocated in mbuf. Mbuf enables zero copy for requests and responses flowing through the proxy. By default an mbuf is 16K bytes in size and this value can be tuned between 512 and 65K bytes using -m or --mbuf-size=N argument. Every connection has at least one mbuf allocated to it. This means that the number of concurrent connections nutcracker can support is dependent on the mbuf size. A small mbuf allows us to handle more connections, while a large mbuf allows us to read and write more data to and from kernel socket buffers.
|
71
|
+
|
72
|
+
If nutcracker is meant to handle a large number of concurrent client connections, you should set the mbuf size to 512 or 1K bytes.
|
73
|
+
|
74
|
+
## Maximum Key Length
|
75
|
+
The memcache ascii protocol [specification](https://github.com/twitter/twemproxy/blob/master/notes/memcache.txt) limits the maximum length of the key to 250 characters. The key should not include whitespace, or '\r' or '\n' character. For redis, we have no such limitation. However, nutcracker requires the key to be stored in a contiguous memory region. Since all requests and responses in nutcracker are stored in mbuf, the maximum length of the redis key is limited by the size of the maximum available space for data in mbuf (mbuf_data_size()). This means that if you want your redis instances to handle large keys, you might want to choose large mbuf size set using -m or --mbuf-size=N command-line argument.
|
76
|
+
|
77
|
+
## Node Names for Consistent Hashing
|
78
|
+
|
79
|
+
The server cluster in twemproxy can either be specified as list strings in format 'host:port:weight' or 'host:port:weight name'.
|
80
|
+
|
81
|
+
servers:
|
82
|
+
- 127.0.0.1:6379:1
|
83
|
+
- 127.0.0.1:6380:1
|
84
|
+
- 127.0.0.1:6381:1
|
85
|
+
- 127.0.0.1:6382:1
|
86
|
+
|
87
|
+
Or,
|
88
|
+
|
89
|
+
servers:
|
90
|
+
- 127.0.0.1:6379:1 server1
|
91
|
+
- 127.0.0.1:6380:1 server2
|
92
|
+
- 127.0.0.1:6381:1 server3
|
93
|
+
- 127.0.0.1:6382:1 server4
|
94
|
+
|
95
|
+
|
96
|
+
In the former configuration, keys are mapped **directly** to **'host:port:weight'** triplet and in the latter they are mapped to **node names** which are then mapped to nodes i.e. host:port pair. The latter configuration gives us the freedom to relocate nodes to a different server without disturbing the hash ring and hence makes this configuration ideal when auto_eject_hosts is set to false. See [issue 25](https://github.com/twitter/twemproxy/issues/25) for details.
|
97
|
+
|
98
|
+
Note that when using node names for consistent hashing, twemproxy ignores the weight value in the 'host:port:weight name' format string.
|
99
|
+
|
100
|
+
## Hash Tags
|
101
|
+
|
102
|
+
[Hash Tags](http://antirez.com/post/redis-presharding.html) enables you to use part of the key for calculating the hash. When the hash tag is present, we use part of the key within the tag as the key to be used for consistent hashing. Otherwise, we use the full key as is. Hash tags enable you to map different keys to the same server as long as the part of the key within the tag is the same.
|
103
|
+
|
104
|
+
For example, the configuration of server pool _beta_, aslo shown below, specifies a two character hash_tag string - "{}". This means that keys "user:{user1}:ids" and "user:{user1}:tweets" map to the same server because we compute the hash on "user1". For a key like "user:user1:ids", we use the entire string "user:user1:ids" to compute the hash and it may map to a different server.
|
105
|
+
|
106
|
+
beta:
|
107
|
+
listen: 127.0.0.1:22122
|
108
|
+
hash: fnv1a_64
|
109
|
+
hash_tag: "{}"
|
110
|
+
distribution: ketama
|
111
|
+
auto_eject_hosts: false
|
112
|
+
timeout: 400
|
113
|
+
redis: true
|
114
|
+
servers:
|
115
|
+
- 127.0.0.1:6380:1 server1
|
116
|
+
- 127.0.0.1:6381:1 server2
|
117
|
+
- 127.0.0.1:6382:1 server3
|
118
|
+
- 127.0.0.1:6383:1 server4
|
@@ -0,0 +1,415 @@
|
|
1
|
+
## Redis Commands Supported
|
2
|
+
|
3
|
+
### Keys Command
|
4
|
+
|
5
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
6
|
+
| Command | Supported? | Format |
|
7
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
8
|
+
| DEL | Yes | DEL key [key …] |
|
9
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
10
|
+
| DUMP | No | DUMP key |
|
11
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
12
|
+
| EXISTS | Yes | EXISTS key |
|
13
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
14
|
+
| EXPIRE | Yes | EXPIRE key seconds |
|
15
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
16
|
+
| EXPIREAT | Yes | EXPIREAT key timestamp |
|
17
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
18
|
+
| KEYS | No | KEYS pattern |
|
19
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
20
|
+
| MIGRATE | No | MIGRATE host port key destination-db timeout |
|
21
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
22
|
+
| MOVE | No | MOVE key db |
|
23
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
24
|
+
| OBJECT | No | OBJECT subcommand [arguments [arguments …]] |
|
25
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
26
|
+
| PERSIST | Yes | PERSIST key |
|
27
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
28
|
+
| PEXPIRE | Yes | PEXPIRE key milliseconds |
|
29
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
30
|
+
| PEXPIREAT | Yes | PEXPIREAT key milliseconds-timestamp |
|
31
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
32
|
+
| PTTL | Yes | PTTL key |
|
33
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
34
|
+
| RANDOMKEY | No | RANDOMKEY |
|
35
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
36
|
+
| RENAME | No | RENAME key newkey |
|
37
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
38
|
+
| RENAMENX | No | RENAMENX key newkey |
|
39
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
40
|
+
| RESTORE | No | RESTORE key ttl serialized-value |
|
41
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
42
|
+
| SORT | No | SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination] |
|
43
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
44
|
+
| TTL | Yes | TTL key |
|
45
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
46
|
+
| TYPE | Yes | TYPE key |
|
47
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
48
|
+
|
49
|
+
### Strings Command
|
50
|
+
|
51
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
52
|
+
| Command | Supported? | Format |
|
53
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
54
|
+
| APPEND | Yes | APPEND key value |
|
55
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
56
|
+
| BITCOUNT | Yes | BITCOUNT key [start] [end] |
|
57
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
58
|
+
| BITOP | No | BITOP operation destkey key [key ...] |
|
59
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
60
|
+
| DECR | Yes | DECR key |
|
61
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
62
|
+
| DECRBY | Yes | DECRBY key decrement |
|
63
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
64
|
+
| GET | Yes | GET key |
|
65
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
66
|
+
| GETBIT | Yes | GETBIT key offset |
|
67
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
68
|
+
| GETRANGE | Yes | GETRANGE key start end |
|
69
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
70
|
+
| GETSET | Yes | GETSET key value |
|
71
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
72
|
+
| INCR | Yes | INCR key |
|
73
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
74
|
+
| INCRBY | Yes | INCRBY key increment |
|
75
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
76
|
+
| INCRBYFLOAT | Yes | INCRBYFLOAT key increment |
|
77
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
78
|
+
| MGET | Yes | MGET key [key ...] |
|
79
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
80
|
+
| MSET | No | MSET key value [key value ...] |
|
81
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
82
|
+
| MSETNX | No | MSETNX key value [key value ...] |
|
83
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
84
|
+
| PSETEX | Yes | PSETEX key milliseconds value |
|
85
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
86
|
+
| SET | Yes | SET key value |
|
87
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
88
|
+
| SETBIT | Yes | SETBIT key offset value |
|
89
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
90
|
+
| SETEX | Yes | SETEX key seconds value |
|
91
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
92
|
+
| SETNX | Yes | SETNX key value |
|
93
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
94
|
+
| SETRANGE | Yes | SETRANGE key offset value |
|
95
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
96
|
+
| STRLEN | Yes | STRLEN key |
|
97
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
98
|
+
|
99
|
+
### Hashes
|
100
|
+
|
101
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
102
|
+
| Command | Supported? | Format |
|
103
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
104
|
+
| HDEL | Yes | HDEL key field [field ...] |
|
105
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
106
|
+
| HEXISTS | Yes | HEXISTS key field |
|
107
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
108
|
+
| HGET | Yes | HGET key field |
|
109
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
110
|
+
| HGETALL | Yes | HGETALL key |
|
111
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
112
|
+
| HINCRBY | Yes | HINCRBY key field increment |
|
113
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
114
|
+
| HINCRBYFLOAT | Yes | HINCRBYFLOAT key field increment |
|
115
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
116
|
+
| HKEYS | Yes | HKEYS key |
|
117
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
118
|
+
| HLEN | Yes | HLEN key |
|
119
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
120
|
+
| HMGET | Yes | HMGET key field [field ...] |
|
121
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
122
|
+
| HMSET | Yes | HMSET key field value [field value ...] |
|
123
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
124
|
+
| HSET | Yes | HSET key field value |
|
125
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
126
|
+
| HSETNX | Yes | HSETNX key field value |
|
127
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
128
|
+
| HVALS | Yes | HVALS key |
|
129
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
130
|
+
|
131
|
+
### Lists
|
132
|
+
|
133
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
134
|
+
| Command | Supported? | Format |
|
135
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
136
|
+
| BLPOP | No | BLPOP key [key ...] timeout |
|
137
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
138
|
+
| BRPOP | No | BRPOP key [key ...] timeout |
|
139
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
140
|
+
| BRPOPLPUSH | No | BRPOPLPUSH source destination timeout |
|
141
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
142
|
+
| LINDEX | Yes | LINDEX key index |
|
143
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
144
|
+
| LINSERT | Yes | LINSERT key BEFORE|AFTER pivot value |
|
145
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
146
|
+
| LLEN | Yes | LLEN key |
|
147
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
148
|
+
| LPOP | Yes | LPOP key |
|
149
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
150
|
+
| LPUSH | Yes | LPUSH key value [value ...] |
|
151
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
152
|
+
| LPUSHX | Yes | LPUSHX key value |
|
153
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
154
|
+
| LRANGE | Yes | LRANGE key start stop |
|
155
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
156
|
+
| LREM | Yes | LREM key count value |
|
157
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
158
|
+
| LSET | Yes | LSET key index value |
|
159
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
160
|
+
| LTRIM | Yes | LTRIM key start stop |
|
161
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
162
|
+
| RPOP | Yes | RPOP key |
|
163
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
164
|
+
| RPOPLPUSH | Yes* | RPOPLPUSH source destination |
|
165
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
166
|
+
| RPUSH | Yes | RPUSH key value [value ...] |
|
167
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
168
|
+
| RPUSHX | Yes | RPUSHX key value |
|
169
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
170
|
+
|
171
|
+
* RPOPLPUSH support requires that source and destination keys hash to the same server. You can ensure this by using the same [hashtag](https://github.com/twitter/twemproxy/blob/master/notes/recommendation.md#hash-tags) for source and destination key. Twemproxy does no checking on its end to verify that source and destination key hash to the same server, and the RPOPLPUSH command is forwarded to the server that the source key hashes to
|
172
|
+
|
173
|
+
### Sets
|
174
|
+
|
175
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
176
|
+
| Command | Supported? | Format |
|
177
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
178
|
+
| SADD | Yes | SADD key member [member ...] |
|
179
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
180
|
+
| SCARD | Yes | SCARD key |
|
181
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
182
|
+
| SDIFF | Yes* | SDIFF key [key ...] |
|
183
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
184
|
+
| SDIFFSTORE | Yes* | SDIFFSTORE destination key [key ...] |
|
185
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
186
|
+
| SINTER | Yes* | SINTER key [key ...] |
|
187
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
188
|
+
| SINTERSTORE | Yes* | SINTERSTORE destination key [key ...] |
|
189
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
190
|
+
| SISMEMBER | Yes | SISMEMBER key member |
|
191
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
192
|
+
| SMEMBERS | Yes | SMEMBERS key |
|
193
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
194
|
+
| SMOVE | Yes* | SMOVE source destination member |
|
195
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
196
|
+
| SPOP | Yes | SPOP key |
|
197
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
198
|
+
| SRANDMEMBER | Yes | SRANDMEMBER key |
|
199
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
200
|
+
| SREM | Yes | SREM key member [member ...] |
|
201
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
202
|
+
| SUNION | Yes* | SUNION key [key ...] |
|
203
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
204
|
+
| SUNIONSTORE | Yes* | SUNIONSTORE destination key [key ...] |
|
205
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
206
|
+
|
207
|
+
* SIDFF, SDIFFSTORE, SINTER, SINTERSTORE, SMOVE, SUNION and SUNIONSTORE support requires that the supplied keys hash to the same server. You can ensure this by using the same [hashtag](https://github.com/twitter/twemproxy/blob/master/notes/recommendation.md#hash-tags) for all keys in the command. Twemproxy does no checking on its end to verify that all the keys hash to the same server, and the given command is forwarded to the server that the first key hashes to.
|
208
|
+
|
209
|
+
|
210
|
+
### Sorted Sets
|
211
|
+
|
212
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
213
|
+
| Command | Supported? | Format |
|
214
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
215
|
+
| ZADD | Yes | ZADD key score member [score] [member] |
|
216
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
217
|
+
| ZCARD | Yes | ZCARD key |
|
218
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
219
|
+
| ZCOUNT | Yes | ZCOUNT key min max |
|
220
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
221
|
+
| ZINCRBY | Yes | ZINCRBY key increment member |
|
222
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
223
|
+
| ZINTERSTORE | Yes* | ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] |
|
224
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
225
|
+
| ZRANGE | Yes | ZRANGE key start stop [WITHSCORES] |
|
226
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
227
|
+
| ZRANGEBYSCORE | Yes | ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] |
|
228
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
229
|
+
| ZRANK | Yes | ZRANK key member |
|
230
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
231
|
+
| ZREM | Yes | ZREM key member [member ...] |
|
232
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
233
|
+
| ZREMRANGEBYRANK | Yes | ZREMRANGEBYRANK key start stop |
|
234
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
235
|
+
| ZREMRANGEBYSCORE | Yes | ZREMRANGEBYSCORE key min max |
|
236
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
237
|
+
| ZREVRANGE | Yes | ZREVRANGE key start stop [WITHSCORES] |
|
238
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
239
|
+
| ZREVRANGEBYSCORE | Yes | ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] |
|
240
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
241
|
+
| ZREVRANK | Yes | ZREVRANK key member |
|
242
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
243
|
+
| ZSCORE | Yes | ZSCORE key member |
|
244
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
245
|
+
| ZUNIONSTORE | Yes* | ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] |
|
246
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
247
|
+
|
248
|
+
* ZINTERSTORE and ZUNIONSTORE support requires that the supplied keys hash to the same server. You can ensure this by using the same [hashtag](https://github.com/twitter/twemproxy/blob/master/notes/recommendation.md#hash-tags) for all keys in the command. Twemproxy does no checking on its end to verify that all the keys hash to the same server, and the given command is forwarded to the server that the first key hashes to.
|
249
|
+
|
250
|
+
|
251
|
+
### Pub/Sub
|
252
|
+
|
253
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
254
|
+
| Command | Supported? | Format |
|
255
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
256
|
+
| PSUBSCRIBE | No | PSUBSCRIBE pattern [pattern ...] |
|
257
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
258
|
+
| PUBLISH | No | PUBLISH channel message |
|
259
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
260
|
+
| PUNSUBSCRIBE | No | PUNSUBSCRIBE [pattern [pattern ...]] |
|
261
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
262
|
+
| SUBSCRIBE | No | SUBSCRIBE channel [channel ...] |
|
263
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
264
|
+
| UNSUBSCRIBE | No | UNSUBSCRIBE [channel [channel ...]] |
|
265
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
266
|
+
|
267
|
+
### Transactions
|
268
|
+
|
269
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
270
|
+
| Command | Supported? | Format |
|
271
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
272
|
+
| DISCARD | No | DISCARD |
|
273
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
274
|
+
| EXEC | No | EXEC |
|
275
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
276
|
+
| MULTI | No | MULTI |
|
277
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
278
|
+
| UNWATCH | No | UNWATCH |
|
279
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
280
|
+
| WATCH | No | WATCH key [key ...] |
|
281
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
282
|
+
|
283
|
+
### Scripting
|
284
|
+
|
285
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
286
|
+
| Command | Supported? | Format |
|
287
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
288
|
+
| EVAL | Yes* | EVAL script numkeys key [key ...] arg [arg ...] |
|
289
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
290
|
+
| EVALSHA | Yes* | EVALSHA sha1 numkeys key [key ...] arg [arg ...] |
|
291
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
292
|
+
| SCRIPT EXISTS | No | SCRIPT EXISTS script [script ...] |
|
293
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
294
|
+
| SCRIPT FLUSH | No | SCRIPT FLUSH |
|
295
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
296
|
+
| SCRIPT KILL | No | SCRIPT KILL |
|
297
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
298
|
+
| SCRIPT LOAD | No | SCRIPT LOAD script |
|
299
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
300
|
+
|
301
|
+
* EVAL and EVALSHA support is limited to scripts that take at least 1 key. If multiple keys are used, all keys must hash to the same server. You can ensure this by using the same [hashtag](https://github.com/twitter/twemproxy/blob/master/notes/recommendation.md#hash-tags) for all keys. If you use more than 1 key, the proxy does no checking to verify that all keys hash to the same server, and the entire command is forwarded to the server that the first key hashes to
|
302
|
+
|
303
|
+
### Connection
|
304
|
+
|
305
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
306
|
+
| Command | Supported? | Format |
|
307
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
308
|
+
| AUTH | No | AUTH password |
|
309
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
310
|
+
| ECHO | No | ECHO message |
|
311
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
312
|
+
| PING | No | PING |
|
313
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
314
|
+
| QUIT | No | QUIT |
|
315
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
316
|
+
| SELECT | No | SELECT index |
|
317
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
318
|
+
|
319
|
+
### Server
|
320
|
+
|
321
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
322
|
+
| Command | Supported? | Format |
|
323
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
324
|
+
| BGREWRITEAOF | No | BGREWRITEAOF |
|
325
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
326
|
+
| BGSAVE | No | BGSAVE |
|
327
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
328
|
+
| CLIENT KILL | No | CLIENT KILL ip:port |
|
329
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
330
|
+
| CLIENT LIST | No | CLIENT LIST |
|
331
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
332
|
+
| CONFIG GET | No | CONFIG GET parameter |
|
333
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
334
|
+
| CONFIG SET | No | CONFIG SET parameter value |
|
335
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
336
|
+
| CONFIG RESETSTAT | No | CONFIG RESETSTAT |
|
337
|
+
+-------------------+-------------+--------------------------------------------------------------------------------------------------------------------+
|
338
|
+
| DBSIZE | No | DBSIZE |
|
339
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
340
|
+
| DEBUG OBJECT | No | DEBUG OBJECT key |
|
341
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
342
|
+
| DEBUG SEGFAULT | No | DEBUG SEGFAULT |
|
343
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
344
|
+
| FLUSHALL | No | FLUSHALL |
|
345
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
346
|
+
| FLUSHDB | No | FLUSHDB |
|
347
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
348
|
+
| INFO | No | INFO |
|
349
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
350
|
+
| LASTSAVE | No | LASTSAVE |
|
351
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
352
|
+
| MONITOR | No | MONITOR |
|
353
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
354
|
+
| SAVE | No | SAVE |
|
355
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
356
|
+
| SHUTDOWN | No | SHUTDOWN [NOSAVE] [SAVE] |
|
357
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
358
|
+
| SLAVEOF | No | SLAVEOF host port |
|
359
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
360
|
+
| SLOWLOG | No | SLOWLOG subcommand [argument] |
|
361
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
362
|
+
| SYNC | No | SYNC |
|
363
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
364
|
+
| TIME | No | TIME |
|
365
|
+
+-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
|
366
|
+
|
367
|
+
## Note
|
368
|
+
|
369
|
+
- redis commands are not case sensitive
|
370
|
+
- only vectored commands 'MGET key [key ...]' and 'DEL key [key ...]' needs to be fragmented
|
371
|
+
|
372
|
+
## Performance
|
373
|
+
|
374
|
+
### Setup
|
375
|
+
|
376
|
+
+ redis-server running on machine A.
|
377
|
+
+ nutcracker running on machine A as a local proxy to redis-server.
|
378
|
+
+ redis-benchmark running on machine B.
|
379
|
+
+ machine A != machine B.
|
380
|
+
+ nutcracker built with --enable-debug=no
|
381
|
+
+ nutcracker running with mbuf-size of 512 (-m 512)
|
382
|
+
+ redis-server built from redis 2.6 branch
|
383
|
+
|
384
|
+
### redis-benchmark against redis-server
|
385
|
+
|
386
|
+
$ redis-benchmark -h <machine-A> -q -t set,get,incr,lpush,lpop,sadd,spop,lpush,lrange -c 100 -p 6379
|
387
|
+
SET: 89285.71 requests per second
|
388
|
+
GET: 92592.59 requests per second
|
389
|
+
INCR: 89285.71 requests per second
|
390
|
+
LPUSH: 90090.09 requests per second
|
391
|
+
LPOP: 90090.09 requests per second
|
392
|
+
SADD: 90090.09 requests per second
|
393
|
+
SPOP: 93457.95 requests per second
|
394
|
+
LPUSH (needed to benchmark LRANGE): 89285.71 requests per second
|
395
|
+
LRANGE_100 (first 100 elements): 36496.35 requests per second
|
396
|
+
LRANGE_300 (first 300 elements): 15748.03 requests per second
|
397
|
+
LRANGE_500 (first 450 elements): 11135.86 requests per second
|
398
|
+
LRANGE_600 (first 600 elements): 8650.52 requests per second
|
399
|
+
|
400
|
+
### redis-benchmark against nutcracker proxing redis-server
|
401
|
+
|
402
|
+
$ redis-benchmark -h <machine-A> -q -t set,get,incr,lpush,lpop,sadd,spop,lpush,lrange -c 100 -p 22121
|
403
|
+
SET: 85470.09 requests per second
|
404
|
+
GET: 86956.52 requests per second
|
405
|
+
INCR: 85470.09 requests per second
|
406
|
+
LPUSH: 84745.77 requests per second
|
407
|
+
LPOP: 86206.90 requests per second
|
408
|
+
SADD: 84745.77 requests per second
|
409
|
+
SPOP: 86956.52 requests per second
|
410
|
+
LPUSH (needed to benchmark LRANGE): 84745.77 requests per second
|
411
|
+
LRANGE_100 (first 100 elements): 29761.90 requests per second
|
412
|
+
LRANGE_300 (first 300 elements): 12376.24 requests per second
|
413
|
+
LRANGE_500 (first 450 elements): 8605.85 requests per second
|
414
|
+
LRANGE_600 (first 600 elements): 6587.62 requests per second
|
415
|
+
|