Linux系统调优介绍,所以针对以上问题,可


前言:

Linux服务器运行了很多应用,在高负载下,服务器可能会出现性能瓶颈,例如CPU利用率过高、内存不足、磁盘I/O瓶颈等,从而导致系统卡顿,服务无法正常运行等问题。所以针对以上问题,可以通过调整内核参数和系统的相关组件,优化应用程序来提高服务器的性能和稳定性,避免系统崩溃和服务中断。

Linux系统优化考虑的两个方面:

  • 硬件层面:例如加内存、换用企业级SSD、提高带宽等操作。
  • 软件层面:系统内核参数、硬盘IO以及资源分配方面的配置。

在软件层面如何进行系统优化:

主要从系统内核参数、CPU、IO、网络、内存这几个方面来进行优化。

  • 内存调优:优化系统的内存使用效率,减少内存泄漏和内存碎片等问题。
  • 磁盘调优:提高磁盘的读写速度和可靠性,减少数据丢失和损坏的风险。
  • CPU调优:优化CPU的利用率,提高系统的性能和稳定性。
  • 网络调优:提高网络的性能和稳定性,减少数据传输的延迟和丢失。
  • 进程和线程调优:优化系统的进程调度算法、减少进程和线程的竞争等,提高系统的并发性能和稳定性。

系统优化的步骤:

1、使用系统监控工具、性能测试工具等,收集系统的性能数据和指标,了解系统当前的运行状态,从而识别系统的瓶颈和优化空间。

2、使用追踪工具进行追踪,定位到具体的应用程序和进程。

3、根据定位到的应用程序和进程进行分析,分析导致出问题的原因,从而对内存、磁盘、CPU等方面进行优化。

系统性能的相关概念:

IOPS:Input/Output Per Second。是指每秒钟可以进行的输入/输出操作次数,是衡量存储设备性能的重要指标之一

吞吐量:Throughput。系统在单位时间内能够处理的事务数量。

响应时间:Response Time。系统从接收请求到返回结果所需的时间。

带宽:Bandwidth。数据传输的速度,通常以每秒传输的比特数(bps)或字节(Bps)来衡量。

延时:Latency。指从请求发出到收到响应所需的时间。

瓶颈:Bottleneck。操作系统中限制系统性能的关键因素或资源。当系统中某个组件的处理能力达到极限,无法满足其他组件的需求时,就会出现瓶颈。

工作负载:Workload。是指计算机系统中正在运行的应用程序或任务的集合。

缓存:cache。缓存的作用就是用来提高系统性能的一种技术。

CPU缓存::CPU缓存是一种硬件设备,通常是集成在CPU芯片中。CPU缓存分为三个级别,包括L1、L2和L3缓存,这些级别按照缓存大小和访问速度逐渐递减。用于存储CPU需要频繁访问的数据和指令,以便更快地执行计算任务。CPU缓存速度非常快,通常比内存缓存快几个数量级,因此能够大大提高计算机的运行速度。

内存缓存:内存缓存通常是通过在系统内存中划分出一部分空间来实现的,这部分空间被称为缓存区。缓存区是由操作系统内核管理的,它在系统启动时就被分配出来,并在系统运行期间一直存在。

当应用程序需要访问内存中的数据时,内存缓存会首先检查缓存区中是否已经缓存了该数据。如果已经缓存,则可以直接从缓存区中读取数据,从而避免了从内存中读取数据的时间和能耗。如果缓存区中没有该数据,则需要从内存中读取,并将数据存储到缓存区中以供下一次访问使用。

缓冲:Buffer。缓冲通常是在内存中分配一块空间来实现的,这些空间被称为缓冲区。缓冲区是用于临时存储数据的区域,数据在这里被暂时保存并等待被进一步处理。

如将数据从一个设备传输到另一个设备时,缓冲可以暂存数据,以防止数据在传输过程中丢失或损坏。因为如果发送方速度太快,接受方不能及时接收就会导致数据丢失。

输入缓冲区(Input Buffer):用于存储输入设备(例如键盘、鼠标等)发送过来的数据,等待系统进一步处理。

输出缓冲区(Output Buffer):用于存储输出设备(例如打印机、屏幕等)接受数据,等待设备进行处理。

文件缓冲区(File Buffer):用于存储文件数据的内存区域,通过将文件数据缓存到内存中,可以减少访问磁盘的次数,提高文件读写的效率。

磁盘缓存(Disk Cache):用于存储磁盘上的数据,通过将常用的数据缓存到内存中,可以加速磁盘访问,提高系统的性能。

Linux资源信息的监控

通过对系统性能参数的监控和收集,了解当前系统的负载、CPU使用情况,内存使用、IO等信息。

一:查看系统整体的信息:

1、vmstat工具

vmstat是系统自带的一个工具,vmstat主要查看的是内存和进程的使用情况,其它例如进程、系统IO、上下文切换这些信息也可以查看。

例如:

procs:显示进程的活动情况。

  r :正在运行的以及处于排队状态的线程数,这个值和进程有关系,如果值长期大于cpu的核数(lscpu查看cpu个数),说明cpu不够,任务运行的进程太多。
  b :进程阻塞的数量,阻塞状态就是一只处于排队状态。这个值长期大于0就表明cpu资源严重不够了。一直轮不到给你分配cpu

