前因
场景1:线上的数据异步同步使用的是rabbitmq,当对数据库数据进行增删改时候会发送一条mq消息到同步服务,同时进行查库写入es。
场景2:线上redis数据读取mysql中数据写入,由于该数据为访问量巨大的数据,所以未设置过期时间,有增删改操作时,会读库重新写入redis。
场景3:线上数据库实时读取,当修改为某项后异步刷新列表,发现该数据未进行修改,重新刷新后才显示正确数据
排查过程
以上问题,我们排查过程比较迅速,第一时间对比es,redis,mysql中数据,发现了数据不同步的情况,然后查看代码,发现未有对数据进行代码层改动,
我们已知数据库为主从模式,由此主从延时故障找到。
解决方案
方案1:发mq消息时,直接将整条数据发送并且写入。但是一旦数据量过大,会造成压力,并且有删改的情况出现时,我们一般不会去获取整条数据,还是得查询数据库后发送
方案2:redis设置有效期,过完有效期redis会重新加载数据入库,但是有效期内的数据是不正确的
方案3:增加主库数据库读,在写mq,写redis这些场景下直接读取主库,避免了碰到主从延时的问题,数据也能及时更新,但是此种方案有可能对主库造成大压力。
后果
以上几种方案,我们使用了方案二和方案三并行的情况,保证主从有延时的情况下,数据不会出错。
反思:
1.发生了一次主从延时,我们后面在结构优化,数据读的场景都会考虑到此种情况,从而针对进行改进
2.在一定的范围内,还是建议数据库独立,尽量不使用公共数据库(此种方案的决定方是运维)