admin管理员组

文章数量:1655377

为什么80%的码农都做不了架构师?>>>   

调优 Haproxy 代理 Ceph

今天同事告诉我安装的 Haproxy 代理 Ceph 通过压力测试软件压测的时候,使用与直接压主机的配置去压 Haproxy 的时候会被压死。

简单分析,确定调优方向

我们使用 Ceph 做对象存储,使用 Haproxy 代理 Ceph 两个网关,做负载均衡及高可用。
Haproxy 的工作情况大致是将从网卡接收到的数据写到内存缓存下,再从网卡写出。
在操作系统看流程是这样的:网卡接收到请求,通过中断告知 CPU,CPU 根据操作系统的计算,分配一块内存给网卡写入数据,内核将数据从内核空间复制到用户空间,haproxy 接收到数据,根据负载策略选择一个 IP 地址,将数据写出,从用户空间复制到内核空间,然后内核调用网卡写出。
这有点像是用瓢在两个缸倒水,想要尽快倒完,可以增快倒水速度(CPU频率),增加人数(进程数),把瓢做大点(缓存)。
分析完这个流程,首先想到的是先去调多工作进程数,与 CPU 数量一致或少一个即可,再完成进程绑定操作。
其次看能否调整 haproxy 的 IO 模型。
代理对象存储,传输数据量较大,可以调整 tcp 连接相关参数来调整数据缓存。
Haproxy 是工作在用户空间的应用,与 lvs 工作方式不同,仅是模拟 tcp 代理,查看文件打开数量限制。
大胆猜测下 Haproxy 因为缓存太小频繁操作,导致 CPU 飙升。资源占用太多被内核杀掉,后资源空闲 systemd 检测到程序异常,主动启动应用。开启进程数需先关注。

查看主机配置

  • CPU
  # 查看物理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

  • Memory

  free -g
      total        used        free      shared  buff/cache   available
  Mem:             62           0          61           0           1          61
  Swap:            15           0          15

  • 总结
  32C 62G

查看状态

  • 查看 Haproxy 进程数

  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

小结

至此已经可以去设置进程数以及进程亲缘性绑定来实现一定程度上的优化,为了验证下前面的猜测先不做优化,看看是否猜对了。

压测时观测相关指标数据及命令


  # 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也可以得知。

  • 进程信息

有个 haproxy 进程在不断切换 CPU

  • 压测结果

这次没压死,但是这个结果甚是意外,性能相当不错

  • 再次压测

各个进程CPU使用率在 8% 上下。

优化思路

看到这个结果我心里哇凉哇凉的,这意味着仅调整进程数,瓶颈就不会出现在 haproxy。估计5个进程就会让后面的 Ceph 出现瓶颈,当然可能本机内核参数也会出现影响。先暂时做如下调整:1 调整工作进程为 30,并完成进程绑定,注意留出给内核与stats。2 调整最大连接数为 65535。内核参数暂不做修改。下面给出影响较大的内核参数。

调优 Haproxy

  • 增加 haproxy 工作进程数,并完成进程亲缘性绑定。
  # 注 下面完成了工作进程数及亲缘性绑定,若想做的极致一点还可以通过在内核启动文件即 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    

调优个人建议及认识

  • 调优首则,有性能问题再调,前期可以根据给的建议配置先配置好使用
  • Cache is king,依据目前的制造工艺,此“定律”起到很大作用
  • 调整参数前应该考虑这么一个问题,Linux 是很强大的,已经根据大多数场景做了默认配置,但根据最终应用场景的不同,某些参数的设置并不合适,就需要进行调整,例如做反代非常出名的 F5, A10,NetScaler 等硬件反向代理软件,就是结合硬件对 Linux 对反代功能优化。
  • 调优如果不涉及代码级别的话,就是调整参数去让其充分利用内存与多进程(线程)来换取时间。减少磁盘 IO。
  • 调优的前提是得大概知道什么现象是由什么问题导致的,而一个具体软件的运行流程、工作流程或者说这个软件所处理的业务对问题的发现具有重大指导意义。这或许就是面试时许多人问的原理吧。在了解了这点后,出现性能或者抛异常后,寻找问题面就会缩小很多,例如这里调优 haproxy 不会去涉及磁盘 IO 的问题。
  • 优化的原则是前期不要过度优化,前期仅针对直接最影响性能的参数进行调整。默认的配置已经满足大多数场景。若业务量上升负载再次出现瓶颈,再进行优化。
  • 优化需要注意的事:选择更合适的软件可能更简单,例如访问压力更大的情况下选用 LVS 更合适;不要去过度压榨计算机性能,尤其是花不多的钱购买硬件能解决的,例如给 mysql 服务器添加固态硬盘存储 binlog。

转载于:https://my.oschina/seal90/blog/1841547

本文标签: 调优haproxyCeph