memory:显示系统的内存使用情况。

  swap:交换分区使用了多少。0表示还没有任何使用,如果已经开始使用交换分区了,说明内存已经不够用了
  buff:缓冲区还剩多少 单位为k,一般是往硬盘里面写的时候会占用这个值。
  cache:缓存还剩多少 单位也是k

swap:显示系统的交换空间使用情况。

  说明:si和so只要大于0,说明内存有问题了。例如内存泄露、内存不够等情况。
  si:swap input:硬盘到交换分区的一个大小。
  so:swap output:从交换分区到硬盘的一个大小。

io:显示系统的磁盘I/O活动情况。

  bi:往硬盘里面写的一个值
  bo:往硬盘里面读的一个值。单位是k
  说明:如果系统的bi和bo值很大,说明io有问题。

system:显示系统的CPU使用情况。

  in:中断的数目,
  cs:上下文切换的数目
  说明:如果系统中存在大量的上下文切换和终端,说明系统可能存在某些问题

cpu:显示系统的CPU使用率。

  us:用户进程所消耗的时间
  sy:系统进程消耗的一个时间
  id:系统的空闲时间
  wa:硬盘io出现了阻塞,数据太多入口被堵死了。但是写不进去,所以就开始等待。 如果wa这个值比较大说明cpu的资源够,但是io有问题导致浪费了cpu。
  st:在虚拟化的时候会用到。

2、mpstat工具

mpstat工具和vmstat不同点在于mpstat主要监视CPU使用情况,包括每个CPU的使用率、上下文切换、中断和软中断等信息。

例如:

CPU:显示每个CPU的编号,all表示所有的cpu

%usr:显示用户空间进程使用CPU的百分比。

  说明:如果%usr较高,表示用户空间进程占用了大量CPU资源,可能是某个进程出现了问题或者某个进程需要更多的CPU资源。

%nice:显示优先级较低的用户空间进程使用CPU的百分比。

%sys:显示内核空间进程使用CPU的百分比。

  说明:如果%sys较高,表示内核空间进程占用了大量CPU资源,可能是某个内核模块出现了问题或者某个进程在等待内核资源。

%iowait:显示CPU等待I/O完成的百分比。

  说明:如果%iowait较高,表示CPU正在等待I/O操作完成,可能是磁盘、网络或其他I/O设备出现了瓶颈。

%irq:显示CPU处理硬件中断的百分比。

  说明:如果%irq较高,表示CPU正在处理大量硬件中断,可能是某个硬件设备出现了问题。

%soft:显示CPU处理软件中断的百分比。

  说明:如果%soft较高,表示CPU正在处理大量软件中断,可能是某个进程出现了问题或者某个内核模块在处理大量请求。

%steal:显示被虚拟机偷走的CPU时间的百分比。

%guest:显示虚拟机使用CPU的百分比。

%idle:显示CPU空闲的百分比。

  说明:如果%idle较低,表示CPU正在忙碌,可能是系统负载过高或者某个进程占用了大量CPU资源。

3、iostat工具

iostat主要监视磁盘I/O使用情况,包括每个磁盘的读写速度、I/O等待时间、I/O请求队列长度等,主要使用iostat工具来了解系统磁盘I/O使用情况,识别磁盘I/O瓶颈和瓶颈进程。

Device:sda1
r/s:458.09        # 表示每秒从设备中读取的次数。
rkB/s:56330.40    # 每秒读取的数据量,单位为KB。
rrqm/s:0.63       # 每秒从磁盘发出的读取请求队列的长度,单位为请求。
%rrqm:0.14        # 表示从磁盘发出的读取请求占总读取请求的百分比。
r_await:4.17      # 表示读操作的平均等待时间,单位为毫秒。
rareq-sz:122.97   # 平均每个读取请求的数据量,单位为扇区
w/s:67.28         # 表示每秒向设备中写入的次数。
wkB/s:788.53      # 每秒钟写的数量,单位是kb  
wrqm/s:54.32      # 每秒从磁盘发出的写入请求队列的长度,单位为请求
%wrqm:44.67       # 表示从磁盘发出的写入请求占总写入请求的百分比。
w_await:6.75      # 表示写操作的平均等待时间,单位为毫秒。
wareq-sz:11.72    # 平均每个写入请求的数据量,单位为扇区
d/s:0.00
dkB/s:0.00
drqm/s :0.00
%drqm:0.00
d_await:0.00
dareq-sz :0.00
aqu-sz :2.37      # 请求队列的平均长度。
%util:96.96       # 表示磁盘花费在处理请求的时间百分比 经常超过80%或90%,则说明磁盘正在高负载下运行

总结:

r/sw/srkB/swkB/sr_awaitw_await 等指标的值都很大,并且 %util 的值也很高时,可以初步判断磁盘可能存在性能问题。

4、sar工具:

相比于vmstat和pmstat,star工具提供了更全面的系统性能监控和历史数据分析功能。可以将输出的信息重定向到一个文件里面,便于后续的分析。

(1)查看CPU的使用情况:

