MySQL连接速度与PHP文件访问速度的比较

3
假设我有一个简单的VPS设置,使用LAMP(因此在同一服务器上具有PHP和MySQL,并且没有其他任何附加内容)。假设我想在我的网站上制作一个自己编写的ajax聊天客户端。
显然,每个参与对话的人都必须不断地监听新话题。由于很有可能两个或更多的参与者在同一秒钟内说了一些话(而每秒刷新一次可能会导致系统负载异常),所以我认为我需要为每个参与者存储自上次刷新以来发生的事情列表。
哪种方法是“最佳”的(从系统负载的角度考虑)?以下是一些可能的方法:
(A)使用MySQL,每秒连接到数据库并请求WHERE participant_id = $participant_id的事件?(然后删除所有这些事件,以便只获取一次)
(B)创建一个名为$participant_id.php的文件,并将事件追加到其中(以PHP格式,以便可以包含,然后在下一次刷新时清空或删除该文件?
(C)是否有其他有用的替代方案?

将最后 x 秒的文本存储在内存中似乎是可行的。您仍然可以将文本记录到 MySQL 中,但在正常情况下,您不需要向 MySQL 请求它,因为所需的一切都在内存中或已发送给客户端。 - goat
在回答您之前,您是否考虑过使用消息队列? - Jé Queue
@Chris:我该如何在PHP中将它们存储在RAM中?或者您会推荐其他非PHP的方法吗? - user1111929
@Xepoch:我之前没有考虑过消息队列,我会去了解一下这些消息队列。感谢你的提示! - user1111929
您是否需要保存聊天记录以备后用?如果不需要,请查看我的回答。 - dqhendricks
3个回答

1

在 A 和 B 上,你仍然有效地进行轮询。你可以轮询 MySQL,这并不太糟糕,或者你可以在 select() 上得到文件更改的通知,但你仍然需要解析以查看文件端的新数据是否是正确的内容。

从概念和支持易用性来看,数据库真的很难被击败,因为你不必担心锁定语义。在这种结构中,调试和消息跟踪非常清晰。

然而,我建议你调查一下 PHP 的 msg_send()msg_receive() 函数,将这些数据放入底层消息队列中。你的问题似乎是一个应该通过这种机制来解决的消息队列问题。


实际上,在(B)中我只需要一个file_exists,对吧?这应该是资源非常便宜的。但如果我理解正确,msg_receive()仍然是更好的方法?我主要担心的是用户意外离开聊天/游戏/...会导致他们的消息队列永久存在。对于文件,我可以根据时间戳每周手动删除旧文件,但似乎找不到任何关于如何处理消息队列的方法... - user1111929
1
您可以设置多个队列,并在没有活动时删除队列。http://www.php.net/manual/en/function.msg-remove-queue.php 您还可以通过对队列进行状态检查来查找最后一条消息的时间。http://www.php.net/manual/en/function.msg-stat-queue.php - Jé Queue

1
另一种选择是使用套接字连接。每个连接到套接字服务器守护程序的人都可以向守护程序发送消息,然后守护程序将消息发送给所有或部分订阅者,这使得聊天即时且无需保存数据。
从客户端创建套接字连接的好方法是使用Socket IO。请参见下文。

http://socket.io/

创建套接字服务器守护程序的好技术是使用node.js。这是一个基于服务器端事件驱动的JavaScript库,非常适用于此类任务。请参见下文。

http://nodejs.org/


这听起来非常有趣,但同时也很奇怪。我会好好研究一下这个机制。另外,按照这种方式记录聊天记录真的不可能吗(假设人们没有黑客攻击客户端)? - user1111929
@user1111929,您所说的“记录”聊天是什么意思?您想将其全部保存在服务器上以供以后使用吗? - dqhendricks
这确实是一个好处。不仅对于聊天示例有用,而且我还将在小型多人游戏(如跳棋、二十一点、UNO等)中使用此系统,这时调试应用程序以防崩溃或抓住作弊者可能会很有用。但这不是一个主要问题。 - user1111929
1
@user1111929,你可以使用这种方法在发送给订阅者的同时记录所有内容。Node.js允许进行平面文件写入以及数据库连接。另一种选择是始终将调试客户端连接到套接字服务器上,以接收所有消息,并将其用于日志记录。这样,您就不会将调试代码与生产代码混合在一起,并且性能可能更快。 - dqhendricks

0
有没有人知道其他有用的替代方案?
如果你在 PHP 上搜索简单的解决方案,我可以提供两种方法:
缓存
这意味着您保留 MySQL 以存储数据,但安装 APC(对于小型服务器和应用程序而言,这是最简单和最快的解决方案)或 Memcached(更适合使用多个服务器)。对于每个读取请求,您都会检查 APC/Memcached 是否有您的数据,并仅在缓存被删除或更新时才向 MySQL 请求。每次写入请求时,您都会将数据插入 MySQL 并更新缓存。
其他数据库
在这种情况下,您将 MySQL 更改为基于内存的数据库之一(例如 MongoDB)。您可能不必担心硬盘使用情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接