外观
MySQL 网络优化
网络基础配置
操作系统网络优化
TCP 参数优化
bash
# 调整 TCP 缓冲区大小
sysctl -w net.core.rmem_default=262144
sysctl -w net.core.wmem_default=262144
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
# 启用 TCP 窗口缩放
sysctl -w net.ipv4.tcp_window_scaling=1
# 启用时间戳
sysctl -w net.ipv4.tcp_timestamps=1
# 启用选择性确认
sysctl -w net.ipv4.tcp_sack=1
# 调整 SYN 队列大小
sysctl -w net.ipv4.tcp_max_syn_backlog=4096
sysctl -w net.ipv4.tcp_synack_retries=2
# 启用 SYN cookies
sysctl -w net.ipv4.tcp_syncookies=1
# 调整 TIME_WAIT 相关参数
sysctl -w net.ipv4.tcp_fin_timeout=30
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_tw_recycle=0
# 调整 keepalive 参数
sysctl -w net.ipv4.tcp_keepalive_time=600
sysctl -w net.ipv4.tcp_keepalive_probes=3
sysctl -w net.ipv4.tcp_keepalive_intvl=15
# 调整最大文件描述符
echo "* soft nofile 65535" >> /etc/security/limits.conf
echo "* hard nofile 65535" >> /etc/security/limits.conf持久化配置
bash
# 将优化后的参数保存到 /etc/sysctl.conf
echo "net.core.rmem_default=262144" >> /etc/sysctl.conf
echo "net.core.wmem_default=262144" >> /etc/sysctl.conf
echo "net.core.rmem_max=16777216" >> /etc/sysctl.conf
echo "net.core.wmem_max=16777216" >> /etc/sysctl.conf
echo "net.ipv4.tcp_rmem=4096 87380 16777216" >> /etc/sysctl.conf
echo "net.ipv4.tcp_wmem=4096 65536 16777216" >> /etc/sysctl.conf
echo "net.ipv4.tcp_window_scaling=1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_timestamps=1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_sack=1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_max_syn_backlog=4096" >> /etc/sysctl.conf
echo "net.ipv4.tcp_synack_retries=2" >> /etc/sysctl.conf
echo "net.ipv4.tcp_syncookies=1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_fin_timeout=30" >> /etc/sysctl.conf
echo "net.ipv4.tcp_tw_reuse=1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_tw_recycle=0" >> /etc/sysctl.conf
echo "net.ipv4.tcp_keepalive_time=600" >> /etc/sysctl.conf
echo "net.ipv4.tcp_keepalive_probes=3" >> /etc/sysctl.conf
echo "net.ipv4.tcp_keepalive_intvl=15" >> /etc/sysctl.conf
# 重新加载配置
sysctl -pMySQL 网络配置
基本网络参数
ini
# 监听地址,0.0.0.0 表示监听所有地址
bind-address = 0.0.0.0
# 监听端口
port = 3306
# 最大连接数
max_connections = 1000
# 最大错误连接数
tmax_connect_errors = 10000
# 连接超时时间(秒)
connect_timeout = 10
# 握手超时时间(秒)
# MySQL 5.7+ 新增
mysqlx_connect_timeout = 30连接优化参数
ini
# 跳过 DNS 反向解析
skip-name-resolve
# DNS 解析超时时间(秒)
# 如果不跳过 DNS 解析,建议设置合理的超时时间
dns-cache-ttl = 3600
# 启用 TCP Keepalive
tcp_keepalive_time = 600
tcp_keepalive_intvl = 75
tcp_keepalive_probes = 9
# 启用压缩传输
# 默认关闭,需要客户端支持
# 建议在网络带宽有限时启用
compression-algorithms = zlib,zstd
# 压缩级别,1-9,默认 6
# 仅在启用压缩时有效
# 级别越高,压缩率越高,但 CPU 消耗越大
compression-level = 6
# 最小压缩长度,默认 1024 字节
# 仅当数据包大小超过此值时才压缩
min-compress-length = 1024传输优化参数
ini
# 最大允许的数据包大小
# 建议根据实际需求设置,不宜过大
max_allowed_packet = 64M
# 网络缓冲区大小
# 建议设置为系统 TCP 缓冲区的一半
net_buffer_length = 16K
# 读取缓冲区大小
read_buffer_size = 128K
# 随机读取缓冲区大小
read_rnd_buffer_size = 256K
# 写入缓冲区大小
write_buffer_size = 256K
# 排序缓冲区大小
sort_buffer_size = 512K
# 连接读取缓冲区大小
net_read_timeout = 30
# 连接写入缓冲区大小
net_write_timeout = 60连接优化
连接池优化
应用层连接池
- 推荐使用:HikariCP(Java)、DBCP2(Java)、pymysqlpool(Python)、pgbouncer(通用)
- 关键配置:
- 最小连接数:根据最小负载设置
- 最大连接数:根据最大负载和服务器资源设置
- 连接超时:合理设置,避免长时间等待
- 最大空闲时间:避免连接长时间空闲
- 验证查询:定期验证连接有效性
MySQL 连接池配置示例(HikariCP)
java
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
config.setUsername("user");
config.setPassword("password");
config.setMinimumIdle(5);
config.setMaximumPoolSize(20);
config.setConnectionTimeout(30000);
config.setIdleTimeout(600000);
config.setMaxLifetime(1800000);
config.setValidationTimeout(5000);
config.setConnectionTestQuery("SELECT 1");
HikariDataSource dataSource = new HikariDataSource(config);连接管理
连接复用
- 避免频繁创建和关闭连接:使用连接池复用连接
- 合理设置连接超时:避免连接长时间占用
- 及时释放连接:应用程序使用完连接后及时关闭
- 使用长连接:对于频繁访问数据库的应用,使用长连接
连接监控
sql
-- 查看当前连接数
SHOW GLOBAL STATUS LIKE 'Threads_connected';
-- 查看最大连接数
SHOW GLOBAL VARIABLES LIKE 'max_connections';
-- 查看连接状态
SHOW PROCESSLIST;
-- 查看连接详细信息
SELECT * FROM information_schema.processlist WHERE COMMAND != 'Sleep';
-- 查看连接统计信息
SHOW GLOBAL STATUS LIKE 'Connections';
SHOW GLOBAL STATUS LIKE 'Aborted_connects';
SHOW GLOBAL STATUS LIKE 'Aborted_clients';传输优化
压缩传输
启用压缩
ini
# 服务器端启用压缩
# MySQL 8.0.19+ 支持的语法
compression-algorithms = zlib,zstd
# 客户端连接时启用压缩
# 使用命令行参数
mysql --compress -u user -p
# 使用连接字符串参数
jdbc:mysql://localhost:3306/mydb?useCompression=true
# 设置压缩级别
# MySQL 8.0.19+ 支持
compression-level = 6压缩效果评估
sql
-- 查看压缩统计信息
SHOW GLOBAL STATUS LIKE 'Compression%';
-- 压缩连接数
SHOW GLOBAL STATUS LIKE 'Compression_connections';
-- 压缩的数据量
SHOW GLOBAL STATUS LIKE 'Compression_bytes_sent';
SHOW GLOBAL STATUS LIKE 'Compression_bytes_received';
SHOW GLOBAL STATUS LIKE 'Compression_bytes_uncompressed_sent';
SHOW GLOBAL STATUS LIKE 'Compression_bytes_uncompressed_received';数据传输优化
只选择需要的列
sql
-- 避免 SELECT *
SELECT id, name, email FROM users WHERE id = 1;
-- 不要在 SELECT 中使用函数或表达式,除非必要
SELECT id, name, DATE_FORMAT(created_at, '%Y-%m-%d') AS created_date FROM users;限制结果集大小
sql
-- 使用 LIMIT 限制返回行数
SELECT * FROM users LIMIT 100;
-- 使用分页查询
SELECT * FROM users ORDER BY id LIMIT 0, 100;使用批量操作
sql
-- 批量插入
INSERT INTO users (name, email) VALUES ('user1', 'user1@example.com'), ('user2', 'user2@example.com'), ('user3', 'user3@example.com');
-- 批量更新
UPDATE users SET status = 1 WHERE id IN (1, 2, 3);
-- 批量删除
DELETE FROM users WHERE id IN (1, 2, 3);安全连接优化
SSL/TLS 配置
生成 SSL 证书
bash
# 生成 CA 私钥
openssl genrsa 2048 > ca-key.pem
# 生成 CA 证书
openssl req -sha1 -new -x509 -nodes -days 3650 -key ca-key.pem > ca-cert.pem
# 生成服务器私钥
openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem > server-req.pem
# 生成服务器证书
openssl x509 -sha1 -req -in server-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem
# 生成客户端私钥
openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout client-key.pem > client-req.pem
# 生成客户端证书
openssl x509 -sha1 -req -in client-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 02 > client-cert.pem
# 验证证书
openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem配置 SSL
ini
# 启用 SSL
ssl = ON
# SSL 证书路径
ssl_ca = /path/to/ca-cert.pem
ssl_cert = /path/to/server-cert.pem
ssl_key = /path/to/server-key.pem
# 要求所有连接使用 SSL
# 生产环境建议启用
require_secure_transport = ON
# 允许的 SSL 协议
# MySQL 8.0+ 支持的协议
tls_version = TLSv1.2,TLSv1.3
# 加密算法
# 推荐使用强加密算法
ssl_cipher = 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384'客户端使用 SSL 连接
bash
# 使用 SSL 连接
mysql --ssl-ca=/path/to/ca-cert.pem --ssl-cert=/path/to/client-cert.pem --ssl-key=/path/to/client-key.pem -u user -p
# 验证 SSL 连接
mysql> SHOW STATUS LIKE 'Ssl_cipher';连接安全
限制连接来源
ini
# 使用 bind-address 限制监听地址
bind-address = 192.168.1.100
# 使用防火墙限制连接来源
# iptables 示例
iptables -A INPUT -p tcp --dport 3306 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -j DROP限制用户连接权限
sql
-- 只允许从特定 IP 连接
CREATE USER 'user'@'192.168.1.%' IDENTIFIED BY 'password';
-- 只允许本地连接
CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
-- 授予最小必要权限
GRANT SELECT, INSERT, UPDATE ON mydb.* TO 'user'@'192.168.1.%';复制网络优化
主从复制网络优化
二进制日志优化
ini
# 使用 row 格式,减少网络传输
# 虽然 row 格式的二进制日志更大,但复制更可靠
# 适合网络带宽充足的场景
binlog_format = row
# 二进制日志压缩
# MySQL 8.0+ 支持
# 减少网络传输量
binlog_row_image = minimal
# 二进制日志缓存大小
# 提高写入性能
binlog_cache_size = 32M
max_binlog_cache_size = 512M
# 单个二进制日志大小
# 避免过大的日志文件
max_binlog_size = 1G
# 二进制日志过期时间
# 避免占用过多磁盘空间
binlog_expire_logs_seconds = 604800复制线程优化
ini
# 从库 I/O 线程数量
# MySQL 8.0+ 支持多线程复制
# 默认为 1
slave_parallel_workers = 4
# 并行复制类型
# LOGICAL_CLOCK:基于逻辑时钟的并行复制
# DATABASE:基于数据库的并行复制
slave_parallel_type = LOGICAL_CLOCK
# 从库 SQL 线程延迟阈值
# 用于监控复制延迟
slave_transaction_retries = 10
# 从库心跳间隔(秒)
# 用于检测主从连接状态
master_info_repository = TABLE
relay_log_info_repository = TABLE
relay_log_recovery = ON半同步复制优化
ini
# 启用半同步复制
plugin_load_add = 'rpl_semi_sync_master=semisync_master.so'
plugin_load_add = 'rpl_semi_sync_slave=semisync_slave.so'
# 主库启用半同步复制
rpl_semi_sync_master_enabled = 1
# 主库等待确认的超时时间(毫秒)
# 超时后降级为异步复制
rpl_semi_sync_master_timeout = 10000
# 从库启用半同步复制
rpl_semi_sync_slave_enabled = 1
# 主库至少需要多少个从库确认
# MySQL 5.7+ 支持
rpl_semi_sync_master_wait_for_slave_count = 1
# 主库是否等待从库的确认
# ON:等待所有从库确认
# OFF:等待至少一个从库确认
rpl_semi_sync_master_wait_no_slave = OFF组复制网络优化
组复制参数
ini
# 组复制本地地址
loose-group_replication_local_address = "192.168.1.100:33061"
# 组复制种子地址
loose-group_replication_group_seeds = "192.168.1.100:33061,192.168.1.101:33061,192.168.1.102:33061"
# 组复制通信超时时间(毫秒)
loose-group_replication_member_expel_timeout = 5000
# 组复制网络重试次数
loose-group_replication_transaction_size_limit = 150000000
# 组复制消息压缩
# MySQL 8.0+ 支持
# 减少网络传输量
loose-group_replication_compression_threshold = 1024
# 组复制压缩算法
# MySQL 8.0+ 支持
# 可选:none, zlib, lz4, zstd
loose-group_replication_message_compression_algorithms = "zlib,zstd,lz4"监控与诊断
网络监控
系统级监控
bash
# 监控网络连接
netstat -an | grep 3306 | wc -l
# 监控网络流量
iftop -i eth0
# 监控网络连接状态
ss -s
# 监控 TCP 连接
ss -t state ESTABLISHED '( dport = :3306 or sport = :3306 )'
# 监控 UDP 连接
ss -u state ESTABLISHED '( dport = :3306 or sport = :3306 )'MySQL 级监控
sql
-- 查看连接状态
SHOW GLOBAL STATUS LIKE 'Threads%';
-- 查看连接错误
SHOW GLOBAL STATUS LIKE 'Aborted%';
-- 查看网络统计信息
SHOW GLOBAL STATUS LIKE 'Bytes%';
-- 查看复制状态
SHOW SLAVE STATUS\G;
-- 查看组复制状态
SELECT * FROM performance_schema.replication_group_members;
SELECT * FROM performance_schema.replication_group_member_stats;网络诊断
连接测试
bash
# 使用 telnet 测试连接
telnet mysql-server.example.com 3306
# 使用 mysql 客户端测试连接
mysql -h mysql-server.example.com -u user -p
# 使用 ping 测试网络延迟
ping -c 10 mysql-server.example.com
# 使用 traceroute 测试网络路径
traceroute mysql-server.example.com
# 使用 mtr 测试网络质量
mtr mysql-server.example.com性能测试
bash
# 使用 sysbench 测试网络性能
sysbench --db-driver=mysql --mysql-host=mysql-server.example.com --mysql-port=3306 --mysql-user=user --mysql-password=password --mysql-db=test --table_size=1000000 --threads=16 --time=60 --events=0 --rand-type=uniform /usr/share/sysbench/oltp_read_write.lua run
# 使用 mysqlslap 测试性能
mysqlslap --host=mysql-server.example.com --user=user --password=password --concurrency=16 --iterations=5 --create-schema=test --query="SELECT * FROM test.users LIMIT 100" --delimiter=";最佳实践
网络配置最佳实践
- 根据实际需求调整参数:不要盲目复制配置,根据实际负载和服务器资源调整
- 监控关键指标:定期监控网络连接数、流量、延迟等指标
- 使用连接池:所有应用程序都应使用连接池
- 启用压缩:在网络带宽有限的场景下启用压缩
- 使用 SSL/TLS:在生产环境中启用 SSL/TLS 加密
- 限制连接来源:使用防火墙和用户权限限制连接来源
连接管理最佳实践
- 合理设置连接数:避免设置过大的最大连接数
- 定期清理空闲连接:使用连接池的最大空闲时间参数
- 验证连接有效性:使用连接池的验证查询
- 及时释放连接:应用程序使用完连接后及时关闭
- 监控连接泄漏:定期检查长时间运行的连接
复制网络最佳实践
- 使用可靠的网络:主从复制应使用可靠的网络连接
- 调整复制线程数:根据服务器CPU核数调整并行复制线程数
- 使用半同步复制:在对数据一致性要求高的场景下使用
- 监控复制延迟:定期监控复制延迟,及时发现问题
- 备份二进制日志:定期备份二进制日志,用于灾难恢复
常见问题(FAQ)
Q1: 如何优化 MySQL 网络性能?
A1: 可以从以下几个方面优化:
- 优化操作系统网络参数
- 优化 MySQL 网络配置
- 使用连接池
- 启用压缩传输
- 优化数据传输
- 使用 SSL/TLS 加密
- 优化复制网络
Q2: 何时启用压缩传输?
A2: 建议在以下场景启用压缩传输:
- 网络带宽有限
- 传输的数据量较大
- 客户端与服务器之间的网络延迟较高
- 应用程序对响应时间不敏感
Q3: 如何调整最大连接数?
A3: 应根据以下因素调整最大连接数:
- 服务器CPU核数:一般为CPU核数的2-4倍
- 内存大小:每个连接大约需要 2-10MB 内存
- 应用程序负载:根据最大并发需求
- 其他服务占用的资源:考虑服务器上其他服务的资源占用
Q4: 如何减少连接泄漏?
A4: 可以通过以下方式减少连接泄漏:
- 使用连接池管理连接
- 确保应用程序使用完连接后及时关闭
- 设置合理的连接超时和最大空闲时间
- 定期监控长时间运行的连接
- 使用连接池的验证查询
Q5: 如何优化主从复制网络?
A5: 可以从以下几个方面优化:
- 使用 row 格式的二进制日志
- 调整二进制日志缓存大小
- 启用并行复制
- 调整复制线程数
- 使用半同步复制
- 监控复制延迟
Q6: 如何诊断网络问题?
A6: 可以使用以下工具诊断网络问题:
- ping:测试网络延迟
- traceroute:测试网络路径
- mtr:测试网络质量
- telnet:测试连接
- mysql 客户端:测试数据库连接
- netstat/ss:监控网络连接
- iftop:监控网络流量
Q7: 如何选择合适的连接池?
A7: 选择连接池时应考虑:
- 性能:连接池的性能和资源消耗
- 可靠性:连接池的稳定性和容错能力
- 功能:支持的功能和配置选项
- 社区支持:社区活跃度和文档质量
- 与应用程序的兼容性:是否支持应用程序的开发语言和框架