# %user:用户空间进程所占用CPU时间的百分比。
# %nice:被nice值提高的用户空间进程所占用CPU时间的百分比。
# %system:内核空间进程所占用CPU时间的百分比。
# %iowait:CPU等待I/O操作完成所占用CPU时间的百分比。
# %steal:被虚拟化程序(如VMware)偷走的CPU时间的百分比。
# %idle:CPU空闲时间的百分比。
  • 如果%user和%system占用率较高,可能表示系统负载较高,需要进一步检查进程、IO等情况。
  • 如果%iowait占用率较高,可能表示IO瓶颈
  • 如果%idle占用率较高,可能表示系统资源未充分利用

(2)监视内存使用情况:

# kbmemfree:可用内存大小(单位:KB)
# kbmemused:已用内存大小(单位:KB)
# %memused:已用内存占总内存的百分比
# kbbuffers:缓存的内存大小(单位:KB)
# kbcached:缓存的文件系统缓存大小(单位:KB)
# kbcommit:提交内存大小(单位:KB)
# %commit:提交内存占总内存的百分比
# kbactive:活跃内存大小(单位:KB)
# kbinact:非活跃内存大小(单位:KB)
# kbdirty:脏页的内存大小(单位:KB)
  • 如果可用内存(kbmemfree)较少,已用内存(kbmemused)和已用内存占总内存的百分比(%memused)较高,可能表示内存不足
  • 如果缓存的内存(kbbuffers)和缓存的文件系统缓存(kbcached)较高,可能表示系统的文件系统缓存良好
  • 如果提交内存(kbcommit)较高,可能表示应用程序提交的内存较多
  • 如果活跃内存(kbactive)和非活跃内存(kbinact)较高,可能表示系统当前运行的应用程序较多

(3)监视磁盘I/O使用情况:

# tps:每秒传输的I/O请求数(包括读写请求)	
# rtps:每秒读请求传输的I/O请求数
# wtps:每秒写请求传输的I/O请求数
# bread/s:每秒读取的数据块数量(单位:512字节)
# bwrtn/s:每秒写入的数据块数量(单位:512字节)
  • 如果tps较高,可能表示磁盘I/O瓶颈
  • 如果rtps或wtps较高,可以进一步确认是读操作或写操作的问题
  • 如果bread/s或bwrtn/s较高,可能表示磁盘I/O吞吐量不足

(4)查看网络的基本信息:DEV

主要查看的是接收和发送数据包的速率、接收和发送数据量的速率

# IFACE:网络接口名称。
# rxpck/s:每秒接收的数据包数量。
# txpck/s:每秒发送的数据包数量。
# rxkB/s:每秒接收的数据量(KB)。
# txkB/s:每秒发送的数据量(KB)。
# rxcmp/s:每秒接收的压缩数据包数量。
# txcmp/s:每秒发送的压缩数据包数量。
# rxmcst/s:每秒接收的多播数据包数量。
  • 如果rxkB/stxkB/s非常高,但%ifutil非常低,则可能存在网络拥塞的问题

  • 如果rxcmp/stxcmp/s非常高,可能存在数据压缩的问题。

  • 如果rxmcst/s非常高,可能存在多播网络流量的问题。

    数据压缩:为了减少数据的传输量,可以对数据进行压缩。压缩的过程是将原始数据使用某种压缩算法进行编码,使其占用更少的带宽。

(5)查看网络的错误信息EDEV

可以查看网络设备的错误和丢包数。

# rxerr/s:每秒接收的错误数。
# txerr/s:每秒发送的错误数
# coll/s:每秒发生的冲突数。
# rxdrop/s:每秒接收的丢包数
# txdrop/s:每秒发送的丢包数。
# txcarr/s:每秒发生的载波错误数。
# rxfram/s:每秒接收的帧错误数。
# rxfifo/s:每秒钟由于接收FIFO队列溢出而丢失的数据包数。
# txfifo/s:每秒钟由于发送FIFO队列溢出而丢失的数据包数。
  • rxerr/srxdrop/s的值很高,可能存在网络中的接收问题,例如硬件故障或网络拥塞等。
  • txerr/stxdrop/s的值很高,可能存在网络中的发送问题,例如硬件故障或网络拥塞等
  • coll/s的值很高,可能存在网络中的冲突问题,例如网络中存在多个设备尝试同时发送数据包/

使用场景总结:

  • 需要实时监控系统资源,可以使用 vmstat 和 iostat
  • 需要对系统历史性能进行分析,可以使用 sar
  • 分布式系统中进行性能分析和监控,则可以选择 pmstat,因为分布式系统的性能监控比较复杂,pmstat的实时监控功能更灵活。
  • 如果只是想看看系统的状态,以上工具都可以。

二:查看某个进程的资源占用信息:

1、top

用来实时显示实时地显示系统中所有进程的资源占用情况。

在没有htop工具的情况下查看系统资源的信息。

按下 c 快捷键将会显示进程的完整命令行参数。

在top命令中按下快捷键盘’c‘之后。

2、ps

主要用来列出系统中所有进程的信息。

例如:运行了某个脚本,查看脚本是否启动

# 运行一个测试脚本
ehigh@ubuntu:~$ bash test.sh &
[1] 21738

# 查看这个脚本是否正常启动
ehigh@ubuntu:~$ ps -ef | grep test.sh
ehigh     21738  14974  0 11:04 pts/19   00:00:00 bash test.sh

3、htop

ttop 命令的一个增强版,可以实时地显示系统中所有进程的资源占用情况。

4、pidstat

