Хранение посетителей сайта без использования соединений MySQL

У нас есть аналитическое приложение, которое позволяет пользователям создавать различные отчеты. У нас есть одна настройка базы данных 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 ответа

Вы полностью закрываете соединения каждый раз?

Если это так, и вы никак не можете избежать исчерпания соединений, то я подозреваю, что решение будет грязным.

Возможно, запишите информацию в определенное место, например, в текстовый файл, и получите задание CRON, которое выполняется каждые 30 секунд или около того, чтобы обработать содержимое этого файла (файлов).

Или, возможно, HTTP-вызов страницы на вашем сайте, которая хранит данные в массиве переменных сеанса, а затем стирает переменные сеанса и сохраняет все данные в таблице каждые 30 секунд или около того.

Во-первых, стоит проверить приложение на наличие ошибок управления соединениями - в зависимости от того, как вы подключаетесь к MySQL (подсказка: в наши дни PDO в значительной степени стандартен), возможно, ваш код сохраняет соединения открытыми дольше, чем вам нужно, особенно если у вас есть где-то в приложении долго выполняющиеся процессы, которые поддерживают соединение с базой данных открытым во время работы.

Далее - проверьте количество подключений, которые ваш сервер MySQL настроен на прием; в Linux с достаточным объемом оперативной памяти вы должны поддерживать тысячи открытых соединений; если ваше приложение открывает соединения только тогда, когда оно им необходимо, это примерно соответствует количеству одновременных запросов страниц, которые вы поддерживаете (и каждый запрос страницы должен выполняться за миллисекунды). Возможно, вы достигли этого уровня, но обычно на этом уровне вы достигаете других узких мест (как правило, ЦП базы данных).

Если обе эти вещи так же хороши, как и собираются, стандартное решение - создать асинхронную инфраструктуру - ваша веб-страница сохраняет запрос на запись записи базы данных в очередь некоторого описания и движется дальше; второй процесс просматривает очередь и обрабатывает записи любым удобным для него способом.

Вы можете создать собственное решение для этого или использовать один из множества серверов очередей (например, Beanstalk, Amazon SQS, RabbitMQ).

Другие вопросы по тегам