转载自http://blog.itpub.net/20625855/viewspace-1692022/
之前写了twemproxy的安装配置,今天主要内容是参数解析和它提供监控:
参数解读:
listen:
监听地址和端口(name:port 或者ip:port),也可以用sock文件(/var/run/nutcracker.sock)的绝对路径
hash:hash函数的名字:
one_at_a_time
md5
crc16
crc32 (crc32 implementation compatible with libmemcached)
crc32a (correct crc32 implementation as per the spec)
fnv1_64
fnv1a_64(默认配置)
fnv1_32
fnv1a_32
hsieh
murmur
jenkins
hash_tag:两个字符组成的字符串(比如{}),指定key的部分做hash运算。
例如两个key aaaa,xxx:{aaaa}:xxxx;指定{}中间部分做hash运算
他们将被分配到同一server(找不到的场景使用完整的key做hash)
distribution: 数据分配方式:
ketama:一致性hash算法,根据server构造hash ring,为每个阶段分配hash范围
它的优点是一个节点down后,整个集群re-hash,有部分key-range会跟之
前的key-range重合,所以它只能合适做单纯的cache
modula:根据key做hash值取模,根据结果分配到对应的server
这种方式如果集群做re-hash,所有的key值都会目标错乱
random:不管key值的hash结果是啥,随机选取一个server作为操作目标
适合只读场景,需要配合数据加载?
timeout:单位毫秒,等待到server建立连接的时间或者接收server相应过程的等待时间
默认是无限期等待
等待超时报错:SERVER_ERROR Connection timed out
backlog:TCP backlog队列,默认512
preconnect: 在进程启动的时候,twemproxy是否需要预连接到所有的server,默认值是false
redis:使用redis还是memcached协议,默认false(即memcached)
redis_auth: 连接redisserver的验证
server_connections:每一个server能够打开的最大连接值,默认最大是1
auto_eject_host: 当连接一个server失败次数超过server_failure_limit值时,是否把这个
server驱逐出集群,默认是false
server_retry_timeout:单位毫秒,当auto_eject_host打开后,重试被临时驱逐的server之前
的等待时间
server_failure_limit: 当auto_eject_host打开后,驱逐一个server之前重试次数
servers: serverpool中包含的的server的地址、端口和权重的列表(name:port:weight or ip:port:weight)
配置例子:
alpha:
listen: 127.0.0.1:22121
hash: fnv1a_64
distribution: ketama
auto_eject_hosts: true
redis: true
server_retry_timeout: 2000
server_failure_limit: 1
servers:
- 127.0.0.1:6379:1
beta:
listen: 127.0.0.1:22122
hash: fnv1a_64
hash_tag: "{}"
distribution: ketama
auto_eject_hosts: false
timeout: 400
redis: true
servers:
- 127.0.0.1:6380:1 server1
- 127.0.0.1:6381:1 server2
- 127.0.0.1:6382:1 server3
- 127.0.0.1:6383:1 server4
gamma:
listen: 127.0.0.1:22123
hash: fnv1a_64
distribution: ketama
timeout: 400
backlog: 1024
preconnect: true
auto_eject_hosts: true
server_retry_timeout: 2000
server_failure_limit: 3
servers:
- 127.0.0.1:11212:1
- 127.0.0.1:11213:1
delta:
listen: 127.0.0.1:22124
hash: fnv1a_64
distribution: ketama
timeout: 100
auto_eject_hosts: true
server_retry_timeout: 2000
server_failure_limit: 1
servers:
- 127.0.0.1:11214:1
- 127.0.0.1:11215:1
- 127.0.0.1:11216:1
- 127.0.0.1:11217:1
- 127.0.0.1:11218:1
- 127.0.0.1:11219:1
- 127.0.0.1:11220:1
- 127.0.0.1:11221:1
- 127.0.0.1:11222:1
- 127.0.0.1:11223:1
omega:
listen: /tmp/gamma
hash: hsieh
distribution: ketama
auto_eject_hosts: false
servers:
- 127.0.0.1:11214:100000
- 127.0.0.1:11215:1
配置文件的语法检查可以使用-t参数来做
监控:
nutcracker有两个参数:
-s, --stats-port=N : set stats monitoring port (default: 22222)
-a, --stats-addr=S : set stats monitoring ip (default: 0.0.0.0)
启动后,访问http://xx.xx.xx.xx:22222/
{"service":"nutcracker", "source":"bjm6-24-32.58os.org", "version":"0.3.0", "uptime":344017, "timestamp":1433757840,
"total_connections":749874, "curr_connections":4, "1o": {"client_eof":610078, "client_err":139766, "client_connections":1,
"server_ejects":20, "forward_error":505857, "fragments":0, "xxx.xxx.xxx.32:30001": {"server_eof":1, "server_err":4,
"server_timedout":0, "server_connections":1, "server_ejected_at":1433674556689492, "requests":3028841, "request_bytes":137924947,
"responses":3028700, "response_bytes":21150788, "in_queue":0, "in_queue_bytes":0, "out_queue":0,
"out_queue_bytes":0},"xxx.xxx.xxx.33:30001": {"server_eof":1, "server_err":4, "server_timedout":0, "server_connections":1,
"server_ejected_at":1433674556688643, "requests":118, "request_bytes":5235, "responses":3, "response_bytes":17, "in_queue":0,
"in_queue_bytes":0, "out_queue":0, "out_queue_bytes":0},"xxx.xxx.xxx.34:30001": {"server_eof":1, "server_err":4, "server_timedout":0,
"server_connections":0, "server_ejected_at":1433674556690998, "requests":251, "request_bytes":11264, "responses":2,
"response_bytes":12, "in_queue":0, "in_queue_bytes":0, "out_queue":0, "out_queue_bytes":0},"xxx.xxx.xxx.35:30001": {"server_eof":1,
"server_err":4, "server_timedout":0, "server_connections":1, "server_ejected_at":1433674556687407, "requests":70058868,
"request_bytes":2900003041, "responses":70058722, "response_bytes":467091290, "in_queue":0, "in_queue_bytes":0, "out_queue":0,
"out_queue_bytes":0}}}
各个项的含义可以通过下面查看说明:
$ nutcracker --describe-stats
pool stats:
client_eof "# eof on client connections"
client_err "# errors on client connections"
client_connections "# active client connections"
server_ejects "# times backend server was ejected"
forward_error "# times we encountered a forwarding error"
fragments "# fragments created from a multi-vector request"
server stats:
server_eof "# eof on server connections"
server_err "# errors on server connections"
server_timedout "# timeouts on server connections"
server_connections "# active server connections"
requests "# requests"
request_bytes "total request bytes"
responses "# responses"
response_bytes "total response bytes"
in_queue "# requests in incoming queue"
in_queue_bytes "current request bytes in incoming queue"
out_queue "# requests in outgoing queue"
out_queue_bytes "current request bytes in outgoing queue"
日志只有在编译安装的时候启用( --enable-debug=log),默认情况下日志写到stderr.
可以使用 -o 或者 --output 命令指定输出文件,使用-v标记日志级别
生成环境推荐:
1、log level:
推荐编译时候打开日志,使用等级6记录日志信息
2、liveness:
分布式事务,failure将会是常态,为了应对failure,推荐为每一个server pool配置如下:
resilient_pool:
auto_eject_hosts: true
server_retry_timeout: 30000
server_failure_limit: 3
auto_eject_hosts,server_failure_limit:确保dead server会被驱逐出hash环
server_retry_timeout:确保闪断的server不会被标记成dead server
3、timeout:
nutceacker通常需要配置timeout,而不是依赖客户端的超时配置:
resilient_pool_with_timeout:
auto_eject_hosts: true
server_retry_timeout: 30000
server_failure_limit: 3
timeout: 400
默认场景,nutcracker一直等到请求发送到server,配置timeout后,请求
超时后将会返回错误信息( SERVER_ERROR Connection timed out\r\n (memcached)
or -ERR Connection timed out\r\n (redis))
4、 error response:
发现错误信息返回的情况,可以认为是一个客户端的瞬间失效,最好重新发起请求
5、read, writev and mbuf
所有的请求和响应都在mbuf里面,mbuf默认大小是16K(512b-16M),可以使用
-m or -mbuf-size=N来配置,每一个连接都会获得至少一个mbuf,这意味着nutcracker支持的
并发的连接数依赖于mbuf的大小,小的mbuf可以控制更多的连接,大的mbuf可以让我们
读或者写更多的数据导socker buffer。如果并发量很大的场景,推荐使用比较小的mbuf(512 or 1K)
6、mbuf-size=N
每一个客户端连接最好需要一个mbuf,一个服务请求最少是两个连接(client->proxy、proxy->server)
所以最少需要两个mbufs
1000个客户端连接的场景计算:1000*2*mbuf=32M,如果每个连接有10个操作,这个值将会是320M,假设
连接是10000,那么将会消耗3.2G内存!这种场景下最好调小mbuf值比如512b,1000*2*512*10=10M
这个就是当并发量高的场景下使用小的mbuf的原因
7、key长度:
memcached的长度上限是250, redis没有类似限制,但是nutcracker需要key存储在连续的内存里面,而因为
所有的请求和响应都在mbuf中,所以redis key的长度将会受限制于mbuf,也就是说如果你的redis实例如果要
操作超长的key,你必须把mbuf调大
8、server name
配置1:
servers:
- 127.0.0.1:6379:1
- 127.0.0.1:6380:1
- 127.0.0.1:6381:1
- 127.0.0.1:6382:1
配置2:
servers:
- 127.0.0.1:6379:1 server1
- 127.0.0.1:6380:1 server2
- 127.0.0.1:6381:1 server3
- 127.0.0.1:6382:1 server4
配置1 keys直接使用host:port:weight做匹配;
配置2 跟node name匹配
第二种场景可以让我们方便的移动节点到不同的服务器上,而不会打乱hash ring
9、server_connections: > 1
当值大于1的时候,“read my last write”的请求会导致不一致。
最后注意使用twemproxy最redis命令的支持情况:
https://github.com/twitter/twemproxy/blob/master/notes/redis.md