[TOC]

0x00 前言简述


0x01 Linux系统参数

1.内核参数

1
2
3
4
5
6
7
8
9
10
sysctl -a | grep "sched_rt"

# CPU
# 内核进程CPU调度设置(RT实时、CFS完全公平调度)
kernel.sched_rt_period_us = 1000000
kernel.sched_rt_runtime_us = 950000
kernel.sched_cfs_bandwidth_slice_us = 5000

# 启用用户名称空间
kernel.unprivileged_userns_clone = 1

vm 参数

  • vm.swappiness: 主要作用在内存与交换分区之间优化,该值的大小对如何使用swap分区是有着很大的联系的,并对系统使用效率有一定的影响,因为Swap分区数据存于磁盘性能会相对内存低,尤其是读写频繁的情绪IO消耗会更大 (注意具体环境具体分析);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 参数值:
swapniess 策略
* 0 Linux3.5以及以上:宁愿OOM killer也不用swap,Linux3.4以及更早:宁愿swap也不要OOM killer
* 1 Linux3.5以及以上:宁愿swap也不要OOM killer
* 60 默认值
* 100 操作系统会主动地使用swap


# 临时生效 (此参数值越低,就会让Linux系统尽量少用swap分区,多用内存;参数值越高就是反过来,使内核更多的去使用swap空间)
sysctl -w vm.swappiness=0 # 表示最大限度使用物理内存然后才再使用swap空间(优先使用物理内存-推荐值除非是VPS内存不够用的)
sysctl -w vm.swappiness=100 # 表示积极的使用swap分区并且把内存上的数据及时的搬运到swap空间里面;

# 参数路径
cat /proc/sys/vm/swappiness

# 默认值: 60
# 推荐值:

Tips : OOM(Out Of Memory) killer机制是指Linux操作系统发现可用内存不足时,强制杀死一些用户进程(非内核进程),来保证系统有足够的可用内存进行分配。
Tips : swappiness参数在Linux 3.5版本前后的表现并不完全相同,Redis运维人员在设置这个值需要关注当前操作系统的内核版本。


  • vm.max_map_count: 限制一个进程可以拥有的VMA(虚拟内存区域)的数量。
    描述: 此文件包含进程可能拥有的最大内存映射区数。内存映射区被用作调用malloc的副作用直接由mmap和mprotect调用,也可以在加载共享库时使用。虽然大多数应用程序只需要不到1000个映射,但某些程序特别是malloc调试器可能会消耗大量映射,例如每次分配最多一到两个映射。