实时地显示某个进程的 CPU 使用率、内存占用等。

5、strace

追踪某个进程的系统调用信息,可以捕获和打印出应用程序和内核之间发生的所有系统调用和信号,包括传递的参数和返回值,以及发生的错误。

例如:

# 查看执行某个命令的系统调用信息
strace `ls -l /tmp`

# 查看某个进程的系统调用:查看pid为1435这个进程的系统调用
sudo strace -p 1435 

一般可以使用strace工具来查看某个进程读取了哪些文件,进程运行慢,时间都花费在了哪些地方以及系统的调用函数等。

使用场景总结:

  • 如果想要查看系统进程和资源的占用情况,就使用top或htop。
  • 如果想要追踪某个进程的系统调用,调用耗时等信息就是用strace工具
  • 如果只是查看某个进程特定的详细信息,就使用ps工具,想要进行深入分析就是用pidstat工具。

系统调优方法

操作系统:操作系统是一个系统软件,操作系统的作用是管理和控制计算机硬件

内核:内核是操作系统的核心部分,是操作系统管理计算机硬件和软件资源的核心代码。操作系统则由内核和其他系统工具程序共同组成的。例如文件管理器、用户界面、设备驱动程序等。

程序:指的是一组计算机指令和数据,可以被计算机执行。程序是静态的,通常存储在硬盘或其他存储设备中,需要通过操作系统加载到内存中才能运行。

进程:是计算机中正在运行的程序的实例。进程是操作系统中进行资源分配的基本单位。

线程:是进程中的一个执行单元,是操作系统调度的最小单位。

内核空间:内核空间是操作系统的核心部分,是操作系统内核运行的地址空间。内核空间是操作系统独占的,只有内核才能访问这个地址空间。

用户空间:是程序运行的地址空间。用户空间是操作系统分配给应用程序的地址空间,应用程序可以在这个空间中运行和使用系统资源。

进程和程序的关系:首先程序被加载到内存中,没有开始运行的时候,只是一组静态的代码和数据。当程序被操作系统调用并开始执行时,就成为了一个进程。一个进程里面包含了程序代码、数据、寄存器等系统资源,所以每个进程都是一个程序的实体,进程是操作系统中进行资源分配和调度的基本单位。

两个虚拟文件系统:

在Linux中,/sys和/proc是两个不同的虚拟文件系统,里面的信息都是动态生成的,因为这两个目录中的数据信息随着系统状态的变化而变化。这两个文件提供了操作内核数据的接口。

/proc文件系统:主要用于展示进程相关的信息,例如可以查询内核状态和进程信息,例如CPU、内存、网络、硬件等系统信息。

/sys文件系统:则用于展示设备和内核参数的信息。/sys中不包含进程的信息,只有系统的状态和设备信息。

说明:

  • 修改了/proc/sys中的参数后可以通过sysctl工具来实现持久化配置。
  • 修改了/sys 中的信息不能使用sysctl工具来持久化配置,需要写入到/etc/rc.locl这个文件中实现持久化配置。

例如:echo deadline > /sys/block/sda/queue/scheduler就需要放到/etc/rc.locl中。

一:限制和控制进程的资源使用

1、ulimit工具

进程资源限制和控制的内容:

  • 进程的最大 CPU 时间
  • 进程可以使用的最大虚拟内存
  • 进程可以使用的最大物理内存
  • 进程可以打开的最大文件数
  • 进程可以创建的最大子进程数等等

使用ulimit工具进行资源限制的时候有两种方式:

方式一:通过在/etc/security/limits.conf 中修改资源限制,这样设置重启也会生效,可以针对系统中的所有用户或特定用户进行设置。

例如:显示当前用户进程的所有限制信息

ehigh@ubuntu:~$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited  # unlimited表示不限制
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited    #文件的最大大小,一个block=4kb
pending signals                 (-i) 47424
max locked memory       (kbytes, -l) 65536
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535   # 一个进程可以同时打开的最大文件数
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 4096        # 一个用户可以创建的最大进程数。
virtual memory          (kbytes, -v) unlimited   # 虚拟内存的最大大小
file locks                      (-x) unlimited

# 如果要查看指定进程的限制信息需要使用-p参数指定进程的pid
		# 例如:ehigh@ubuntu:~$ ulimit -a -p 1 表示查看进程为1的进程及其子进程的限制信息

例如:调整当前shell中某个进程的资源限制信息

# 限制当前shell 进程及其子进程的资源信息
-c:设置进程的核心转储文件大小限制,单位为字节。
	# 核心转储文件(core dump file)是指在程序崩溃或异常终止时,系统保存的程序内存映像文件,通常用于分析和调试程序崩溃的原因。
# 例如,要将当前进程的核心转储文件大小限制设置为 10MB,可以使用命令:ulimit -c 10000000
-m:设置进程的最大内存限制,单位为 KB。
# 例如,要将当前进程的最大内存限制设置为 1GB,可以使用命令:ulimit -m 1048576

-n:设置进程可以打开的最大文件数。
# 例如,要将当前进程可以打开的最大文件数设置为 2000,可以使用命令:ulimit -n 2000

-u:设置进程可以创建的最大用户进程数。
# 例如,要将当前进程可以创建的最大用户进程数设置为 100,可以使用命令:ulimit -u 100

