Как обойти большой json файл и обновить все связанные записи в MySQL, с отставанием от файла < 2 сек.?

Здравствуйте. Есть скрипт парсер (parse.php), который сохраняет результат парсинга на сервере в файле и формате JSON. Этот парсер обновляет данные каждые 1.5-3 секунды. По крону запускается другой PHP скрипт (work.php), который каждые 2 секунды get'ит актуальный JSON, парсит его json_decode и обходит циклом по массиву.

Структура массива такая:
events : {
              1 : {
                      id, data, title и т.д
              },
              2 : {
                      id, data, title и т.д
              },
}


На каждую итерацию work.php отправляет ID в скрипт getEvent.php с помощью fsockopen.
В getEvent присутствует ignore_user_abort(true);

В getEvent.php опять же идет get актуального JSON, декод и скрипт ищет в "events" ID, которое ему отправил work.php затем обрабатывает эти данные и обновляет их в базе MYSQL, данные в Mysql не должны отставать от данных в JSON файле более чем на 2 секунды.

В чем суть вопроса?) Эти манипуляции жрут 3ГБ оперативки и загружают процессор 4 x Xeon E5 2099.998 MHz на 90%! Мне нужно какое-то альтернативное решение чтобы проделывать вот это вот все.

Оперативка кушается потому что в work.php каждые 2 секунды get'ится json + в 600-800 открытых getEvent.php тоже get'ится этот же json. Еще таким образом у меня на сервере около 700 активных процессов. Кто может подсказать как упростить в плане нагрузки мой код? или подсказать какой-то другой способ обойти такой массив и обновить данные в MySql, чтобы они не отставали от данных в json файле более чем на 2 секунды.

Помогите, спасите, голова ломается уже)) Смотрел в сторону демонов, но это опять же куча оперативки и куча процессов на сервере.
  • Вопрос задан
  • 593 просмотра
Решения вопроса 1
gzhegow
@gzhegow
aka "ОбнимиБизнесмена"
Сначала если есть возможность менять парсер - убери json
Его считывают в память целиком, его нельзя "прочитать построчно" с помощью итератора двигаясь по файлу считывая по 1 строке

Похоже у тебя реализована очередь, но только своя. Может быть взять очередь (приспособить редис, там есть простенькие очереди в комплекте - или посмотреть какие еще очереди бывают - там их десяток помоему), чтобы задачи валились в список, а второй скрипт разгребал список, запускаясь по времени или когда очередь начнет выполнять задачу, а не висел в памяти и while (true) ждал пока ему скажут "работай"...

Яндекс решает задачу аналитики кто куда чего кликнул именно очередями, сбрасывая "отставание" с "2 секунды" до "какая мне разница, как проц освободится, так и сделаем" - да задачи начинают обрабатываться последовательно, а не параллельно.

Ещё можешь свой скрипт на ноде написать, там асинхронка может помочь. или сделать с помощью
new class extends \Threaded подключив расширение pthreads.so/.dll

Принцип будет в том чтобы в одном скрипте сделать в несколько потоков, которые не знают друг про друга, делают твою задачу.

Но учитывай, что запись и обновление в SQL все равно ставится в очередь, так что предел скорости присутствует
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
Правильное решение - парсер должен сам сразу писать в БД.

Если это невозможно надо постараться максимально устранить накладки и двойные обработки:
На каждую итерацию work.php отправляет ID в скрипт getEvent.php с помощью fsockopen.
... В getEvent.php опять же идет гет актуального JSON, декод и скрипт ищет в "events" ID, которое ему отправил work.php затем обрабатывает эти данные и обновляет их в базе MYSQL

Вот это что за хрень? Почему work.php не может сразу отправить данные getEvent? Зачем getEvent заново гетит JSON и заново ищет там ID?
А потом вы жалуетесь что:
Оперативка кушается потому что в work.php каждые 2 секунды гетится json + в 600-800 открытых getEvent.php тоже гетится этот же json.


чтобы они не отставали от данных в json файле более чем на 2 секунды.

И сколько гигабайт в вашем JSON что процесс не может его обойти и отправить мускул за 2 секунды?
Ответ написан
mayton2019
@mayton2019
Bigdata Engineer
При такой постановке - действительно ничего нельзя сделать. Просто он не предназначен для таких операций. Но хотя-бы первый раз его надо затянуть в базу. И всегда там хранить эти данные и там-же обрабатывать.
Ответ написан
VladimirAndreev
@VladimirAndreev
php web dev
1. Зачем тут крон вообще? Реализуйте и парсер, и воркер как вечнозапущенные скрипты
2. Зачем файл, если есть rabbitmq?
3. М.б. имеет смысл еще и третий воркер добавить, который бы только писал в базу, но "оптом"?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