
配置排查走不通
按照常规思路,我们先拉出了fe.conf开始逐行检查。端口配置正常,JAVA_OPTS_FOR_JDK_17参数合理,Xmx8192m/Xms8192m设置一致,lower_case_table_names=2虽然是比较特殊的设置,但跟这次的CPU飙升问题没有直接关系。
查完一遍之后,团队成员面面相觑:配置本身没有明显的错误。那问题到底在哪里?这时有经验的老同事提了一个思路:配置没问题,不代表使用方式没问题。FE热起来不一定是因为"配错了",也可能是"用法把FE打热了"。这句话点醒了不少人。
写入方式的深层问题
把代码翻出来仔细看之后,发现了几个之前没太注意的问题。首先,批量写入之前会先查一遍版本——每次真正写入前都要执行类似SELECTbiz_key,versionFROMxxxWHEREbiz_keyIN(...)的查询。也就是说,每个批次实际上对应至少2条SQL:先查一遍,再插一遍。其次,代码里还有listPendingRows(200)轮询加单条markSuccess/markFail更新的逻辑。
到这一步,大家开始意识到一个中期判断可能是对的:FECPU高,未必是2000条批次本身太大,更可能是Doris同时承担了大量"小查询+小更新+批量插入"的混合流量导致的。
为了进一步定位问题,我们开始调整JDBC参数。原来连接的URL大概是这样的:useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8。这组参数能正常连接,但对Doris这种场景不太友好,缺少了一些关键的性能优化参数。
意外出现的新问题
加上useServerPrepStmts=true、useLocalSessionState=true、rewriteBatchedStatements=true、cachePrepStmts=true以及sessionVariables=group_commit=async_mode这些参数后,本来以为问题应该能缓解了,结果冒出了一个新异常:Parameterindexoutofbounds.44930isnotbetweenvalidvaluesof1and44928。
这个异常栈里有几个关键信号:ServerPreparedStatement.checkBounds、ClientPreparedStatement.setString、Parameterindexoutofbounds。从这些信息来看,问题已经不是Doris表结构或者UniqueKey+sequence_col配置的问题了,而是JDBC驱动在绑定PreparedStatement参数的时候直接崩了。
这时候排查方向不得不再次修正。我们开始深入分析MyBatis的batchUpsert到底是怎么工作的。结果发现,这根本不是标准JDBC的addBatch/executeBatch模式,而是通过标签在XML里拼接出一条超长的INSERT...VALUES(...),(...),...语句。