默认值: 65536
推荐值: 调整为默认的4倍即为: sysctl -w vm.max_map_count=262144

  • vm.overcommit_memory : 用来设置内存分配策略(Redis 推荐配置为1)
    参数说明:
    1
    2
    3
    4
    * 0	表示内核将检查是否有足够的可用内存。如果有足够的可用内存,内存申请通过,否则内存申请失败,并把错误返回给应用进程
    * 1 表示内核允许超量使用内存直到用完为止
    * 2 表示内核决不过量的("never overcommit")使用内存,即系统整个内存地址空间不能超过swap+50%的RAM值,50%是overcommit_ratio默认值,此参数同样支持修改
    `
    默认值: 0
    推荐值: 1 (针对于作为Redis内存数据库服务的机器)

Tips:注意:本文的可用内存代表物理内存与swap之和。


net 参数

描述: Linux系统下TCP连接断开后,会以TIME_WAIT状态保留一定的时间,然后才会释放端口。当并发请求过多的时候,就会产生大量的TIME_WAIT状态的连接,无法及时断开的话,会占用大量的端口资源和服务器资源。此时我们可以优化TCP的内核参数,来及时将TIME_WAIT状态的端口清理掉。

实用示例1.提升服务器负载能力

1
2
3
4
5
6
7
8
9
10
11
12
13
# (1) 查看当前TCP连接的状态和对应的连接数量:
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
ESTABLISHED 229
TIME_WAIT 18000 # 占用18000个端口此时由于端游占用一个少一个,会严重的影响到后继的新连接,所以我们需要让系统更快的释放TIME_WAIT连接。

# 如下调整提升服务器负载能力之外,还能够防御小流量的Dos、CC和SYN攻击
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_fastopen = 3


  • net.ipv4.tcp_syncookies : 表示开启SYNCookies 当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击
    默认值: 0 (表示关闭)
    推荐值: 1

  • net.ipv4.tcp_tw_reuse : 表示开启重用允许将TIME-WAITsockets重新用于新的TCP连接
    默认值: 0 (表示关闭)
    推荐值: 1

  • net.ipv4.tcp_tw_recycle : 表示开启TCP连接中TIME-WAITsockets的快速回收
    默认值: 0 (表示关闭)
    推荐值: 1

  • net.ipv4.tcp_fin_timeout : 表示修改系統TCP默认的 TIMEOUT 时间。
    默认值: 60
    推荐值: 30

  • net.ipv4.tcp_synack_retries : 为了打开对端的连接内核需要发送一个SYN并附带一个回应前面一个SYN的ACK(所谓三次握手中的第二次握手),该设置决定了内核放弃连接之前发送SYN+ACK包的数量。
    默认值: 5
    推荐值: 2|1

  • net.ipv4.tcp_syn_retries : 在内核放弃建立连接之前发送SYN包的数量。
    默认值: 6
    推荐值: 2|1

  • net.ipv4.tcp_max_orphans : 系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。
    默认值: 65535 (缺省)
    建议值: 一般缺省

  • net.ipv4.tcp_available_congestion_control : TCP可用的拥塞算法

    1
    2
    sudo sysctl -a | grep "net.ipv4.tcp_available_congestion_control"
    # 可用算法 : net.ipv4.tcp_available_congestion_control = reno cubic
  • net.ipv4.tcp_congestion_control : 设置TCP 拥塞算法为cubic

    1
    2
    sudo sysctl -a | grep "net.ipv4.tcp_congestion_control"
    # 默认值: net.ipv4.tcp_congestion_control = cubic
  • net.ipv4.tcp_fastopen : 在Linux支持TFO的内核版本下用来加速连续TCP连接的数据交互的TCP协议扩展(Client内核版本为3.6;Server内核版本为3.7中使用)

    1
    2
    3
    4
    5
    6
    7
    sudo sysctl -a | grep "net.ipv4.tcp_fastopen"
    # net.ipv4.tcp_fastopen = 1
    # net.ipv4.tcp_fastopen_blackhole_timeout_sec = 3600
    # net.ipv4.tcp_fastopen_key = 00000000-00000000-00000000-00000000
    # 缺省值: 1
    # 其中1表示客户端开启,2表示服务端开启,3表示客户端和服务器同时开启
    # 推荐值: 3 (未验证效果)


实用示例2.优化TCP的可使用端口范围及提升服务器并发能力(注意一般流量小的服务器上没必要设置如下参数)

1
2
3
4
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.ip_local_port_range = 1024 65535

  • net.ipv4.tcp_keepalive_time : 表示当keepalive启用的时候TCP发送keepalive消息的频度。
    默认值: 7200 (2 Hour)
    推荐值: 1200 (s)

  • net.ipv4.ip_local_port_range : 表示用于向外连接的端口范围

    1
    2
    3
    # sudo sysctl -a | grep "ip_local_port_range"
    默认值: net.ipv4.ip_local_port_range = 32768 60999
    推荐值: 1024 65535
  • net.ipv4.tcp_max_syn_backlog : 表示SYN队列的长度设置此参数可以容纳更多等待连接的网络连接数。
    默认值: 1024
    推荐值: 8192

  • net.ipv4.tcp_max_tw_buckets : 表示系统同时保持TIME_WAIT的最大数量,如果超过这个数字,TIME_WAIT将立刻被清除并打印警告信息。
    默认值: 65536
    推荐值: 5000

  • net.ipv4.tcp_mem : TCP读写buffer

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    sudo sysctl -a | grep "net.ipv4.tcp_mem"
    #默认值(16G): net.ipv4.tcp_mem = 189924 253234 379848
    #默认值(512G): net.ipv4.tcp_mem = 6171576 8228769 12343152
    net.ipv4.tcp_mem = 94500000 915000000 927000000

    #建议值:
    #值含义: 上述内存单位是页,而不是字节
    net.ipv4.tcp_mem[0]:低于此值,TCP没有内存压力。
    net.ipv4.tcp_mem[1]:在此值下,进入内存压力阶段。
    net.ipv4.tcp_mem[2]:高于此值,TCP拒绝分配socket。
  • net.ipv4.tcp_wmem : TCP写buffer

    1
    2
    3
    sudo sysctl -a | grep "net.ipv4.tcp_wmem"
    #默认值: net.ipv4.tcp_wmem = 4096 16384 4194304
    #建议值: net.ipv4.tcp_wmem = 8192 436600 873200
  • net.ipv4.tcp_rmem : TCP读buffer

    1
    2
    3
    sudo sysctl -a | grep "net.ipv4.tcp_rmem"
    #默认值: net.ipv4.tcp_rmem = 4096 131072 6291456
    #建议值:32768 436600 873200


实用示例3.优化核套接字TCP的缓存区设置

1
2
3
4
5
6
net.core.netdev_max_backlog = 8192
net.core.somaxconn = 32768
net.core.rmem_max = 12582912
net.core.rmem_default = 6291456
net.core.wmem_max = 12582912
net.core.wmem_default = 6291456

  • net.core.netdev_max_backlog : 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
    缺省值: 1000,对于512G的内存为262144(1G*512)
    推荐值: 对于16G的内存设置为262114

  • net.core.somaxconn : 记录的那些尚未收到客户端确认信息的连接请求的最大值(结合高并发请求数来调节此值;)。
    默认值: 4096
    推荐值: 16384

  • net.core.rmem_default : 这个参数表示内核套接字接收receive缓存区默认的大小(通常小于等于rmem_max值);

  • net.core.rmem_max : 这个参数表示内核套接字接收receive缓存区的最大大小;
    1
    2
    3
    4
    5
    sudo sysctl -a | egrep "net.core.rmem_default|net.core.rmem_max"
    默认值:
    # net.core.rmem_default = 212992
    # net.core.rmem_max = 212992
    推荐值: 6291456 12582912
  • net.core.wmem_default : 这个参数表示内核套接字发送send缓存区默认的大小(通常小于等于wmem_max值);
  • net.core.wmem_max : 这个参数表示内核套接字发送send缓存区的最大大小;
    1
    2
    3
    4
    5
    6
    7
    sudo sysctl -a | egrep "net.core.wmem_default|net.core.wmem_max" | head -n5
    默认值:
    # net.core.wmem_default = 212992
    # net.core.wmem_max = 212992
    推荐值:
    # net.core.wmem_default = 6291456
    # net.core.wmem_max = 12582912


fs 参数

描述: 该参数主要针对于文件描述符系统级别的资源进行限制。

1
2
fs.file-max = 1646839
fs.aio-max-nr = 1048576

  • fs.file-nr : 表示进程当前打开的句柄数以及最大的句柄数;

    1
    2
    3
    4
    5
    $ cat /proc/sys/fs/file-nr
    # 16640 0 52698870

    $ sudo sysctl -a | egrep "fs.file-nr"
    # 16640 0 52698870
  • fs.file-max : 表示进程(比如一个worker进程)可以同时打开的最大句柄数,这个参数直线限制最大并发连接数,需根据实际情况配置;

    1
    2
    3
    4
    默认值:
    # fs.file-max = 52698870 (512G)
    推荐值:
    # fs.file-max = 1646839 (16G)
  • fs.aio-max-nr : 同时可以拥有的的异步IO请求数目。

1
2
3
4
5
# 默认值
fs.aio-max-nr = 65536

# 推荐值(1024*1024 = 1024K)
fs.aio-max-nr = 1048576

2.系统参数

描述: 在对于Linux服务器系统参数调优时候往往需要修改以下相关参数;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
~$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 63708
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
open files (-n) 1024 # 最大文件打开句柄数
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) 63708
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited

# 指标解释 - <item> can be one of the following:
# - core - limits the core file size (KB)
# - data - max data size (KB)
# - fsize - maximum filesize (KB)
# - memlock - max locked-in-memory address space (KB)
# - nofile - max number of open file descriptors
# - rss - max resident set size (KB)
# - stack - max stack size (KB)
# - cpu - max CPU time (MIN)
# - nproc - max number of processes
# - as - address space limit (KB)
# - maxlogins - max number of logins for this user
# - maxsyslogins - max number of logins on the system
# - priority - the priority to run user process with
# - locks - max number of file locks the user can hold
# - sigpending - max number of pending signals
# - msgqueue - max memory used by POSIX message queues (bytes)
# - nice - max nice priority allowed to raise to values: [-20, 19]
# - rtprio - max realtime priority
# - chroot - change root to directory (Debian-specific)


open files 参数

描述: 该参数主要设置是单个进程能够设置Linux最大文件句柄数, 常常在调优时对其优化保证以后服务器在高并发下正常运行。否则在高并非的情况下很容报Too many open files错误。

默认值: 1024
最大值: 65535 (不能超过2^16)

参数设置:

1
2
3
4
5
6
7
8
9
10
# 方式1
ulimit -HSn 65535

# 方式2./etc/security/limits.conf | 此方法需要重启系统
# 软限制(soft limit):内核实际执行的限制,任何进程都可以将软限制设置为小于或等于对进程限制的硬限制的值、最大线程数和文件数。
# 硬限制(hard limit):可以在任何时候任何进程中设置,但硬限制需要由超级用户修改。
# soft nofile :可打开的文件描述符的最大数(超过会警告);
* soft nofile 65535
# hard nofile :可打开的文件描述符的最大数(超过会报错)
* hard nofile 65535


max user processes 参数

描述: 该参数主要设置是单个用户最大进程数。

默认值: 63708
最大值: 65535 (不能超过2^16)

参数设置

1
2
3
4
5
6
7
8
# 方式1
ulimit -HSu 65535

# 方式2./etc/security/limits.conf | 此方法需要同样也需要重启系统
# 单个用户可用的最大进程数量(超过会警告);
* soft nproc 65535
# 单个用户可用的最大进程数量(超过会报错);
* hard nproc 65535

Tips : 用户可用的最大进程数量以及打开的文件描述符的最大数设置与下述两个内核参数有关。

  • (1) 所有进程打开的文件描述符数不能超过它/proc/sys/fs/file-max内核可分配的所有进程最大文件数。
  • (2) 单个进程打开的文件描述符数不能超过它/proc/sys/fs/nr_open内核可分配的单个进程最大文件数。

/proc/sys/fs/file-handle