踩坑,发现一个ShardingJdbc读写分离的BUG
2023-10-08 03:16:05
前言
最近公司准备接入ShardingJdbc做读写分离了,老大让我们理一理有没有写完数据立马读的场景。
让我们回想一下ShardingJdbc读写分离是怎么工作的?ShardingJdbc是通过在写库和读库上分别创建两个数据源,然后通过中间件来实现读写分离的。
我们来看一张经典的读写分离架构图:
+-----------------------------+
| |
| |
| +--------------+ |
| | 写数据库 | |
| +--------------+ |
| |
+-----------------------------+
|
|
V
+-----------------------------+
| |
| |
| +--------------+ |
| | 读数据库 | |
| +--------------+ |
| |
+-----------------------------+
当我们进行写操作的时候,中间件会将数据路由到写库,当我们进行读操作的时候,中间件会将数据路由到读库。
发现问题
在理业务代码的时候,我们发现了一个问题,就是有一个场景是:写完数据立马读,也就是说,我们刚在写库中插入了一条数据,然后紧接着就从读库中读取这条数据。
我们知道,在读写分离架构中,读库和写库是两个独立的数据库,所以当我们刚在写库中插入了一条数据,这条数据并不会马上同步到读库中。
因此,如果我们在这个场景下进行读操作,我们就很有可能会读不到刚插入的数据。
解决问题
为了解决这个问题,我们需要在读写分离架构中引入一个额外的机制,来保证写完数据立马读。
这个机制就是:读写分离中间件在将数据路由到读库之前,先检查一下读库中是否有这条数据,如果没有,就从写库中读取这条数据,然后再将这条数据同步到读库中。
这样,我们就保证了写完数据立马读。
踩坑
我们在实际使用ShardingJdbc的时候,就遇到了这个问题。
我们发现,在写完数据立马读的场景下,ShardingJdbc并不会自动将数据同步到读库中,导致我们读不到刚插入的数据。
为了解决这个问题,我们不得不手动在读写分离中间件中添加了一个额外的机制,来保证写完数据立马读。
总结
我们在使用ShardingJdbc做读写分离的时候,一定要注意写完数据立马读的场景,并采取相应的措施来保证写完数据立马读。
否则,我们就很有可能会读不到刚插入的数据。
思考
除了手动在读写分离中间件中添加额外的机制之外,还有没有其他更好的办法来解决这个问题呢?
这个问题留给大家思考。