Linux服务器性能调优
Linux服务器性能调优
1. 性能监控跟踪工具
- CPU利用率
top:提供正在运行进程和系统负荷的概览信息,以及显示活跃进程列表。
vmstat:也是一个实时性能监控工具,可以由用户指定数据的显示频率。
- 内存利用率
top、vmstat
ps:可以获取每个进程的内存占用情况。
- I/O利用率
iostat:监视系统的I/O活动,检查磁盘的传输速率。
sar:是一个全面的系统活动收集工具,包括I/O、CPU、内存、网络等。
- 网络利用率
netstat:监视网络连接的常用工具,显示每种网络协议(如TCP/UDP)的活跃socket列表,还提供网络路由信息,及网络接口的累计统计数据。
接口数据
协议统计数据
2. 基准测试工具
- 操作系统
LMbench、Reaim
- 磁盘
IOzone、dbench
- 网络
Netperf
- 应用
1) Java 应用volanomark、SPECjvm
2) Web服务器 SPECWeb、TPC-W
3) 文件服务器 PostMark
4) 数据库服务器TPC-C、TPC-H
3. 系统调优
3.1调度器
调度器的职能是确保每一个任务都能获得公平的处理器时间片。
可调参数:
CHILD_PENALTY |
子进程所继承的父进程平均睡眠时间的百分比。 |
CREDIT_LIMIT |
定义了一个任务的sleep_avg取值高于MAX_SLEEP_AVG从而被当作高度交互式任务的次数。 |
EXIT_WEIGHT |
判定父进程是否由于创建了相对于其自身来说成为处理器贪婪进程的子进程而受到处罚。 |
INTERACTIVE_DELTA |
定义在判断任务是否为交互式的时候所添加的偏移量。 |
MAX_SLEEP_AVG |
定义为了计算调度奖励值,任务能够积累的最大平均睡眠时间。 |
MAX_TIMESLICE |
是为具有最高静态优先级的任务分配的时间片长度。 |
MIN_TIMESLICE |
是为具有最低静态优先级的任务分配的时间片长度。 |
PARENT_PENALTY |
允许父进程保持的平均休眠时间的百分比。 |
PRIO_BOUNS_RATIO |
规定了用于为交互式任务提供临时优先级奖励值的优先级范围百分比。 |
STARVATION_LIMIT |
为了避免超时数组中的任务饿死,判断是否将一个交互式任务置入活跃数组或超时数组中的放大系数。 |
3.2虚存
Linux是通过虚存子系统来管理物理内存。
可调参数:
dirty_background_ratio |
是在尝试一个回写操作之前所持有的脏内存比例。 |
dirty_expire_centisecs |
是数据可以保持为脏状态的最大厘秒数。 |
dirty_ratio |
过量脏内存的比例。 |
dirty_writeback_centisecs |
执行回写操作之间的时间间隔,单位也是厘秒。 |
lower_zone_protection |
是为内存区域回退操作的阻止因子分配的权重。 |
min_free_kbytes |
规定了可用于诸如中断处理程序发起的紧急分配内存池的大小。 |
nr_pdflush_thread |
规定回写线程池的当前大小。 |
overcommit_memory |
是一个允许内存过量使用的标志。 |
overcommit_ratio |
指定了当overcommit_memory参数置为2时所考虑的物理内存百分比。 |
page-cluster |
内核一次性读入的页面数,等于2的page-cluster值的次方。 |
swappiness |
表示实际内存和虚拟内存区域进行数据交换的倾向性大小,数值越大表示倾向性越大,即交换的页面文件越多,反之亦然。 |
3.3 I/O子系统
I/O子系统分为I/O调度和块I/O层。
Linux2.6内核可选的几种I/O调度器:
deadline |
最终期限调度器,基于请求超时的方法。基本思想是积极的对请求重新排队以改进I/O性能,同时确保没有I/O请求被饿死。
提供了最小的读取延迟和尚佳的吞吐量,特别适合于读取较多的环境(如数据库) |
anticipatory |
前瞻调度器,基本思想是延时读写请求,希望能对它们进行排序,减少磁盘操作,获得最高的效率。
用写入延时换取最大的写入吞吐量,适合写入较多的环境(比如文件服务器) |
CFQ |
完全公平排队调度器,默认算法,基本思想是在所有I/O请求发起者之间公平分配I/O带宽。
为所有任务分配等量的带宽,避免进程被饿死并实现了较低的延迟,可以认为是上述两种调度器的折中,适用于有大量进程的多用户系统。 |
noop |
具有极小的开销,提供了基本的合并和排序功能,主要是针对非磁盘类型的块设备。 |
3.4文件系统
Linux支持的4种日志文件系统对比:
特性 |
Ext3 |
ReiserFS |
XFS |
JFS |
在IA32体系结构上支持的最大块长度 |
4KB |
4KB |
4KB |
4KB |
文件系统的最大容量 |
16384GB |
17592GB |
18000Pb |
4Pb |
文件的最大长度 |
2048GB |
1Eb* |
9000Pb |
4Pb |
增加文件系统的容量 |
补丁 |
可以 |
可以 |
可以 |
在线快照 |
可以 |
可以 |
可以 |
可以 |
访问控制列表 |
支持 |
支持 |
支持 |
支持 |
扩展属性 |
支持 |
支持 |
支持 |
支持 |
磁盘inode动态分配 |
不支持 |
支持 |
支持 |
支持 |
数据日志 |
支持 |
补丁 |
不支持 |
不支持 |
日志置于外部设备上 |
支持 |
支持 |
支持 |
支持 |
3.5网络
主要为以下系统内核参数:
net.core.rmem_default |
Socket读缓冲区全局默认大小 |
net.core.wmem_default |
Socket写缓冲区全局默认大小 |
net.core.rmem_max |
Socket读缓冲区全局最大长度 |
net.core.wmem_max |
Socket写缓冲区全局最大长度 |
net.core.netdev_max_backlog |
排队传递给设备队列的输入报文最大数量。(每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目) |
net.core.somaxconn |
限制监听队列最大数据包的数量,超过这个数量就会导致链接超时或者触发重传机制。 |
net.core.optmem_max |
Socket缓冲区的最大初始长度 |
net.ipv4.tcp_rmem |
TCP Socket读缓冲区,该变量是由3个整数组成,分别为最小、默认、最大长度,最大值受限于net.core.rmem_max。 |
net.ipv4.tcp_wmem |
TCP Socket写缓冲区,该变量也是由3个整数组成,分别为最小、默认、最大长度,最大值受限于net.core.wmem_max。 |
net.ipv4.tcp_mem |
定义TCP内存管理区域的范围,可以控制内存管理行为,该参数也包含3个整数,分别为TCP没有内存压力时的页数上限、进入内存压力区域时的页数、拒绝socket分配时的页数,单位是页。 |
net.ipv4.tcp_window_scaling |
TCP窗口缩放,默认打开。 |
net.ipv4.tcp_sack |
TCP选择性应答,默认打开。减少重传。 |
net.ipv4.tcp_dsack |
对Sack特性的改进,能够检测不必要的重传,默认打开,如果禁用了sack,也应该禁用它。 |
net.ipv4.tcp_fack |
TCP向前应答,对Sack协议加以完善,改进了TCP的拥塞控制机制,如果禁用了sack,也应该禁用它。 |
net.ipv4.tcp_max_syn_backlog |
控制每个端口的TCP syn队列长度。 |
net.ipv4.tcp_synack_retries |
控制内核向某个输入的syn/ack段重新发送响应的次数。 |
net.ipv4.tcp_retries2 |
控制内核向已经建立连接的远程主机重新发送数据的次数。 |
net.ipv4.tcp_keepalive_time |
TCP启动探测的空闲连接时间,单位是秒。 |
net.ipv4.tcp_keepalive_intvl |
TCP保持空闲连接,探测的时间间隔,单位是秒。 |
net.ipv4.tcp_keepalive_probes |
TCP保持空闲连接,探测的次数。 |
net.ipv4.ip_local_port_range |
系统上可用的临时端口范围。 |
3.6进程间通信
包括信号量、消息队列、共享内存段三种资源。
信号量参数:
名称 |
描述 |
默认值 |
最大值 |
semmni |
信号量集合最大数目 |
128 |
2GB |
semmsl |
每个信号量集合的信号量最大数目 |
250 |
65536 |
semmns |
系统内的信号量最大数目 |
32000 |
2GB |
semopm |
每个semop系统调用的最大操作数目 |
32 |
2GB |
semvmx |
信号量最大取值 |
32767 |
65536 |
消息队列参数:
名称 |
描述 |
默认值 |
最大值 |
msgmni |
最大消息队列数 |
16 |
2GB |
msgmax |
最大消息长度(字节数) |
8192 |
2GB |
msgmnb |
消息队列中的最大字节数 |
16384 |
2GB |
共享内存段参数:
名称 |
描述 |
默认值 |
最大值 |
shmmax |
共享内存段的最大字节数 |
0x200000 |
4GB |
shmmin |
共享内存段的最小字节数 |
1 |
2GB |
shmmni |
共享内存段的最大数目 |
4096 |
2GB |
shmall |
系统中共享内存段的最大页数 |
0x200000 |
4GB |
4. 具体应用服务器
4.1 Web 服务器(受网络I/O层面的影响)
分为操作系统(网络)级和 Web Server 本身的调优
- 操作系统:
1) 网卡速率检测(ethtool)、网卡吞吐量(iptraf)、网络流量监控(netperf、iperf、tcptrace)
2) 内核参数
- Web Server:
1) 选择高并发的 Web Server(如Nginx),及配置参数优化(如并发数),增加 cache 机制(如Squid)。
2) 另外需要关注 Web 请求日志分析。
4.2文件服务器(受磁盘I/O层面影响)
- 选择文件系统 ext2、ext3、JFS、ReiserFS、XFS 还是其他。
- block、inode 优化,block 采用1024还是4096,inode 和 block 是一对一还是一对多,创建文件系统时规划好。
- 是否采用 LVM 逻辑卷管理工具。
- 日志优化,分离日志到其他分区(磁盘)。
- 通过挂载选项调优。
4.3数据库服务器(受磁盘I/O层面影响)
分为操作系统级和数据库本身的调优
- 操作系统:
大内存、高效的磁盘 I/O(采用多大的数据块2K、4K还是8K)。
- 数据库:
1) 日志文件和数据文件分离,采用原始设备还是文件系统来运行日志文件。
2) 表的访问要均衡的分配到所有磁盘上。
3) 并发连接数、查询缓存等配置参数的优化。
5. 业务服务器优化参数示例
业务服务器包括Web Server、数据库等:
- 基础网络参数优化
- 具体应用优化(包括Nginx、MySQL)
- 首先是关于系统open file的配置,系统默认是1024 ,可根据实际情况进行配置,如改为50万,修改 /etc/security/limits.conf文件,增加如下内容:
5.1网络优化参数
* soft nofile 500000 * hard nofile 500000 |
- 系统内核相关优化参数,主要修改系统的 /etc/sysctl.conf 文件,增加的内容如下:
#add by ethan net.ipv4.tcp_tw_reuse = 1 #将处于TIME-WAIT状态的sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 #表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout = 30 #修改系統默认的 TIMEOUT 时间
net.ipv4.tcp_timestamps = 0 # tcp时间戳,是为了提高tcp性能的扩展选项,用于计算RTT(TCP往返传输时间)和减少重复发包,2.6内核的Linux默认是打开的。设置为0解决服务器不响应SYN包的现象。
net.core.somaxconn = 4096 #限制socket监听队列最大数据包的数量,超过这个数量就会导致链接超时或者触发重传机制,默认的128。
net.ipv4.tcp_max_orphans = 3276800 #系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。这个限制仅仅是为了防止简单的 DoS攻击,缺省值是8192。
net.core.netdev_max_backlog = 262144 #排队传递给设备队列的输入报文最大数量。
net.ipv4.tcp_syn_retries = 5 #外向syn握手重试次数,对于一个新建连接,内核要发送多少个SYN连接请求才决定放弃,默认5
net.ipv4.tcp_synack_retries = 5 # syn-ack握手状态重试次数,相当于三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK包的数量,默认5
#add by wind net.ipv4.tcp_max_tw_buckets = 60000 #系统在同时所处理的最大 timewait sockets 数目,默认是180000。
net.ipv4.tcp_max_syn_backlog = 262144 # SYN 队列长度,对于那些依然还未获得客户端确认的连接请求﹐需要保存在队列中最大数目。
net.ipv4.tcp_keepalive_time = 1200 #当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是7200秒。
net.ipv4.tcp_keepalive_probes = 3 # TCP发送keepalive探测以确定该连接已经断开的次数,缺省值是9。
net.ipv4.tcp_keepalive_intvl = 30 #探测消息发送的频率,缺省是75秒。
net.ipv4.tcp_mem = 94500000 915000000 927000000 # (3个INTEGER变量):low, pressure, high #low:当TCP使用了低于该值的内存页面数时,TCP不会考虑释放内存。 #pressure:当TCP使用了超过该值的内存页面数量时,TCP试图稳定其内存使用,进入pressure模式,当内存消耗低于low值时则退出pressure状态。 #high:允许所有tcp sockets 用于排队缓冲数据报的页面量,如果超过这个值,TCP 连接将被拒绝。
net.ipv4.ip_local_port_range = 1024 65000 #允许系统打开的端口范围,用于向外连接的端口范围。缺省情况下其实很小:1024到4999。
kernel.msgmnb = 65536 #每个消息队列的最大字节限制。
kernel.msgmax = 65536 #单个消息的最大大小。 kernel.shmmax = 68719476736 #单个共享内存段的最大大小。
kernel.shmall = 4294967296 #可分配的共享内存数量的系统级限制。
net.ipv4.tcp_sack = 1 #选择性确认,减少重传。
net.ipv4.tcp_window_scaling = 1 # tcp滑动窗口大小是否可变
net.ipv4.tcp_rmem = 4096 87380 4194304 # TCP socket 读缓冲区最小、默认、最大大小
net.ipv4.tcp_wmem = 4096 16384 4194304 # TCP socket 写缓冲区最小、默认、最大大小
net.core.wmem_default = 8388608 # socket写缓冲区全局默认大小
net.core.rmem_default = 8388608 # socket读缓冲区全局默认大小
net.core.rmem_max = 16777216 # socket读缓冲区全局最大大小
net.core.wmem_max = 16777216 # socket写缓冲区全局最大大小 |
5.2 Nginx优化参数
worker_processes 8; #指定工作衍生的进程数(一般等于CPU的总核数或总核数的两倍)
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000; #指定工作进程到不同的CPU上
worker_rlimit_nofile 102400; #指定文件描述符数量
events { use epoll; #使用的网络I/O模型,linux系统推荐采用epoll,FreeBSD系统推荐采用kqueue。
worker_connections 102400; #允许的连接数 }
http { server_names_hash_bucket_size 128; #指定的是servername的哈希表大小。
client_header_buffer_size 4k; #客户端请求的http头部缓冲区大小。
large_client_header_buffers 4 32k; #针对过大的header使用。
client_max_body_size 8m; #设置客户端能够上传的文件大小
open_file_cache max=102400 inactive=20s; #指定打开文件缓存,建议和打开文件数一致,inactive 是指经过多长时间文件没被请求后删除缓存
open_file_cache_valid 30s; #是指多长时间检查一次缓存的有效信息
open_file_cache_min_uses 1; #指定了在open_file_cache参数中一定的时间范围内可以使用的最小文件数
sendfile on; #支持系统的sendfile功能
tcp_nopush on; #支持系统的tcp_nopush功能
tcp_nodelay on; #支持系统的tcp_nodelay功能
keepalive_timeout 0; #持久化连接的超时时间
fastcgi_connect_timeout 300; # fastcgi连接超时时间
fastcgi_send_timeout 300; # fastcgi发送数据超时时间
fastcgi_read_timeout 300; # fastcgi读取数据超时时间
fastcgi_buffer_size 64k; # fastcgi缓冲区大小
fastcgi_buffers 4 64k; # fastcgi缓冲区的多少和大小
fastcgi_busy_buffers_size 128k; # fastcgi忙碌时的缓冲区大小
fastcgi_temp_file_write_size 128k; #在写入fastcgi_temp_path时将用多大的数据块
gzip on; #支持gzip功能
gzip_min_length 1k; #允许压缩的页面最小字节数
gzip_buffers 4 16k; #gzip缓冲区大小
gzip_http_version 1.0; #识别http的协议版本
gzip_comp_level 2; # gzip压缩比,1 压缩比最小处理速度最快,9 压缩比最大但处理最慢(传输快但比较消耗cpu)。
gzip_types text/plain application/x-javascript text/css application/xml; #匹配类型进行压缩
gzip_vary on; #启用应答头“Vary: Accept-Encoding”,注意,由于一个bug将导致IE 4-6无法缓存内容。 } |
5.3 MySQL优化参数
[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql port = 3306 federated skip-name-resolve back_log = 1024 max_connections = 2048 table_open_cache = 2048 max_allowed_packet = 16M binlog_cache_size = 1M max_heap_table_size = 400M read_buffer_size = 2M read_rnd_buffer_size = 16M sort_buffer_size = 4M join_buffer_size = 8M thread_cache_size = 300
# master-master replication options log-bin=/var/lib/mysql/master server-id=2 binlog-do-db=asterisk replicate-do-db=asterisk
binlog_cache_size=1M slave-skip-errors=all slave-net-timeout=30
# You should try [number of CPUs]*(2..4) for thread_concurrency thread_concurrency = 128 query_cache_size = 64M query_cache_limit = 2M ft_min_word_len = 4 thread_stack = 192K transaction_isolation = REPEATABLE-READ tmp_table_size = 64M log_bin_trust_function_creators=1
#*** MyISAM Specific options
key_buffer_size = 512M bulk_insert_buffer_size = 64M myisam_sort_buffer_size = 128M myisam_max_sort_file_size = 10G myisam_repair_threads = 1 myisam_recover # *** INNODB Specific options ***
innodb_additional_mem_pool_size = 16M innodb_buffer_pool_size = 60G innodb_data_file_path = ibdata1:10M:autoextend innodb_write_io_threads = 16 innodb_read_io_threads = 16 innodb_thread_concurrency = 64 innodb_flush_log_at_trx_commit = 2 innodb_log_buffer_size = 8M innodb_log_file_size = 256M innodb_log_files_in_group = 3 innodb_max_dirty_pages_pct = 90 innodb_lock_wait_timeout = 120 innodb_file_per_table=1 group_concat_max_len=102400 innodb_use_sys_malloc=0 innodb_flush_method=O_DIRECT
[myisamchk] key_buffer_size = 512M sort_buffer_size = 512M read_buffer = 8M write_buffer = 8M
[mysqlhotcopy] interactive-timeout
[mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid
[mysql] socket=/var/lib/mysql/mysql.sock |