0

几周前,我发布了一个关于排队数据库访问请求的问题,以防止在发生大量并发数据库请求时出现“连接过多”错误。人们告诉我 ConnectionPool 是我当时同意的正确方法。但是,我终于意识到这不是解决方案,尤其是当有很多不同的客户端通过网络访问 mysql 服务器时,因为连接池在客户端,它不能防止所有客户端的连接总和超过最大连接数mysql服务器。

我认为mysql服务器上应该有一些中间件作为队列或池工作,有人熟悉吗?谢谢你。

我知道这个问题被广泛提出,我也很惊讶,好像没有完整的解决方案。

4

2 回答 2

1

HAProxy 应该为您执行 TCP 级别的排队。不过,在中间构建一个应用程序服务器会比 TCP 更有意识地处理传入流。这可能需要重写服务器和客户端,但可以让您更好地控制正在发生的事情。

于 2012-07-19T22:10:08.973 回答
1

你问的其实是一个相当复杂的问题。

首先你需要确定数据中的错位是否可以接受,例如:如果你在数据库中存储收到的 Likes 的数量,你在 12:00:00 询问这个数字,DB 中的数字是500,有人在12:00:01发了一个LIKE,你在12:00:02再次查询;是否可以再次收到“500”,即使正确的数字应该是 501,只要过一会儿答案“501”就出来了吗?

如果这是可以接受的(YouTube 中臭名昭著的“301 错误”),那么您可能会开始缓存一些 SELECT 响应。

您甚至可以将它们缓存在中间件中,即有一个特殊的进程连续运行并占用一个与 MySQL 的连接,并在队列中回答请求。您可以在服务器内部将它作为端口 8001 上的 Web 服务器运行,并使用 Apache ReverseProxy、HAproxy、磅或 NginX 位置在外部代理它。

即使比较棘手,您也可以对特殊的 UPDATE/DELETE 查询执行相同的操作。

如果有的话,最好先缓存通过 AJAX 异步运行的查询,因为使用代理序列化查询可能会明显降低应用程序的速度。

你有一个三重目标:

  • 尽可能快地在 MySQL 上运行查询(查看索引和 MySQL 缓存)以释放 ConnectionPool 并使其尽可能轻负载。
  • 重构应用程序以便从查询中提取所有信息(例如,具有特定属性的行数以及作为数据的行通常使用两个查询检索,但是通过适当的管理,您只需要一个和一个 SQLNumRows() 调用。另外,当一个查询可能一次性返回所有信息时,通常会运行具有不同信息的类似查询:通常,一个查询用于检查用户/密码,另一个查询用于获取完整的用户配置文件)。
  • 将尽可能多的调用转移到根本不绑定到 MySQL 的东西(NginX、中间件)或轻微(排队进程);在后一种情况下,使用已知数量的连接以可预测地运行。

不幸的是,没有简单的“灵丹妙药”来解决这个问题(当然,除了增加连接数,可能会在几个作为主从运行的主机上复制数据库。虽然不是真正的灵丹妙药,但它更容易设计和实现) .

于 2012-07-19T22:24:27.473 回答