nutcracker 0.2.4.1 → 0.2.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/README.md +28 -10
  2. data/Rakefile +5 -19
  3. data/bin/nutcracker +6 -1
  4. data/ext/nutcracker/ChangeLog +9 -0
  5. data/ext/nutcracker/Makefile.in +54 -29
  6. data/ext/nutcracker/README.md +13 -11
  7. data/ext/nutcracker/aclocal.m4 +46 -26
  8. data/ext/nutcracker/config/config.guess +209 -240
  9. data/ext/nutcracker/config/config.sub +157 -70
  10. data/ext/nutcracker/config/depcomp +66 -8
  11. data/ext/nutcracker/config/install-sh +18 -11
  12. data/ext/nutcracker/config/ltmain.sh +2632 -1384
  13. data/ext/nutcracker/config/missing +4 -49
  14. data/ext/nutcracker/configure +2866 -2118
  15. data/ext/nutcracker/configure.ac +1 -1
  16. data/ext/nutcracker/contrib/Makefile.in +17 -10
  17. data/ext/nutcracker/m4/libtool.m4 +1437 -812
  18. data/ext/nutcracker/m4/ltoptions.m4 +24 -8
  19. data/ext/nutcracker/m4/ltversion.m4 +6 -6
  20. data/ext/nutcracker/m4/lt~obsolete.m4 +9 -3
  21. data/ext/nutcracker/notes/recommendation.md +21 -2
  22. data/ext/nutcracker/notes/redis.md +9 -9
  23. data/ext/nutcracker/scripts/redis-check.sh +9 -0
  24. data/ext/nutcracker/src/Makefile.in +18 -11
  25. data/ext/nutcracker/src/hashkit/Makefile.am +1 -0
  26. data/ext/nutcracker/src/hashkit/Makefile.in +23 -13
  27. data/ext/nutcracker/src/hashkit/nc_crc16.c +66 -0
  28. data/ext/nutcracker/src/hashkit/nc_hashkit.h +2 -0
  29. data/ext/nutcracker/src/hashkit/nc_modula.c +18 -6
  30. data/ext/nutcracker/src/nc_conf.c +14 -35
  31. data/ext/nutcracker/src/nc_conf.h +1 -1
  32. data/ext/nutcracker/src/nc_message.h +2 -0
  33. data/ext/nutcracker/src/nc_server.c +9 -7
  34. data/ext/nutcracker/src/proto/Makefile.in +16 -9
  35. data/ext/nutcracker/src/proto/nc_redis.c +17 -4
  36. data/lib/nutcracker/version.rb +1 -1
  37. data/lib/nutcracker.rb +60 -2
  38. metadata +3 -2
@@ -1,13 +1,14 @@
1
1
  # Helper functions for option handling. -*- Autoconf -*-
2
2
  #
3
- # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
3
+ # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
4
+ # Inc.
4
5
  # Written by Gary V. Vaughan, 2004
5
6
  #
6
7
  # This file is free software; the Free Software Foundation gives
7
8
  # unlimited permission to copy and/or distribute it, with or without
8
9
  # modifications, as long as this notice is preserved.
9
10
 
10
- # serial 6 ltoptions.m4
11
+ # serial 7 ltoptions.m4
11
12
 
12
13
  # This is to help aclocal find these macros, as it can't see m4_define.
13
14
  AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
@@ -125,7 +126,7 @@ LT_OPTION_DEFINE([LT_INIT], [win32-dll],
125
126
  [enable_win32_dll=yes
126
127
 
127
128
  case $host in
128
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
129
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
129
130
  AC_CHECK_TOOL(AS, as, false)
130
131
  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
131
132
  AC_CHECK_TOOL(OBJDUMP, objdump, false)
@@ -133,13 +134,13 @@ case $host in
133
134
  esac
134
135
 
135
136
  test -z "$AS" && AS=as
136
- _LT_DECL([], [AS], [0], [Assembler program])dnl
137
+ _LT_DECL([], [AS], [1], [Assembler program])dnl
137
138
 
138
139
  test -z "$DLLTOOL" && DLLTOOL=dlltool
139
- _LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl
140
+ _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
140
141
 
141
142
  test -z "$OBJDUMP" && OBJDUMP=objdump
142
- _LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl
143
+ _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
143
144
  ])# win32-dll
