《twemproxy(nutcracker)部署与使用》
twemproxy 是 Twitter 开源的一个轻量级缓存代理层,内部命令行程序名为 nutcracker,常用于 Redis/Memcached 的分片与高可用聚合:客户端只连代理,代理按一致性哈希把 key 分散到多个后端实例。
说明:
nutcracker是二进制的正式名字,twemproxy是项目名,两者指同一个东西。
1 特点
- 对客户端透明:客户端只连接 twemproxy 的监听地址。
- 支持一致性哈希(ketama)分布,后端节点变化时最小影响已有 key。
- 自动摘除故障节点(auto_eject_hosts)并在超时后重试恢复。
- 内置监控端口(默认 22222)输出 stats 信息。
代码仓库:https://github.com/twitter/twemproxy
2 命令行参数
Usage: nutcracker [-?hVdDt] [-v verbosity level] [-o output file]
[-c conf file] [-s stats port] [-a stats addr]
[-i stats interval] [-p pid file] [-m mbuf size]
Options:
-h, --help : 帮助
-V, --version : 显示版本并退出
-t, --test-conf : 测试配置文件语法是否正确后退出
-d, --daemonize : 以守护进程方式运行
-D, --describe-stats : 打印 stats 字段说明后退出
-v, --verbose=N : 日志级别(默认 5,范围 0-11)
-o, --output=S : 日志文件(默认 stderr)
-c, --conf-file=S : 配置文件(默认 conf/nutcracker.yml)
-s, --stats-port=N : 监控端口(默认 22222)
-a, --stats-addr=S : 监控监听 IP(默认 0.0.0.0)
-i, --stats-interval=N : stats 聚合周期,毫秒(默认 30000)
-p, --pid-file=S : pid 文件(默认关闭)
-m, --mbuf-size=N : mbuf 块大小(默认 16384 字节)
3 检查配置文件语法
# 不指定 -c 时,nutcracker 会到默认路径 /etc/nutcracker 下找配置
nutcracker -c /etc/nutcracker/nutcracker.yml -t
4 配置文件示例
serv_group:
listen: /var/run/nutcracker.sock
hash: fnv1a_64
backlog: 1024
distribution: ketama
server_connections: 10
auto_eject_hosts: true
server_retry_timeout: 60000
server_failure_limit: 3
timeout: 150
redis: true
redis_db: 0
preconnect: true
servers:
- 127.0.0.1:6301:1 node1
servers中127.0.0.1:6301:1最后的1表示该后端在哈希中的权重。listen可以是 unix socket,也可以是host:port。
5 后端 Redis 节点配置
以 6301 为例,多节点时仅调整端口、pid/log/db 文件路径:
port 6301
pidfile /var/run/redis/redis-node.pid
logfile "/var/log/redis/redis-node.log"
dbfilename redis-node.rdb
dir /var/run/redis/
slave-read-only yes
bind 0.0.0.0
protected-mode yes
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
loglevel notice
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
slave-serve-stale-data yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
6 搭建分片集群(多个 Redis 节点)
6.1 启动多个 Redis 后端
配置按端口命名:/etc/redis/node0.conf、/etc/redis/node1.conf、/etc/redis/node2.conf,只改监听端口、pid/log/db 路径:
port 6300
pidfile /var/run/redis/node0.pid
logfile "/var/log/redis/node0.log"
dbfilename node0.rdb
redis-server /etc/redis/node0.conf
redis-server /etc/redis/node1.conf
redis-server /etc/redis/node2.conf
6.2 修改 nutcracker 配置并启动
serv_group:
listen: /var/run/nutcracker.sock
hash: fnv1a_64
backlog: 1024
distribution: ketama
server_connections: 10
auto_eject_hosts: true
server_retry_timeout: 60000
server_failure_limit: 3
timeout: 150
redis: true
redis_db: 0
preconnect: true
servers:
- 127.0.0.1:6300:1 node0
- 127.0.0.1:6301:1 node1
- 127.0.0.1:6302:1 node2
使用 init 脚本启动:/etc/init.d/nutcracker start
6.3 init.d 启停脚本参考
#!/bin/sh
### BEGIN INIT INFO
# Provides: nutcracker
# Required-Start: $network $remote_fs $local_fs
# Required-Stop: $network $remote_fs $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Stop/start nutcracker
### END INIT INFO
PATH=/usr/local/sbin:/sbin:/usr/sbin:/bin:/usr/bin:$PATH
DESC=nutcracker
NAME=nutcracker
CONFFILE=/etc/nutcracker/$NAME.yml
LOGFILE=/var/log/nutcracker.log
DAEMON=/usr/local/sbin/nutcracker
PIDFILE=/var/run/$NAME.pid
STATSPORT=22222
DAEMON_ARGS="-c $CONFFILE -o $LOGFILE -p $PIDFILE -s $STATSPORT -v 11 -m 2048 -d"
SCRIPTNAME=/etc/init.d/$NAME
ulimit -Sn 100000
[ -x $DAEMON ] || exit 0
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
. /lib/init/vars.sh
. /lib/lsb/init-functions
do_start()
{
mkdir -p /var/run/nutcracker
touch $PIDFILE
chmod 755 /var/run/nutcracker
echo -n "Starting ${NAME}: "
start-stop-daemon --start --quiet -m --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_ARGS
case "$?" in
0|1) echo "STARTED." ;;
2) echo "FAILED." ;;
esac
}
do_stop()
{
echo -n "Stopping ${NAME}: "
start-stop-daemon --stop --quiet --pidfile $PIDFILE --exec $DAEMON || true
case "$?" in
0|1) echo "STOPPED." ;;
2) echo "FAILED." ;;
esac
}
case "$1" in
start) do_start ;;
stop) do_stop ;;
status) status_of_proc -p $PIDFILE "$DAEMON" nutcracker ;;
restart) do_stop; do_start ;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
exit 3
;;
esac
exit 0
注意:脚本中 DAEMON 路径必须与机器上 which nutcracker 的实际路径一致。
7 验证代理是否生效
# 检查配置语法
nutcracker -t -c /etc/nutcracker/nutcracker.yml
# 查看 nutcracker 监听端口(一个业务监听 + 一个 22222 监控端口)
netstat -nltp | grep nutcracker
tcp 0 0 127.0.0.1:44111 0.0.0.0:* LISTEN 103/nutcracker
tcp 0 0 0.0.0.0:22222 0.0.0.0:* LISTEN 103/nutcracker
然后用 redis-cli 直接连接代理的监听端口,就像连接一台普通 Redis:
redis-cli -p 2411 set key1 value1
redis-cli -p 2411 get key1
8 使用建议与注意事项
auto_eject_hosts: true时,后端连续失败达到server_failure_limit会被临时剔除,server_retry_timeout到期后重新探测恢复。- 建议用
nutcracker -t校验配置后再 restart,避免全局不可用。 - 监控端口 22222 仅内网开放,stats 输出可配合 Prometheus 采集。
阅读 —
·
全站 —