《twemproxy(nutcracker)部署与使用》

《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 采集。
阅读 — · 全站 —
🎸 我的歌单 0 首