144
145
 
145
146
  AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
@@ -325,9 +326,24 @@ dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
325
326
  # MODE is either `yes' or `no'. If omitted, it defaults to `both'.
326
327
  m4_define([_LT_WITH_PIC],
327
328
  [AC_ARG_WITH([pic],
328
- [AS_HELP_STRING([--with-pic],
329
+ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
329
330
  [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
330
- [pic_mode="$withval"],
331
+ [lt_p=${PACKAGE-default}
332
+ case $withval in
333
+ yes|no) pic_mode=$withval ;;
334
+ *)
335
+ pic_mode=default
336
+ # Look at the argument we got. We use all the common list separators.
337
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
338
+ for lt_pkg in $withval; do
339
+ IFS="$lt_save_ifs"
340
+ if test "X$lt_pkg" = "X$lt_p"; then
341
+ pic_mode=yes
342
+ fi
343
+ done
344
+ IFS="$lt_save_ifs"
345
+ ;;
346
+ esac],
331
347
  [pic_mode=default])
332
348
 
333
349
  test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
@@ -7,17 +7,17 @@
7
7
  # unlimited permission to copy and/or distribute it, with or without
8
8
  # modifications, as long as this notice is preserved.
9
9
 
10
- # Generated from ltversion.in.
10
+ # @configure_input@
11
11
 
12
- # serial 3012 ltversion.m4
12
+ # serial 3337 ltversion.m4
13
13
  # This file is part of GNU Libtool
14
14
 
15
- m4_define([LT_PACKAGE_VERSION], [2.2.6])
16
- m4_define([LT_PACKAGE_REVISION], [1.3012])
15
+ m4_define([LT_PACKAGE_VERSION], [2.4.2])
16
+ m4_define([LT_PACKAGE_REVISION], [1.3337])
17
17
 
18
18
  AC_DEFUN([LTVERSION_VERSION],
19
- [macro_version='2.2.6'
20
- macro_revision='1.3012'
19
+ [macro_version='2.4.2'
20
+ macro_revision='1.3337'
21
21
  _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
22
22
  _LT_DECL(, macro_revision, 0)
23
23
  ])
@@ -1,13 +1,13 @@
1
1
  # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
2
2
  #
3
- # Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
3
+ # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
4
4
  # Written by Scott James Remnant, 2004.
5
5
  #
6
6
  # This file is free software; the Free Software Foundation gives
7
7
  # unlimited permission to copy and/or distribute it, with or without
8
8
  # modifications, as long as this notice is preserved.
9
9
 
10
- # serial 4 lt~obsolete.m4
10
+ # serial 5 lt~obsolete.m4
11
11
 
12
12
  # These exist entirely to fool aclocal when bootstrapping libtool.
13
13
  #
@@ -77,7 +77,6 @@ m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
77
77
  m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
78
78
  m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
79
79
  m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
80
- m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])])
81
80
  m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
82
81
  m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
83
82
  m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
@@ -90,3 +89,10 @@ m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
90
89
  m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
91
90
  m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
92
91
  m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
92
+ m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
93
+ m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
94
+ m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
95
+ m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
96
+ m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
97
+ m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
98
+ m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
@@ -34,6 +34,8 @@ Failures are a fact of life, especially when things are distributed. To be resil
34
34
 
35
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
36
 
37
+ Note that an ejected server will not be included in the hash ring for any requests until the retry timeout passes. This will lead to data partitioning as keys originally on the ejected server will now be written to a server still in the pool.
38
+
37
39
  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
40
 
39
41
  ## Timeout
