Этот код — заготовка для дальнейшего развития. У меня на рабочих серверах реализовано все что надо — и отслеживание умерших обработчиков, и их перезапуск…
Код из топика может взять любой желающий и развивать далее.
Лайти перезапускает программу для записи в пайп при ее падении.
«Вежливая» перезагрузка сервера подразумевает прекращение приема новых соединений до момента пока сервер не отработает все оставшиеся соединения и не перезапустится.
Идея для накопления данных в обработчике и составления большого запроса на вставку — интересна.
Вот только насчет записи в БД несколькими потоками вы ошиблись. Опыт показал что это позволяет вносить записи гораздо быстрее.
Пройдусь по пунктам :)
1) Вы забыли про буферизацию записи, а значит ваше умозаключение о равенстве частоты записей в секунду на диск будут ограничивать частоту записей в файл лога. Это ваше первое упущение. Но тем не менее, запись лога в файл не подходит для реализованной мной системы.
2) Учет данных в БД был мною описан как довольно простой. Могу сказать больше — осуществляется вставка записей в таблицу с одним первичным ключом. Что касается куска кода — то приведен он мной тут как раз по теме статьи, т.к. писал я о способе избавления от минусов однопоточного сервера. И код мой, как показала практика, справляется с задачей на ура. Напомню — топик мой о примере решения проблемы, а не обсуждение построенной мной системы.
3) Решение с СУБД отлажено и работает уже не первый год. И еще раз предлагаю почитать название топика — речь идет о решении проблем сложного логирования однопоточного сервера, а не обсуждение работы СУБД.
4) Напомню еще раз — писать в моей задаче нужно не в файл, а в БД. Т.к. необходим живой анализ и учет трафика. Если писать в файл (неважно какой, физический файл, mmap или еще что), а потом вычитывать оттуда данные и писать в БД — то это ничем не отличается от приведенного мною решения с записью данных в буфер памяти PHP. Разве что только PHP скрипт — это drop-in решение и не требует абсолютно никаких дополнительных действий при развертывании.
5) Вопрос отслеживания обработчиков и поднятия их после падения мною решен, просто я не стал это приводить в этом топике и оставил этот вопрос на решение тому, кто решит воспользоваться. Напомню — код никогда в статьях не приводится как конечный результат, а как подсказка и руководство к дальнейшим изысканиям. Готовые решения на SourceForge
И вот что добавлю. Не все записи что отдает сервер должны попадать в лог, и агрегатор с этим справляется — он отбрасывает ненужные записи до того как они попадают в обработчик и дополнительного ожидания обработки со стороны сервера н таких записях не происходит. Ну и про производительность решения в СУБД — если писатьв один поток данные в БД — то конечно буффер будет расти и система не будет успевать отправлять данные на хранение. Но если писать в несколько потоков — то мы получим многократное увеличение производительности, т.к. будут получены все плюсы concurent inserts в MySQL, а так же мы победим overhead от обработки запроса и подготовки его выполнения в СУБД.
И подведу итог: самомнение и высокомерие некоторых мешает им даже прочитать и осознать что писал их собеседник. Вы решили сразу написать пять увесистых параграфов, вместо того, чтоб просто хорошенько задуматься. Вы начали искать способ сказать что я не прав, вместо того чтоб понять о чем я писал. А вы так и не поняли.
А насчет ваших прогнозов о моем росте как специалиста — спасибо. Правда ваше высокомерие опять заставило вас ошибиться. Я уже являюсь разработчиком со стажем и руковожу весьма большим региональным проектом. Будьте сдержанней в высказываниях и заочной оценке собеседника.
Интересное решение :)
Вот только в моих условиях оно не подойдет. Нужна действительно произвольная выборка и перемешивание таблицы хоть ночью хоть днем сильно бы сказалось на производительности, т.к. нагрузка на сервер постоянно очень большая и записей в таблице очень много.
А теперь выполните запрос с ORDER BY RAND() сразу в пятьдесят потоков. И посмотрите в список тредов сервера. Вы увидите как они в сильной задумчивости подвиснут в статусе 'Copying to tmp table'
В вашем коде много лишних действий.
1) Вы делаете выборку всех идентификаторов. Если таких много — это лишняя нагрузка как на БД так и на интерпретатор PHP
2) Вы делаете по одному запросу на каждую результирующую запись. Для БД это лишняя работа по инициализации запроса и блокировке таблиц.
3) У вас часто идет лишнее присваивание промежуточным переменным. Не забывайте что PHP присваивает по значению, а значит происходит лишнее копирование участков памяти. Если текст в выборке большой, а сам этот код вызывается часто — то это довольно много лишней работы.
Если вы хотите придерживаться вашего алгоритма с выборкой ключей и выбора по ним произвольных значений — то как минимум нужно сформировать составной запрос через UNION, а только потом отправлять его в БД.
Вы еще забыли прочитать текст моего топика. Вопрос идет о выборе нескольких действительно произвольных записей. Все варианты с выборкой по первичному ключу не дают равномерного распределения вероятности выборки, если ключ разряженный.
Задача была выбрать действительно произвольные записи и не одну, а несколько. Приведенный вами пример из комментариев к мануалу не годится, т.к. при наличии большой дырки в первичном ключе часто будет попадать в выборку запись стоящая после этой «дырки».
Именно про не числовые ключи и про составные ключи я и сделал оговорку в тексте топика. Если бы таблица была «простой», то я бы точно не изголялся с нетривиальным кодом и хитростями.
Код из топика может взять любой желающий и развивать далее.
«Вежливая» перезагрузка сервера подразумевает прекращение приема новых соединений до момента пока сервер не отработает все оставшиеся соединения и не перезапустится.
Вот только насчет записи в БД несколькими потоками вы ошиблись. Опыт показал что это позволяет вносить записи гораздо быстрее.
Внимательно изучите код.
1) Вы забыли про буферизацию записи, а значит ваше умозаключение о равенстве частоты записей в секунду на диск будут ограничивать частоту записей в файл лога. Это ваше первое упущение. Но тем не менее, запись лога в файл не подходит для реализованной мной системы.
2) Учет данных в БД был мною описан как довольно простой. Могу сказать больше — осуществляется вставка записей в таблицу с одним первичным ключом. Что касается куска кода — то приведен он мной тут как раз по теме статьи, т.к. писал я о способе избавления от минусов однопоточного сервера. И код мой, как показала практика, справляется с задачей на ура. Напомню — топик мой о примере решения проблемы, а не обсуждение построенной мной системы.
3) Решение с СУБД отлажено и работает уже не первый год. И еще раз предлагаю почитать название топика — речь идет о решении проблем сложного логирования однопоточного сервера, а не обсуждение работы СУБД.
4) Напомню еще раз — писать в моей задаче нужно не в файл, а в БД. Т.к. необходим живой анализ и учет трафика. Если писать в файл (неважно какой, физический файл, mmap или еще что), а потом вычитывать оттуда данные и писать в БД — то это ничем не отличается от приведенного мною решения с записью данных в буфер памяти PHP. Разве что только PHP скрипт — это drop-in решение и не требует абсолютно никаких дополнительных действий при развертывании.
5) Вопрос отслеживания обработчиков и поднятия их после падения мною решен, просто я не стал это приводить в этом топике и оставил этот вопрос на решение тому, кто решит воспользоваться. Напомню — код никогда в статьях не приводится как конечный результат, а как подсказка и руководство к дальнейшим изысканиям. Готовые решения на SourceForge
И вот что добавлю. Не все записи что отдает сервер должны попадать в лог, и агрегатор с этим справляется — он отбрасывает ненужные записи до того как они попадают в обработчик и дополнительного ожидания обработки со стороны сервера н таких записях не происходит. Ну и про производительность решения в СУБД — если писатьв один поток данные в БД — то конечно буффер будет расти и система не будет успевать отправлять данные на хранение. Но если писать в несколько потоков — то мы получим многократное увеличение производительности, т.к. будут получены все плюсы concurent inserts в MySQL, а так же мы победим overhead от обработки запроса и подготовки его выполнения в СУБД.
И подведу итог: самомнение и высокомерие некоторых мешает им даже прочитать и осознать что писал их собеседник. Вы решили сразу написать пять увесистых параграфов, вместо того, чтоб просто хорошенько задуматься. Вы начали искать способ сказать что я не прав, вместо того чтоб понять о чем я писал. А вы так и не поняли.
А насчет ваших прогнозов о моем росте как специалиста — спасибо. Правда ваше высокомерие опять заставило вас ошибиться. Я уже являюсь разработчиком со стажем и руковожу весьма большим региональным проектом. Будьте сдержанней в высказываниях и заочной оценке собеседника.
Вот только в моих условиях оно не подойдет. Нужна действительно произвольная выборка и перемешивание таблицы хоть ночью хоть днем сильно бы сказалось на производительности, т.к. нагрузка на сервер постоянно очень большая и записей в таблице очень много.
1) Вы делаете выборку всех идентификаторов. Если таких много — это лишняя нагрузка как на БД так и на интерпретатор PHP
2) Вы делаете по одному запросу на каждую результирующую запись. Для БД это лишняя работа по инициализации запроса и блокировке таблиц.
3) У вас часто идет лишнее присваивание промежуточным переменным. Не забывайте что PHP присваивает по значению, а значит происходит лишнее копирование участков памяти. Если текст в выборке большой, а сам этот код вызывается часто — то это довольно много лишней работы.
Если вы хотите придерживаться вашего алгоритма с выборкой ключей и выбора по ним произвольных значений — то как минимум нужно сформировать составной запрос через UNION, а только потом отправлять его в БД.