存储网站访问者而不会耗尽MySQL连接

时间:2013-04-30 10:11:44

标签: mysql web connection visitor-statistic

我们有一个分析应用程序,允许用户运行许多不同的报告。我们有一个主从MySQL数据库设置。

我们跟踪的一件事是我们客户网站上的访问者。每当访客登陆我们的客户网站时,我们会将各种信息写入我们的主数据库。问题是我们在高峰流量时间(通常在晚上)用完了MySQL数据库连接。我们知道我们需要以某种方式暂存正在编写的访问者数据。但是,我们用来销售此产品的一件事是,您可以在网站上查看访问者数据。我们可以允许网站访问者和报告可用数据之间的短暂延迟(1-2分钟)。

暂存访问者数据的最佳方式是什么?还有另一种可扩展的方法吗?

导致锁定的查询是:

SELECT VisitID,VistSourceID 
FROM visitorvisits 
LEFT JOIN visitornumbers 
ON VinuVlviID=VlviID 
WHERE vistNosID='12345' AND 
VistCampaignID='1' AND 
('2013-04-03 14:30:48' >= DATE_ADD(VistDateStart, INTERVAL VistTimeStart HOUR_SECOND)) 
AND ('2013-04-03 14:30:48' <= DATE_ADD(VistDateEnd, INTERVAL VistTimeEnd HOUR_SECOND) 
OR VistStatusCode='1')

这个目的的赎罪是:

+----+-------------+--------------------------+--------+-----------------------------------------------------------------------------------+----------------+---------+----------------------------------------------+------+-------------+
| id | select_type | table                    | type   | possible_keys                                                                     | key            | key_len | ref                                          | rows | Extra       |
+----+-------------+--------------------------+--------+-----------------------------------------------------------------------------------+----------------+---------+----------------------------------------------+------+-------------+
|  1 | SIMPLE      | visitornumbers           | ref    | idx_vistNosID,idx_visitNosVisitID                                                     | idx_vistNoID | 4       | const                                        | 4527 | Using where |
|  1 | SIMPLE      | visitorvisits            | eq_ref | PRIMARY,idx_VistCampaignID,idx_VistStatusCode,idx_VistCampaignID_VistDateStart_VistVistorID | PRIMARY        | 4       | mhdblive.visitorvisits.visitNosVisitID |    1 | Using where |
+----+-------------+--------------------------+--------+-----------------------------------------------------------------------------------+----------------+---------+----------------------------------------------+------+-------------+

2 个答案:

答案 0 :(得分:0)

您是否每次都完全关闭连接?

如果你是,并且你无法避免连接耗尽,那么我怀疑解决方案会很混乱。

可能会将信息写入固定位置(如文本文件),并且每隔30秒左右运行一次CRON作业来处理该文件的内容。

或者可能是对您网站上的页面的HTTP调用,该页面将数据存储在会话变量数组中,然后擦除会话变量并每隔30秒左右将所有详细信息存储在表中。

答案 1 :(得分:0)

首先,值得检查连接管理错误的应用程序 - 取决于你如何连接到MySQL(提示:PDO现在几乎是标准),你的代码可能会保持连接打开的时间超过你需要的时间 - 特别是如果您在应用程序中的某个位置有长时间运行的进程,则在运行时保持数据库连接处于打开状态。

下一步 - 检查MySQL服务器配置为接受的连接数;在Linux上,有足够的RAM,你应该能够支持数以千计的开放连接;如果您的应用程序仅在需要时打开连接,则大致转换为您支持的并发页面请求数(并且每个页面请求应以毫秒为单位执行)。您可能达到此级别,但通常,您在该级别上会遇到其他瓶颈(通常是数据库CPU)。

如果这些事情都和他们将要获得的一样好,那么标准的解决方案是创建一个异步基础架构 - 您的网页存储将数据库记录写入某个描述的队列的请求,然后继续;第二个进程查看队列并以最佳方式处理写入。

您可以自己制作解决方案,也可以使用众多队列服务器中的一个(例如,Beanstalk,Amazon SQS,RabbitMQ)。

相关问题