tencent cloud

TencentOS Server

Network Kernel Optimization

Baixar
Modo Foco
Tamanho da Fonte
Última atualização: 2026-10-19 17:22:48
Traduzido por IA

Feature Overview

This document describes how to tune network kernel parameters in TencentOS Server 4, covering TCP core parameters, connection tracking (conntrack), buffer management, interrupt and multi-queue optimization, and congestion control selection, helping users achieve more stable network performance in high-concurrency gateway, cross-region transfer, and container network scenarios.

Background Information

Network kernel tuning refers to systematic parameter adjustment for the TCP protocol stack, connection tracking, and interrupt handling in scenarios such as high-concurrency Web services, API gateways, and cross-region data synchronization. Common issues in typical scenarios include:
Port exhaustion: A large number of short-lived connections enter the TIME_WAIT state, causing source port exhaustion and new connection failures.
Connection tracking table full: When the conntrack table reaches its entry limit, new connections are rejected.
Limited throughput: The default TCP buffer is not suitable for high-bandwidth, long-latency (large BDP) links, and the window cannot be filled.
Low bandwidth utilization: Packet loss on public network links causes the cubic congestion control algorithm to reduce its window frequently, preventing full utilization of the available bandwidth.
TencentOS Server 4 has a built-in Linux 6.6 LTS kernel and supports features such as the bbr congestion control algorithm, million-level conntrack, and TCP Fast Open by default. By tuning parameters appropriately, you can enable a single CVM to handle more concurrent connections and utilize public network bandwidth more efficiently.

Must-Knows

tcp_tw_reuse NAT conflict risk: tcp_tw_reuse=1 may cause five-tuple conflicts in NAT environments, where the source port is reused when a client passes through a NAT Gateway. If a Tencent Cloud CVM accesses external services through a NAT Gateway as a client, enabling this parameter is not recommended. It is recommended to enable it only in the server role.
BBR not suitable for private networks: The BBR congestion control algorithm is suitable for public network links with long latency and packet loss. In private network scenarios with short latency, such as between CVMs or in container networks, BBR may perform worse than the default cubic algorithm. If your private network business uses a hybrid deployment, it is recommended to use the cubic algorithm.
nf_conntrack_buckets is read-only: net.netfilter.nf_conntrack_buckets is read-only at runtime and cannot be modified through sysctl. You must set it through the kernel boot parameter nf_conntrack.hashsize=<N>, which takes effect after a reboot.
Progressive parameter adjustment: Network parameter tuning should be performed incrementally after baseline testing. If multiple parameters are modified simultaneously, it is difficult to determine the specific impact of each parameter on performance.
Default value differences: Default values of some parameters may vary depending on the kernel minor version and memory size. It is recommended to run sysctl -a | grep <parameter_name> to verify the actual default values.
Persistent file location: It is recommended to store persistent configuration files in the /etc/sysctl.d/ directory. Do not directly modify the /etc/sysctl.conf file to avoid configuration conflicts.
Permission requirements: All sysctl, ethtool, and /proc/irq write operations require root privileges. Run them as the root user or a user with sudo privileges.
Kernel module loading: Before using BBR, confirm that the tcp_bbr module is loaded. If it is not loaded by default, run modprobe tcp_bbr to load the module manually.
Connection tracking module loading: Before using conntrack-related parameters, confirm that the nf_conntrack module is loaded. If it is not loaded by default, run modprobe nf_conntrack to load the module manually.
NIC RSS/RFS support confirmation: Interrupt and multi-queue optimization depends on the NIC hardware multi-queue (RSS) capability. Run ethtool -l <NIC_name> first to confirm that the NIC supports combined queue adjustment.
Baseline data: Before tuning, it is recommended to collect baseline performance data using tools such as iperf3 and wrk to facilitate comparison of tuning results.
Persistent file location: It is recommended to store persistent configuration files in the /etc/sysctl.d/ directory. Do not directly modify the /etc/sysctl.conf file to avoid configuration conflicts.

API and Parameter Description

TCP Connection and Timeout Parameters

