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

时间:2011-11-16 20:57:12

标签: mysql relational-database database-replication amazon-rds horizontal-scaling

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

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

有谁知道处理此问题的具体策略?我已经读过关于“读你写什么”的能力的概念部分解决方案。但是,有没有人有任何想法如何实现这样的解决方案 - 无论是概念上的,还是特别是在Spring / Hibernate堆栈中?

1 个答案:

答案 0 :(得分:1)

我没有这样做,但这是一个想法。在每次读取查询之前,您可以在写入数据库上安装一个memcache服务器。执行写操作时,在memcache中添加某种键,当复制 1 时,请删除该键。

当您执行memcache读取并且您正在读取单个记录时,如果找到记录的键,则应仅从主设备读取它。如果您正在选择多个记录,则从从属设备读取它们,然后根据memcache密钥查询每个找到的ID。如果在memcache中找到任何内容,则只重新读取master数据库中的那些记录。

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

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

所有人都说:不要忘记有很多案例可以接受滞后。例如,如果您有一个用户更新其个人资料的网站,如果他们的更改未完全传播五分钟,则在大多数情况下这很好。关键是,imo,如果没有必要,不要过度设计某些东西以获得即时传播。