Linux性能优化实战学习笔记:第四十三讲

1、上节回顾

上一节,咱们了解了 NAT(网络地址转换)的原理,学会了如何排查 NAT 带来的性能问题,最后还总结了 NAT 性能优化的基本思路。我先带你简单回顾一下。算法

NAT 基于 Linux 内核的链接跟踪机制,实现了 IP 地址及端口号重写的功能,主要被用来解决公网 IP 地址短缺的问题。数据库

在分析 NAT 性能问题时,能够先从内核链接跟踪模块 conntrack 角度来分析,好比用systemtap、perf、netstat 等工具,以及 proc 文件系统中的内核选项,来分析网络协议
栈的行为;而后,经过内核选项调优、切换到无状态 NAT、使用 DPDK 等方式,进行实际优化。缓存

经过前面的学习,你应该已经体会到,网络问题比咱们前面学过的 CPU、内存或磁盘 I/O都要复杂。不管是应用层的各类 I/O 模型,冗长的网络协议栈和众多的内核选项,抑或是
各类复杂的网络环境,都提升了网络的复杂性。性能优化

不过,也不要过度担忧,只要你掌握了 Linux 网络的基本原理和常见网络协议的工做流程,再结合各个网络层的性能指标来分析,你会发现,定位网络瓶颈并不难。bash

找到网络性能瓶颈后,下一步要作的就是优化了,也就是如何下降网络延迟,并提升网络的吞吐量。学完相关原理和案例后,我就来说讲,优化网络性能问题的思路和一些注意事项。网络

因为网络优化思路的内容比较多,咱们分两节来学习,今天咱们先来看上篇。负载均衡

2、肯定优化目标

跟 CPU 和 I/O 方面的性能优化同样,优化前,我会先问问本身,网络性能优化的目标是什么?换句话说,咱们观察到的网络性能指标,要达到多少才合适呢?异步

实际上,虽然网络性能优化的总体目标,是下降网络延迟(如 RTT)和提升吞吐量(如BPS 和 PPS),但具体到不一样应用中,每一个指标的优化标准可能会不一样,优先级顺序也截然不同。tcp

就拿上一节提到的 NAT 网关来讲,因为其直接影响整个数据中心的网络出入性能,因此NAT 网关一般须要达到或接近线性转发,也就是说, PPS 是最主要的性能目标。工具

再如,对于数据库、缓存等系统,快速完成网络收发,即低延迟,是主要的性能目标。而对于咱们常常访问的 Web 服务来讲,则须要同时兼顾吞吐量和延迟。

因此,为了更客观合理地评估优化效果,咱们首先应该明确优化的标准,即要对系统和应用程序进行基准测试,获得网络协议栈各层的基准性能。

在 怎么评估系统的网络性能 中,我已经介绍过,网络性能测试的方法。简单回顾一下,Linux 网络协议栈,是咱们须要掌握的核心原理。它是基于 TCP/IP 协议族的分层结构,我
用一张图来表示这个结构。

 

 

明白了这一点,在进行基准测试时,咱们就能够按照协议栈的每一层来测试。因为底层是其上方各层的基础,底层性能也就决定了高层性能。因此咱们要清楚,底层性能指标,其
实就是对应高层的极限性能。咱们从下到上来理解这一点。

首先是网络接口层和网络层,它们主要负责网络包的封装、寻址、路由,以及发送和接收。每秒可处理的网络包数 PPS,就是它们最重要的性能指标(特别是在小包的状况
下)。你能够用内核自带的发包工具 pktgen ,来测试 PPS 的性能

再向上到传输层的 TCP 和 UDP,它们主要负责网络传输。对它们而言,吞吐量(BPS)、链接数以及延迟,就是最重要的性能指标。你能够用 iperf 或 netperf ,来测试传输层的性能。

不过要注意,网络包的大小,会直接影响这些指标的值。因此,一般,你须要测试一系列不一样大小网络包的性能。

最后,再往上到了应用层,最须要关注的是吞吐量(BPS)、每秒请求数以及延迟等指标。你能够用 wrk、ab 等工具,来测试应用程序的性能。

不过,这里要注意的是,测试场景要尽可能模拟生产环境,这样的测试才更有价值。好比,你能够到生产环境中,录制实际的请求状况,再到测试中回放。

总之,根据这些基准指标,再结合已经观察到的性能瓶颈,咱们就能够明确性能优化的目标。

3、网络性能工具

同前面学习同样,我建议从指标和工具两个不一样维度出发,整理记忆网络相关的性能工具。

第一个维度,从网络性能指标出发,你更容易把性能工具同系统工做原理关联起来,对性能问题有宏观的认识和把握。这样,当你想查看某个性能指标时,就能清楚知道,能够用
哪些工具。

这里,我把提供网络性能指标的工具,作成了一个表格,方便你梳理关系和理解记忆。你能够把它保存并打印出来,随时查看。固然,你也能够把它当成一个“指标工具”指南来使用。

再来看第二个维度,从性能工具出发。这可让你更快上手使用工具,迅速找出想要观察的性能指标。特别是在工具备限的状况下,咱们更要充分利用好手头的每个工具,用少
量工具也要尽力挖掘出大量信息。

一样的,我也将这些经常使用工具,汇总成了一个表格,方便你区分和理解。天然,你也能够当成一个“工具指标”指南使用,须要时查表便可。