Parameter
Default Value
Recommended Value (High Concurrency)
Description
net.ipv4.tcp_tw_reuse
2
1
Reuses ports in the TIME_WAIT state. Values: 2=Reuse allowed only on loopback interfaces (kernel default), 1=Reuse enabled globally (requires tcp_timestamps to be enabled), 0=Disabled. For high-concurrency servers, 1 is recommended; for the client role in NAT environments, enabling this is not recommended (see notes).
net.ipv4.tcp_fin_timeout
30
15
FIN-WAIT-2 timeout in seconds
net.ipv4.tcp_keepalive_time
7200
600
keepalive probe interval in seconds
net.ipv4.tcp_keepalive_intvl
75
30
Probe retry interval in seconds
net.ipv4.tcp_keepalive_probes
9
3
Number of probes
net.ipv4.tcp_max_tw_buckets
4096
1048576
Maximum number of TIME_WAIT connections (the actual default value may be automatically adjusted based on memory size)
net.ipv4.tcp_max_syn_backlog
1024
8192
SYN queue length
net.core.somaxconn
128
65535
listen() backlog upper limit
Note:
The default value of this parameter in the kernel is related to system memory. The calculation formula is TCP_TIMEWAIT_LEN * TCP_TW_BUCKETS_FACTOR, which can be simplified to a linear estimation based on memory: default value = a proportional value of (memory_size_in_pages * PAGE_SIZE / 4096).
Actual empirical values: approximately 4096 for 4 GB of memory, 16384 for 16 GB of memory, and 65536 for 64 GB of memory. For precise values, run sysctl net.ipv4.tcp_max_tw_buckets on the target machine.

TCP Buffer Parameters

Parameter
Recommended Value (High Throughput)
Description
net.core.rmem_max
16777216
Maximum receive buffer value (16 MB)
net.core.wmem_max
16777216
Maximum send buffer value (16 MB)
net.ipv4.tcp_rmem
4096 87380 16777216
TCP receive buffer (min/default/max)
net.ipv4.tcp_wmem
4096 65536 16777216
TCP send buffer (min/default/max)
net.core.netdev_max_backlog
5000
Receive queue length from NIC to kernel

Connection Tracking (conntrack) Parameters

Parameter
Recommended Value
Description
net.netfilter.nf_conntrack_max
1048576
Maximum value of the connection tracking table
net.netfilter.nf_conntrack_buckets
262144
Number of hash buckets (read-only, set through the kernel boot parameter nf_conntrack.hashsize=<N>. Recommended not to exceed nf_conntrack_max / 4. The maximum value is limited by system memory.)
net.netfilter.nf_conntrack_tcp_timeout_established
3600
ESTABLISHED timeout in seconds
net.netfilter.nf_conntrack_tcp_timeout_time_wait
30
TIME_WAIT timeout in seconds

Other TCP Parameters

Parameter
Recommended Value
Description
net.ipv4.tcp_timestamps
1
Enable timestamps (RTT calculation)
net.ipv4.tcp_window_scaling
1
Enable window scaling
net.ipv4.tcp_sack
1
Selective acknowledgment
net.ipv4.tcp_dsack
1
Duplicate SACK
net.ipv4.tcp_fastopen
3
TCP Fast Open (client + server)
Note:
net.ipv4.tcp_low_latency has been removed since Linux 4.x. The kernel ignores this parameter, and it is no longer listed as a recommended tuning item.

Operation Steps

1. Loading the BBR Congestion Control Module

# Load the tcp_bbr kernel module
modprobe tcp_bbr

# Confirm that the module is loaded
lsmod | grep tcp_bbr
# Expected output: tcp_bbr 20480 0 (or other non-empty output, indicating that the module is loaded)

# Confirm that BBR is in the list of available algorithms
sysctl net.ipv4.tcp_available_congestion_control
# Expected output: net.ipv4.tcp_available_congestion_control = reno cubic bbr

2. Switching the Congestion Control Algorithm to BBR

# View the current algorithm
sysctl net.ipv4.tcp_congestion_control
# Expected output: net.ipv4.tcp_congestion_control = cubic

# Switch to BBR (recommended for high-bandwidth public network scenarios, not recommended for private network scenarios)
sysctl -w net.ipv4.tcp_congestion_control=bbr
# Expected output: net.ipv4.tcp_congestion_control = bbr

# Verify that the switch is successful
sysctl net.ipv4.tcp_congestion_control
# Expected output: net.ipv4.tcp_congestion_control = bbr

3. Viewing and Adjusting the conntrack Table

# Confirm that the nf_conntrack module is loaded (if it is not loaded, the conntrack parameter path does not exist)
modprobe nf_conntrack

# View current connection tracking statistics
sysctl net.netfilter.nf_conntrack_count
# Expected output: net.netfilter.nf_conntrack_count = 12345 (sample value, the number of currently tracked connections)

sysctl net.netfilter.nf_conntrack_max
# Expected output: net.netfilter.nf_conntrack_max = 65536 (current maximum value)