# 限制指定的进程需要使用 -p 参数
	例如:将进程 ID 为 12345 的进程的最大打开文件数限制设置为 1000,命令为:ulimit -n 1000 -p 12345	

说明:使用 ulimit -a 命令查看资源限制信息时,显示的是当前用户(也就是执行该命令的用户)的资源限制信息,

例如:如果使用 root 用户登录 Linux 系统,并在一个 shell 终端下执行 ulimit -a 命令,则显示的是 root 用户的资源限制信息。

假设在这个shell终端下限制只能开启10个进程,超过了10个就会受到限制。

但是如果 root 用户在另外一个 shell 终端下执行相同的命令,不会受到在另一个终端中设置的资源限制信息影响。

如果在~/.bashrc/etc/profile中进行设置了,另外终端在该用户登录的时候会加载里面的配置,配置就会生效。

方式二:直接在命令行进行修改资源限制,只能针对当前 shell 会话的用户生效。当会话结束时,修改会自动恢复到默认值。持久化生效需要在在环境变量中进行添加。(例如 ~/.bashrc/etc/profile)中设置,每次用户登录时都会加载这些环境文件并应用资源限制。

# 格式 各列之间用 空格 或 Tab键 分隔。
<domain> <type> <item> <value>

# 说明
<domain>:需要对哪些用户或者组进行限制
	tom:表示对tom这个用户生效
	@tom:表示对tom这个用户组都生效
<type>:指定资源限制的类型,一般使用两种,soft和hard
	# soft:软限制,超过限制值就警告
	# hard:硬限制,效果限制值就拒绝
	# unlimited,表示无限制。
<item>:指定要限制那种资源
	# nofile:最多可以打开多少个文件
	# nproc:可以创建的最大进程数
	# fsize:单个文件的最大大小限制(单位:KB)
<value>:指定限制的值
	# unlimited,表示无限制
	
# 例如:
tom    hard    nproc    300
# 将用户tom的进程数量硬性限制为300个,也就是说,一旦用户tom创建的进程数超过了300个,系统就会拒绝创建新的进程并返回错误信息。	

2、PAM

PAM模块是一种Linux系统的身份验证框架。它允许管理员在登录过程中通过使用各种模块来实现不同的身份验证方式。PAM还可用于对访问系统的用户进行授权,以及在用户登录或注销时执行各种操作。

PAM的使用场景:

  • 限制用户访问、控制远程访问、限制资源使用、实现单点登录等。

3、cgroup

是一种Linux内核特性,用于限制、隔离和管理进程组的资源使用。以使用cgroup来限制进程的CPU、内存、IO等资源使用,以及隔离进程组并防止它们对系统的其他部分造成干扰。

使用场景:

  • 限制某个用户或进程的资源使用、限制 Docker 容器的资源使用、限制服务器上运行的某个应用程序的资源使用等。

使用场景说明:

PAM、cgroup和ulimit不会相互排斥,可以结合使用。

  • 如果需要对用户进行身份验证,限制用户对系统资源的访问,或者实现单点登录等功能,可以使用 PAM。
  • 如果需要限制某个用户的进程可以打开的文件数量、可以使用的 CPU 时间等,可以使用 ulimit。
  • 如果需要限制某个进程或容器的 CPU 使用率、内存使用量、网络带宽等,可以使用 cgroups。

二:CPU的优化方法

1、设置CPU的亲和性

使用场景:系统中的CPU资源较为紧张,或者应用程序的负载不均衡,可以考虑使用CPU亲和性设置来优化CPU资源的利用

通过taskset命令进行设置CPU的亲和性,该命令可以将进程或线程绑定到指定的CPU核心上,以提高程序的性能和可靠性。

例如,以下命令将进程ID为1234的进程绑定到CPU核心0和1上:

taskset -c 0,1 -p 1234

2、调整CPU的调度策略

默认的CFS策略已经能够满足日常需求,如果在某些特定的情况下可以改变调度策略来进行优化,例如高负载、需要实时响应等场景。

实现方法:需要编译内核加上对应的驱动程序,风险极大。

3、调整时间片大小

场景:如果应用程序需要更快的响应时间,可以考虑减小时间片大小。

实现方法:需要编译内核启用对cpu时间片大小修改的支持,风险极大。

缺点:会增加系统的开销,可能会降低系统的整体性能,因为需要增加系统上下文的切换次数。

4、调整CPU的迁移开销

场景:通过CPU迁移开销的调整,可以提高系统的负载均衡和响应速度

实现方法:也是需要编译内核加上对应的驱动程序才可以,通过修改对应的值来调整CPU的迁移开销。修改内核风险极大。

缺点:减小CPU迁移开销可能会导致更频繁的CPU迁移,从而增加系统的开销和延迟,导致进程的局部性和缓存效率下降,从而降低系统的整体性能。

二:内存的优化方法:

1、优化对swap分区的使用

swap分区是一块硬盘空间,用于存放内存中不常用的数据。在Linux系统中,合理设置swap分区的大小可以有效地提高系统的稳定性和性能。因为swap分区的速度太慢,一般都是直接关闭swap分区的使用。

关闭swap分区的方法:

 swapoff -a  # 临时关闭

2、调整虚拟内存参数

