正文
摘要
继续补充假期落下的内容.
其实有很多知识需要学习, 自己掌握的还是偏少一些.
bcc的全貌
# 注意 bcc 需要较高的内核. 3.10 系列的内核基本不可用.
argdist drsnoop mdflush pythonstat tclstat
bashreadline execsnoop memleak readahead tcpaccept
bindsnoop exitsnoop mountsnoop reset-trace tcpcong
biolatency ext4dist mysqld_qslower rubycalls tcpconnect
biolatpcts ext4slower netqtop rubyflow tcpconnlat
biopattern filelife netqtop.c rubygc tcpdrop
biosnoop fileslower nfsdist rubyobjnew tcplife
biotop filetop nfsslower rubystat tcpretrans
bitesize funccount nodegc runqlat tcprtt
bpflist funcinterval nodestat runqlen tcpstates
cachestat funclatency offcputime runqslower tcpsubnet
cachetop funcslower offwaketime shmsnoop tcpsynbl
capable gethostlatency oomkill slabratetop tcptop
cobjnew hardirqs opensnoop sofdsnoop tcptracer
compactsnoop javacalls perlcalls softirqs threadsnoop
cpudist javaflow perlflow solisten tplist
cpuunclaimed javagc perlstat sslsniff trace
dbslower javaobjnew phpcalls stackcount ttysnoop
dbstat javastat phpflow statsnoop vfscount
dcsnoop javathreads phpstat swapin vfsstat
dcstat killsnoop pidpersec syncsnoop virtiostat
deadlock klockstat profile syscount wakeuptime
deadlock.c kvmexit pythoncalls tclcalls xfsdist
dirtop pythonflow tclflow xfsslower tclobjnew
llcstat pythongc
本次总结来源
计划基于51cto的文档进行学习和总结工作
博客地址为:
https://blog.51cto.com/hongchen99/5840053
https://blog.51cto.com/hongchen99/5845370
https://blog.51cto.com/hongchen99/5868472
原作者写的非常经典. 我这里想着边学习变总结一下.
希望能够窥探一二.
第一部分: CPU
CPU是冯诺依曼计算机体系结果的核心.
CPU性能的好坏决定了系统的并发承载能力和响应时间.
很多问题都是通过CPU的占用情况进行暴露的.
所以感觉性能调优的第一部分应该是从CPU占用量着手
根据CPU的使用情况慢慢的向内存和IO深入分析.
CPU性能问题的来源
除去非常孱弱的部分国产CPU
大部分情况下物理机器的CPU都很难单独成为性能瓶颈.
如果是无法用到全部核心的单线程模式:
Redis的核心进程, 数据库/操作系统/中间件因为序列号导致只能够使用单一核心
如上情况下可能会出现CPU的瓶颈.
CPU的核心参数主要有:
主频, IPC , CPI , 内存带宽, 缓存大小, 指令集, 流水线等.
CPU性能监测工具-传统
命令 |
内容 |
uptime |
展示系统平均负载和系统运行时间 |
top |
按进程展示系统资源使用情况- 之前总结过 |
mpstat |
按每个 CPU 展示 CPU 使用情况 |
vmstat |
系统整体资源使用情况 |
pidstat |
按进程展示 CPU 使用情况 |
perf |
定时采样调用栈信息、事件统计、PMC 跟踪、跟踪点、USDT probes、kprobes 以及 uprobes 等 |
ftrace |
汇报内核函数调用统计、kprobes 和 uprobes 事件跟踪 |
bcc相关CPU监控工具
命令 |
内容 |
execsnoop |
列出新进程的运行信息 |
exitsnoop |
列出进程运行时长和退出原因 |
runqlat |
统计 CPU 运行队列的延迟信息 |
runqlen |
统计 CPU 运行队列的长度 |
runqslower |
当运行队列中等待时长超过阈值时打印 |
cpudist |
统计在 CPU 上运行的时间 |
profile |
采样 CPU 运行的调用栈信息 |
命令 |
内容 |
offcputime |
统计线程脱离 CPU 时的跟踪信息和等待时常 |
syscount |
按类型和进程统计系统调用次数 |
argdist |
可以用来进行系统调用分析 |
trace |
可以用来进行系统调用分析 |
funccount |
统计函数调用次数 |
softirqs |
统计软中断时间 |
hardirqs |
统计硬中断时间 |
llcstat |
按进程统计 LLC 命中率 |
简单总结
CPU的运行时间其实分为 多种
内核态 用户态 等待io 等.
如果idle的时间较少, 一般就会存在比较严重的性能问题.
CPU优化的核心目标是减少 中断和切换, 将最多的时间用于处理业务代码
CPU的上下文切换有多种
上下文切换的核心本质是. 核心态执行代码用来替换正在运行的用户态的程序.
进程的上下文切换 需要刷新TLB, 保存所有的寄存器状态,然后刷入要载入进程的寄存器等信息.
根据CPU的不同 进程切换的时间不一样. 一般的理解需要 1500-3000个cycle才可以.
所以理论上切换进程的时间有 1.5微秒甚至更高.
对应的还有线程上下文切换, 不需要切换TLB等页表信息. 切换效率较高.
但是为了高并发下的性能, 优化方向是协程的机制.
不需要上下文切换. 需要用户态管理协程的上下文. 效率最高. 也是java最新版的一个特性.
中断的机制
中断是系统实现交互的核心设计方式
主要有软中断和硬中断.
键盘和硬盘以及网卡都可以实现中断.
中断用于保证系统暂时放弃正在处理的工作. 加急处理输入输出相关的信息.
对应的RT内核和非RT内核也是对中断的抢占模式的区别
实时内核需要核心任务进程必须在严格规定的时间范围内进行处理和响应
但是非实时内核可能就需要等待时间片轮转和任务队列的处理.
在比如刹车的场景下非实时内核是无法实现快速的任务切换的.
CPU核心的优化策略
1. 中断负载, 主要是网卡的队列和中断进行负载. 提高IO性能.
2. CPU绑定 现在都是多核CPU 甚至是有区分NUMA的, 建议将网卡和应用程序绑定到相同numa节点下的CPU核心上.
可以最大化性能响应时间和吞吐量.
3. 调整进程优先级. 可以使用nice 等命令修改优先级, 保证产品可以尽快的得到响应.
4. 尽量使用多线程, 不使用多进程模式, redis对比memcache 以及 nginx 对比 apache 都是多线程的处理机制
比多进程的处理机制要优秀的多的代表. 可以适当使用类似于go语言的协程, 性能会更加优秀.
5. 耗时的IO尽量使用异步, 不适用同步, 同步的阻塞模式会导致性能极具下降, 可以使用异步或者是消息队列模式
进行优化 性能会有极大的提升.
第二部分 内存
Linux 采用虚拟内存的管理机制
使用段页式内存管理
分页内存主要是解决内存页面的寻址处理
分段内存主要是解决内存的权限读写等问题.
段页式内存协同处理, 是虚拟内存的核心机制.
Linux的内核也分为内核态和用户态.
32位和64位的内存管理也是差异比较巨大.
32为内存一般分为高地址内存和低地址内存.
部分存储内核态的核心内存, 另一一部分是用户态的内存.
需要特别注意. 每一个进程其实都有自己独立的用户态内存地址.
虚拟地址的都是完整的一套.
是通过TLB等将虚拟地址转换到具体的物理地址来实现管理.
虚拟内存也是操作系统安全性的最大保证手段之一
一方面内核态的内存不允许随意访问
另一方面内核态映射的具体物理地址也通过加密方式进行隐藏, 避免出现安全隐患.
很多CPU内核级别的安全漏洞都是利用CPU的预取还有乱序执行的特点.在内存里面抓取临近内存的信息进行分析
视图获取相同CPU管理内存下的其他用户的核心数据.
内存监控工具-传统工具
命令 |
内容 |
dmesg |
OM Killer 事件的详细信息 |
swapon/swapoff |
换页设备管理 |
free |
显示系统内存用量信息 |
ps |
按进程展示系统资源使用情况 |
pmap |
按进程统计信息,包括内存用量 |
vmstat |
系统整体资源使用情况 |
top |
按进程展示系统资源使用情况 |
sar |
可以显示换页错误和也扫描频率 |
perf |
内存相关的 PMC 统计信息和事件采样信息 |
内存监控工具-bcc相关工具
命令 |
内容 |
cachestat |
展示文件系统缓存信息 |
cachetop |
以类似于 top 的方式展示文件系统缓存信息 |
oomkill |
展示 OOM Killer 事件的详细信息 |
memleak |
展示可能有内存泄露的代码路径 |
shmsnoop |
跟踪共享内存相关的调用信息 |
swapin |
按进程展示页换入信息 |
内存优化的策略
保证系统有足够的可用内存.
不要过分的使用全部内存
linux有一套 buffer和cache的机制 会最大限度的使用内存作为缓冲.
作为硬件层需要的优化:
1. 尽量通道装满.
2. 尽量使用满载内存的近端CPU进行绑定.
3. 尽量使用高工作频率的内存.
4. 尽量保证系统稳定和温度范围, 降低系统刷新频率, 一般改为64ms刷新一次.
5. 尽量保证内存品牌,型号一致, 避免因为有高有低导致被降频处理.
6. 硬件有异常立即更换,避免引起故障.
内存优化策略
软件层面的优化主要有:
1. 建议管理swap, 实现fastfailure,避免系统卡顿, 带病运行.
2. 建议操作系统的内存使用, 避免大量cache和buffer的使用.
3. 优化数据库的内存使用,尽量专用软件, 避免内存和CPU的争抢.
4. JVM等内存配置. 合理设置堆区还有GC方法.
5. 尽量保留一定的内存用于突发burst的使用情况.
6. 核心参数优化, 以及tcp部分内存用量的优化等.
第三部分 文件系统与io
Linux系统使用VFS的虚拟文件层进行处理.
一般分为 索引节点 indexnode 还有目录想 directory entry 的方式进行管理
主要是记录文件的 meta info 以及具体的 目录结果.
/proc/sys/vm/drop_caches 1 2 3 就有部分对应的是清理 索引节点和目录节点的内存缓存.
最大的缓存内容是具体文件内容的缓存 一般是按照 操作系统的page进行处理.
linux 其实有多种文件系统,应对不同的应用场景.
像是ext3 ext4 xfs aufs 等等.
文件系统与io监控工具-传统
命令 |
内容 |
df |
显示文件系统用量信息 |
mount |
挂载文件系统到系统上 |
strace |
跟踪系统中的系统调用(这个命令可能会导致应用程序的性能下降 90%) |
perf |
文件系统相关的跟踪点 |
du |
文件系统使用情况分目录 |
iostat |
按磁盘分别输出 I/O 统计信息,可提供 IOPS、吞吐量、I/O 请求时长 |
iotop |
top 的 I/O 版本 |
lsof |
列出当前系统中打开的文件 |
文件系统与io监控工具-bcc
命令 |
内容 |
fileslower |
展示较慢的文件读/写操作 |
filetop |
按 IOPS 和字节书排序展示文件 |
writeback |
展示写回事件和对应的延迟信息 |
dcstat |
目录缓存命中率统计信息 |
dcsnoop |
跟踪目录缓存的查找操作 |
mountsnoop |
跟踪系统中的挂载和卸载操作 |
xfsslower |
统计过慢的 XFS 操作 |
xfsdist |
以直方图统计常见的 XFS 操作延迟 |
命令 |
内容 |
ext4slower |
统计过慢的 EXT4 操作 |
ext4dist |
以直方图统计常见的 EXT4 操作延迟 |
nfsslower |
统计过慢的 NFS 操作 |
nfsdist |
以直方图统计常见的 NFS 操作延迟 |
biolatency |
以直方图形式统计块 I/O 延迟 |
biosnoop |
按 PID 和延迟阈值跟踪块 I/O |
biotop |
top 工具的磁盘版:按进程统计块 I/O |
bitesize |
按进程统计磁盘 I/O 请求尺寸直方图 |
biostacks |
跟踪磁盘 I/O 相关的初始化软件栈信息 |
文件系统与IO的优化策略
硬件方面:
1. 更快更好的硬件,比如SSD,比如快速Raid卡.或者是高速15k的硬盘.绝对不能使用SMR硬盘.
2. 更换更好的协议, 比如使用NVMe 换掉SCSI协议.
3. 拒绝使用RAID6,不推荐RAID5,建议RAID10.
4. 对IO要求高的比如数据库 建议使用物理机 或者是直接使用raw设备.
5. 建议raid增加hot spare 避免故障引起性能下降, 增加处理时间的窗口.
6. 淘汰陈旧的设备, 保证设备更新换代.
7. 缓存以及硬件保护要做好,避免数据丢失. 性能与数据安全需要协调好.
软件方面:
1. 选择合适的文件系统.适当使用条带化提高性能.
2. 多选设备实现多路径访问, 多路径拆分高IO来提高性能.
3. 修改内核参数, 换用更好的更合适的电梯调度算法. 以及IO的depth等参数.
4. 选用好的 IO模型, 建议使用epoll以及zero copy等算法保证性能.