Linux性能调优指南

作者: AlstonWilliams | 来源:发表于2018-02-07 21:53 被阅读221次

    在很久以前,就对性能调优有非常浓厚的兴趣。虽然之前也在做过一些性能调优的工作,但是主要集中在代码层面,以及业务层面。对如何从Linux操作系统方面进行调优,一直都没有一个清晰的认识。不过,最近偶然发现了一本IBM出的Linux调优指南,于是就拜读了一下。

    读完一些之后,就发现这本书确实就是我所需要的一本书。

    虽然之前读过一些关于操作系统的书籍,但是并不懂如何把它们应用到性能调优中。而从网上看到的一些关于性能调优的文章,也主要是集中在检测并发现性能瓶颈这些我们早就清楚的内容。对于发现瓶颈之后,如何调优,从哪些方面进行调优,这背后的原理是什么,为什么要这么调优,却没有详细的说明。

    而这本书恰恰弥补了这个空缺。弥补了操作系统高层理论以及底层调优之间的空缺。我们熟悉的操作系统,以及计算机网络,他们的处理过程,都是一些可以优化的点。

    这本书,其实称为指南更合适。从CPU,内存,IO,计算机网络等方面,一一为我们展示了优化的过程。

    这本指南也不厚,大概只有160页。内容不多,非常精简。同时也造成了一个缺点,就是,很多内容并不能全面铺开。

    但是感觉用这本指南来进入性能调优的世界,还是绰绰有余的。

    这本指南的名称是,《Linux Performance and Tuning Guidelines》

    这篇文章,便是我在读完这本指南的时候,摘录的一些笔记。

    CPU方面

    处理器指标

    • CPU使用率: 每个处理器的利用率
    • user time: CPU执行用户代码的时间,包括nice time
    • system time: CPU执行内核代码的时间,包括IRQ和softirq time
    • waiting: CPU等待IO的时间
    • Idle time: CPU空闲并等待任务的时间
    • nice time: CPU花在改变进程优先级以及执行顺序的时间
    • load average: 任务队列中,等待被CPU执行的任务的总数,以及那些等待不可中断任务完成的任务的总数,它们的平均值。也就是,系统中处于TASK_RUNNABLE以及TASK_UNINTERRUPTIBLE状态的任务的总数的平均值。
    • Runnable process: 等待被CPU执行的任务的总数
    • Blocked: 那些因为IO操作被挂起的进程的数量
    • Context switch: 系统中线程切换的总数。
    • Interrupt: 硬中断和软中断的次数。

    消除CPU瓶颈的方法

    • 确保后台没有不必要的程序
    • 给那些不重要并且是CPU密集型的应用调整优先级,让其优先级相对较低一些
    • 更新CPU

    内存方面

    内存指标

    • Free memory: 空闲内存。在Linux中,内核会将没有使用的内存中的大部分分配给文件系统缓存。所以,Free memory减去buffers以及cache占用的内存的数量,才是系统中真正的空闲内存的数量。
    • swap usage: swap in/out衡量内存是否出现了瓶颈才更加正确。因为Linux内核如果发现内存中的一些page,长时间没有被用到,就回将它放到swap中。而并不是说,只有当内存不足的时候,才会将page放到swap中。如果每秒有200-300次 swap in/out,那么说明系统的内存可能是瓶颈。
    • Buffer and cache: 为文件系统和block size分配的缓存
    • slab: 内核使用的内存数量。需要注意的是,内核使用的page不能被page out到磁盘中
    • active versus inactive memory: inactive memory将会被kswapd daemon swap out到磁盘中。

    free工具输出解释

    0.png

    消除内存瓶颈的方法

    • 调整page的大小
    • 调整处理active和inactive内存的方式
    • 降低page-out的速度
    • 限制服务器上每个用户能够使用的内存的数量
    • 停止不需要的service
    • 增加内存

    文件系统方面

    文件系统指标

    • IOWait: CPU等待IO操作的时间
    • Average queue length: 未完成的IO请求的数量
    • Average wait: IO请求等待被处理的时间,毫秒级
    • Transfers per second: 每秒有多少IO操作被执行
    • Blocks read/write per seconds: 每秒中读和写block的数量。在2.6版本的内核中,以block大小为1KB衡量。不同的内核版本中,block大小不同,从512bytes到4KB不等
    • Kilobytes per second read/write: 每秒读写block device的数据量,用kilobytes来衡量

    Linux中常见的文件系统

    • Ext2
    • Ext3
    • ReiserFS
    • Journal File System(JFS)
    • XFS

    其中,Ext3能够保证数据的一致性。而且,还能够通过配置journal mode,在数据的完整性和速度之间取得一个较好的平衡。

    而JFS和XFS,主要用在需要支持大文件的场景中。

    消除文件系统瓶颈的方法

    • 如果程序访问磁盘的方式是顺序访问,那么就换一个更好的磁盘控制器。如果是随机访问的,那么就增加更多的磁盘控制器
    • 使用RAID。RAID的读性能比较高,但是写性能低一些。而且,优先使用基于硬件实现的RAID。
    • 给磁盘合理分区
    • 增加内存
    • 通过/proc/sys/vm/dirty_background_ratio来调整内存中有多少脏数据时,pdflush daemon才将这些数据写入到磁盘
    • 通过ionice来分配IO操作的优先级:
      • idle: 最低的优先级,只有当没有高优先级的进程访问磁盘时,才有资格访问磁盘
      • Best-effort: 默认优先级。从CPU优先级中继承
      • Real time: 最高的优先级。进程总是能够访问磁盘。
    • 禁止access time updates
    • 选择合适的文件系统,以及合适的journal模式
    • 调整block size:
      如果你的服务器,更多的是处理小的文件,那么将block size调小一点,可能会提高性能。但是如果处理大文件更多,那么调大一点可能会提高性能。但是这一项对性能提升并不大,所以,默认使用操作系统的4k的block size就好。

    网络方面

    网络指标

    • Packets received and sent
    • Bytes received and sent
    • Collisions per second: 网络中发生的碰撞数量。一个配置正确的网络中,应当很少发生碰撞
    • Packet dropped: 被丢弃的包的数量。包括被防火墙过滤掉的,以及由于buffer空间不够而丢掉的
    • Overruns: buffer空间溢出的次数
    • Errors: 出错的包的数量

    数据传输的过程

    • 应用程序开启一个Socket并将数据写入到这个Socket的buffer中
    • 数据经过TCP/IP协议栈一层层地做一些处理,包装。数据并不会层层复制,因为这样性能不好。在内核中,只是修改buffer中的引用,将其传递给下一层
    • 数据通过网络到达另一台主机,我们暂且称它为主机B
    • 如果这个包的MAC地址就是主机B,那么把它放到主机B的socket buffer中
    • 主机B给CPU发出一个硬中断
    • 主机B再将数据通过TCP/IP协议栈的层层处理,传递给应用层

    Linux中的协议栈,更注重的是可靠性和低延迟,而不是低开销和高吞吐量。

    由于每一个数据包都会引发一次中断,所以,Linux中引入了一项叫做NAPI的技术。当第一个数据包到来时,还是跟之前一样,会引发一次中断。但是从此之后,网络接口会启动轮训模式,即,当有数据包到达时,不会发出中断,而是直到buffer都满了的时候,才发出一个中断。这样就能减少中断的次数。

    TCP/IP传输窗口

    TCP/IP传输窗口指的是,在收到ACK响应之前,最多能够发送的数据量。接收主机会通过TCP首部中的window size字段告诉发送主机传输窗口的大小。通过使用传输窗口,TCP能够处理地效率更高一些,因为发送主机不需要等待每一个数据包的ACK。

    高速网络中,可以使用一种叫做窗口伸缩的技术,来增加传输窗口的大小。

    Offload

    如果你的网络适配器支持offload功能,那么你可以内核就可以将一部分工作转移到网络适配器,来减少CPU的工作量,进而提高性能。

    常见的offload功能有:

    • Checksum Offload: 每一个数据包中,都会有一个校验码,用于验证这个数据包是否在传输过程中出现了问题
    • TCP segmentation offload: 当要传输的数据量大于MTU的时候,就要对数据进行分段处理。

    消除网络瓶颈的方法

    • 确保网卡的配置和路由器以及交换机的配置配套
    • 调整网络的拓扑结构
    • 使用更快的网卡
    • 在内核中调整关于网络的参数
      • MTU
      • 接收和发送缓冲区的大小
      • 传输窗口
      • 通过调整net.ipv4.tcp_tw_reuse参数让处于TIME_WAIT状态的Socket对新连接可重用
      • 通过调整tcp_fin_timeout参数,让处于FIN-WAIT-2状态的Socket可以早一些关闭,进而节省内存
      • 通过调整tcp_keepalive_time参数,调整keepalive连接的关闭时间
      • 通过调整tcp_max_syn_backlog参数来调整最大能够容纳的处于半连接状态的socket的数量
    • 关闭一些不需要的服务,以及端口号

    Linux的工具

    性能监控工具

    • top
    • vmstat
    • uptime, w
    • ps, pstree
    • free
    • iostat
    • sar
    • mpstat
    • numastat
    • pmap
    • netstat
    • iptraf
    • tcpdump, etheral
    • nmon
    • strace
    • proc file system
    • KDE System guard
    • Gnome System Monitor

    分析工具

    • lmbench
    • iozone
    • netperf

    /proc

    /proc目录中的内容,对于查看系统状态,应用程序的状态至关重要。

    /proc目录中,又有这么几块:

    • 名称为数字的目录:每一个这样的目录,里面都包含了pid为这个数字的对应的进程的信息,比如,进程使用的虚拟内存
    • acpi: ACPI中包含一些高级配置,以及电源管理等信息。因为ACPI主要是用在笔记本,或者个人PC中,所以,在服务器上,一般是禁用的
    • bus: 包含了一些和bus相关的信息,比如PCI bus或者USB接口
    • irq: 包含和中断相关的信息。每个子目录都对应一种中断。我们可以通过直接修改对应子目录的信息,来将中断绑定到一个CPU上
    • net: 包含和网络相关的统计信息
    • scsi: 包含和SCSI相关的信息
    • sys: 包含和内核相关的参数
    • tty: 包含和tty相关的信息

    从安装Linux就开始调优

    考虑下面几个问题:

    • 安装什么版本的Linux?
      • 商业版的还是开源版本的?
      • 选择商业版的哪一个版本?
    • 选择正确的内核
      有这么几种内核。
      • standard: 应用在单处理器上
      • SMP: 支持SMP以及超线程技术。一些实现也支持NUMA.
      • Xen: 包括一个可以在Xen虚拟机上运行的Linux版本
    • 如何给磁盘分区?
      尽可能使用交换分区而不是交换文件。交换分区相对于交换文件来讲,没有文件系统上的开销。
    • 使用什么文件系统?
    • 安装时,尽可能少安装包还是安装全部的包?
    • 防火墙配置
    • SELinux
    • Runlevel选择
      除非有特别需求,否则服务器上都是使用runlevel 3.

    相关文章

      网友评论

        本文标题:Linux性能调优指南

        本文链接:https://www.haomeiwen.com/subject/zagizxtx.html