返回

踩坑,发现一个ShardingJdbc读写分离的BUG

后端

前言

最近公司准备接入ShardingJdbc做读写分离了,老大让我们理一理有没有写完数据立马读的场景。

让我们回想一下ShardingJdbc读写分离是怎么工作的?ShardingJdbc是通过在写库和读库上分别创建两个数据源,然后通过中间件来实现读写分离的。

我们来看一张经典的读写分离架构图:

+-----------------------------+
|                             |
|                             |
|      +--------------+      |
|      | 写数据库     |      |
|      +--------------+      |
|                             |
+-----------------------------+
            |
            |
            V
+-----------------------------+
|                             |
|                             |
|      +--------------+      |
|      | 读数据库     |      |
|      +--------------+      |
|                             |
+-----------------------------+

当我们进行写操作的时候,中间件会将数据路由到写库,当我们进行读操作的时候,中间件会将数据路由到读库。

发现问题

在理业务代码的时候,我们发现了一个问题,就是有一个场景是:写完数据立马读,也就是说,我们刚在写库中插入了一条数据,然后紧接着就从读库中读取这条数据。

我们知道,在读写分离架构中,读库和写库是两个独立的数据库,所以当我们刚在写库中插入了一条数据,这条数据并不会马上同步到读库中。

因此,如果我们在这个场景下进行读操作,我们就很有可能会读不到刚插入的数据。

解决问题

为了解决这个问题,我们需要在读写分离架构中引入一个额外的机制,来保证写完数据立马读。

这个机制就是:读写分离中间件在将数据路由到读库之前,先检查一下读库中是否有这条数据,如果没有,就从写库中读取这条数据,然后再将这条数据同步到读库中。

这样,我们就保证了写完数据立马读。

踩坑

我们在实际使用ShardingJdbc的时候,就遇到了这个问题。

我们发现,在写完数据立马读的场景下,ShardingJdbc并不会自动将数据同步到读库中,导致我们读不到刚插入的数据。

为了解决这个问题,我们不得不手动在读写分离中间件中添加了一个额外的机制,来保证写完数据立马读。

总结

我们在使用ShardingJdbc做读写分离的时候,一定要注意写完数据立马读的场景,并采取相应的措施来保证写完数据立马读。

否则,我们就很有可能会读不到刚插入的数据。

思考

除了手动在读写分离中间件中添加额外的机制之外,还有没有其他更好的办法来解决这个问题呢?

这个问题留给大家思考。