如何处理MySQL读写分离的最终一致性问题

Jas*_*ust 5 mysql relational-database database-replication amazon-rds horizontal-scaling

我一直在研究扩展 MySQL 的解决方案。除了添加 Memcached 层之外,经常出现的一个问题是读/写分离——所有写入都发送到主服务器,所有读取都发送到一组负载平衡的从服务器。

这种方法明显出现的一个问题是“最终一致性”。当我在主服务器上运行写入操作时,复制到读取从服务器需要一定的时间。因此,如果我请求新创建的行,它可能不存在。

有谁知道处理这个问题的具体策略?我读过有关“读你所写”能力的概念性部分解决方案。但是,有谁知道如何实现这样的解决方案——无论是概念上的,还是具体在 Spring/Hibernate 堆栈中?

hal*_*fer 1

我还没有这样做,但这里有一个想法。您可以在写入数据库上有一个内存缓存服务器,在每次读取查询之前连接到该服务器。当您进行写入时,将某种类型的密钥添加到内存缓存中,当您复制1时,删除该密钥。

当您执行内存缓存读取并且正在读取单个记录时,如果找到记录的键,则应该仅从主服务器读取它。如果您要选择多条记录,请从从属设备读取它们,然后根据内存缓存键查询每个找到的 ID。如果在内存缓存中找到任何记录,则仅从主数据库中重新读取这些记录。

您可能会发现,在某些(大量写入)用例中,此策略会抵消读/写拆分的好处。但我敢打赌,在大多数情况下,对内存缓存的额外检查和偶尔的主重新读取仍然值得。

1如果您使用标准复制并且无法跟踪特定记录是否已完全复制,只需为所有键添加时间戳,并在最坏情况延迟后删除/过期它们。例如,如果您的从服务器落后于主服务器两分钟,请忽略(并删除)任何早于两分钟的密钥,因为它们肯定会被复制。

总而言之:不要忘记在很多情况下延迟是可以接受的。例如,如果您有一个用户更新其个人资料的网站,如果他们的更改在五分钟内没有完全传播,那么在大多数情况下这是可以的。在我看来,关键是如果没有必要,不要过度设计某些东西来获得即时传播。