今天同事告诉我安装的 Haproxy 代理 Ceph 经过压力测试软件压测的时候,使用与直接压主机的配置去压 Haproxy 的时候会被压死。mysql
咱们使用 Ceph 作对象存储,使用 Haproxy 代理 Ceph 两个网关,作负载均衡及高可用。
Haproxy 的工做状况大体是将从网卡接收到的数据写到内存缓存下,再从网卡写出。
在操做系统看流程是这样的:网卡接收到请求,经过中断告知 CPU,CPU 根据操做系统的计算,分配一块内存给网卡写入数据,内核将数据从内核空间复制到用户空间,haproxy 接收到数据,根据负载策略选择一个 IP 地址,将数据写出,从用户空间复制到内核空间,而后内核调用网卡写出。
这有点像是用瓢在两个缸倒水,想要尽快倒完,能够增快倒水速度(CPU频率),增长人数(进程数),把瓢作大点(缓存)。
分析完这个流程,首先想到的是先去调多工做进程数,与 CPU 数量一致或少一个便可,再完成进程绑定操做。
其次看可否调整 haproxy 的 IO 模型。
代理对象存储,传输数据量较大,能够调整 tcp 链接相关参数来调整数据缓存。
Haproxy 是工做在用户空间的应用,与 lvs 工做方式不一样,仅是模拟 tcp 代理,查看文件打开数量限制。
大胆猜想下 Haproxy 由于缓存过小频繁操做,致使 CPU 飙升。资源占用太多被内核杀掉,后资源空闲 systemd 检测到程序异常,主动启动应用。开启进程数需先关注。面试
# 查看物理CPU个数 cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l 32 # 查看每一个物理CPU中core的个数(即核数) cat /proc/cpuinfo| grep "cpu cores"| uniq 1 # 查看逻辑CPU的个数 cat /proc/cpuinfo| grep "processor"| wc -l 32
free -g total used free shared buff/cache available Mem: 62 0 61 0 1 61 Swap: 15 0 15
32C 62G
ps -ef | grep haproxy ipaas 11140 10112 0 17:29 pts/1 00:00:00 grep --color=auto haproxy root 14232 1 0 Jun12 ? 00:00:00 /usr/sbin/haproxy-systemd-wrapper -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid haproxy 14233 14232 0 Jun12 ? 00:00:00 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds haproxy 14234 14233 0 Jun12 ? 01:11:26 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds # 注意: haproxy-systemd-wrapper 从名字上看只是一个配合 systemd 作兼容的。两个 /usr/sbin/haproxy 进程其中一个是 status 收集状态的,另一个是工做进程。在设定进程数时要注意。进程数 = CPU数 - 内核占用0号CPU - status 占用一个CPU。 ps -ef | grep haproxy | wc -l # 彷佛不用执行这个了 明显两个工做进程 # 查看进程在那颗CPU上运行 ps axo psr,command | grep haproxy
至此已经能够去设置进程数以及进程亲缘性绑定来实现必定程度上的优化,为了验证下前面的猜想先不作优化,看看是否猜对了。sql
# CPU 相关 # 查看每CPU负载 #输入top 按 1 # 查看 CPU 负载类型 mpstat -P ALL 1 # 查看 HAProxy 进程调用哪一个系统调用,占用cpu 最多 # strace -p pid -c # 网络相关 # 查看 socket的listen 队列 watch "cat /proc/net/netstat | awk '/TcpExt/ { print \$21,\$22 }'" # 查看某进程由哪一个cpu执行 ps axo psr,command | grep haproxy
压测数据
缓存
由第一个可知 仅有一个 haproxy 进程占用 CPU 较高,右侧图看到消耗内存较少,左下图可知没有包丢失,右下角可知没什么高负载,或者说总体悠闲,这点在左上角图 96.9 id也能够得知。服务器
进程信息
cookie
有个 haproxy 进程在不断切换 CPU网络
此次没压死,可是这个结果甚是意外,性能至关不错app
各个进程CPU使用率在 8% 上下。负载均衡
看到这个结果我内心哇凉哇凉的,这意味着仅调整进程数,瓶颈就不会出如今 haproxy。估计5个进程就会让后面的 Ceph 出现瓶颈,固然可能本机内核参数也会出现影响。先暂时作以下调整:1 调整工做进程为 30,并完成进程绑定,注意留出给内核与stats。2 调整最大链接数为 65535。内核参数暂不作修改。下面给出影响较大的内核参数。frontend
# 注 下面完成了工做进程数及亲缘性绑定,若想作的极致一点还能够经过在内核启动文件即 grub 文件启动参数来实现 内核进程绑定以及进程隔离 # 至于中断隔离不建议使用 # 与此相关的配置有 global nbproc 4 # 配置进程数,不包含 status cpu-map 1 1 # 亲缘性绑定。前一个数字是进程号,后一个数字是CPU内核的号,注意将0号cpu留给内核 cpu-map 2 2 cpu-map 3 3 cpu-map 4 4 ... cpu-map 30 30 stats bind-process 31 # 能够将不一样任务绑定到不一样的内核上独立执行 frontend access_http bind 0.0.0.0:80 # bind-process 1 # 将进程与任务绑定,暂不处理 frontend access_https bind 0.0.0.0:443 ssl crt /etc/yourdomain.pem # bind-process 2 3 4
global maxconn 65535
# 默认的TCP数据接收窗口大小(字节)默认 256K net.core.rmem_default = 524288 # 最大的TCP数据接收窗口(字节) 默认4M,根据文件大小调整下面的是 48M 较大 net.core.rmem_max = 50331648 # 默认的TCP数据发送窗口大小(字节) net.core.wmem_default = 524288 # 最大的TCP数据发送窗口(字节)默认4M,根据文件大小调整下面的是 32M 较大 net.core.wmem_max = 33554432 # 定义了系统中每个端口最大的监听队列的长度,这是个全局的参数 net.core.somaxconn = 65535 # TCP/UDP协议容许使用的本地端口号范围 net.ipv4.ip_local_port_range = 1025 65534 # 容许绑定不存在的 IP net.ipv4.ip_nonlocal_bind = 1 # 表示是否打开TCP同步标签(syncookie),同步标签能够防止一个套接字在有过多试图链接到达时引发过载 # 内核必须打开了CONFIG_SYN_COOKIES项进行编译, net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_syn_retries = 2 # 表示开启TCP链接中TIME-WAIT sockets的快速回收,默认为0,表示关闭 net.ipv4.tcp_tw_recycle = 1 # 容许将TIME-WAIT sockets从新用于新的TCP链接,默认为0,表示关闭 net.ipv4.tcp_tw_reuse = 1 # 最大限度使用物理内存,即物理内存使用完后再使用 swap vm.swappiness = 0