如果一定要使用swap分区,可以通过调整/proc/sys/vm/swappiness的值为0来确保尽量使用物理内存。

# 1. 修改内核参数
ehigh@ubuntu:~$ sudo vim /etc/sysctl.conf
	vm.swappiness = 60
# 2. 生效
ehgh@ubuntu:~$ sysctl -p

3、调整脏页的最大内存量

脏页是指已被修改但尚未写入磁盘的内存页。内核使用 dirty_bytes 值来确定何时开始刷新脏页到磁盘。

调整页面缓存的大小(/proc/sys/vm/dirty_bytes),提高系统的性能。

优化建议:

  • 系统有足够的内存和IO资源,可以增加dirty_bytes的值,以减少频繁写回磁盘的次数,从而提高性能
  • 统资源不足,可以降低dirty_bytes的值,以避免过多的脏页面积累,从而避免系统性能下降或内存耗尽。

优点:增大脏页数据的值可以减少磁盘 I/O和提高提高内存利用率,因为当系统中存在大量可用内存时,增加 dirty_bytes 值可以让内核将更多的脏页存储在内存中,提高内存利用率。

缺点:如果内存不足会导致系统性能下降,可能会造成磁盘IO洪水,如果断电未写入磁盘的脏页数据可能会丢失。

例如:将页面缓存得大小改为1G

# 1. 修改内核参数
ehigh@ubuntu:~$ sudo vim /etc/sysctl.conf
	vm.dirty_bytes=1073741824  # 将脏页的内存量调整为1G
# 2. 生效 
ehigh@ubuntu:~$ sysctl -p

4、使用内存缓存

tmpfs:tmpfs是一种基于内存的文件系统,tmpfs中的数据不需要将数据写入硬盘,因此可以获得更快的文件读写速度。

例如:

# 1. 创建挂载点
mkdir /mnt/cache

# 2. 挂载tmpfs文件系统
mount -t tmpfs -o size=2G tmpfs /mnt/cache

# 3. 将需要进行缓存的文件或目录复制到挂载点目录下
cp -r /path/to/files /mnt/cache

# 4. 应用程序或脚本中的文件路径修改为挂载点目录下的路径

# 5. 当文件读取或写入完成后,可以通过rsync等工具将缓存中的文件同步到硬盘上,从而避免数据的丢失。
rsync -a /mnt/cache/ /path/to/files/

内存缓存适用的场景:

(1)Web服务器:在Web服务器中,通常会缓存静态文件(如CSS、JavaScript、图片等),以提高网站的性能和响应速度。使用tmpfs作为内存缓存,可以将这些静态文件缓存到内存中,提高数据读取速度,减轻磁盘负载。

(2)数据库服务器:在数据库服务器中,经常需要将一些数据放在内存中进行缓存,以提高查询性能。使用tmpfs作为内存缓存,可以将这些数据缓存到内存中,避免频繁的磁盘IO操作,提高查询性能。

(3)虚拟机:在虚拟机环境中,可以使用tmpfs作为内存缓存,以提高虚拟机的磁盘IO性能。例如,可以将虚拟机的磁盘镜像文件(如vmdk、qcow2等)缓存到tmpfs中,避免频繁的磁盘IO操作。

5、配置大页

大页是一种特殊的内存页,它的大小通常是默认页大小的几倍,比如 2MB 或者 1GB。

在内存充足的情况下,可以提高 Linux 系统的性能。使用大页可以减少内存页表的大小,从而提高内存访问的效率。对于一些需要频繁访问内存的应用程序(比如数据库),启用大页可以显著提高性能。

例如:运行虚拟机的时候配置大页能显著提升性能。

如果内存小配置大页会降低系统的性能。

配置实现流程:

# 1. 查看是否开启大页功 默认情况下,已经开启了透明大页功能:
root@ubuntu:~# cat /sys/kernel/mm/transparent_hugepage/enabled 
always [madvise] never

# 2. 查看大页的数目 默认为0
root@ubuntu:~# cat /proc/sys/vm/nr_hugepages
0

# 也可以通过下面的方法查看
root@ubuntu:~# cat /proc/meminfo  | grep -i Hugep
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
FileHugePages:         0 kB
HugePages_Total:       0    # 大页的总数为0
HugePages_Free:        0    # 前可用的大页数
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

# 3. 设置大页的数量  表示使用2000个2M大小的大页
echo 2000 > /proc/sys/vm/nr_hugepages

# 挂载大页
mount -t hugetlbfs nodev /PATH

# 查看是否正常挂载
 cat /proc/mounts | grep hugetlbfs

6、脏数据的回收

脏数据就是对内存中已被修改但尚未写入磁盘的数据进行回收。

脏数据自动回收:

通过修改vm.dirty_expire_centisecsvm.dirty_writeback_centisecs的值来调整脏数据回收的时间间隔。

# 脏数据在内存中存留的时间,单位为1/100秒
ehigh@master-1:~$ cat /proc/sys/vm/dirty_expire_centisecs 
3000

# 脏数据的写入间隔时间,单位为1/100秒
ehigh@master-1:~$ cat /proc/sys/vm/dirty_writeback_centisecs
500

脏数据手动回收:

使用sync命令将内存中的所有脏数据写回磁盘,以减少数据丢失或损坏的风险。

sync命令会强制将文件系统中所有修改过的数据缓存写回磁盘,包括脏数据和元数据。

