nutcracker 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. data/README.md +22 -0
  2. data/Rakefile +55 -0
  3. data/bin/nutcracker +2 -0
  4. data/ext/nutcracker/ChangeLog +66 -0
  5. data/ext/nutcracker/LICENSE +177 -0
  6. data/ext/nutcracker/Makefile.am +7 -0
  7. data/ext/nutcracker/Makefile.in +726 -0
  8. data/ext/nutcracker/NOTICE +124 -0
  9. data/ext/nutcracker/README.md +240 -0
  10. data/ext/nutcracker/aclocal.m4 +956 -0
  11. data/ext/nutcracker/conf/nutcracker.leaf.yml +10 -0
  12. data/ext/nutcracker/conf/nutcracker.root.yml +8 -0
  13. data/ext/nutcracker/conf/nutcracker.yml +67 -0
  14. data/ext/nutcracker/config.h.in +316 -0
  15. data/ext/nutcracker/config/config.guess +1561 -0
  16. data/ext/nutcracker/config/config.sub +1686 -0
  17. data/ext/nutcracker/config/depcomp +630 -0
  18. data/ext/nutcracker/config/install-sh +520 -0
  19. data/ext/nutcracker/config/ltmain.sh +8413 -0
  20. data/ext/nutcracker/config/missing +376 -0
  21. data/ext/nutcracker/configure +18862 -0
  22. data/ext/nutcracker/configure.ac +155 -0
  23. data/ext/nutcracker/contrib/Makefile.am +3 -0
  24. data/ext/nutcracker/contrib/Makefile.in +560 -0
  25. data/ext/nutcracker/contrib/yaml-0.1.4.tar.gz +0 -0
  26. data/ext/nutcracker/contrib/yaml-0.1.4/LICENSE +19 -0
  27. data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.am +20 -0
  28. data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.in +736 -0
  29. data/ext/nutcracker/contrib/yaml-0.1.4/README +27 -0
  30. data/ext/nutcracker/contrib/yaml-0.1.4/aclocal.m4 +956 -0
  31. data/ext/nutcracker/contrib/yaml-0.1.4/config.h.in +80 -0
  32. data/ext/nutcracker/contrib/yaml-0.1.4/config/config.guess +1561 -0
  33. data/ext/nutcracker/contrib/yaml-0.1.4/config/config.sub +1686 -0
  34. data/ext/nutcracker/contrib/yaml-0.1.4/config/depcomp +630 -0
  35. data/ext/nutcracker/contrib/yaml-0.1.4/config/install-sh +520 -0
  36. data/ext/nutcracker/contrib/yaml-0.1.4/config/ltmain.sh +8406 -0
  37. data/ext/nutcracker/contrib/yaml-0.1.4/config/missing +376 -0
  38. data/ext/nutcracker/contrib/yaml-0.1.4/configure +13085 -0
  39. data/ext/nutcracker/contrib/yaml-0.1.4/configure.ac +75 -0
  40. data/ext/nutcracker/contrib/yaml-0.1.4/doc/doxygen.cfg +222 -0
  41. data/ext/nutcracker/contrib/yaml-0.1.4/include/yaml.h +1971 -0
  42. data/ext/nutcracker/contrib/yaml-0.1.4/m4/libtool.m4 +7357 -0
  43. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltoptions.m4 +368 -0
  44. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltsugar.m4 +123 -0
  45. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltversion.m4 +23 -0
  46. data/ext/nutcracker/contrib/yaml-0.1.4/m4/lt~obsolete.m4 +92 -0
  47. data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.am +4 -0
  48. data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.in +484 -0
  49. data/ext/nutcracker/contrib/yaml-0.1.4/src/api.c +1392 -0
  50. data/ext/nutcracker/contrib/yaml-0.1.4/src/dumper.c +394 -0
  51. data/ext/nutcracker/contrib/yaml-0.1.4/src/emitter.c +2329 -0
  52. data/ext/nutcracker/contrib/yaml-0.1.4/src/loader.c +432 -0
  53. data/ext/nutcracker/contrib/yaml-0.1.4/src/parser.c +1374 -0
  54. data/ext/nutcracker/contrib/yaml-0.1.4/src/reader.c +465 -0
  55. data/ext/nutcracker/contrib/yaml-0.1.4/src/scanner.c +3570 -0
  56. data/ext/nutcracker/contrib/yaml-0.1.4/src/writer.c +141 -0
  57. data/ext/nutcracker/contrib/yaml-0.1.4/src/yaml_private.h +640 -0
  58. data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.am +8 -0
  59. data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.in +675 -0
  60. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor-alt.c +800 -0
  61. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor.c +1130 -0
  62. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter-alt.c +217 -0
  63. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter.c +202 -0
  64. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-dumper.c +311 -0
  65. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-emitter.c +327 -0
  66. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-loader.c +63 -0
  67. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-parser.c +63 -0
  68. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-scanner.c +63 -0
  69. data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-reader.c +354 -0
  70. data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-version.c +29 -0
  71. data/ext/nutcracker/extconf.rb +5 -0
  72. data/ext/nutcracker/m4/libtool.m4 +7376 -0
  73. data/ext/nutcracker/m4/ltoptions.m4 +368 -0
  74. data/ext/nutcracker/m4/ltsugar.m4 +123 -0
  75. data/ext/nutcracker/m4/ltversion.m4 +23 -0
  76. data/ext/nutcracker/m4/lt~obsolete.m4 +92 -0
  77. data/ext/nutcracker/notes/c-styleguide.txt +425 -0
  78. data/ext/nutcracker/notes/debug.txt +96 -0
  79. data/ext/nutcracker/notes/memcache.txt +123 -0
  80. data/ext/nutcracker/notes/recommendation.md +118 -0
  81. data/ext/nutcracker/notes/redis.md +415 -0
  82. data/ext/nutcracker/notes/socket.txt +131 -0
  83. data/ext/nutcracker/scripts/multi_get.sh +26 -0
  84. data/ext/nutcracker/scripts/nutcracker.init +73 -0
  85. data/ext/nutcracker/scripts/nutcracker.spec +52 -0
  86. data/ext/nutcracker/scripts/pipelined_read.sh +23 -0
  87. data/ext/nutcracker/scripts/pipelined_write.sh +29 -0
  88. data/ext/nutcracker/scripts/populate_memcached.sh +24 -0
  89. data/ext/nutcracker/scripts/redis-check.py +23 -0
  90. data/ext/nutcracker/scripts/redis-check.sh +564 -0
  91. data/ext/nutcracker/src/Makefile.am +46 -0
  92. data/ext/nutcracker/src/Makefile.in +726 -0
  93. data/ext/nutcracker/src/hashkit/Makefile.am +22 -0
  94. data/ext/nutcracker/src/hashkit/Makefile.in +501 -0
  95. data/ext/nutcracker/src/hashkit/nc_crc32.c +105 -0
  96. data/ext/nutcracker/src/hashkit/nc_fnv.c +82 -0
  97. data/ext/nutcracker/src/hashkit/nc_hashkit.h +74 -0
  98. data/ext/nutcracker/src/hashkit/nc_hsieh.c +93 -0
  99. data/ext/nutcracker/src/hashkit/nc_jenkins.c +230 -0
  100. data/ext/nutcracker/src/hashkit/nc_ketama.c +240 -0
  101. data/ext/nutcracker/src/hashkit/nc_md5.c +379 -0
  102. data/ext/nutcracker/src/hashkit/nc_modula.c +144 -0
  103. data/ext/nutcracker/src/hashkit/nc_murmur.c +99 -0
  104. data/ext/nutcracker/src/hashkit/nc_one_at_a_time.c +51 -0
  105. data/ext/nutcracker/src/hashkit/nc_random.c +146 -0
  106. data/ext/nutcracker/src/nc.c +573 -0
  107. data/ext/nutcracker/src/nc_array.c +204 -0
  108. data/ext/nutcracker/src/nc_array.h +73 -0
  109. data/ext/nutcracker/src/nc_client.c +189 -0
  110. data/ext/nutcracker/src/nc_client.h +28 -0
  111. data/ext/nutcracker/src/nc_conf.c +1766 -0
  112. data/ext/nutcracker/src/nc_conf.h +134 -0
  113. data/ext/nutcracker/src/nc_connection.c +392 -0
  114. data/ext/nutcracker/src/nc_connection.h +99 -0
  115. data/ext/nutcracker/src/nc_core.c +334 -0
  116. data/ext/nutcracker/src/nc_core.h +131 -0
  117. data/ext/nutcracker/src/nc_event.c +214 -0
  118. data/ext/nutcracker/src/nc_event.h +39 -0
  119. data/ext/nutcracker/src/nc_log.c +254 -0
  120. data/ext/nutcracker/src/nc_log.h +120 -0
  121. data/ext/nutcracker/src/nc_mbuf.c +285 -0
  122. data/ext/nutcracker/src/nc_mbuf.h +67 -0
  123. data/ext/nutcracker/src/nc_message.c +828 -0
  124. data/ext/nutcracker/src/nc_message.h +253 -0
  125. data/ext/nutcracker/src/nc_proxy.c +359 -0
  126. data/ext/nutcracker/src/nc_proxy.h +34 -0
  127. data/ext/nutcracker/src/nc_queue.h +788 -0
  128. data/ext/nutcracker/src/nc_rbtree.c +348 -0
  129. data/ext/nutcracker/src/nc_rbtree.h +47 -0
  130. data/ext/nutcracker/src/nc_request.c +588 -0
  131. data/ext/nutcracker/src/nc_response.c +332 -0
  132. data/ext/nutcracker/src/nc_server.c +841 -0
  133. data/ext/nutcracker/src/nc_server.h +143 -0
  134. data/ext/nutcracker/src/nc_signal.c +131 -0
  135. data/ext/nutcracker/src/nc_signal.h +34 -0
  136. data/ext/nutcracker/src/nc_stats.c +1188 -0
  137. data/ext/nutcracker/src/nc_stats.h +206 -0
  138. data/ext/nutcracker/src/nc_string.c +109 -0
  139. data/ext/nutcracker/src/nc_string.h +112 -0
  140. data/ext/nutcracker/src/nc_util.c +619 -0
  141. data/ext/nutcracker/src/nc_util.h +214 -0
  142. data/ext/nutcracker/src/proto/Makefile.am +14 -0
  143. data/ext/nutcracker/src/proto/Makefile.in +482 -0
  144. data/ext/nutcracker/src/proto/nc_memcache.c +1306 -0
  145. data/ext/nutcracker/src/proto/nc_proto.h +155 -0
  146. data/ext/nutcracker/src/proto/nc_redis.c +2102 -0
  147. data/lib/nutcracker.rb +7 -0
  148. data/lib/nutcracker/version.rb +3 -0
  149. 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
+