使用 PHP 和 jQuery 进行实时聊天。在哪里存储信息? mysql还是文件?
Posted
技术标签:
【中文标题】使用 PHP 和 jQuery 进行实时聊天。在哪里存储信息? mysql还是文件?【英文标题】:Live chat with PHP and jQuery. Where to store information? Mysql or file? 【发布时间】:2011-08-05 01:47:35 【问题描述】:有 1 对 1 实时聊天。两种解决方案:
1) 我将每条消息都存储到数据库中,并且在 jQuery 的帮助下,我每秒检查数据库中是否有新消息。当然我也使用缓存。如果有,我们会给出该消息。
2) 我将每条消息存储在一个 html 文件中,并且每秒通过 jQuery 一遍又一遍地显示该文件。
什么更好?还是有第三种选择?总的来说,对于这种项目,mysql 或 file 哪个更好?
非常感谢。
附注最重要的问题是:什么方式更高效,什么方式吃的资源更少!
编辑:现在,对于许多聊天(比如说 2,500 个聊天,这意味着 5,000 个用户)使用长轮询并检查文件何时每秒通过 javascript 编辑是不是很糟糕?我使用非常相似的方法,比如这个聊天:http://css-tricks.com/jquery-php-chat/ 它会杀死我的主机吗?
【问题讨论】:
实时聊天有多不稳定?聊天会话多长时间?实时聊天参数会改变吗? 您需要保持聊天的持久性吗?那么数据库是最好的。如果没有,随机存取存储器就可以了。 Session 变量、memcached、MEMORY TABLEs 怎么样? 它必须一直持续到有人完成聊天。我想让它尽可能有效地使用尽可能少的资源。 Linked in 回到了 Java。没有什么比经过良好调整的服务器进程更有效了,它可以继续运行并可以执行线程、缓存和其他扩展技术。 node.js 非常棒。当然,它一开始就很好,也可以调整到一个很好的水平。 techempower.com/benchmarks/… 有一些基准测试,但任何应用程序都需要根据其不同功能的功能和自己的托管环境、硬件、操作系统、环境变量进行调整...... 【参考方案1】:每个人都给出了广泛的意见,但我认为没有人真正一针见血。
当涉及到存储数据时,数据量、访问速率以及其他几个因素都决定了最佳存储平台。
有些人建议使用 memcached。现在虽然这是一个有效的答案(您可以使用它),但我认为这不是一个好主意,仅基于 memcached 将数据存储在您的服务器内存中这一事实。
您的内存不是用于存储数据,而是用于实际应用程序、操作系统、共享库等。
在内存中存储数据可能会导致当前运行的其他应用程序出现很多问题。如果您在 RAM 中存储太多数据,您的应用程序将无法完成分配给它们的操作。
虽然这比 MySQL 等基于磁盘的存储平台要快,但它并不可靠。
我个人会使用 MySQL 作为您的服务器端存储引擎。这将减少您遇到的问题数量,并使数据非常易于管理。
为了加快对您客户的响应速度,我会考虑在您的服务器上运行 node。
这是因为它是事件驱动且非阻塞的。
这是什么意思?
好吧,当客户端 A 请求一些存储在硬盘驱动器上的数据时,传统上 php 可能会对 C++ 说,获取存储在硬盘驱动器这个扇区上的这块数据。 C++ 会说“好的,没问题”,当它继续获取信息时,PHP 会坐下来等待数据被读取并返回,然后再继续它的操作,阻塞所有其他客户端在同时。
使用节点,它略有不同。 Node 会对内核说,“获取我这块信息,完成后,给我打电话”,然后它会继续接收来自其他可能不需要磁盘访问的客户端的请求。
这么突然,因为我们给内核分配了一个回调,我们不必等待:),快乐的日子。
看看这张图片:
这确实可能是您正在寻找的答案,请参阅以下内容以获取有关节点如何成为您正确选择的更多描述性和详细信息:
http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/【讨论】:
啊,异步编程模型(APM)的威力 如果我使用这种类型的聊天:css-tricks.com/jquery-php-chat,您认为我可以处理 5k-10k 的在线用户吗?以及我需要处理哪些托管参数。 很容易用一个像样的服务器,它为 Plurk 提供动力,它同时有 110K+ 用户在线,amix.dk/blog/post/19490 - 你需要一个可以访问 shell 的专用服务器,显然你需要一个非常大的连接和大核心和内存的数量,您需要了解如何将节点服务器拆分为多个核心>developer.yahoo.com/blogs/ydn/posts/2010/07/…【参考方案2】:第四个选项,如果你已经有了想要使用的 PHP 代码,可能不是你想要的,但也许最有效的是使用基于 javascript 的服务器而不是 php。
Node.js 很容易成为聊天服务器,并且可以将所有最近的消息存储为 Javascript 变量。
您可以使用长轮询或其他彗星技术,这样您就不必等待消息更新。
此外,基于事件的 Javascript 服务器架构意味着没有闲置等待消息的开销。
【讨论】:
我认为这个问题更多地与数据的存储以及数据可以访问的速度有关,与节点的事件驱动框架功能无关,尽管你提到它很好 - 我认为 node.js 解决了存储问题,因为它是事件驱动的,并且能够将所需的数据作为 javascript 变量存储在内存中。我认为答案可能不合适,因为它需要重写任何服务器端代码。 将数据存储在内存中不应该是一种选择,为什么要将那种数据存储在内存中?这就是为什么发明数据库是为了拥有一个在大型环境中可靠的存储平台? 我假设聊天应用程序只会在给定聊天室中存储最后 x 条消息,然后非常频繁地将它们分发给房间中的所有成员,所以这似乎是不必要的处理和慢速磁盘访问开销,以持续读取这些数据并将其写入数据库。据我了解,存储的信息只需要保留足够长的时间即可交付给所有收件人(登录到聊天室),然后就可以删除。因此,不会在内存中膨胀。你不同意这个想法吗?请详细说明在这种情况下如何使用数据库。【参考方案3】:这取决于同时聊天的数量。如果是为了支持,并且您预计平均负载一次为 1 到 5 个聊天会话,那么您不必太担心。只需确保在一段时间内没有活动时停止刷新并显示一条消息供用户单击以恢复聊天会话。
如果访问者会互相聊天,并且您希望同时有大量会话 - 10-50 个,您仍然可以使用 PHP + 数据库。只要确保您没有进行冗余查询并且您的查询被正确缓存。为了减少负载,您还可以拒绝聊天脚本登录网络服务器:
SetEnvIf Request_URI "^/chat.php$" dontlog
CustomLog /var/log/apache2/access.log combined env=!dontlog
编辑:
你可以有延迟模式。例如,如果您在延迟 1 秒的情况下查询 2 次并且没有获得任何数据,则可以将延迟增加到 2 秒。如果您达到 10 个没有响应的查询 - 将延迟增加到 5 秒。 10 分钟后,您可以暂停对话,要求用户单击按钮以恢复聊天。这样,结合上述建议将保证足够低的负载以进行许多并发聊天
编辑2:
我建议你找一些 flash 或 java 解决方案并购买它。拥有 5000-10000 个用户,你必须是天才才能让它在 VPS 上运行,尤其是在 RAM 不多的情况下。并不是说不可能,但是您可以租用更便宜的 VPS,然后用剩下的钱购买一些 java 或 flash 中的解决方案(不知道 flush 是否支持 2 路连接,我不是 flash 专家)。
关于用户数量的注意事项:如果您有 10 000 个用户,我猜您同时进行的聊天不会超过 100 个。去看看约会网站——他们的在线用户不超过 10%,也许他们中的大多数人都在做其他事情而不是聊天
【讨论】:
我该如何延迟呢?那么最新的消息发布后就不会出现了。 是的,但是如果有人等待了 3-4 秒的响应时间,再多一秒不会有任何影响。如果碰巧您等待 10 秒回复,那么 13 秒也没关系。如果您等待 60 秒,那么 65 秒将完全在同一时间缝合 - 您将无法区分。好吧,发布消息的人可能需要再等 5 秒钟才能得到回复,但由于他整整一分钟都不在那里,所以他可能无法指望快速回复。好吧,每隔 5 秒以上刷新一次。 那么,如果我在css-tricks.com/jquery-php-chat 这样的聊天室中使用idea 并添加您的建议,您认为我可以在VPS 上同时处理约5,000-10,000 个用户吗?跨度> 5000 多个用户同时在线,真是大期待。如果你使用 memcache,你可以处理这个数字(取决于专用的 cpu 速度)。我不知道它需要多少内存。但是,如果您使用 memcache 处理程序进行会话并将所有内容缓存到 memcache 中,那么我看不到问题。如果您测量一个使用 memcache 检查新消息的脚本,它将运行几毫秒。这意味着每秒有 100 次查询。如果我是你,我会租用 vps 并进行压力测试。模仿它并不难。但这只是你问题的答案。我会用 java 或 flash 来做。【参考方案4】:第三个选项。使用MEMCACHE。无限快的读/写。非常适合您的应用。
【讨论】:
我不同意,Memcache 将数据放在内存中以跨会话使用,如果他有 1K 人聊天,内存会很快填满 memcache 将滚出最旧的数据,我们用它来存储数百万个数据集【参考方案5】:将聊天消息存储在数据库中,但使用Memcached 作为数据库读取的缓存层。因此,最受欢迎的阅读内容(例如聊天室中的最后 20 条消息)总是会直接从内存中提取出来。
这为您提供了最频繁操作的速度优势和所有消息的持久存储。
【讨论】:
【参考方案6】:只是加入另一个选项...平面文件可以提供资源消耗较少的替代方案。
每个聊天都被分配了一个唯一的 ID 和一个为其存储的平面文件。每个聊天都会在此文件中添加一行。然后每台客户端机器使用 jquery 仅检查文件的修改日期,以查看聊天是否已更新。
虽然我通常不会推荐平面文件而不是数据库,但我有一种偷偷摸摸的感觉,即检查平面文件的修改日期会比 MySQL 替代方案更好地扩展。
我很感兴趣,所以我做了一些测试,结果如下:
在现有数据库连接的情况下,可在 1 秒内运行的“SELECT field FROM table LIMIT 0,1”数量:~ 4,000
打开和关闭数据库连接,但运行相同的查询:~ 1,800
检查各种不同文件的修改日期:~225,000
因此,要检查对话是否已更新,将对话存储在平面文件中并检查最后修改日期会比使用数据库执行任何操作要快。
【讨论】:
【参考方案7】:一般来说,在将数据推送到客户端时,http 连接并不是很有用。鉴于您的流量很大,每隔 x 秒进行一次轮询往往会占用任何服务器上的资源。
您应该尝试将XMPP 与BOSH 结合使用。幸运的是,大部分繁重的工作已经为您完成。您可以非常快速地实现基于纯 jquery(或其他 js 框架)的解决方案。阅读 this 教程,它将对您有很大帮助 - 不仅解决您的特定问题,而且让您更广泛地了解如何通过良好的 ole' http 实现推送技术。
【讨论】:
【参考方案8】:除非它是一个小众脚本 - 在数据库与文件系统之间,最好使用数据库(。)
P.S:- Flash 也为聊天服务器提供了一个很棒的平台,您可能也想研究一下。
【讨论】:
【参考方案9】:如果您将对话定义为只有两个人,那么每秒一个请求将看起来像每个用户每秒一个读取请求,而每当有人写东西时(比如每 10 秒)一个写入请求。因此,每 10 秒,每个对话每秒大约有 2.2 个请求。
对于 50 个对话,即每秒 100 个用户和 220 个请求。对于如此少量的对话,这对服务器来说是很大的负载。将对话写入 JSON 或 XML,可能会提供一个更具可扩展性的解决方案。
This article 讨论 Meebo 的架构 - 长轮询,彗星。
作为事后的想法,您是否考虑过安装像 Jabber 这样的 IM 服务器,而不是从头开始?
【讨论】:
javascript 每秒 220 个请求是不是很多? @hey - 抱歉,有点含糊,我指的是 MySQL 方面。与其说是请求的绝对数量,不如说是用户数量与服务器必须完成的工作量之间的比较。【参考方案10】:您总能找到合适的工具来完成这项工作……符合 XMPP 的软件。尽管文档很差,ejabber
还不错。因为它严格遵循 XMPP 标准:http://code.google.com/p/ijab/ 您可以使用任何 XMPP 客户端。如果您愿意,可以将所有内容存储在 RDBMS 中,并提供 gmail / google talk 中提供的类似功能。
0.02 美元
【讨论】:
【参考方案11】:一个非常快速的替代方案可能是像 MongoDB 这样的 NoSQL 数据库:
-
MongoDB homepage
Some benchmarks
MongoDB's extension homepage on php.net
【讨论】:
【参考方案12】:我不使用它,但您也许可以尝试Photon,这是一个基于 Mongrel 的非常高速的框架。 在author blog(法语)上有一个示例,30 行代码用于实时聊天服务器,并带有视频演示。
【讨论】:
【参考方案13】:我认为将数据存储在数据库中会更好。请参考以下链接 Script Tutorials Chat
【讨论】:
以上是关于使用 PHP 和 jQuery 进行实时聊天。在哪里存储信息? mysql还是文件?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Ratchet Websockets 进行 PHP 实时聊天