问题定义
写后读一致即写完数据之后马上读,直接能读到新的数据,而不是老的数据。
导致这个问题主要是数据库之间的同步延时。这里只讨论一主多从的情况。 如下图:
- 用户添加新评论
- 用户刷新,读请求到从节点1,此时从节点还没有主从复制完成,用户看不到自己的评论
- 用户刷新,读请求到从节点1,此时从节点主从复制完成,用户可以看见自己的评论
- 用户刷新,读请求到从节点2,此时从节点还没有主从复制完成,用户看不到自己的评论
这种情况就会出现很诡异的情况,自己的评论时有时无的。我们预期是一直能看到最新的评论。
解决方法
解决方法之一是把最近有写入操作的用户的读取操作路由到数据库主节点(Pinning User to Master)。其他用户的读取操作还是走从节点。
当用户写入之后的特定的时间窗口内,将用户的读操作固定到主节点,这样读取和写入都转移到了主节点,这意味着读取将从始终具有最新数据副本的数据节点进行,因此可以实现读写一致性。
在时间窗口之后,读操作可以转移到从节点。
代码示例
创建数据库的连接
这里创建2种连接,一个直接和master相连,另一个使用读写分离的方式连接。
- master的连接可以看这个函数
func initMasterDb() {
PDbHost := viper.GetString("MYSQL.HostName")
PDbPort := viper.GetString("MYSQL.Port")
PDbUser := viper.Get