如何提升Docker部署的MySQL 8.0每秒写入次数,目标达1万次/秒?
性能问题核心诊断
你当前每分钟仅写入200行(约每秒3行)的性能表现远低于MySQL 8.0的正常水平,首先可以确定不是硬件上限导致的,问题集中在插入逻辑不合理和MySQL配置缺失关键优化项两个层面,优化后完全可以大幅提升写入速度。
一、优先优化Laravel 数据填充逻辑(性能提升幅度最大)
绝大多数db:seed写入慢的问题都是插入逻辑不合理导致的:
- 禁止在Seeder中循环单条插入数据,每一次
Model::create()都会单独发起事务请求,IO开销极大,改为批量写入,单次提交1000~5000行数据,参考写法:
// 错误写法:单条插入 foreach ($dataList as $item) { YourModel::create($item); } // 正确写法:批量分块插入 $chunk = []; foreach ($dataList as $item) { $chunk[] = $item; if (count($chunk) === 1000) { YourModel::insert($chunk); $chunk = []; } } if (!empty($chunk)) { YourModel::insert($chunk); }
- 测试环境填充数据时,可以临时关闭模型事件、SQL严格校验,进一步降低额外开销。
二、优化MySQL my.cnf 配置
你当前的配置仅调整了IO线程参数,缺失很多写入优化的核心项,替换为以下配置:
[mysqld] # 基础配置 skip-name-resolve max_connections = 1000 default-authentication-plugin = mysql_native_password # Innodb 核心配置(innodb_buffer_pool_size建议设置为分配给Docker内存的70%,以下是4G内存分配的参数值,如果分配8G内存可以改为6G) innodb_buffer_pool_size = 2G innodb_buffer_pool_instances = 2 innodb_log_file_size = 1G innodb_log_buffer_size = 64M innodb_flush_log_at_trx_commit = 2 # 生产环境要高可靠性改为1,测试环境可以改为0,性能更高 innodb_flush_method = O_DIRECT innodb_autoinc_lock_mode = 2 innodb_change_buffering = inserts innodb_io_capacity_max = 4000 # 原有IO配置保留 innodb_io_capacity = 2000 innodb_read_io_threads = 64 innodb_thread_concurrency = 0 # 改为0让MySQL自动调度,性能优于固定值 innodb_write_io_threads = 64 # 测试环境不需要主从同步可以关闭binlog,写入性能提升30%以上 skip-log-bin
注意:修改配置后需要删除原有MySQL卷重启容器才能生效,执行
docker volume rm sailmysql前请提前备份数据。
三、Docker层面优化
- 不要用宿主机目录挂载存储MySQL数据,你当前用的
sailmysql命名卷性能符合要求,无需修改;如果是Windows/Mac运行Docker,不要把MySQL数据目录挂载到本地Windows/Mac的文件系统,否则IO性能会下降10倍以上。 - 给Docker分配至少4核4G以上的资源,资源不足时调整MySQL参数不会有明显效果。
每秒1万次写入目标可行性
- 如果是批量提交写入,普通SSD硬件优化后完全可以达到甚至超过每秒1万行的写入目标,单表简单字段批量写入普遍可以做到每秒2万行以上。
- 如果是单条独立事务写入(每条写入单独提交事务),普通消费级SSD很难达到这个目标,需要更高的IO硬件配置支撑。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

