【问题标题】:Speed of MySQL connection vs PHP file accessMySQL 连接速度与 PHP 文件访问速度
【发布时间】:2011-12-22 15:29:06
【问题描述】:

假设我使用 LAMP 进行了简单的 VPS 设置(因此 PHP 和 MySQL 在同一台服务器上,并且没有附加其他字符串)。并假设我想在我的网站上制作一个自己编写的 ajax 聊天客户端。

显然,对话中的每个参与者都必须不断倾听新事物的说法。由于很可能两个或多个参与者在同一秒内说了什么(每秒刷新一次以上可能会导致疯狂的系统负载),在我看来,我需要为每个参与者存储一个列表自上次刷新以来发生的事情。

执行此操作的“最佳”方式是什么(就系统负载而言)?在下文中,“事件”只是“任何参与者在聊天中说任何话”。显然,这也可以用于更一般的情况。

(A) 使用 MySQL,每秒连接到 db 并询问事件 WHEREparticipant_id = $participant_id? (然后删除所有这些,因此它们只被提取一次)

(B) 创建一个文件 $participant_id.php 并将事件附加到它(以 PHP 格式,以便可以包含它,然后在下次刷新时清空或删除该文件?

(C) 有谁知道其他有用的替代品吗?

【问题讨论】:

  • 在内存中存储最后 x 秒的文本似乎是可行的。您仍然可以将文本记录到 mysql,但在正常情况下您不需要向 mysql 索要它,因为所需的所有内容要么在内存中,要么已发送到客户端。
  • 在我回答之前,您是否考虑过使用消息队列?
  • @Chris:我如何将这些存储在 PHP 的 RAM 中?或者您会为此推荐其他非 php 方法吗?
  • @Xepoch:我没有考虑消息队列,我将阅读这些消息队列。感谢您的提示!
  • 您是否需要保存聊天以供以后使用?否则,请参阅我的答案。

标签: php mysql performance file-io


【解决方案1】:

另一种方法是使用套接字连接。每个连接到套接字服务器守护程序的人都可以向守护程序发送消息,然后守护程序会将消息发送给所有或部分订阅者列表,这使得聊天即时进行,根本不需要保存数据。

从客户端创建套接字连接的一个好方法是套接字 IO。见下文。

http://socket.io/

用于创建套接字服务器守护程序的一个很好的技术是 node.js。这是一个服务器端事件驱动的基于 javascript 的库。对于这样的事情非常有效。见下文。

http://nodejs.org/

【讨论】:

  • 这听起来既有趣又奇怪。我会好好阅读这个机制。另外,以这种方式记录聊天真的不可能吗(假设人们没有入侵客户端,也就是说)?
  • @user1111929 你所说的“登录”聊天到底是什么意思?要将其全部保存在服务器上以备后用?
  • 这将是一个好处,是的。不仅用于聊天示例,而且我还将将此系统用于小型多人游戏(跳棋、二十一点、uno ......),如果应用程序崩溃或捕获作弊者,调试应用程序可能很有用。但这不是主要问题。
  • @user1111929 您可以在使用此方法将所有内容发送给订阅者的同时记录所有内容。 node.js 允许写入平面文件以及数据库连接。另一种方法是让调试客户端始终连接到接收所有消息的套接字服务器,您可以将其用于日志记录。这样您就不会将调试代码与生产代码混合在一起,并且可能会提高性能。
【解决方案2】:

在 A 和 B 上,您仍在有效地进行轮询。您将轮询 MySQL,这确实还不错,或者您可以在 select() 上收到有关文件更改的通知,但是您仍然需要解析以查看新数据是否是文件端的正确内容。

在概念和支持易用性方面,很难击败数据库,因为您不必担心锁定语义。在这个结构中调试和消息跟踪是干净的。

不过,我建议您调查msg_send()msg_receive()(PHP 的)函数,以将此数据放入底层消息队列中。您的问题似乎是应该由该机制解决的消息队列问题。

【讨论】:

  • 其实,在(B)中我只需要一个file_exists,对吧?就资源而言,这应该非常便宜。但是如果我理解正确, msg_receive() 仍然是更好的方法吗?我主要担心的是用户意外离开聊天/游戏/...会导致他们的消息队列永远存在。对于这些文件,我可以每周根据它们的时间戳手动删除旧文件,但我似乎无法在此处找到如何为消息队列执行此操作...
  • 您可以设置多个队列,如果没有活动则删除队列。 php.net/manual/en/function.msg-remove-queue.php你也可以通过统计队列了解最后一条消息的时间php.net/manual/en/function.msg-stat-queue.php
【解决方案3】:

有人知道其他有用的替代品吗?

如果您在 PHP 上搜索简单的解决方案,我可以提供两种方法:

缓存

这意味着您保留 MySQL 用于存储数据,但安装 APC(此解决方案对于小型服务器和应用程序来说最简单、最快)或 Memcached(更适合使用宽度多台服务器)。对于每个读取请求,您检查 APC/Memcached 以获取您的数据,并仅在您的缓存被删除或更新时询问 MySQL。并且在每次写入请求时,您都会在 MySQL 中插入数据并更新缓存。

其他数据库

在这种情况下,您将 MySQL 更改为基于内存的数据库之一(例如 MongoDB)。而且你可能不怕硬盘使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 2011-05-17
    相关资源
    最近更新 更多