linux系统优化
系统调优
L = A(到达率) * W(服务总时间)
L越低越好,W越低越好
AWK简单使用:
1.awk -F: '{print $1}' /path 以‘:’为分隔符打印第一列数据
2.df -P | awk '{print $1 " is mounted on " $NF}' 单独输入设备挂载目录
3.awk -F: 'BEGIN{print "any_string"} {print $1} END{print "any_str"} ' /path 第一行any_string 最后一any_str
处理文本的时候,可以在开始前结束前做加工处理
4.awk -F: '/regix/ {print $1} ' /etc/passwd 正则字符串匹配
5. sar -q | awk '/^[^a-z]+$/ {print $1,$2,$3}' 只输出非字母开头的行首行尾的行 统计负载
6. sar -b -s 开始时间 -e 结束时间 | awk '{print $1,$5+$6}' 显示系统输入输出块大小
gnuplot制图工具使用:
yum install -y gnuplot
set xdata time 指定X轴为时间
set timefmt "%H:%M:%S" 指定时间格式
plot "/data/path" using 1:2 with lines 指定数据文件路径,使用那两列数据制图,点和点之间用线连接
plot "/data/path" using 1:2 title "1 min" with lines,"/data/path" using 1:3 title "5 min" with lines,"/data/path" using 1:4 title "15 min" with lines
多条数据线
自动执行制定换图脚本
vim xxx.gnuplot
xxx同上
:x
运行: gnuplot -persist ~/cpu.gnuplot -persist结果持续存在屏幕上
将数据结果以图片的方式输出到apache目录下
set xdata time 指定X轴为时间
set timefmt "%H:%M:%S" 指定时间格式
set term png size 1024,768
set output "/var/www/html/stat/`data +%F`.png"
set "/data/path" using 1:2 with lines
做计划任务-》 crontab
crontab -e
0 80 * * * sar -b -s 17:00:00 -e 19:30:00 | awk '{print $1,($5+$6)/2}' > xxx.data;gnuplot dinner.gnuplot
查看系统状态命令:
sar
vmstat
mpstat
iostat
time COMMAND
iotop
top
uname -r 内核
sysctl -a | grep agurment
lscpu CPU alive
/etc/device/system/cpux/on-line
用户登录日志:
last
lastlog
lastb
IO磁盘调度算法:
系统主配置文件路径:
/sys/block/sda/queue/scheduler
算法调度参数:
/sys/block/sda/queue/iosched/*
更改磁盘调度算法:
cp xxx > /sys/block/sda/queue/scheduler
tuned使用:
tuned-adm list
tuned-adm active
tuned-adm profile <mode_name>
主配置文件/etc/tune-profiles/
cat /etc/tune-profiles/
mode:
default 电子邮件服务器,对服务器影响较小
desktop-powersave 面向桌面计算机,省电模式,对磁盘sata,cpu,网卡
server-powersave 面向服务器,省电模式
laptop-ac-powersave 笔记本充电时的省电模式
laptop-battery-powersave 笔记本无充电时,高省电,耐耗模式
throughput-performance 高性能 磁盘调度算法 readline
latency-performance 高性能
enterprise-profile-storage 高性能
应用进程优先级:
PR: RT,-99 - 39
NI: -20 - 19
实时:(编程时调用特定函数就能实现)
SCHED_RR 轮询
SCHED_FIFO 队列(只要没有进程优先级高与正在执行的进程,正在执行进程不会被打断)
非实时:
SCHED_NORMAL
SCHED_BATCH 大量数据操作,尽量不会被影响
SCHED_IDLE 系统空间时,才执行进程
如果编程中没有实现实时,可以使用chrt改变进程执行模式:
chrt -f 10 COMMAND 测试:chrt -f md5sum /dev/zero
chrt -r 1 COMMAND 平分CPU
进程调度算法:
CFS Scheduler
引入虚拟时间:Vittual time(值高者优先执行)
Waiting time
No of needed processes
Process priority
缓存查看
x86info -c
查看命令缓存命中率:
valgrind --tool=cachegrind COMMAND
refs 指令缓存
真机查看缓存命中率:
perf stat -e cache-misses COMMAND
pam_limits 限制用户使用资源,必须是用户身份(不能限制IO)
用户配置文件目录
/etc/pam.d/fingerprint-auth-ac
limits主配置文件
/etc/security/limits.conf
limits子配置文件目录
/etc/security/limits.d/
用户查看自身资源限制
ulimit -a
限制用户资源
student hard cpu 1(min) 写在主配置或者子配置文件中都可行
admin soft cpu 5
500(pid):(大于等于) soft cpu 1
限制用户进程内存,只能限制它的虚存VIRT(virtual address)
student hard as 262144(KB)
限制用户进程数
* soft nproc 1024 (max user processes)软限制
student hard nproc 1024
测试命令:boom(){ boom|boom& };boom OR :(){ :|:& };:
cgroup限制CPU,Memory,disk,network
yum install -y libcgroup
主配置文件
/etc/cgconfig.conf
合拼某两项资源则将他们的目录改成一个,注释原先的目录
cpu = /cgroup/cpumen
memory = /cgroup/cpumen
执行脚本:
/etc/init.d/cgconfig start
只要运行cgroup,/下会自动创建一个/cgroup/的目录
lssubsys -m 挂载子系统
自定义group组
vim /etc/cgconfig.conf
group cname{
cpu{
cpu.shares=100(1024代表100%的使用权)
}
}
vim /etc/cgconfig.conf
group poormen{
memory{
memory.limit_in_bytes=268435456(256M未来进程使用的物理内存大小)
memory.memsw.limit_in_bytes=268435456(256M,当内存使用完时,内存+swap空间,swap大小=下-上)
}
}
vim /etc/cgconfig.conf
group io{
blkio{
blkio.weight=100;(需要CFQ梯度算法支持)
blkio.throttle.read_bps_device=(8:0 1000000) 读磁盘最大1Mbps,需要查看磁盘主号从号 ll /dev/sda
}
}
vim /etc/cgconfig.conf
group stopit{
freezer{
}
}
利用cgexec可将进程绑定到预先定义好的CGROUP组
测试:cgexec -g cpu:cname time dd if=/dev/zero of=/dev/null bs=1M count=200000
测试:内存
新建一个内存盘
mkdir /mnt/tmpfs
mount -t tmpfs none /mnt/tmpfs 对该目录操作等于直接操作内存
命令:
cgexec -g memory:poormen dd if=/dev/zero of=/mnt/tmpfs bs=1M count =
测试:IO测试前要把缓存丢弃不然不公平 echo 3 > /proc/sys/vm/drop_caches
命令:
cgexec -g blkio:low time cat /bigfile1 > /dev/null
cgexec -g blkio:hig time cat /bigfile2 > /dev/null
测试:
echo pid > /cgroup/freezer/stopit/tasks
echo FROZEN > /cgroup/freezer/stopit/freezer.state 冷冻
echo THAWED > /cgroup/freezer/stopit/freezer.state 解冻
编辑文件限制用户进程,绑定cgroup
vim /etc/cgrules.conf
student:dd blkio io/
cgroup实现2颗CPU,一颗用于系统,一颗专门执行某命令
isolate 对用户屏蔽CPU,但不能屏蔽baseCPU
isolcpus=1(CPU list:0,1,2,3... )
某CPU免疫interrupts中断 vim /etc/sysconfig/irqbalance
IRQ_AFFINITY_MASK=2(cpu list:1,2,4,8...6=cpu 2+cpu 3 )
vim /etc/cgconfig.conf
group 2ndcpu{
cpuset{
cpuset.cpus=1;(cpu list:0,1,2,3...)
cpuset.mems=0;
}
}
指定当前虚拟机使用哪颗CPU
查询:
virsh dumpxml vmname | grep cpu
watch -n1 virsh vcpuinfo vmname
分配:
echo 1 > /cgroup/cpuset/libvirt/qemu/vmname/cpuset.cpus
strace displays 跟踪 kernel space
只要执行命令有system call那么就会被追踪出来
example:function -> open()
demo:
strace updatedb
strace -e strace=network COMMAND
strace -e stracr=file COMMAND
strace -p pid 跟踪进程
strace -c COMMAND 对命令进行统计所有的系统调用
strace -f COMMAND 跟踪所有子进程
参数:(绝大多少的命令都要调用glibc库)
open打开动态链接库
mmap将命令镜像到内存中
socket建立socket连接
open("/lib64/libresolv.so.2") DNS查询的动态库
sendto 发包
recvfrom 收包
read 读包
ltrace displays 跟踪 kernel space
example:function -> fopen()
主要跟踪glibc库的函数调用
demo:同上
systemtap 追踪应用程序和kernel行为
使用了kprobes子系统来进行监控
开发systemtap环境
依赖包:
kernel-debuginfo
kernel-debuginfo-common
kernel-devel
systemtap
gcc
执行自编systemtap脚本(包括编译、解析、添加至内核运行)
stap -v scriptname.stap kernel中可立即看到效果
留下kernel模块,给生产环境使用
stap -v -p4 -m modulename scriptname.stap
生产环境:
依赖包:
systemtap-runtime
添加systemtap模块至内核
staprun modulename.ko
权限管理:
后门,普通用户如果在stapusr group 中,就可以进入运行/lib/kernel/2.4-/systemtap/*.ko
防止在stapusr组中的普通用户执行不安全的内核模块
root:
cp *.ko /lib/kernel/2.4.-/systemrap/
普通用户只能添加目录里的安全的内核模块
如果把用户添加至stapdev 开发组里,那么该用户可以在任何地方添加.ko文件至内核
内存管理:
x86 指令集 上,内存分页,每页的大小为4KB
物理内存和虚拟内存
程序首先要申请虚拟内存,x86有16E几乎没限制,但内核并不是立刻就全部分配,而是
程序使用多少才分配多少
程序只能看到虚拟内存,并且是连续的。但是虚拟内存转换为物理内存时,可能不是连续的。父进程同一时间可能和多个子进程使用同一个内存页
virtual address to physical address translations are stored in page table
页表也占内存,牺牲了部分内存管理
进程要访问真实的物理内存中的数据要进程page walk,x86有4层结构,层层递归查询到页表,最后才指向页帧(物理内存)
程序访问物理内存首先会查找CPU中的TLB,TLB存储虚拟内存到物理内存的镜像关系,
TLB-Translation look-aside buffer
first check TLB
if TLB hit,return address
else page walk , cache address mapping
x86 平台提供大内存页hug,解决大内存进程使用大量page时,需要大量的page table表项描述导致内存浪费。有2Mpage、4Mpage
内存huge page的使用
huge page是连续的内存段,不是由page合成的,是独立内存区域
一般在开机的时候分配大页,那时候内存很干净,连续段很多
vim /etc/sysctl.conf
vm.nr_hugepages = 10
临时分配内存:
sysctl vm.nr_hugepages = 10
查看内存大页:
grep Huge /proc/meminfo
To use huge page
1.创建伪文件系统hugetlbfs:
mount -t hugetlbfs none /mountpoint
Application use mmap system call on /mountpoint
2.使用共享内存:
Application use shmget and shmat system calls
3.RHEL6.2 引入透明huge page使用
THP自动拼装huge page
khugepaged 自动将普通也切换成大页
THP工作在匿名内存(进程动态使用的内存页)
Memory Allocation
1.process forks or execs child process
child process uses parent process'page frames unitl a write access is made
this is referred to as copy write(COW)
2.new process requests memory
kernel commits additional virtual address space to process
3.new process uses memory
tiggers a page fault exception
minor:kernel allocates a new page frame with help from MMU
major:kernel blocks process while page is retrieved from disk
4.process frees memory
kernel reclaims pages
Swap space:
swap space 'increases' the amount of memory
pages not being used can be paged out to disk,therefore more free memory to use
vmstat:
观察swap的si so值,如果很大说明交换空间不停的被使用,产生的代价很沉重
交换空间大小配置:
system memory -> minimum swap space
4GB 2GB
4-16GB 4GB
16-24GB 8GB
64-256GB 16GB
Buffer Cache:
it (Slab cache防止内存碎片)used to cache file system meta data(dentries and inodes)
与文件内容无关的数据都可以归到Buffer cache
Page Cache:
it used to cache file system block data(file content)
它是文件内容数据,不能交换回磁盘
丢弃缓存:
echo 1 > /proc/sys/vm/drop_caches
-1 block data
-2 meta data
-3 block and meta data
交换可调参数:
/proc/sys/vm/swappiness
swap_tendency = mapped_ratio / 2 + distress + vm_swappiness
mapped_ration is the % of physical memory in use
distress is how hard kernel try to free memory
vm_swappiness is what we can tune
值调小:
内核尽量交换page cache
例子:web server Email,交互式的
swap_tendency < 100
值调大:
内核尽量交换匿名内存和共享内存
例子:非交互式的,业务流量内存大时,尽量不干扰page cache
swap_tendency >=100
默认添加挂载交换分区时,如果没有调节优先级参数,当前挂载交换分区会比之前挂载的分区优先级低一点
性能提高点:只要交换分区的优先级相同那么,内核回轮询使用交换分区
内存页状态:
Free:可分配的内存页
Inactive Clean:page cache OR buffer cache,随时可以被系统回收
Inactive Dirty:程序修改的内存数据,但还未被存盘
Active:内存页被程序使用
如何处理Inactive Dirty,脏页回收,未处理memory page,提高内存空间
每次磁盘设备默认有个,per-BDI Flush Threads
针对内存脏数据可调参数:
vm.dirty_expire_centisecs (脏数据滞后,满足最小时间限制,合并写操作)
vm.dirty_writeback_centisecs (固定时间间隔唤醒per-BDI刷新线程处理脏页数据)
vm.dirty_background_ratio (系统内存有10%都是脏数据)
vm.dirty_ratio (系统内存有40%都是脏数据时,挂起所有写操作,把脏数据同步到磁盘)
OOM:kernel承诺内存过大,不能兑现诺言给程序
kernel解决办法:
随机杀死一些进程,会导致系统会不稳定
自主解决办法:
sysctl -a | grep vm.panic_on_oom
vm.panic_on_oom 设置为1,内存不能兑现时,系统挂起,无数据交互了
x86_64 物理内存架构(64位):
低16M留给ZONE_DMA
4G留给ZONE_DMA32
其他留给ZONE_NORMAL(基本无限大) 内存运行在ZONE_NORMAL中
x86_64 物理内存架构(32位)
低16M留给ZONE_DMA
880M留给ZONE_NORMAL
其他留给ZONE_HIGHMMEM
Memory Overcommit
0:智能判断分配
1:不做判断
2:超过真实内存大小,绝对不会分配(真实大小=swap+物理内存50%)
sysctl vm.overcommit_memory = 2 (安全)
如果想把全部的物理内存也加上,那么需要修改
vm.overcommit_ratio = 100
测试:bigmem -v 2000(默认单位Mib)
超出承诺值最大:
grep Comm /proc/meminfo
只要不超越这个限制程序还是能正常运行的
进程间通信手段:SysV IPC标准
Semaphores 信号量
max number of arrays 允许多少信号量数组个数
max semaphores per array 运行一个程序信号量中存在信号令数组大小
max semaphores system wide 运行总共的信号量个数
max ops per semop call 每个信号量最多发出的system call
sysctl -a | grep kernel.sem
Message queues 消息队列
default max size of queue (bytes) 一个消息队列运行存在多少字节的数据
max size of message (bytes) 一个消息最大长度,可以把一个消息队列占满
max queues system wide 消息队列在系统中的个数,可能是随机的
sysctl -a | grep kernel.msg
Shared memory 共享内存(使用最多)
max number of segments 系统运行的共享内存个数
max seg size (kbytes) 最多共享内存段限制
max total shared memory (kbytes) 全局共享内存段总限制
sysctl -a | grep kernel.shm
ipcs命令查看使用情况
ipcs
进程间通信限制
ipcs -l
文件系统介绍
服务器级别使用的文件系统:ext3,ext4,xfs,btrfs(高效,性能强)(Oracle 开源的文件系统)
用户桌面级别的文件系统:ntfs,fat16,fat32,fat64
ext3优势:使用人数多,兼容性好
ext3劣势:fsck文件系统做例行检查非常慢,文件系统最多支持16TB大小
ext4优势:超大文件系统几百T,Extent大大缩小page页面描述,相对于ext3效率提高10倍,写操作滞后存盘,支持更大的文件系统
ext4劣势:Extent使用之后不和低版本兼容,红帽rhel6最多支持16TB大小文件系统
xfs优势:大文件系统,高效率存储
xfs劣势:大量小文件,碎片文件处理效率低
BTRFS优势:自带raid,快照功能,对数据有效性很高,保护性完整性高
BTRFS劣势:不适合生产
大文件系统效率高到低:BTRFS,XFS,EXT4,EXT3
大量小文件系统效率高到低:BTRFS,EXT4,XFS,EXT3
文件系统修复效率高到低:(EXT4,XFS),BTRFS,EXT3
写操作效率:(EXT4,XFS,BTRFS),EXT3
超大文件写操作:(EXT4,XFS,BTRFS),EXT3
文件系统日志调优(提高a到达率)
目的:让文件系统修复速度加快,避免全盘搜索,保证文件系统的稳定性
模式:
ordered
记录每一步写操作的前后状态
writeback
只记录写操作,不记录是否写完成
journal
文件的源数据和内容数据先写日志区,2次写代价太高(1.对文件系统的要求100%,不允许数据丢失2.面临大量小文件往磁盘写)
新建文件系统,指定外部日志功能:
mkfs.ext4 -O journal_dec -b 4096(block size) /dev/vdb1 其他文件系统的日志文件系统
mkfs.ext4 -J(journal) device=/dev/vdb1 -b 4096 /dev/vda3
tune2fs -l /dev/vda1 文件系统详细信息
对于已经存在的文件系统,指定外部日志:
tune2fs - l /dev/vda1 确认block size
mkfs.ext4 -O journal_dec -b 4096 /dev/vdb2 新建外部日志分区
把需要的修改的文件系统umount下线:
umount /dev/sda1
tune2fs -O '^has_journal' /dev/sda1 把原来的日志功能关闭
tune2fs -j -J device=/dev/vdb2 /dev/sda1 重新指定日志分区
mount /dev/vda1 重新挂载使用
网络负载平衡
yum install -y qperf
两台主机都运行qperf,查看主机基本信息
主机1:qperf
主机2:qperf hostname conf
查看主机网卡速率:
qperf host tcp_bw tcp_lat udp_bw udp_lat
查看不同包大小的网卡速率:
qperf -oo msg_size:1:32k:*2 [-v] host tcp_bw tcp_lat udp_bw udp_lat
可调节参数(系统自动调节)Maximum Buffers:
net.ipv4.tcp.mem
net.ipv4.udp.mem
min pressure max
只有当TCP连接内存占到pressure值时,内核才干预TCP占用内存
如果这个服务器只做网络工作,那么可以修改buffer的min值到四分之三
socket buffer for core networking,include UDP connection:
net.core.rmem_default
net.core.wmem_default
net.core.rmem_max
net.core.wmem_max
这些参数值再小也不会小于:
net.ipv4.udp.rmem_min
net.ipv4.upd.wmen_min
Then tune buffers of TCP specific networking:
net.ipv4.tcp_rmem
net.ipv4.tcp_wmem
min default max
min:minimum receive/send buffer for a TCP connection
default:default buffer size,一般最大的一半
BDP : buffer size = bandwith/8 * delay time (byte)
demo example:
tc qdisc show
模拟2S延迟发包:
tc qdisc add dev eth0 root netem delay 2s
tc qdisc show
另一台机子部署web服务,主机wget服务器的文件
网卡绑定提升带宽:
balance-rr轮询模式:既可以提升容错率,还可以提升网卡带宽速率
active-backup热备:只有一块工作
802.3ad动态链接协商:
修改MTU值,支持Jumbo Frames,所有的网络设备都必须支持大帧:
每个以太网帧最大限制不局限于1500Byte,对于大数据量的传输时可以大大减小开销
主机只需要修改网卡参数:
vim /etc/syscocnfig/network-script/ifcf-eth0
MTU=9000
网络设备来说就需要修改硬件参数
一般来说过路由就没有意义了