Ubuntu16.04操作系统-内核优化

1. 概述

本文所用优化是生产环境中经过长期验证的内核优化策略,针对的服务器与POD主要用于高CPU、高内存、高IO的业务场景。

备注: OS: ubuntu16.04, 内核: 4.15.0-147-generic

主要涵盖以下内容优化:

  • ulimit优化
  • 加强tcp参数
  • 其他内存参数

2. Node 相关调参汇总

ulimit 是一种 linux 系统的内键功能,它具有一套参数集,用于为由它生成的 shell 进程及其子进程的资源使用设置限制。为了让系统能够支持更大的并发,优化linux内核也是重中之重

2.1 最大线程数和文件打开数

编辑 /etc/security/limits.conf

# Standard limits config
*       soft            nofile  20480000
*       hard            nofile  20480000
root       soft            nofile  20480000
root       hard            nofile  20480000
*       soft            core    unlimited
*       hard            core    unlimited
*       soft            nproc   unlimited
*       hard            nproc   unlimited
root       soft            nproc   unlimited
root       hard            nproc   unlimited
  • 调整UserTasksMax,UserTasksMax用于限制一个用户可以创建的最大进程数。
vim /etc/systemd/logind.conf

UserTasksMax=655350
  • 调整pids.max参数来设定进程的最大数量
echo 655350 > /sys/fs/cgroup/pids/user.slice/user-0.slice/pids.max

pids.max表示当前cgroup中最多允许创建的进程数目。当一个进程尝试创建新的进程时,内核会检查当前cgroup的pids.max限制,如果当前进程数目已经等于或超过了该限制,就会阻止新的进程的创建,并返回相应的错误。
使用cgroup的pids.max限制,可以将系统资源分配给不同的进程,从而避免进程数量过多而导致系统CPU、内存和I/O等资源的耗尽。可以通过修改pids.max参数来设定进程的最大数量,以便更好地分配系统资源。

2.2 sysctl优化

编辑 /etc/sysctl.conf

fs.file-max = 20480000
fs.nr_open = 20480000
#最多打开文件数

kernel.msgmnb = 104857600
#ipc消息队列容量

kernel.msgmax = 20480000
#ipc消息队列长度

kernel.msgmni = 4096000
#ipc消息队列上限制

net.ipv4.tcp_syncookies = 1
#打开TCP同步标签(syncookie),防止一个套接字在有过多试图连接到达时引起过载。

kernel.core_uses_pid = 1
#使core文件包含pid信息

kernel.shmall = 18446744073692774399
#允许使用共享内存大小

net.core.somaxconn = 65535
#端口做大监听队列长度

net.core.wmem_default = 33554432
#默认的socket发送缓冲区大小

net.core.rmem_default = 33554432
#默认的socket接收缓冲区大小

net.core.rmem_max = 67108864
#最大的socket接收缓冲区大小

net.core.wmem_max = 67108864
#最大的socket发送缓冲区大小

net.ipv4.tcp_synack_retries = 1
#内核在放弃连接之前发送SYN+ACK包重试次数tcp_max_tw_buckets

net.ipv4.tcp_syn_retries = 1
#内核在放弃连接之前发送SYN包重试次数

net.ipv4.tcp_tw_recycle = 1
#允许将TIME-WAIT sockets重新用于新的TCP连接

net.ipv4.tcp_tw_reuse = 1
#开启TCP连接中TIME-WAIT sockets的快速回收

net.ipv4.tcp_mem = 94500000 915000000 927000000
#允许所有tcp sockets用于排队缓冲数据报的页面数量阈值,low,pressure,high

net.ipv4.tcp_rmem = 8192 128000 33554432

net.ipv4.tcp_wmem = 8192 128000 33554432

net.core.optmem_max = 25165824

net.ipv4.tcp_window_scaling = 1

net.ipv4.tcp_sack = 1

net.ipv4.tcp_fack = 1

net.core.netdev_max_backlog = 60000

net.ipv4.tcp_no_metrics_save = 1

fs.may_detach_mounts = 1

net.ipv4.tcp_max_orphans = 3276800
#系统所能处理不属于任何进程的TCP sockets最大数量

