几周前,我发布了一个关于排队数据库访问请求的问题,以防止在发生大量并发数据库请求时出现“连接过多”错误。人们告诉我 ConnectionPool 是我当时同意的正确方法。但是,我终于意识到这不是解决方案,尤其是当有很多不同的客户端通过网络访问 mysql 服务器时,因为连接池在客户端,它不能防止所有客户端的连接总和超过最大连接数mysql服务器。
我认为mysql服务器上应该有一些中间件作为队列或池工作,有人熟悉吗?谢谢你。
我知道这个问题被广泛提出,我也很惊讶,好像没有完整的解决方案。
几周前,我发布了一个关于排队数据库访问请求的问题,以防止在发生大量并发数据库请求时出现“连接过多”错误。人们告诉我 ConnectionPool 是我当时同意的正确方法。但是,我终于意识到这不是解决方案,尤其是当有很多不同的客户端通过网络访问 mysql 服务器时,因为连接池在客户端,它不能防止所有客户端的连接总和超过最大连接数mysql服务器。
我认为mysql服务器上应该有一些中间件作为队列或池工作,有人熟悉吗?谢谢你。
我知道这个问题被广泛提出,我也很惊讶,好像没有完整的解决方案。
HAProxy 应该为您执行 TCP 级别的排队。不过,在中间构建一个应用程序服务器会比 TCP 更有意识地处理传入流。这可能需要重写服务器和客户端,但可以让您更好地控制正在发生的事情。
你问的其实是一个相当复杂的问题。
首先你需要确定数据中的错位是否可以接受,例如:如果你在数据库中存储收到的 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 异步运行的查询,因为使用代理序列化查询可能会明显降低应用程序的速度。
你有一个三重目标:
不幸的是,没有简单的“灵丹妙药”来解决这个问题(当然,除了增加连接数,可能会在几个作为主从运行的主机上复制数据库。虽然不是真正的灵丹妙药,但它更容易设计和实现) .