@@ -52,7 +54,7 @@ By default, nutcracker waits indefinitely for any request sent to the server. Ho
52
54
 
53
55
  ## Error Response
54
56
 
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).
57
+ 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
58
 
57
59
  For example, when a memcache server is down, this error response is usually:
58
60
 
@@ -72,7 +74,7 @@ All memory for incoming requests and outgoing responses is allocated in mbuf. Mb
72
74
  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
75
 
74
76
  ## 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.
77
+ The memcache ascii protocol [specification](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
78
 
77
79
  ## Node Names for Consistent Hashing
78
80
 
@@ -116,3 +118,20 @@ For example, the configuration of server pool _beta_, aslo shown below, specifie
116
118
  - 127.0.0.1:6381:1 server2
117
119
  - 127.0.0.1:6382:1 server3
118
120
  - 127.0.0.1:6383:1 server4
121
+
122
+
123
+ ## Graphing Cache-pool State
124
+
125
+ When running nutcracker in production, you often would like to know the list of live and ejected servers at any given time. You can easily answer this question, by generating a time series graph of live and/or dead servers that are part of any cache pool. To do this your graphing client must collect the following stats exposed by nutcracker:
126
+
127
+ - **server_eof** which is incremented when server closes the connection normally which should not happen because we use persistent connections.
128
+ - **server_timedout** is incremented when the connection / request to server timedout.
129
+ - **server_err** is incremented for any other kinds of errors.
130
+
131
+ So, on a given server, the cumulative number of times a server is ejected can be computed as:
132
+
133
+ ```c
134
+ (server_err + server_timedout + server_eof) / server_failure_limit
135
+ ```
136
+
137
+ A diff of the above value between two successive time intervals would generate a nice timeseries graph for ejected servers.
@@ -7,7 +7,7 @@
7
7
  +-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
8
8
  | DEL | Yes | DEL key [key …] |
9
9
  +-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
10
- | DUMP | No | DUMP key |
10
+ | DUMP | Yes | DUMP key |
11
11
  +-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
12
12
  | EXISTS | Yes | EXISTS key |
13
13
  +-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
@@ -37,7 +37,7 @@
37
37
  +-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
38
38
  | RENAMENX | No | RENAMENX key newkey |
39
39
  +-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
40
- | RESTORE | No | RESTORE key ttl serialized-value |
40
+ | RESTORE | Yes | RESTORE key ttl serialized-value |
41
41
  +-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
42
42
  | SORT | No | SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination] |
43
43
  +-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
@@ -168,7 +168,7 @@
168
168
  | RPUSHX | Yes | RPUSHX key value |
169
169
  +-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
170
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
171
+ * RPOPLPUSH support requires that source and destination keys hash to the same server. You can ensure this by using the same [hashtag](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
172
 
173
173
  ### Sets
174
174
 
@@ -204,7 +204,7 @@
204
204
  | SUNIONSTORE | Yes* | SUNIONSTORE destination key [key ...] |
205
205
  +-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
206
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.
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](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
208
 
209
209
 
210
210
  ### Sorted Sets
@@ -245,7 +245,7 @@
245
245
  | ZUNIONSTORE | Yes* | ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] |
246
246
  +-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