如何调整脏数据回收的时间:

  • 如果追求系统的性能,可以把vm.dirty_expire_centisecsvm.dirty_writeback_centisecs的值改大,减少磁盘IO的操做。
  • 如果追求数据的安全性,可以把vm.dirty_expire_centisecsvm.dirty_writeback_centisecs的值改小,防止数据丢失。

7、清理缓存

只有在应用程序出现崩溃或无响应的情况,系统出现“内存不足”或“无法为应用程序分配足够的内存”中各种情况可以考虑清理缓存,以确保系统的正常运行。

注意:清空缓存可能会导致系统性能下降,因为需要重新从磁盘读取数据。因此,在清空缓存之前,需要仔细考虑清空缓存的必要性,并确保系统有足够的内存来重新缓存数据。

例如:free非常小,而available比较大,说明系统正在使用大量的缓存来提高性能,并且这些缓存可以被重新分配给新的进程或应用程序,这种情况清理缓存会影响性能。

清空文件系统缓存:

ehigh@ubuntu:~$ sudo sync && echo 3 > /proc/sys/vm/drop_caches

清空内存缓存:

ehigh@ubuntu:~$ sudo echo 1 > /proc/sys/vm/drop_caches

三:磁盘的优化方法:

1、挂载参数优化

在挂载硬盘时,使用noatime选项可以避免在每次读取文件时更新文件的访问时间,减少磁盘IO操作,提高硬盘性能。在/etc/fstab文件中添加noatime选项即可。

2、文件系统优化

对于大量小文件的读写,使用 ext4 文件系统可能比使用 XFS 文件系统更适合。

Linux中一个文件的组成:

Linux上的一个文件 ≈ 一个Inode + 若干Block

Inode:存放文件的属性信息,每个Inode有一个唯一的Inode号,Inode的节点号是一个32位无符号的整型数,因此每个文件系统上的inode节点总数最多为2^32个(约42亿个)。

Block:存放文件真正的数据部分,一个Block的大小默认是4KB。

# nodes per group:表示每个块组中 inode 的数量
# Blocks per group:表示每个块组block的数量

Inode的默认分配策略:

一般系统会将1%的磁盘空间分配为inode区域,如果默认每个block的大小是4KB,Inode的默认大小是256Byte,那么一个block可以存放16个Inode。

Inode数量对硬盘的影响:

硬盘在格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。

Inode数量多:能存储更多的文件,可能会造成增加磁盘碎片的概率,影响文件系统的性能,还会使得文件系统的检查变慢,导致开机变慢。

Inode数量少:存储的文件数量变少,但是最大可存储文件数量也大大减少

调整Inode的数量:

如果硬盘上存放有很多小文件,会导致Inode的数量快速被用完,造成inode 节点不足的问题。

例如:创建文件系统时手动设置 inode 数量:

# 将 inode 数量设置为 2000000
mkfs.ext4 -N 2000000 /dev/sdb1

3、根据不同的场景选择磁盘调度算法

在Linux系统中,磁盘的三种调度算法分别为 CFQ、Deadline 和 NOOP

CFQ调度算法

Linux系统默认的磁盘调度算法,会根据每个进程的优先级和历史I/O请求时间来计算每个队列的权重,然后按照权重顺序调度I/O请求。

使用场景:适合多任务环境下的桌面系统和服务器系统。例如Web服务器、数据库服务器

Deadline调度算法

将I/O请求分为两类:实时I/O请求和普通I/O请求。实时I/O请求是指需要立即响应的请求,例如鼠标、键盘输入等。普通I/O请求是指需要等待一定时间才能得到响应的请求,例如文件读写操作等。

将实时I/O请求插入到队列头部,优先处理;对于普通I/O请求,则会设置一个截止时间(deadline),在此之前尽可能地处理请求。

使用场景:适合需要响应速度较快的应用程序,例如实时音视频应用、游戏等。

NOOP调度算法

一种简单的调度算法,它不会对I/O请求进行排序或调度,而是按照请求的先后顺序依次处理。在高负载的情况下,NOOP调度算法可以减少CPU的消耗,但是在磁盘较忙的情况下可能会导致响应时间较长。

使用场景:适合低负载的系统,例如桌面系统或者轻负载的服务器系统。或者SSD磁盘

修改磁盘调度算法:/sys/block/<device>/queue/scheduler文件

例如:

# 1. 编辑内核参数的配置文件
sudo vim /etc/default/grub

# 2. 找到GRUB_CMDLINE_LINUX_DEFAULT行,并在双引号中添加要修改的内核参数, elevator=cfq表示调度算法设置为cfq
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash elevator=cfq"

# 3. 更新GRUB配置
sudo update-grub

$ 4. 重启系统
sudo reboot

# 注意:内核参数是区分大小写,写调度算法名称的时候需要全部小写
# 例如:
elevator=deadline
elevator=cfq
elevator=noop


# 查看当前磁盘使用的调度算法
root@ecs-1746-0001:/sys/block# cat /sys/block/vda/queue/scheduler
[mq-deadline] none   # 方括号中的算法名称表示当前生效的调度算法。

4、设置预读取数据的大小

默认情况下,Linux 内核会自动根据设备类型和性能来选择合适的预读取大小。