net.ipv4.ip_local_port_range = 10240 65535
#TCP/UDP协议打开的本地端口号范围

net.ipv4.tcp_fin_timeout = 10
#对于本端断开的socket连接,TCP保持在FIN-WAIT-2状态的时间

net.ipv4.tcp_keepalive_time = 100
# tcp 心跳保活时间

net.ipv4.tcp_max_syn_backlog = 262144
#对于那些依然还未获得客户端确认的连接请求,需要保存在队列中最大数目

net.ipv4.tcp_max_tw_buckets = 20000
#系统在同时所处理的最大timewait sockets 数目

kernel.perf_event_paranoid = 2
#perf输出信息权限

kernel.yama.ptrace_scope = 0
#允许trace

net.ipv4.udp_mem = 67108864 89478485 134217728
#允许所有udp sockets用于排队缓冲数据报的页面数量阈值,low,pressure,high

net.ipv4.udp_rmem_min = 33554432
#udp接受缓存最小值

net.ipv4.udp_wmem_min = 33554432
#udp发送缓存最小值

kernel.pid_max = 655300
#系统允许的最大线程数

kernel.sem = 2500 64000 320 1280
#ipc sem相关配数目阈值

vm.overcommit_memory = 1
#内核允许分配所有的物理内存,而不管当前的内存状态如何

fs.file-max = 20480000
#系统所有进程总共可以打开的文件数量

fs.inotify.max_user_instances = 1280
#每一个real user ID可创建的inotify instatnces的数量上限

vm.swappiness = 10
#更倾向于使用内存而非swap分区

net.ipv4.neigh.default.gc_thresh1 = 2048
#arp表gc 参数

net.ipv4.neigh.default.gc_thresh2 = 4096
#arp表gc 参数

net.ipv4.neigh.default.gc_thresh3 = 8192
#arp表gc 参数

fs.inotify.max_queued_events = 163840
#fsnotify 文件该表通知相关参数

fs.inotify.max_user_instances = 12800
#fsnotify 文件该表通知相关参数

fs.inotify.max_user_watches = 81920
#fsnotify 文件该表通知相关参数

net.netfilter.nf_conntrack_tcp_timeout_established = 1200
#nf跟踪表超时参数

net.netfilter.nf_conntrack_max = 4116480
#nf跟踪表最大阈值

net.nf_conntrack_max = 4116480
#nf跟踪表最大阈值

net.ipv4.ip_local_reserved_ports = 5666,59317-59367,10248,10250,10255,10520
#本地保留端口

vm.max_map_count = 2097152
#map的最大内存个数

net.ipv4.ipfrag_high_thresh = 419430400
#ip 分片的内存阈值

net.ipv4.ipfrag_low_thresh = 314572800
#ip 分片的内存阈值

net.ipv4.ipfrag_time = 100
#ip 分片的内存阈值

net.ipv4.ip_forward = 1
#开启ip转发

fs.mqueue.msg_default = 100
#fs 消息队列参数

fs.mqueue.msg_max = 100
#fs 消息队列参数

fs.mqueue.msgsize_default = 32768
#fs 消息队列参数

fs.mqueue.msgsize_max = 32768
#fs 消息队列参数

fs.mqueue.queues_max = 2560
#fs 消息队列参数

net.ipv4.tcp_timestamps = 0
#关闭tcp timestamps校验,容器fullnat 模式下不校验timestamp 防止协议栈拒绝tcp 请求

2.3 tcp 握手队列相关优化

net.ipv4.tcp_syncookies = 1
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192

# 端口范围
net.ipv4.ip_local_port_range = "1024 65000"

# timewait相关优化
net.ipv4.tcp_max_tw_buckets = 50000
net.ipv4.tcp_fin_timeout = 30

2.4 优化 arp 缓存的 gc 阀值

# 以下三个参数是 arp 缓存的 gc 阀值,相比默认值提高了,避免在某些场景下arp缓存溢出导致网络超时,参考:https://k8s.imroc.io/troubleshooting/cases/arp-cache-overflow-causes-healthcheck-failed
net.ipv4.neigh.default.gc_thresh1="2048"
net.ipv4.neigh.default.gc_thresh2="4096"
net.ipv4.neigh.default.gc_thresh3="8192"

