ClickHouse上传超250万行90列CSV时出现Connection reset by peer报错
ClickHouse大体积CSV插入报错排查与解决方案
根因定位
你遇到的两个错误存在关联:服务端插入过程中返回Code: 33(无法读取完整数据)错误后主动断开连接,才导致客户端收到Connection reset by peer的210错误。
Code33错误属于数据传输/反序列化阶段错误,和表的分区、排序键配置无关联,因此你调整这两个参数无法解决问题
排查解决步骤
1. 校验CSV文件本身合法性
- 先测试小批量数据是否可正常插入,排除格式不匹配问题,执行测试命令:
head -n 1000 {filepath}.csv | sudo docker run -i --rm yandex/clickhouse-client -m --host {host} -u {user} --input_format_allow_errors_num=10 --input_format_allow_errors_ratio=0.1 --max_memory_usage=15000000000 --format_csv_allow_single_quotes 0 --input_format_skip_unknown_fields 1 --query='INSERT INTO table_name FORMAT CSVWithNames'
如果小批量数据也插入失败,优先检查以下问题:
- CSV是否存在未转义的双引号、分隔符、换行符异常,导致字段错位
- CSV编码是否为UTF-8,是否存在不可见特殊字符,可执行
file {filepath}.csv查看编码格式 - 表字段类型和CSV内容是否匹配,重点检查Nullable类型字段的空值格式、数值类型字段是否存在非数值内容、String类型字段是否存在超长异常值
2. 调整插入参数适配大文件场景
你当前配置的input_format_allow_errors_num和input_format_allow_errors_ratio仅对CSV解析阶段的错误生效,无法覆盖数据传输/反序列化阶段的错误,需要新增以下参数:
- 增加
--max_block_size=1048576调整单次传输的数据块大小,避免单次传输数据量过大导致传输中断 - 增加
--receive_timeout=3600 --send_timeout=3600延长传输超时时间,避免大文件传输过程中超时被服务端断连 - 调整插入方式,将本地CSV目录挂载到Docker容器内再执行插入,避免管道传输缓冲区溢出断流,优化后命令示例:
sudo docker run -i --rm -v {本地CSV所在目录绝对路径}:/csv_tmp yandex/clickhouse-client -m --host {host} -u {user} \ --input_format_allow_errors_num=10 \ --input_format_allow_errors_ratio=0.1 \ --max_memory_usage=20000000000 \ --format_csv_allow_single_quotes 0 \ --input_format_skip_unknown_fields 1 \ --max_block_size=1048576 \ --receive_timeout=3600 \ --send_timeout=3600 \ --query='INSERT INTO table_name FORMAT CSVWithNames' < /csv_tmp/{csv文件名}.csv
3. 校验服务端配置限制
- 检查服务端全局
max_memory_usage配置,客户端设置的内存上限不能超过服务端全局限制,否则插入查询会被服务端主动Kill导致断连 - 检查服务端
keep_alive_timeout配置是否过短,大文件插入过程中心跳超时也会触发服务端主动断连 - 查看服务端系统日志,确认是否存在OOM Kill记录,服务端内存不足杀掉插入进程也会返回Code33错误
4. 分块插入规避大文件压力
如果以上调整仍无法解决问题,将250万行的CSV拆分为多个10-20万行的小文件分批插入,避免单次插入压力过大,拆分命令示例:
split -l 200000 {filepath}.csv csv_split_
拆分完成后循环插入所有小文件即可。
内容的提问来源于stack exchange,提问作者Abhinav Raj
相关产品推荐
相关产品推荐