通过设置块设备的预读取数据大小/sys/block/vda/queue/read_ahead_kb,以加快读取速度。

# 磁盘缓存的默认大小是128kb
root@ecs-1746-0001:~# cat /sys/block/vda/queue/read_ahead_kb
128

预读取大小的设置规则:

一般预读取大小在 64KB 到 256KB 之间是比较合适,如果太小浪费磁盘IO,太大浪费内存资源。高速 SSD 设备,预读取的大小页不要超过 1MB。

5、优化磁盘碎片

磁盘碎片是指硬盘上存储的文件在写入和删除过程中被分割成不连续的片段,使得文件在硬盘上的物理位置不再是连续的。所以导致磁盘的读写速度变慢。

查看和清理磁盘碎片:

ext4文件系统:

# 查看是否存在磁盘碎片
ehigh@ubuntu:~$ sudo dumpe2fs /dev/sda1

# 清理磁盘碎片  清理sda1的磁盘碎片
ehigh@ubuntu:~$ sudo e4defrag /dev/sda1

xfs文件系统:

# 查看是否存在磁盘碎片
ehigh@ubuntu:~$ sudo xfs_db	-c  frag /dev/sda1

# 清理磁盘碎片
ehigh@ubuntu:~$ sudo xfs_fsr /dev/sda1

四:对网络进行优化:

1、调整TCP/IP参数来优化网络

Linux系统默认的TCP/IP参数适用于多数情况,但是对于高负载或者高流量的应用需要调整TCP窗口大小、最大并发连接数、最大传输单元(MTU)等参数。

例如:如果需要处理10000个并发连接,可以将这两个参数设置为10000:

echo "10000" > /proc/sys/net/ipv4/tcp_max_syn_backlog  # TCP最大连接数,默认是1024
echo "10000" > /proc/sys/net/core/somaxconn # 最大同步连接数,默认是1024

2、开启TCP的快速连接机制

在Linux内核版本3.7及以上,TCP快速打开已经默认启用。CP快速打开可以减少TCP三次握手的时间,从而提高连接速度和性能。

例如:

root@ecs-1746-0001:~# echo "2" > /proc/sys/net/ipv4/tcp_fastopen 

# 0:禁用TCP Fast Open功能。
# 1:启用TCP Fast Open客户端功能,但不启用服务器端功能。这是默认值。
# 2:启用TCP Fast Open客户端和服务器端功能。

3、启用TCP拥塞控制算法

例如,Cubic、Reno、BIC等。选择适合自己应用的拥塞控制算法可以提高网络性能和稳定性。

Cubic算法:更为适用于高延迟、高带宽的网络环境

Reno算法:适合传输速度相对较快,延迟较低,丢包率也较低的网络环境

# 当前系统中可用的TCP拥塞控制算法
root@ecs-1746-0001:~# cat /proc/sys/net/ipv4/tcp_available_congestion_control
reno cubic

# 设置TCP拥塞控制算法
root@ecs-1746-0001:~# echo 'cubic' > /proc/sys/net/ipv4/tcp_congestion_control

# 持久化设置
root@ecs-1746-0001:~# vim /etc/sysctl.conf
net.ipv4.tcp_congestion_control=cubic

4、调整网络缓冲区大小

Linux系统默认的网络缓冲区大小适用于大多数情况,但是对于高负载或者高流量的应用,需要调整增大套接字缓冲区大小、读写缓冲区大小等。

例如:如果需要处理大量的网络流量,可以将这些参数设置为较大的值

echo "16777216" > /proc/sys/net/core/wmem_max
echo "16777216" > /proc/sys/net/core/rmem_max
echo "16777216" > /proc/sys/net/core/optmem_max

5、禁用IPv6

如果没有使用IPv6,禁用IPv6协议,从而减少网络连接的负载。

禁用IPV6:

root@ecs-1746-0001:~# vim /etc/sysctl.conf
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1

root@ecs-1746-0001:~# sysctl -p

6、TCP窗口大小

通过修改窗口的大小,提升网络的传输速度和网络性能。

例如:

sudo vim /etc/sysctl.conf
net.ipv4.tcp_window_scaling = 1  # 启用TCP窗口扩展功能
net.ipv4.tcp_rmem = 4096 131072 6291456  # 最小值、默认值和最大值
net.ipv4.tcp_wmem = 4096 16384 4194304

7、调整连接队列和最大连接数

如果TCP的连接队列太小,就会导致客户端连接请求被拒绝,如果连接队列太大,就会占用过多的内存资源

如果TCP的最大连接数设置得太低,会导致系统无法支持足够的并发连接,从而导致系统响应变慢或者连接超时。

调整TCP的连接队列和最大连接数:

# 查看当前系统的最大连接数:
# 查看当前的TCP最大连接数是否接近系统的最大连接数,如果接近就修改为一个更大的值。
ss -n | grep tcp | grep ESTABLISHED | wc -l

# 查看TCP的最大连接数  默认TCP的最大连接数是256
ehigh@ubuntu:~$ cat /proc/sys/net/core/somaxconn
256

# 设置TCP的最大连接数
ehigh@ubuntu:~$ sudo sysctl -w net.core.somaxconn=2048

# 设置TCP的连接队列   一般设置为最大连接数的两倍
sysctl -w net.core.somaxconn=1024

相关内容