# Temporarily increase the maximum value of the conntrack table (takes effect at runtime)
sysctl -w net.netfilter.nf_conntrack_max=1048576
# Expected output: net.netfilter.nf_conntrack_max = 1048576
Warning
nf_conntrack_buckets is read-only at runtime and cannot be modified through sysctl. To adjust the number of hash buckets, set it in the kernel boot parameter:
# View the current buckets value
cat /sys/module/nf_conntrack/parameters/hashsize
# Modify grub boot parameters (a restart is required for the changes to take effect)
grubby --update-kernel=ALL --args="nf_conntrack.hashsize=262144"
# Note: A restart will cause service interruption. Make sure no critical services are running before proceeding.
reboot

4. Verification After conntrack Adjustment

# Confirm that max has been updated (the nf_conntrack module must be loaded, otherwise the parameter path does not exist)
sysctl net.netfilter.nf_conntrack_max
# Expected output: net.netfilter.nf_conntrack_max = 1048576

# Confirm that the current connection count is not close to max to avoid saturation.
sysctl net.netfilter.nf_conntrack_count
# Expected output: a value far below max, with utilization below 70%

# View conntrack statistics (check insert_failed and drop, which should be 0)
cat /proc/net/stat/nf_conntrack
# Or use ctstat to view the summary (ctstat is provided by the iproute-tc package. If it is not installed, run dnf install iproute-tc)
ctstat -s 1
# Expected output: insert_failed=0, drop=0 (if insert_failed keeps increasing, the table is still full)

5. Interrupt and Multi-Queue Optimization (RSS)

# View the actual NIC name by using ip link
ip link show

# RSS (Receive Side Scaling): View the NIC multi-queue configuration
ethtool -l <NIC name>
# Expected output: Channel parameters are displayed, where Combined under Pre-set maximums indicates the maximum supported queue count, and Combined under Current hardware settings indicates the current queue count (for example, Combined: 2)

# Set the queue count (requires NIC support. The <queue count> is determined by the number of CPU cores, typically equal to the core count, and must not exceed the maximum Combined value in Pre-set maximums)
ethtool -L <NIC name> combined <queue count>
# Expected output: no errors. Run ethtool -l <NIC name> again to see that Combined queues have been updated

6. Interrupt Affinity Binding (IRQ Affinity)

# View the actual NIC name by using ip link
ip link show
# View the NIC interrupt distribution (Note: In virtualized environments, NIC interrupts are identified by the underlying device name, such as virtio0-input.0,
# Using the NIC name with grep may produce no output. Run ethtool -i <NIC name> first to view the driver/bus-info, and then search by the device name.
grep virtio /proc/interrupts
# Expected output: multiple lines, each corresponding to an interrupt of a transmit/receive queue (such as virtio0-input.0 and virtio0-output.0),
# Interrupt counts across queues should be roughly evenly distributed

# Set interrupt affinity (replace <IRQ number> with the actual interrupt number and bind it to a specific CPU mask;
# The mask must not exceed the number of CPUs. For example, on a 2-CPU machine, the maximum valid mask is 3, and writing f will report "write error: Value too large for defined data type".
echo f > /proc/irq/<IRQ_number>/smp_affinity
# Expected output: no errors (f means binding to CPU 0-3, and ff means binding to CPU 0-7. Use f on a 4-CPU machine and ff on an 8-CPU machine)

# Verify affinity
cat /proc/irq/<IRQ_number>/smp_affinity_list
# Expected output: 0-3 (or the corresponding CPU list)

7. RPS (Receive Packet Steering) Configuration

# Set the RPS CPU mask (replace <NIC name> with the actual NIC. rx-0 is the first receive queue)
# ffff is a 16-bit CPU mask, indicating binding to CPU 0-15. If the number of CPUs exceeds 16, use a longer mask.
echo ffff > /sys/class/net/<NIC_name>/queues/rx-0/rps_cpus
# Expected output: No errors.

# Set the RPS flow table size
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries
# Expected output: No errors.

# Verify the RPS configuration
cat /sys/class/net/<NIC_name>/queues/rx-0/rps_cpus
# Expected output: ffff

8. Interrupt Optimization Verification

# View the actual NIC name by using ip link
ip link show

# Check whether the interrupt distribution is balanced across queues (in virtualized environments, search by the underlying device name, such as virtio)
grep virtio /proc/interrupts
# Expected output: The interrupt counts are roughly even across queues, with no single core saturated.

# View softirq network processing statistics (each line corresponds to one CPU, and values are in hexadecimal format without a prefix)
cat /proc/net/softnet_stat
# Expected output: multiple lines, where the second column (drop, in hexadecimal) should be 00000000,
# The third column (time_squeeze, in hexadecimal) should be small and not grow continuously.