247
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.
248
+ * ZINTERSTORE and ZUNIONSTORE support requires that the supplied keys hash to the same server. You can ensure this by using the same [hashtag](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
249
 
250
250
 
251
251
  ### Pub/Sub
@@ -297,8 +297,8 @@
297
297
  +-------------------+------------+---------------------------------------------------------------------------------------------------------------------+
298
298
  | SCRIPT LOAD | No | SCRIPT LOAD script |
299
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
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](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
302
 
303
303
  ### Connection
304
304
 
@@ -383,7 +383,7 @@
383
383
 
384
384
  ### redis-benchmark against redis-server
385
385
 
386
- $ redis-benchmark -h <machine-A> -q -t set,get,incr,lpush,lpop,sadd,spop,lpush,lrange -c 100 -p 6379
386
+ $ redis-benchmark -h <machine-A> -q -t set,get,incr,lpush,lpop,sadd,spop,lpush,lrange -c 100 -p 6379
387
387
  SET: 89285.71 requests per second
388
388
  GET: 92592.59 requests per second
389
389
  INCR: 89285.71 requests per second
@@ -412,4 +412,4 @@
412
412
  LRANGE_300 (first 300 elements): 12376.24 requests per second
413
413
  LRANGE_500 (first 450 elements): 8605.85 requests per second
414
414
  LRANGE_600 (first 600 elements): 6587.62 requests per second
415
-
415
+
@@ -18,6 +18,11 @@ printf '*3\r\n$3\r\nset\r\n$3\r\nfoo\r\n$3\r\noof\r\n' | socat ${debug} ${timeou
18
18
  printf '*3\r\n$3\r\nset\r\n$3\r\nbar\r\n$3\r\nrab\r\n' | socat ${debug} ${timeout} - TCP:localhost:${port},shut-close
19
19
  printf '*4\r\n$3\r\ndel\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$6\r\nfoobar\r\n' | socat ${debug} ${timeout} - TCP:localhost:${port},shut-close
20
20
 
21
+ printf '\ndump\n'
22
+ printf '*2\r\n$4\r\ndump\r\n$3\r\nfoo\r\n' | socat ${debug} ${timeout} - TCP:localhost:${port},shut-close
23
+ printf '*3\r\n$3\r\nset\r\n$3\r\nfoo\r\n$3\r\noof\r\n' | socat ${debug} ${timeout} - TCP:localhost:${port},shut-close
24
+ printf '*2\r\n$4\r\ndump\r\n$3\r\nfoo\r\n' | socat ${debug} ${timeout} - TCP:localhost:${port},shut-close
25
+
21
26
  printf '\nexists\n'
22
27
  printf '*2\r\n$6\r\nexists\r\n$3\r\nfoo\r\n' | socat ${debug} ${timeout} - TCP:localhost:${port},shut-close
23
28
  printf '*3\r\n$3\r\nset\r\n$3\r\nfoo\r\n$3\r\noof\r\n' | socat ${debug} ${timeout} - TCP:localhost:${port},shut-close
@@ -46,6 +51,10 @@ printf '*3\r\n$7\r\npexpire\r\n$3\r\nfoo\r\n$1\r\n0\r\n' | socat ${debug} ${time
46
51
  printf '*3\r\n$3\r\nset\r\n$3\r\nfoo\r\n$3\r\noof\r\n' | socat ${debug} ${timeout} - TCP:localhost:${port},shut-close
47
52
  printf '*3\r\n$7\r\npexpire\r\n$3\r\nfoo\r\n$1\r\n0\r\n' | socat ${debug} ${timeout} - TCP:localhost:${port},shut-close
48
53
 
54
+ printf '\nrestore\n'
55
+ printf '*2\r\n$3\r\ndel\r\n$3\r\nfoo\r\n' | socat ${debug} ${timeout} - TCP:localhost:${port},shut-close
56
+ printf '*4\r\n$7\r\nrestore\r\n$3\r\nfoo\r\n$1\r\n0\r\n$3\r\noof\r\n' | socat ${debug} ${timeout} - TCP:localhost:${port},shut-close
57
+
49
58
  printf '\npttl\n'
50
59
  printf '*2\r\n$4\r\npttl\r\n$3\r\nfoo\r\n' | socat ${debug} ${timeout} - TCP:localhost:${port},shut-close
51
60
  printf '*3\r\n$3\r\nset\r\n$3\r\nfoo\r\n$3\r\noof\r\n' | socat ${debug} ${timeout} - TCP:localhost:${port},shut-close
@@ -1,9 +1,9 @@
1
- # Makefile.in generated by automake 1.11 from Makefile.am.
1
+ # Makefile.in generated by automake 1.11.3 from Makefile.am.
2
2
  # @configure_input@
3
3
 
4
4
  # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
5
- # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
6
- # Inc.
5
+ # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
6
+ # Foundation, Inc.
7
7
  # This Makefile.in is free software; the Free Software Foundation
8
8
  # gives unlimited permission to copy and/or distribute it,
9
9
  # with or without modifications, as long as this notice is preserved.
@@ -136,6 +136,7 @@ CXXFLAGS = @CXXFLAGS@
136
136
  CYGPATH_W = @CYGPATH_W@
137
137
  DEFS = @DEFS@
138
138
  DEPDIR = @DEPDIR@
139
+ DLLTOOL = @DLLTOOL@
139
140
  DSYMUTIL = @DSYMUTIL@
140
141
  DUMPBIN = @DUMPBIN@
141
142
  ECHO_C = @ECHO_C@
@@ -159,6 +160,7 @@ LIPO = @LIPO@
159
160
  LN_S = @LN_S@
160
161
  LTLIBOBJS = @LTLIBOBJS@
161
162
  MAKEINFO = @MAKEINFO@
163
+ MANIFEST_TOOL = @MANIFEST_TOOL@
162
164
  MKDIR_P = @MKDIR_P@
163
165
  NM = @NM@
164
166
  NMEDIT = @NMEDIT@
@@ -184,6 +186,7 @@ abs_builddir = @abs_builddir@
184
186
  abs_srcdir = @abs_srcdir@
185
187
  abs_top_builddir = @abs_top_builddir@
186
188
  abs_top_srcdir = @abs_top_srcdir@
189
+ ac_ct_AR = @ac_ct_AR@
187
190
  ac_ct_CC = @ac_ct_CC@
188
191
  ac_ct_CXX = @ac_ct_CXX@
189
192
  ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
@@ -217,7 +220,6 @@ libdir = @libdir@
217
220
  libexecdir = @libexecdir@
218
221
  localedir = @localedir@
219
222
  localstatedir = @localstatedir@
220
- lt_ECHO = @lt_ECHO@
221
223
  mandir = @mandir@
222
224
  mkdir_p = @mkdir_p@
223
225
  oldincludedir = @oldincludedir@
@@ -347,7 +349,7 @@ clean-binPROGRAMS:
347
349
  list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
348
350
  echo " rm -f" $$list; \
349
351
  rm -f $$list
350
- nutcracker$(EXEEXT): $(nutcracker_OBJECTS) $(nutcracker_DEPENDENCIES)
352
+ nutcracker$(EXEEXT): $(nutcracker_OBJECTS) $(nutcracker_DEPENDENCIES) $(EXTRA_nutcracker_DEPENDENCIES)
351
353
  @rm -f nutcracker$(EXEEXT)
352
354
  $(LINK) $(nutcracker_OBJECTS) $(nutcracker_LDADD) $(LIBS)
353
355
 
@@ -411,7 +413,7 @@ clean-libtool:
411
413
  # (which will cause the Makefiles to be regenerated when you run `make');
412
414
  # (2) otherwise, pass the desired values on the `make' command line.
413
415
  $(RECURSIVE_TARGETS):
414
- @failcom='exit 1'; \
416
+ @fail= failcom='exit 1'; \
415
417
  for f in x $$MAKEFLAGS; do \
416
418
  case $$f in \
417
419
  *=* | --[!k]*);; \
@@ -436,7 +438,7 @@ $(RECURSIVE_TARGETS):
436
438
  fi; test -z "$$fail"
437
439
 
438
440
  $(RECURSIVE_CLEAN_TARGETS):
439
- @failcom='exit 1'; \
441
+ @fail= failcom='exit 1'; \
440
442
  for f in x $$MAKEFLAGS; do \
441
443
  case $$f in \
442
444
  *=* | --[!k]*);; \
@@ -615,10 +617,15 @@ install-am: all-am
615
617
 
616
618
  installcheck: installcheck-recursive
617
619
  install-strip:
618
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
619
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
620
- `test -z '$(STRIP)' || \
621
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
620
+ if test -z '$(STRIP)'; then \
621
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
622
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
623
+ install; \
624
+ else \
625
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
626
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
627
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
628
+ fi
622
629
  mostlyclean-generic:
623
630
 
624
631
  clean-generic:
@@ -10,6 +10,7 @@ noinst_LIBRARIES = libhashkit.a
10
10
  noinst_HEADERS = nc_hashkit.h
11
11
 
12
12
  libhashkit_a_SOURCES = \
13
+ nc_crc16.c \
13
14
  nc_crc32.c \
14
15
  nc_fnv.c \
15
16
  nc_hsieh.c \
@@ -1,9 +1,9 @@
1
- # Makefile.in generated by automake 1.11 from Makefile.am.
1
+ # Makefile.in generated by automake 1.11.3 from Makefile.am.
2
2
  # @configure_input@
3
3
 
4
4
  # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
5
- # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
6
- # Inc.
5
+ # 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
6
+ # Foundation, Inc.
7
7
  # This Makefile.in is free software; the Free Software Foundation
8
8
  # gives unlimited permission to copy and/or distribute it,
9
9
  # with or without modifications, as long as this notice is preserved.
@@ -53,10 +53,11 @@ LIBRARIES = $(noinst_LIBRARIES)
53
53
  ARFLAGS = cru
54
54
  libhashkit_a_AR = $(AR) $(ARFLAGS)
55
55
  libhashkit_a_LIBADD =
56
- am_libhashkit_a_OBJECTS = nc_crc32.$(OBJEXT) nc_fnv.$(OBJEXT) \
57
- nc_hsieh.$(OBJEXT) nc_jenkins.$(OBJEXT) nc_ketama.$(OBJEXT) \
58
- nc_md5.$(OBJEXT) nc_modula.$(OBJEXT) nc_murmur.$(OBJEXT) \
59
- nc_one_at_a_time.$(OBJEXT) nc_random.$(OBJEXT)
56
+ am_libhashkit_a_OBJECTS = nc_crc16.$(OBJEXT) nc_crc32.$(OBJEXT) \
57
+ nc_fnv.$(OBJEXT) nc_hsieh.$(OBJEXT) nc_jenkins.$(OBJEXT) \
58
+ nc_ketama.$(OBJEXT) nc_md5.$(OBJEXT) nc_modula.$(OBJEXT) \
59
+ nc_murmur.$(OBJEXT) nc_one_at_a_time.$(OBJEXT) \
60
+ nc_random.$(OBJEXT)
60
61
  libhashkit_a_OBJECTS = $(am_libhashkit_a_OBJECTS)
61
62
  DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
62
63
  depcomp = $(SHELL) $(top_srcdir)/config/depcomp
@@ -96,6 +97,7 @@ CXXFLAGS = @CXXFLAGS@
96
97
  CYGPATH_W = @CYGPATH_W@
97
98
  DEFS = @DEFS@
98
99
  DEPDIR = @DEPDIR@
100
+ DLLTOOL = @DLLTOOL@
99
101
  DSYMUTIL = @DSYMUTIL@
100
102
  DUMPBIN = @DUMPBIN@
101
103
  ECHO_C = @ECHO_C@
@@ -119,6 +121,7 @@ LIPO = @LIPO@
119
121
  LN_S = @LN_S@
120
122
  LTLIBOBJS = @LTLIBOBJS@
121
123
  MAKEINFO = @MAKEINFO@
124
+ MANIFEST_TOOL = @MANIFEST_TOOL@
122
125
  MKDIR_P = @MKDIR_P@
123
126
  NM = @NM@
124
127
  NMEDIT = @NMEDIT@
@@ -144,6 +147,7 @@ abs_builddir = @abs_builddir@
144
147
  abs_srcdir = @abs_srcdir@
145
148
  abs_top_builddir = @abs_top_builddir@
146
149
  abs_top_srcdir = @abs_top_srcdir@
150
+ ac_ct_AR = @ac_ct_AR@
147
151
  ac_ct_CC = @ac_ct_CC@
148
152
  ac_ct_CXX = @ac_ct_CXX@
149
153
  ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
@@ -177,7 +181,6 @@ libdir = @libdir@
177
181
  libexecdir = @libexecdir@
178
182
  localedir = @localedir@
179
183
  localstatedir = @localstatedir@
180
- lt_ECHO = @lt_ECHO@
181
184
  mandir = @mandir@
182
185
  mkdir_p = @mkdir_p@
183
186
  oldincludedir = @oldincludedir@
@@ -200,6 +203,7 @@ AM_CFLAGS = -Wall -Wshadow -Wno-unused-parameter -Wno-unused-value
200
203
  noinst_LIBRARIES = libhashkit.a
201
204
  noinst_HEADERS = nc_hashkit.h
202
205
  libhashkit_a_SOURCES = \
206
+ nc_crc16.c \
203
207
  nc_crc32.c \
204
208
  nc_fnv.c \
205
209
  nc_hsieh.c \
@@ -248,7 +252,7 @@ $(am__aclocal_m4_deps):
248
252
 
249
253
  clean-noinstLIBRARIES:
250
254
  -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
251
- libhashkit.a: $(libhashkit_a_OBJECTS) $(libhashkit_a_DEPENDENCIES)
255
+ libhashkit.a: $(libhashkit_a_OBJECTS) $(libhashkit_a_DEPENDENCIES) $(EXTRA_libhashkit_a_DEPENDENCIES)
252
256
  -rm -f libhashkit.a
253
257
  $(libhashkit_a_AR) libhashkit.a $(libhashkit_a_OBJECTS) $(libhashkit_a_LIBADD)
254
258
  $(RANLIB) libhashkit.a
@@ -259,6 +263,7 @@ mostlyclean-compile:
259
263
  distclean-compile:
260
264
  -rm -f *.tab.c
261
265
 
266
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nc_crc16.Po@am__quote@
262
267
  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nc_crc32.Po@am__quote@
263
268
  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nc_fnv.Po@am__quote@
264
269
  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nc_hsieh.Po@am__quote@
@@ -393,10 +398,15 @@ install-am: all-am
393
398
 
394
399
  installcheck: installcheck-am
395
400
  install-strip:
396
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
397
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
398
- `test -z '$(STRIP)' || \
399
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
401
+ if test -z '$(STRIP)'; then \
402
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
403
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
404
+ install; \
405
+ else \
406
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
407
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
408
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
409
+ fi
400
410
  mostlyclean-generic:
401
411
 
402
412
  clean-generic:
@@ -0,0 +1,66 @@
1
+ /*
2
+ * twemproxy - A fast and lightweight proxy for memcached protocol.
3
+ * Copyright (C) 2011 Twitter, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #include <nc_core.h>
19
+
20
+ static const uint16_t crc16tab[256] = {
21
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
22
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
23
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
24
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
25
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
26
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
27
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
28
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
29
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
30
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
31
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
32
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
33
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
34
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
35
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
36
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
37
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
38
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
39
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
40
+ 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
41
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
42
+ 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
43
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
44
+ 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
45
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
46
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
47
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
48
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
49
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
50
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
51
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
52
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
53
+ };
54
+
55
+ uint32_t
56
+ hash_crc16(const char *key, size_t key_length)
57
+ {
58
+ uint64_t x;
59
+ uint32_t crc = 0;
60
+
61
+ for (x=0; x < key_length; x++) {
62
+ crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ *key++) & 0x00ff];
63
+ }
64
+
65
+ return crc;
66
+ }
@@ -24,6 +24,7 @@
24
24
  #define HASH_CODEC(ACTION) \
25
25
  ACTION( HASH_ONE_AT_A_TIME, one_at_a_time ) \
26
26
  ACTION( HASH_MD5, md5 ) \
27
+ ACTION( HASH_CRC16, crc16 ) \
27
28
  ACTION( HASH_CRC32, crc32 ) \
28
29
  ACTION( HASH_FNV1_64, fnv1_64 ) \
29
30
  ACTION( HASH_FNV1A_64, fnv1a_64 ) \
@@ -56,6 +57,7 @@ uint32_t hash_one_at_a_time(const char *key, size_t key_length);
56
57
  void md5_signature(const unsigned char *key, unsigned int length, unsigned char *result);
57
58
  uint32_t hash_md5(const char *key, size_t key_length);
58
59
  uint32_t hash_crc32(const char *key, size_t key_length);
60
+ uint32_t hash_crc16(const char *key, size_t key_length);
59
61
  uint32_t hash_fnv1_64(const char *key, size_t key_length);
60
62
  uint32_t hash_fnv1a_64(const char *key, size_t key_length);
61
63
  uint32_t hash_fnv1_32(const char *key, size_t key_length);
@@ -36,6 +36,8 @@ modula_update(struct server_pool *pool)
36
36
  uint32_t continuum_index; /* continuum index */
37
37
  uint32_t continuum_addition; /* extra space in the continuum */
38
38
  uint32_t server_index; /* server index */
39
+ uint32_t weight_index; /* weight index */
40
+ uint32_t total_weight; /* total live server weight */
39
41
  int64_t now; /* current timestamp in usec */
40
42
 
41
43
  now = nc_usec_now();
@@ -45,6 +47,7 @@ modula_update(struct server_pool *pool)
45
47
 
46
48
  nserver = array_n(&pool->server);
47
49
  nlive_server = 0;
50
+ total_weight = 0;
48
51
  pool->next_rebuild = 0LL;
49
52
 
50
53
  for (server_index = 0; server_index < nserver; server_index++) {
@@ -61,6 +64,13 @@ modula_update(struct server_pool *pool)
61
64
  } else {
62
65
  nlive_server++;
63
66
  }
67
+
68
+ ASSERT(server->weight > 0);
69
+
70
+ /* count weight only for live servers */
71
+ if (!pool->auto_eject_hosts || server->next_retry <= now) {
72
+ total_weight += server->weight;
73
+ }
64
74
  }
