我已在同一个数据中心内使用本地后端连接配置了两个 MySQL 服务器(MySQL-1
,MySQL-2
)master-master
,其选项如下:
innodb_flush_log_at_trx_commit=1
sync_binlog=1
我们使用负载平衡器在两个 MySQL 服务器之间轮询 MySQL 请求。这种方法效果很好,但我担心复制延迟。例如,如果用户 A 在 MySQL-1 中插入一行,然后用户 A 从 MySQL-2 中选择,则数据可能未成功复制。
基本上,我的问题是,预计延迟应该是多少(毫秒、秒)?还有其他 MySQL 选项可以设置以防止/减少延迟吗?
答案1
这取决于您的服务器性能,该性能与每台服务器必须处理的查询数量、表的大小等有关。使用此类复制解决方案应该是同步的,这肯定会在事务期间造成一些延迟。这只是因为除非在两个节点上都执行了事务,否则不应将每个事务视为完全提交。
我认为更安全选项是根据客户端的源 IP 来平衡请求(如果支持/可能)。在这种情况下,来自同一客户端的所有请求都将转发到同一 DB 服务器。
答案2
我在主服务器 -> 多从服务器设置中遇到了同样的问题。它甚至比你的情况更糟糕,因为读取肯定来自从服务器,而不是 50/50 的机会。
每次用户写入数据库(例如论坛帖子或点击“喜欢”按钮)时,他们都将获得一个 HTTP 重定向到该页面应该显示他们的帖子,但是绝不确实如此。重定向和后续请求的往返时间比复制滞后时间短。
观察延迟情况,SHOW SLAVE STATUS
我们发现延迟几乎总是在一秒以下。不过,偶尔也会高于一秒。由于复制 SQL 是单线程的,因此 10 秒的慢查询将导致复制延迟 10 秒。
我们最终的解决方案是修改所有“刚刚发布”的页面,使其始终从主服务器而不是从从服务器读取。对于您来说,确保每个 Web 服务器都知道上一个请求刚刚写入哪个数据库将很困难。
更好的解决方案可能是将最近写入的数据保留到 memcached 实例中。即使您的 memcached 数据的过期时间为 10 秒,这也足以弥补复制延迟。
答案3
滞后主要取决于:
- 写入(插入和更新)操作的数量
- 硬件(磁盘速度和 CPU)
- 服务器负载(选择)
之前不可能计算滞后。我建议你做一些密集的(对你而言)并发写入和读取操作测试。