0

我们有一个分析应用程序,它允许用户运行许多不同的报告。我们有一个单一的主从 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 |
+----+-------------+--------------------------+--------+-----------------------------------------------------------------------------------+----------------+---------+----------------------------------------------+------+-------------+
4

2 回答 2

0

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

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

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

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

于 2013-04-30T11:49:11.400 回答
0

首先,检查应用程序是否存在连接管理错误是值得的——取决于你连接 MySQL 的方式(提示:PDO 几乎是当今的标准),你的代码可能使连接保持打开的时间超过你需要的时间——尤其是如果你有应用程序中某处长时间运行的进程在运行时保持数据库连接打开。

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

如果这两件事都像他们将要得到的一样好,标准的解决方案是创建一个异步基础设施——你的网页将写入数据库记录的请求存储到一些描述的队列中,然后继续;第二个进程查看队列并以最佳方式处理写入。

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

于 2013-04-30T14:02:25.643 回答