2.5 开启 ipv4 转发

net.ipv4.tcp_max_orphans="32768"
vm.max_map_count="262144"
kernel.threads-max="30058"
net.ipv4.ip_forward="1"

2.6 转发磁盘 IO 优化

# 磁盘 IO 优化: https://www.cnblogs.com/276815076/p/5687814.html
# vm.dirty_background_bytes和vm.dirty_bytes是另一种指定这些参数的方法。如果设置_bytes版本,则_ratio版本将变为0,反之亦然。
# 可以通过下面方式看内存中有多少脏数据:cat /proc/vmstat | egrep "dirty|writeback", nr_dirty 值表示多少页
# vm.dirty_background_bytes = 0
# vm.dirty_bytes = 0
vm.dirty_background_ratio = 5
vm.dirty_expire_centisecs = 300
vm.dirty_ratio = 10
vm.dirty_writeback_centisecs = 50
vm.dirtytime_expire_seconds = 43200

# fd优化
fs.file-max=655360
fs.inotify.max_user_instances="8192"
fs.inotify.max_user_watches="524288"
# 最大线程数量
kernel.pid_max = 655350

# 系统保留的空闲物理内存大小
vm.min_free_kbytes=2097152

3. Pod 相关调参汇总

# socket buffer优化
net.ipv4.tcp_wmem = 4096        16384   4194304
net.ipv4.tcp_rmem = 4096        87380   6291456
net.ipv4.tcp_mem = 381462       508616  762924
net.core.rmem_default = 8388608
# 读写 buffer 调到 25M 避免大流量时导致 buffer 满而丢包 "netstat -s" 可以看到 receive buffer errors 或 send buffer errors
net.core.rmem_max = 26214400 
net.core.wmem_max = 26214400
 
# timewait相关优化
# 这个优化意义不大
net.ipv4.tcp_max_tw_buckets = 131072 
# 通常默认本身是开启的
net.ipv4.tcp_timestamps = 1  
# 仅对客户端有效果,对于高并发客户端,可以复用TIME_WAIT连接端口,避免源端口耗尽建连失败
net.ipv4.tcp_tw_reuse = 1 
# 对于高并发客户端,加大源端口范围,避免源端口耗尽建连失败(确保容器内不会监听源端口范围的端口)
net.ipv4.ip_local_port_range="1024 65535" 
# 缩短TIME_WAIT时间,加速端口回收
net.ipv4.tcp_fin_timeout=30 
 
# 握手队列相关优化
# 没有启用syncookies的情况下,syn queue(半连接队列)大小除了受somaxconn限制外,也受这个参数的限制,默认1024,优化到8096,避免在高并发场景下丢包
net.ipv4.tcp_max_syn_backlog = 10240 
# 表示socket监听(listen)的backlog上限,也就是就是socket的监听队列(accept queue),当一个tcp连接尚未被处理或建立时(半连接状态),会保存在这个监听队列,默认为 128,在高并发场景下偏小,优化到 32768。参考 https://imroc.io/posts/kubernetes-overflow-and-drop/
net.core.somaxconn = 65535 
net.ipv4.tcp_syncookies = 1

# fd优化
# 提升文件句柄上限,像 nginx 这种代理,每个连接实际分别会对 downstream 和 upstream 占用一个句柄,连接量大的情况下句柄消耗就大。
fs.file-max=1048576 
# 表示同一用户同时最大可以拥有的 inotify 实例 (每个实例可以有很多 watch)
fs.inotify.max_user_instances="8192" 
# 表示同一用户同时可以添加的watch数目(watch一般是针对目录,决定了同时同一用户可以监控的目录数量) 默认值 8192 在容器场景下偏小,在某些情况下可能会导致 inotify watch 数量耗尽,使得创建 Pod 不成功或者 kubelet 无法启动成功,将其优化到 524288
fs.inotify.max_user_watches="524288" 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SRExianxian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值