启动redis实例
nohup ./redis-server &
使用redis-cli连接并设置tcp-keepalive属性和timeout属性,两个属性都是0,redis默认是不开启的。
[root@redis-7-106 logs]# redis-cli -p 6379
127.0.0.1:6379> config get tcp-keepalive
1) "tcp-keepalive"
2) "0"
127.0.0.1:6379> config get timeout
1) "timeout"
2) "0"
127.0.0.1:6379>
使用config set 命令分别设置tcp-keepalive属性和timeout属性的值,或者在redis.conf配置文件中修改这两个属性,要注意修改配置文件需要重启redis服务。
127.0.0.1:6379> config set tcp-keepalive 60
OK
127.0.0.1:6379> config get tcp-keepalive
1) "tcp-keepalive"
2) "60"
127.0.0.1:6379> config set timeout 300
OK
127.0.0.1:6379> config get timeout
1) "timeout"
2) "300"
127.0.0.1:6379>
使用redis-cli从其他服务器远程连接这个redis实例(从其他服务器便于观察)
# 其他服务器 10.4.7.1 redis-cli 连接
~ % /Users/domino/redis/redis-3.2.3/src/redis-cli -h 10.4.7.106 -p 6379
# redis实例服务器 通过client list命令查看客户端连接
127.0.0.1:6379> client list
id=44 addr=127.0.0.1:37536 laddr=127.0.0.1:6379 fd=8 name= age=369 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=40928 argv-mem=10 obl=0 oll=0 omem=0 tot-mem=61466 events=r cmd=client user=default redir=-1
id=45 addr=10.4.7.1:55544 laddr=10.4.7.106:6379 fd=9 name= age=142 idle=142 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 obl=0 oll=0 omem=0 tot-mem=20496 events=r cmd=command user=default redir=-1
# 可以看到一个连接是本机redis-cli连接,另一个是其他服务器的连接
通过netstat命令观察连接情况
[root@redis-7-106 ~]# netstat -nap | egrep -i 6379 | egrep -i \.7\.1\:
tcp 0 0 10.4.7.106:6379 10.4.7.1:55544 ESTABLISHED 10083/./redis-serve
通过tcpdump查看
# 先通过ifconfig查看网卡,可见使用的是ens33
[root@redis-7-106 logs]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.4.7.106 netmask 255.255.252.0 broadcast 10.4.7.255
inet6 fe80::f002:29f9:88c3:a1a2 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:54:70:ec txqueuelen 1000 (Ethernet)
RX packets 27209007 bytes 15499242089 (14.4 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 23136520 bytes 2780588807 (2.5 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# 使用tcpdump 查看 tcp端口6379的往来通信,这里我把redis-server 的tcp-keepalive配置改为了5秒,所以交互很频繁,说明tcp-keepalive生效。
[root@redis-7-106 ~]# tcpdump -nei ens33 "tcp port 6379"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
# 可以看到 redis-server向 10.4.7.1的客户端发送心跳检测
17:05:07.673530 00:0c:29:54:70:ec > fa:ff:c2:d5:49:64, ethertype IPv4 (0x0800), length 66: 10.4.7.106.6379 > 10.4.7.1.56667: Flags [.], ack 250714536, win 227, options [nop,nop,TS val 68425312 ecr 2278728736], length 0
# 10.4.7.1客户端向 redis-server进行返回
17:05:07.673882 fa:ff:c2:d5:49:64 > 00:0c:29:54:70:ec, ethertype IPv4 (0x0800), length 66: 10.4.7.1.56667 > 10.4.7.106.6379: Flags [.], ack 1, win 2058, options [nop,nop,TS val 2278733740 ecr 68415295], length 0
…………
在客户端空闲超过timeout配置设置的300秒以后,查看client list,可以看到空闲的远程客户端已经被不在了。tcpdump也不会有新的结果展示。说明timeout参数也生效了。
[root@redis-7-106 logs]# netstat -naplo | egrep -i 6379 | egrep -i \.7\.1\:
[root@redis-7-106 ~]# tcpdump -nei ens33 "tcp port 6379"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
[root@redis-7-106 logs]# redis-cli -p 6379
127.0.0.1:6379> client list
id=99 addr=127.0.0.1:37546 laddr=127.0.0.1:6379 fd=8 name= age=356 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=40928 argv-mem=10 obl=0 oll=0 omem=0 tot-mem=61466 events=r cmd=client user=default redir=-1
redis server 可以断开 KA 丢失的连接或空闲的连接。这将使 Redis服务免受 TCP 连接耗尽问题的影响。