otter 带表情包同步踩坑及解决方案
一、事情发生
在年末22点44分突然收到微信告警otter同步异常告警,channel_id为6的同步channel挂起,而且一直没有恢复,一直在告警
微信的otter告警是我们使用python脚本去获取zookeeper中每个channel的状态,每1分钟会检查一次状态,如果发现状态异常就通过微信告警平台告警。
微信告警是一个针对运维异常状态的一个告警服务,目前汇集了所有系统的告警信息,会根据告警的等级对不同用户进行微信推送。

二、原因分析
发生告警后通过跳板机登录otter查看otter状态为挂起,点击解挂或停止重启也会挂起,就这样反复,而且channel同步的位点则没有变化,位点最后更新时间也不会变化;查看日志发现otter同步报错,但报错信息很简单也一直报同样的错误,通过错误日志没办法定位问题原因。

由于是otter双向同步,只有一个pipeline同步有异常(位点没有更新,最后同步时间没更新),所以直接到同步的node节点下看日志,一般otter的同步日志写在自己的pipeline id下/app/otter/logs/11,通过查看两边的pipeline日志后发现同步写入数据库时报插入错误,
java.sql.SQLException: Incorrect string value: ‘\xF0\x9F\xA4\xAA’ for column ‘nickname’ at row 1

看日志是在nickname这一个字段出现在不确定的字符,通过查看binlog日志发现是一个用户表情包

到此原因基本确定了。
- otter在通过binlog双边同步时,发现有一个用户表情时在写入时序列化为
\xF0\x9F\xA4\xAA无法插入报错 - otter不断在此点位上重试,每次重试都报错
三、 临时方案
为了解决此报错,在两边追上同步进度,现在需要跳过一个报错的位点,从下一个位点继续开始同步,对此我们已有具体的操作步骤:
- 确定otter当前同步的位点及时间
- 查找binlog临近位点信息,确定此事务下一个位点位置
- 找到下一个位点及时间,更新zookeeper对应的位点信息
- 重启继续同步
以上操作有很多具体的流程,经过以上操作后很快同步完成。
四、整体问题解决
以上步骤只是临时解决方案,为了彻底解决需要从根本上找到问题的原因,在otter的issue里有这个问题,建议是两边数据库和表字段都需要设置为UFT8MB4字符集。

通过查看两边数据库,在插入端的数据库和数据库表都设置的为utf8,但字段是utf8mb4,如果需要修改数据库实例需要重启,在生产环境重启会影响业务,影响特别大。


通过进一步的排查发现在otter同步的时候我们设置数据库的数据源也是UTF8,所以有可能在同步的时候就已经有问题,所以准备是在otter端直接修改字符集,但在修改验证数据源时发现otter提示和数据库字符集不一致。

为了保证通过客户端修改产生问题,通过查看源码发现这个配置没有写在zookeeper中,所在找到数据库表data_media_source,直接修改字符编码集(properties字段json字段中的encode)。

修改后重启channel,即可生效。
博客讲述了在年末时,OTTER双向同步出现异常,因表情包字符无法插入数据库引发的同步挂起问题。通过分析日志发现是由于字段值包含不支持的UTF8字符。临时解决方案是跳过错误位点继续同步,而永久解决办法是将数据库和表字段改为UTF8MB4字符集。在生产环境中,由于改动数据库涉及风险,最终通过直接修改OTTER的数据源字符集来解决问题,避免了数据库重启的影响。
7366

被折叠的 条评论
为什么被折叠?