4、网络性能优化

总的来讲,先要得到网络基准测试报告,而后经过相关性能工具,定位出网络性能瓶颈。再接下来的优化工做,就是水到渠成的事情了。

固然,仍是那句话,要优化网络性能,确定离不开 Linux 系统的网络协议栈和网络收发流程的辅助。你能够结合下面这张图再回忆一下这部分的知识。

接下来,咱们就能够从应用程序、套接字、传输层、网络层以及链路层等几个角度,分别来看网络性能优化的基本思路

5、应用程序

应用程序,一般经过套接字接口进行网络操做。因为网络收发一般比较耗时,因此应用程序的优化,主要就是对网络 I/O 和进程自身的工做模型的优化。

相关内容,其实咱们在 C10K 和 C1000K 回顾 的文章中已经学过了。这里咱们简单回顾一下。

一、从网络 I/O 的角度来讲,主要有下面两种优化思路。

第一种是最经常使用的 I/O 多路复用技术 epoll,主要用来取代 select 和 poll。这实际上是解决C10K 问题的关键,也是目前不少网络应用默认使用的机制。

第二种是使用异步 I/O(Asynchronous I/O,AIO)。AIO 容许应用程序同时发起不少I/O 操做,而不用等待这些操做完成。等到 I/O 完成后,系统会用事件通知的方式,告诉
应用程序结果。不过,AIO 的使用比较复杂,你须要当心处理不少边缘状况。

二、而从进程的工做模型来讲,也有两种不一样的模型用来优化。

第一种,主进程 + 多个 worker 子进程。其中,主进程负责管理网络链接,而子进程负责实际的业务处理。这也是最经常使用的一种模型。

第二种,监听到相同端口的多进程模型。在这种模型下,全部进程都会监听相同接口,而且开启 SO_REUSEPORT 选项,由内核负责,把请求负载均衡到这些监听进程中去。
除了网络 I/O 和进程的工做模型外,应用层的网络协议优化,也是相当重要的一点。我总结了常见的几种优化方法。

  1. 使用长链接取代短链接,能够显著下降 TCP 创建链接的成本。在每秒请求次数较多时,这样作的效果很是明显。
  2. 使用内存等方式,来缓存不常变化的数据,能够下降网络 I/O 次数,同时加快应用程序的响应速度。
  3. 使用 Protocol Buffer 等序列化的方式,压缩网络 I/O 的数据量,能够提升应用程序的吞吐。
  4. 使用 DNS 缓存、预取、HTTPDNS 等方式,减小 DNS 解析的延迟,也能够提高网络I/O 的总体速度。

6、套接字

套接字能够屏蔽掉 Linux 内核中不一样协议的差别,为应用程序提供统一的访问接口。每一个套接字,都有一个读写缓冲区。

  • 读缓冲区,缓存了远端发过来的数据。若是读缓冲区已满,就不能再接收新的数据。
  • 写缓冲区,缓存了要发出去的数据。若是写缓冲区已满,应用程序的写操做就会被阻塞。

因此,为了提升网络的吞吐量,你一般须要调整这些缓冲区的大小。好比:

增大每一个套接字的缓冲区大小 net.core.optmem_max;
增大套接字接收缓冲区大小 net.core.rmem_max 和发送缓冲区大小net.core.wmem_max;
增大 TCP 接收缓冲区大小 net.ipv4.tcp_rmem 和发送缓冲区大小net.ipv4.tcp_wmem。

至于套接字的内核选项,我把它们整理成了一个表格,方便你在须要时参考:

不过有几点须要你注意。

  • tcp_rmem 和 tcp_wmem 的三个数值分别是 min,default,max,系统会根据这些设置,自动调整 TCP 接收 / 发送缓冲区的大小。
  • udp_mem 的三个数值分别是 min,pressure,max,系统会根据这些设置,自动调整UDP 发送缓冲区的大小。

固然,表格中的数值只提供参考价值,具体应该设置多少,还须要你根据实际的网络情况来肯定。好比,发送缓冲区大小,理想数值是吞吐量 * 延迟,这样才能够达到最大网络利用率。

除此以外,套接字接口还提供了一些配置选项,用来修改网络链接的行为。

  • 为 TCP 链接设置 TCP_NODELAY 后,就能够禁用 Nagle 算法;
  • 为 TCP 链接开启 TCP_CORK 后,可让小包聚合成大包后再发送(注意会阻塞小包的发送);
  • 使用 SO_SNDBUF 和 SO_RCVBUF ,能够分别调整套接字发送缓冲区和接收缓冲区的大小。

7、小结

今天,咱们一块儿梳理了常见的 Linux 网络性能优化方法

在优化网络性能时,你能够结合 Linux 系统的网络协议栈和网络收发流程,而后从应用程序、套接字、传输层、网络层再到链路层等,进行逐层优化。

固然,其实咱们分析、定位网络瓶颈,也是基于这些进行的。定位出性能瓶颈后,就能够根据瓶颈所在的协议层进行优化。好比,今天咱们学了应用程序和套接字的优化思路:

在应用程序中,主要优化 I/O 模型、工做模型以及应用层的网络协议;
在套接字层中,主要优化套接字的缓冲区大小。

而其余各个网络层的优化方法,建议你先本身想想,下一节,咱们再来一块儿总结。

相关文章
相关标签/搜索