65
75
 
66
76
  pool->nlive_server = nlive_server;
@@ -85,9 +95,9 @@ modula_update(struct server_pool *pool)
85
95
  * Allocate the continuum for the pool, the first time, and every time we
86
96
  * add a new server to the pool
87
97
  */
88
- if (nlive_server > pool->nserver_continuum) {
98
+ if (total_weight > pool->nserver_continuum) {
89
99
  struct continuum *continuum;
90
- uint32_t nserver_continuum = nlive_server + MODULA_CONTINUUM_ADDITION;
100
+ uint32_t nserver_continuum = total_weight + MODULA_CONTINUUM_ADDITION;
91
101
  uint32_t ncontinuum = nserver_continuum * MODULA_POINTS_PER_SERVER;
92
102
 
93
103
  continuum = nc_realloc(pool->continuum, sizeof(*continuum) * ncontinuum);
@@ -110,12 +120,14 @@ modula_update(struct server_pool *pool)
110
120
  continue;
111
121
  }
112
122
 
113
- pointer_per_server = 1;
123
+ for (weight_index = 0; weight_index < server->weight; weight_index++) {
124
+ pointer_per_server = 1;
114
125
 
115
- pool->continuum[continuum_index].index = server_index;
116
- pool->continuum[continuum_index++].value = 0;
126
+ pool->continuum[continuum_index].index = server_index;
127
+ pool->continuum[continuum_index++].value = 0;
117
128
 
118
- pointer_counter += pointer_per_server;
129
+ pointer_counter += pointer_per_server;
130
+ }
119
131
  }
120
132
  pool->ncontinuum = pointer_counter;
121
133