9. Persisting Configuration

Note: The tcp_congestion_control = bbr setting depends on the tcp_bbr module being loaded (see the automatic module loading configuration at startup below). If the module is not loaded, writing this parameter will fail or be skipped.
# Write to /etc/sysctl.d/ for persistence
cat > /etc/sysctl.d/99-tos-net-tune.conf << 'EOF'
net.core.somaxconn = 65535
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_congestion_control = bbr
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 1048576
net.netfilter.nf_conntrack_max = 1048576
EOF

# Configure the BBR module to load automatically at boot
echo "tcp_bbr" > /etc/modules-load.d/tcp_bbr.conf

# Apply the configuration
sysctl --system
# Expected output: * Applying /etc/sysctl.d/99-tos-net-tune.conf ... and listing each parameter value

10. Verification After Configuration Is Persisted

# Verify that each key parameter has been persisted and taken effect
sysctl net.ipv4.tcp_congestion_control
# Expected output: net.ipv4.tcp_congestion_control = bbr

sysctl net.core.somaxconn
# Expected output: net.core.somaxconn = 65535

sysctl net.netfilter.nf_conntrack_max
# Expected output: net.netfilter.nf_conntrack_max = 1048576

FAQs

Q1: Error "cannot stat /proc/sys/...: No such file or directory" When sysctl -w Is Run

Cause: The corresponding kernel module is not loaded (for example, when nf_conntrack is not loaded, the conntrack parameter path does not exist).
Solution: Load the corresponding kernel module and try again.
# Load the corresponding module
modprobe nf_conntrack
# Confirm that the parameter path appears
ls /proc/sys/net/netfilter/nf_conntrack_max

Q2: BBR Not Taking Effect After Switching, tcp_congestion_control Still cubic

Cause: The tcp_bbr module is not loaded, or bbr is not in the tcp_available_congestion_control list.
Solution: Manually load the tcp_bbr module and confirm that it is in the list of available algorithms.
# Manually load the module
modprobe tcp_bbr
# Confirm that bbr is in the available list
sysctl net.ipv4.tcp_available_congestion_control
# If bbr is not available, check the kernel version (TencentOS Server 4 with kernel 6.6 LTS has built-in BBR support)
uname -r

Q3: Error "Operation not permitted" or "Invalid argument" When ethtool -L Is Run

Cause: Some environments (such as certain SR-IOV passthrough modes) do not support dynamically modifying the number of NIC queues.
Solution: Check whether the NIC supports queue adjustment. If not, use RPS software distribution instead of hardware RSS.
# Check whether the NIC supports queue adjustment
ethtool -l <NIC name>
# If "Maximum" is not supported after Combined queues is output, adjustment is not possible
# Use RPS (software distribution) instead of hardware RSS (ffff is a 16-bit CPU mask representing CPUs 0-15; use a longer mask when there are more than 16 CPUs)
echo ffff > /sys/class/net/<NIC_name>/queues/rx-0/rps_cpus

Q4: conntrack Table Still Frequently Full After Adjustment, Causing New Connection Failures

Cause: nf_conntrack_max is increased, but nf_conntrack_buckets is not adjusted accordingly, resulting in severe conflicts due to too few hash buckets.
Solution: Increase the number of hash buckets in nf_conntrack_buckets accordingly.
# View the current buckets (read-only)
cat /sys/module/nf_conntrack/parameters/hashsize
# Adjust buckets through kernel boot parameters (a restart is required; the recommended value does not exceed nf_conntrack_max / 4, and the maximum value is limited by system memory)
grubby --update-kernel=ALL --args="nf_conntrack.hashsize=262144"
# Restart (a restart will cause service interruption, so perform it within a maintenance window)
reboot
# Confirm that buckets have been updated after the restart.
cat /sys/module/nf_conntrack/parameters/hashsize

Q5: Some Parameters Not Taking Effect After Restart Despite Persisted Configuration

Cause: The same parameters exist in multiple files under /etc/sysctl.conf and /etc/sysctl.d/, causing a conflict in the loading order.
Solution: Check for duplicate definitions of parameters with the same name and consolidate them into a single configuration file.
# Check for duplicate definitions.
grep -r "tcp_congestion_control" /etc/sysctl.conf /etc/sysctl.d/
# Consolidate them into /etc/sysctl.d/99-tos-net-tune.conf and delete the conflicting entries in other files.
# Confirm the loading order (the 99- prefix ensures that it is loaded last)
sysctl --system


Ajuda e Suporte

Esta página foi útil?

comentários