一
进程调度:
OS: 硬件抽象,虚拟计算机
system call 不再面对硬件,而是面对硬件所输出的接口
CPU: 基于时序完成运算 time slice
优先级:
调度器: Big O 大o标准
衡量一个算法的时间复杂度的标准 多个
O(1)
就调度器本身而言,无论被等待的进程个数有多少,算法从这些被调度进程当中选择一个所需要的时长是恒定的;
如何实现:
所有进程按优先级进行排队,0-139 即:140个优先级--140个队列
待调度的进程一定是优先级最高的进程 空闲CPU 扫描140个优先级的头部--时间恒定
0-99: 实时优先级
100-139:
静态优先级: 用户手动指定,修改nice值
0-139:
动态优先级:内核维护追踪进程状态的机制,每个进程此前被调度次数和消耗时长来增加或降低指定进程优先级的
内核维护每个进程,进程本身所消耗的CPU时长,消耗较多的进程会降低其优先级,消耗较少的进程会提升其优先级
看内核源码--内核调度如何实现
Memory:
虚拟地址空间
内核空间
用户空间
PAE: 物理地址扩展
32bits,4bits 64G
线性地址空间依然为4G
MySQL: 单进程多线程
2.7G
page frame: 分页
RSS
strace
tlb、LSB
huge page:
NUMA 多颗CPU
CPU亲缘性绑定
nginx专有CPU
0000,0001,0101,1111
cpu 1,3
taskset -p mask pid
taskset mask --program
taskset -c 0,5,7,9 --myprogram
taskset -p -c cpu1,cpu2,... pid 对当前系统生效,重启后失效,可以写脚本
/etc/grub2.conf
linux16 /vmlinuz-3.10.0-862.el7.x86_64 root=UUID=17bafb33-37b7-4df5-9731-7626d2358a8c ro crashkernel=auto biosdevname=0 net.ifnames=0 rhgb quiet LANG=en_US.UTF-8
在其后面添加 isolcpus=cpu number,...,cpu number
系统启动时,仅隔离cpu,不能隔离进程,定义内核用的CPU
# 进程运行在哪颗CPU上
[root@node1 ~]# ps axo psr,comm
PSR COMMAND
1 systemd
0 kthreadd
0 ksoftirqd/0
0 kworker/0:0
... ...
[root@node1 ~]# ps axo psr,comm,pid
PSR COMMAND PID
0 systemd 1
0 kthreadd 2
0 ksoftirqd/0 3
0 kworker/0:0 4
... ...
# CPU详细信息
[root@node1 ~]# cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 158
model name : Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
stepping : 9
microcode : 0x48
cpu MHz : 2808.002
cache size : 6144 KB
# 更改pickup进程的CPU亲缘性
[root@node1 ~]# ps axo psr,comm,pid |grep pickup
1 pickup 1079
[root@node1 ~]# taskset -p -c 0 1079
pid 1079's current affinity list: 0,1
pid 1079's new affinity list: 0
[root@node1 ~]# ps axo psr,comm,pid |grep pickup
0 pickup 1079
[root@node1 ~]# taskset -p -c 0,1 1079
1079进程pickup,运行在0或1上都可以
taskset -p -c cpu1,cpu2,... pid 对当前系统生效,重启后失效,可以写脚本
IRQ中断请求
ISR中断服务路由 中断请求分给哪个cpu的
IRQ smp_affinity
/proc/irq/IRQ_NUMBER/smp_affinity
/proc/interrupts文件 列出每个I/O设备中每个CPU的中断数
每个CPU核处理的中断数,中断类型,以及用逗号分开的注册为接收中断的驱动程序列表。
0号cpu忙,需要留给内核用
[root@node1 ~]# cat /proc/interrupts
CPU0 CPU1
0: 49 0 IO-APIC-edge timer
1: 12 0 IO-APIC-edge i8042
8: 1 0 IO-APIC-edge rtc0
9: 0 0 IO-APIC-fasteoi acpi
12: 15 0 IO-APIC-edge i8042
14: 0 0 IO-APIC-edge ata_piix
15: 1820 0 IO-APIC-edge ata_piix
16: 18 886 IO-APIC-fasteoi vmwgfx, eth1
17: 6750 0 IO-APIC-fasteoi ioc0, snd_ens1371
... ...
[root@node1 ~]# cat /proc/irq/0/smp_affinity
ffffffff,ffffffff,ffffffff,ffffffff 表示系统中的任意CPU提供IRQ
将这个值设定为1,即表示只有cpu0可以提供这个中断
[root@node1 ~]# echo 1 > /proc/irq/0/smp_affinity
对当前系统生效,重启后失效,可以写脚本
这里使用的CPU应该为/etc/grub2.conf中isolcpus定义CPU集合之外的其他CPU。
实际上,买个服务器是最佳方案,不提倡这样优化,除非没有钱买服务器,需要压榨它最后一点性能
这样做可能影响系统不稳定
做压测可以这样做
生成环境,越简单越标准越好
numactl 控制NUMA策略
NUMA亲和性管理守护进程(numad)
5万以上服务器
二
0-139
一般:数字越小,优先级越高
实时优先级:1-99,数字越大,优先级越高
动态优先级:数字越小,优先级越高
调度类别:
SCHED_FIFO:real-time(实时优先级调度) 内核级别的实时进程
启动该程序时,以指定的优先级,放在 SCHED_FIFO中启动
chrt -f [1-99] /path/to/program arguments
SCHED_RR:real-time
chrt -r [1-99] /path/to/program arguments
SCHED_NORMAL,SCHED_OTHER:100-139 用户空间--cfs:完全公平调度
nice,renice(已经启动的进程)
电商站点:
搜索引擎占用资源很大,内核可能会降低该搜索引擎的优先级,一旦其他服务需要资源,就会让其他服务优先使用该资源
而我们急需的搜索引擎得不到该有的资源,此时需要调整其优先级或者把其放到实时优先级中
建议使用CPU Utilization工具:
htop,dstat,glance,sar
sar -P ALL 1 2 -P显示cpu的利用率、ALL所有cpu、1时间间隔、2显示批次
# 查看CPU利用率
[root@node1 ~]# yum -y install sysstat
[root@node1 ~]# sar -P ALL 1 2
Linux 3.10.0-862.el7.x86_64 (node1.fgq.com) 03/19/2019 _x86_64_ (2 CPU)
11:59:21 AM CPU %user %nice %system %iowait %steal %idle
11:59:22 AM all 0.00 0.00 0.00 0.00 0.00 100.00
11:59:22 AM 0 0.00 0.00 0.00 0.00 0.00 100.00
11:59:22 AM 1 0.00 0.00 0.00 0.00 0.00 100.00
11:59:22 AM CPU %user %nice %system %iowait %steal %idle
11:59:23 AM all 0.00 0.00 1.00 0.00 0.00 99.00
11:59:23 AM 0 0.00 0.00 1.00 0.00 0.00 99.00
11:59:23 AM 1 0.00 0.00 0.00 0.00 0.00 100.00
Average: CPU %user %nice %system %iowait %steal %idle
Average: all 0.00 0.00 0.50 0.00 0.00 99.50
Average: 0 0.00 0.00 0.50 0.00 0.00 99.50
Average: 1 0.00 0.00 0.00 0.00 0.00 100.00
%steal 被虚拟化拿走的cpu占比
[root@node1 ~]# iostat -c 1 2
Linux 3.10.0-862.el7.x86_64 (node1.fgq.com) 03/19/2019 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.04 0.00 0.13 0.00 0.00 99.82
avg-cpu: %user %nice %system %iowait %steal %idle
0.50 0.00 2.50 0.00 0.00 97.00
# 查看队列
[root@node1 ~]# uptime
14:06:44 up 2:41, 1 user, load average: 0.00, 0.01, 0.05
平均负载:等待运行的队列的平均长度(1分钟-5分钟-15分钟)
[root@node1 ~]# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 1465836 2076 292432 0 0 10 4 34 36 0 0 100 0 0
0 0 0 1465836 2076 292464 0 0 0 0 110 94 0 0 100 0 0
0 0 0 1465836 2076 292464 0 0 0 0 86 77 0 0 100 0 0
r--运行队列,b--阻塞队列
cpu上等待运行队列很长,表明运行的进程很多,可能是cpu性能较低或者io导致
strace 通过系统调用,来判断进程阻塞原因
sysdig 编译,更加美观,通过/proc 和 /sys 内容来用更加直观的方式表示出来
sysdig安装使用
文档:https://github.com/draios/sysdig/wiki/How-to-Install-Sysdig-for-Linux
[root@node1 ~]# rpm --import https://s3.amazonaws.com/download.draios.com/DRAIOS-GPG-KEY.public
[root@node1 ~]# curl -s -o /etc/yum.repos.d/draios.repo https://s3.amazonaws.com/download.draios.com/stable/rpm/draios.repo
[root@node1 ~]# yum list dkms
epel-release-latest-7.noarch.rpm已经安装了
[root@node1 ~]# yum -y install kernel-devel
[root@node1 ~]# yum -y install sysdig
[root@node1 ~]# csysdig
[root@node1 ~]# sysdig |less
参考文档:https://github.com/draios/sysdig/wiki/sysdig-examples
查看网络带宽占用最高的进程
[root@node1 ~]# sysdig -c topprocs_net
数据交换ip是192.168.25.1
[root@node1 ~]# sysdig -s2000 -X -c echo_fds fd.cip=192.168.25.1
线性地址-->物理地址
缺页异常
重新加载数据到内存中
访问权限受限
写时复制: 子进程从父进程中复制自己所要修改的数据到一个新的地址空间中
共享库
两个进程所用到的共享库,在内存中只保留一份,节约内存空间
/lib64/下面的.so文件--都是被调用时要执行的代码段--无数据
数据处理--是根据各个进程地址空间中自己的数据来处理数据,调用代码无影响,所以可以复用共享库
缺页异常
PAE--物理地址扩展
CPU跟外部IO设备交互的方式:
poll: 轮询,盲等待
中断:
DMA: 自带的芯片
32位地址空间--3段: ZONE_HIGHMEM ZONE_NORMAL ZONE_DMA Reserved
64位地址空间: ZONE_NORMAL ZONE_DMA
物理内存中--页框
线性内存中--页面
1G=256000个页面
valgrind 开源
代码写完后是否有内存泄露,内存泄露--导致内存空间不足,不能及时释放内存
systemtap,oprofile,valgrind 好用的工具,需要写脚本
优化内存使用
容量调节
参数位于/proc/sys/vm目录中
overcommit_memory
0--默认
1--内核执行无内存过量使用处理,会增大内存超载的可能性,但可增强大量使用内存任务的性能
2--内存不等于或大于总可用swap大小以及overcommit_ratio制定的物理RAM比例的内存请求
减小内存过度使用的风险,该设置最好
overcommit_ratio
overcommit_memory 设定为2,指定所考虑的物理RAM比例。默认50。
总物理内存地址空间:swap+ram*overcommit_ratio
4g swap,物理内存 2g,可使用超载空间=4+2*0.5=5g
4g swap,物理内存 64g,可使用超载空间=4+64*0.5=36g
显然不行,此时需要把overcommit_ratio设定值较大一点,如0.9或者0.95
或者直接把overcommit_memory 设定为1,不用再考虑 overcommit_ratio的设定了
nr_hugepages
默认0。设定为正值,只有系统中有足够的连续可用页时可分配超大页。
内存参数设置为开机有效
[root@node1 ~]# vim /etc/sysctl.conf
添加如下信息
# 不允许使用过量内存
vm.overcommit_memory = 1
[root@node1 ~]# free -m 设定之前先查看内存是否够用
[root@node1 ~]# sysctl -p
vm.overcommit_memory = 1
[root@node1 ~]# free -m
total used free shared buff/cache available
Mem: 1821 117 1035 9 668 1487
Swap: 0 0 0
[root@node1 ~]# cat /proc/meminfo
AnonHugePages: 10240 kB
CmaTotal: 0 kB
CmaFree: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
[root@node1 ~]# vim /etc/sysctl.conf
添加如下信息:
# 内存中可以分配的超大页个数
vm.nr_hugepages = 10
[root@node1 ~]# sysctl -p
vm.overcommit_memory = 1
vm.nr_hugepages = 10
[root@node1 ~]# cat /proc/meminfo
... ...
HugePages_Total: 10
HugePages_Free: 10
... ...
可以把这个内存页变成文件系统挂载到某个目录下--基于内存的文件系统
容量相关内核可调节参数
较大内存使用 /proc/sys/kernel目录中
msgmax 消息队列 队列中单个消息允许的大小65536,2*6 64k
msgmnb 内核中维护多少个队列
msgmni 消息队列识别符的最大数量,64位架构机器默认是1985,32位是1736
Linux安装oracle,需要跳大
shmall 共享内存 规定一次在该系统中可以使用的共享内存总量--每一片最大能有多大
shmmax 内核可允许的最大共享内存片段--片数*片的最大值=该值的最大值能有多大
shmmni 可允许有多少片
threads-max 进程请求时,需要创建线程,一批可以有多少个,最小为20
容量相关文件系统可调节参数
aio-max-nr 异步io时最大事件总量。65535,nginx可能会跳大
file-max 当前系统允许打开的最大文件数量
一般不调整,调大后,内存消耗增多,确保内存可用
Out-of-Memory Kill
内存不足,kill掉进程
oom_adj
被kill的优先级-16到15之间,帮助决定某个进程的oom_score。该值越高,被oom_killer杀死的进程数就越多
oom_adj值设定-17,则该进程禁用omm_killer
搜索引擎耗内存,避免被kill掉--可调整oom_adj值为-17
但是在pid文目录中调整进程参数不会写进写配置文件中,需要写脚本(获取id号,而后修改其值)或者手动进行
调整虚拟内存
swappiness 值0-100,默认值60 内核使用交换内存倾向性的 值越小,越不用swap
min_free_kbytes 空闲内存可用最低标准
dirty_ratio 百分比值,脏数据(内存中被修改的数据,还没有同步到磁盘),默认30%占比,自己修改为40%较好
[root@node1 ~]# cat /proc/sys/vm/dirty_ratio
30
dirty_background_ratio
drop_caches
slab
buddy system 避免外碎片
slab sysstem 避免内碎片
[root@node1 ~]# cat /proc/slabinfo
slabinfo - version: 2.1
# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
xfs_dqtrx 0 0 528 62 8 : tunables 0 0 0 : slabdata 0 0 0
xfs_dquot 0 0 488 67 8 : tunables 0 0 0 : slabdata 0 0 0
xfs_ili 1104 1104 168 48 2 : tunables 0 0 0 : slabdata 23 23 0
xfs_inode 4658 4658 960 34 8 : tunables 0 0 0 : slabdata 137 137 0
... ...
[root@node1 ~]# cat /proc/buddyinfo
Node 0, zone DMA 2 9 5 1 3 3 3 2 1 1 1
Node 0, zone DMA32 309 204 48 100 59 21 4 3 2 6 379
IO
I/O scheduler
CFQ: Completely Fair Queue
Deadline:
Anticipatory:
Noop: 先到先得,no operation
每磁盘一个调度器
sata 格式固态硬盘--性能提升2-3倍
pci-e 性能接近内存
io压力测试工具:
aio-stress,fio,iozone
修改磁盘调度器的方式:
ls /sys/block/sda/queue/iosched/ 调度参数
fifo_batch front_merges read_expire write_expire writes_starved
cat /sys/block/sda/queue/scheduler
noop [deadline] cfq []表明deadline是正在使用的调度器
echo "cfg" > /sys/block/sda/queue/scheduler 更改调度器为cfg
cat /sys/block/sda/queue/scheduler
noop deadline [cfq]
ls /sys/block/sda/queue/iosched/ 该目录下文件发生变化,因为调度器变化,随之相关的参数也发生变化
back_seek_max fifo_expire_async group_idle quantum slice_async_rq slice_sync
back_seek_penalty fifo_expire_sync low_latency slice_async slice_idle target_latency
nginx server cfq
mysql server deadline,可能造成延迟
文件系统
文件系统
查看单个文件是否发生碎片化,即离散的存放到非连续磁盘块上
filefraq -v /path/to/file
显示大量非连续磁盘块,即磁盘中有碎片
dumpe2fs /dev/some_device_partion
调优
格式化选项
4k/页框
选择合适大小的块 大量小文件用小磁盘块 少量大文件用大磁盘块
外部日志
挂载选项
Barriers 准确写入,影响数据延迟
nobarrier 挂载时禁用barrier
noatime 访问时间,阻止元数据更新
预读支持
blockdev
ext4文件系统
内节点表初始化 lazy_itble_init=1 延迟初始化文件系统到所有内节点表
auto-fsync noauto_da_alloc 禁用fsync(),因为该选项耗时
日志i/o优先权 journal_ioprio=n 默认3,0-7,0最高优先权
xfs文件系统
用它很好
网络优化
tcp state
client-->server 3握手4挥手
参考相关优化文档即可--百度
千兆带宽
1000*1024 k
1000*1024*1024 字节 bps
1000*1024*1024/8 B
1000*1024*1024/8 * 2.5*10^-3 s(秒)
核心缓冲大小
net.core.rmem_default 接收
net.core.rmem_max
net.core.wmem_default 写入
net.core.wmem_max
[root@node1 ~]# cat /proc/sys/net/core/rmem_default
212992
[root@node1 ~]# cat /proc/sys/net/core/rmem_max
212992
[root@node1 ~]# cat /proc/sys/net/core/wmem_default
212992
[root@node1 ~]# cat /proc/sys/net/core/wmem_max
212992
tcp--socket
net.ipv4.tcp_mem 接收和发送
net.ipv4.tcp_rmem
net.ipv4.tcp_wmem
[root@node1 ~]# cat /proc/sys/net/ipv4/tcp_mem
42054 56073 84108
[root@node1 ~]# cat /proc/sys/net/ipv4/tcp_rmem
4096 87380 6291456
[root@node1 ~]# cat /proc/sys/net/ipv4/tcp_wmem
4096 16384 4194304
分片重组缓冲大小
net.ipv4.ipfrag_high_thresh 用于tcp分片重组的内存空间最大值
net.ipv4.ipfrag_low_thresh
net.ipv4.ipfrag_time
[root@node1 ~]# cat /proc/sys/net/ipv4/ipfrag_high_thresh
4194304
[root@node1 ~]# cat /proc/sys/net/ipv4/ipfrag_low_thresh
3145728
[root@node1 ~]# cat /proc/sys/net/ipv4/ipfrag_max_dist
64
[root@node1 ~]# cat /proc/sys/net/ipv4/ipfrag_secret_interval
600
[root@node1 ~]# cat /proc/sys/net/ipv4/ipfrag_time
30
net.ipv4.tcp_tw_reuse 大量请求来临时,可以迅速响应
net.ipv4.tcp_syncookies syn队列阻塞时,大量并发请求来临,可以响应
net.ipv4.tcp_max_orphans tcp孤儿进程,最多运行出现多少个,该值一般只能增大,不能减少
net.ipv4.tcp_fin_timeout 一般不改,大于该值,会网络异常
net.ipv4.tcp_max_tw_buckets 该值一般只能增大,不能减少,减小ddos攻击
net.core.somaxconn 不调也可以
[root@node1 ~]# cat /proc/sys/net/ipv4/tcp_tw_reuse
0
[root@node1 ~]# cat /proc/sys/net/ipv4/tcp_syncookies
1
[root@node1 ~]# cat /proc/sys/net/ipv4/tcp_max_orphans
8192
[root@node1 ~]# cat /proc/sys/net/ipv4/tcp_fin_timeout
60
[root@node1 ~]# cat /proc/sys/net/ipv4/tcp_max_tw_buckets
8192
[root@node1 ~]# cat /proc/sys/net/core/somaxconn
128
nginx优化
参考文档--百度
小结:
memory优化:
nr_hugepages
swappiness 交换内存倾向性
overcommit_memory
disk io:
设定io scheduler cfq deadline ...
filesystem
nobarrier,noatime--对于频繁访问数据,提升性能
network io:
参考百度文档
iftop
哪个接口带宽占用比较大
lsof
进程打开的文件
tsar 比sar好用,类似htop
htop 追踪,类似strace
网友评论