sniperHW/flyfish

多条件操作、事务、sql回写错误怎么处理?

Opened this issue · 1 comments

我是看了知乎的文章过来的,感谢你的分享。https://zhuanlan.zhihu.com/p/86545815
因为对冷热数据分离很有兴趣,有几点疑问想请教您,希望有时间的时候能回复一下。

1、在多条件查询时,如果key有多个,或者多个field组成的关联主键,这种情况下怎么设计key?假设有2个field组成的关联主键,我只用1个想要查询出多行记录,这个是不是只能用通配符遍历key,当key数量大时应该会影响性能吧。另外,如果我不想通主键查询,而是通过其他field查询该怎么办呢?那岂不是要遍历当前表的所有行了。再扩展到多表的查询,比如union,join这种,应该就只能自己在代码中实现了吧。
2、假设我的代码中有大量的db操作,需要改写成flyfish的api。1中的问题我想总归能解决的。可是因为redis事务的不完整,也就是后面操作失败的情况下,前面的操作不支持回滚,那怎么改写db事务呢。这一点我还没想通,能想到的就是完全回写。对于简单的事务,在开启multi后,保存住所有要操作数据的原始状态,捕获exec执行结果,exec失败后,再把所有数据根据原始状态重新写一遍。当然了,这里也有并发风险。
3、异步回写sql的过程中,如果发生了错误,比如人为编码错误,或者表格式约束,导致mysql提示错误,这时候即使有日志能错误捕获,但是也不能轻易尝试再次回写了。因为保不齐,下一个操作已经把当前数据改写掉了。想问下这种异常情况下,该怎么处理比较好呢?

因为还没有阅读兄弟的源码,如果你已经解释过的问题我还提了出来也请不要生气。

1、flyfish的设计目标就是针对游戏中最普遍的数据访问模式提供一套可靠的kv缓存系统。真正的落地数据库并不一定必须是sql数据库,例如使用tikv作为数据库也是可以的。所以如果应用涉及大量关系数据库的操作,直接选择成熟的分布式关系数据系统更合适。
2、flyfish是一个分布式缓存,事务中操作的多个kv可能被缓存在多个分片上,所以要实现事务的话就必须实现分布式事务。这一块我暂时还没有考虑好用什么方案实现。不过这块跟db事务应该没关系,因为数据回写都是异步的。只要把flyfish作为统一的数据访问接口,flyfish中的数据最终跟db上的数据将达成一致。
3、目前就是这样的设计,如果在回写过程中发生不可重试性错误,本次任务就不再尝试了,但是并没有把kv的dirty标记清除,也就是下次再触发回写时,之前变更的内容还会再次尝试回写回去。之所以这么设计是因为,如果flyfish先使用了新配置,例如增加了一个字段,而数据库还未应用新的配置,此时回写肯定会失败的。如果后面数据库更新了配置,那么之后的回写就会成功。