<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; color: #000000"><div data-marker="__QUOTED_TEXT__"><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; color: #000000"><div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; color: #000000"><div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; color: #000000"><div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; color: #000000"><div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; color: #000000"><div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; color: #000000"><div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; color: #000000"><div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; color: #000000"><div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; color: #000000"></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>Gena Makhomed Wrote:<br>-------------------------------------------------------<br>> On 15.02.2024 12:49, Anatoliy Melnik via nginx-ru wrote:<br>> <br>> >>>>> Если вы предлагаете писать напрямую с nginx-а в файл --<br>> >>>>> сделайте у себя ротацию файлов с интервалом 30 сек<br>> >>>>> при 200-250 тыс подключений/сек...<br>> >>>>><br>> >>>>> Если у вас уже есть такое рабочее решение -<br>> >>>>> поделитесь опытом, буду рад вас выслушать.<br>> <br>> > "Я намеренно ввел вас в заблуждение путем публикации сообщения,<br>> допускающее двойное толкование в ту или иную сторону по желанию<br>> сторон."<br>> <br>> Почему / зачем?</div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Был шанс увидеть в ответ нестандартное решение.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br>> <br>> > Дальнейшее перемалывание темы ротации лично для меня интереса не<br>> представляет.<br>> <br>> Тогда прекращаем.<br>> <br>> >>> Вы почему-то упорно пытаетесь отказать мне в праве самостоятельно<br>> >>> решать что мне надо :)<br>> <br>> Так я и не пытался решать за Вас, как именно будет лучше поступить<br>> в Вашей конкретной ситуации - скорее я рассматривал все множество<br>> задач сбора статистики и обработки информации из логов - и на всем<br>> этом множестве задач старался увидеть наиболее оптимальный способ<br>> решения задачи, если абстрагироваться от затрат времени<br>> и сил на реализацию решения в виде програмного кода.<br>> </div><div data-marker="__QUOTED_TEXT__">Т.е. насколько я понимаю некоего идеального коня в сферическом вакууме.<br></div><div data-marker="__QUOTED_TEXT__">Не получиться "универсальный анализ логов".<br>мне нужны средние, кому-то подавай количество больше чем, кому-то нужен разброс будет от min до max.<br>Например 100 коннектов по 1К и 100 по 1М для кого-то то же самое, что и 200 по 0.5005М, а для кого-то это суперважно.<br></div><div data-marker="__QUOTED_TEXT__">соответственно и обработка разной получится. в 1 проход или в 2.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"> <br>> >> Решайте сами, я просто хотел понять Вашу исходную задачу X,<br>> >> поэтому и задавал уточняющие вопросы.<br>> <br>> > Спасибо. Как уже упоминалось ранее -- по озвученной на самом старте<br>> теме я уже все решил.<br>> <br>> С моей точки зрения более важным является обеспечение более высокой<br>> надежности работы системы, чтобы логи не терялись в процессе записи,<br>> чем экономия свободного места на диске и экономия ресурсов NVMe SSD.<br>> </div><div data-marker="__QUOTED_TEXT__">> Поэтому с моей точки зрения - я не могу признать решение<br>> через syslog и unix socket более оптимальным, чем вариант<br>> записи логов напрямую в файлы и ротации логов через SIGUSR1.<br>> <br>> а ротацию логов можно делать и чаще, чем раз в 30 секунд,<br>> например, раз 15, или раз в 10 или даже раз в 5 секунд,<br>> если хочется уменьшить отставание статистики по времени.<br>> <br>> По сути - лог-файл на диске - это можете воспринимать примерно,<br>> как то же самое, что и unix socket, только с буфером не в памяти,<br>> а в виде файла на диске и без существенных ограничений по размеру<br>> такого буфера, что будет лучше сглаживать всплески нагрузки<br>> и может позволить большую асинхронность между процессом<br>> записи информации в лог и процессом чтения информации<br>> из лога. А во всем остальном - никакой существенной<br>> разницы нет, учитывая только что запись логов в файлы<br>> меньше грузит процесор и использует немного больше<br>> свободного места на диске.<br>> <br>> Но мне например, лучше чтобы процессор был немного свободнее,<br>> чем проистаивающее и никак не используемое место на диске.<br>> <br>> Но самое главное - что запись логов в файлы не приводит к потере<br>> данных, а запись логов в unix socket может приводить к потерям<br>> даных, если читатель будет не успевать забирать данные из unix<br>> socket.<br>> <br>> Более надежное и более простое решение, и более экономно<br>> расходующее процесор сервера - и будет более оптимальным.<br>> </div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">1. Т.к. мне практически всегда нужны некоторые усредненные данные, </div><div data-marker="__QUOTED_TEXT__">то абсолютная полнота статистики не является основным условием.<br>Хорошо, если она присутствует, но и если потеряно даже половина данных -- </div><div data-marker="__QUOTED_TEXT__">на средних значениях это слабо скажется :)<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">2. пока я наблюдал скорее проблему "писатель не успевает записывать", </div><div data-marker="__QUOTED_TEXT__">а не "читатель не успевает забирать". <br>Эта же проблема и при файлах присутствует -- NVME не у всех всегда везде.<br>Система дисковая как ни крути - общий ресурс, и если ее интенсивно нагрузить </div><div data-marker="__QUOTED_TEXT__">чем-то еще логи тоже могут получить проблему читатель-писатель.<br>Сжатие на лету -- это не только ресурс CPU при сжатии перед записью, это еще и </div><div data-marker="__QUOTED_TEXT__">ресурс при распаковке для анализа, у меня это происходит со всеми данными.<br>Т.е. если nginx потратил ресурс на запаковку, то я в ответ должен потратить ресурс на распаковку...<br>И где тут экономия CPU?? <br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Мое мнение:<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Единственный плюс прямой записи в файл -- это длительное хранение данных, чего лично мне вот вообще не требуется.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">При необходимости обработки и анализа полученных данных пока опыт эксплуатации показывает преимущества юникс-сокета.<br>Об этом чуть ниже.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br>> > При желании добраться из пунта А в пункт Б именно на машине и<br>> проблеме "машина не едет" 2 концептуальных решения:<br>> > 1.Заменить машину.<br>> > 2.Устранить причины "не едет" в имеющейся.<br>> > Соответственно 2 пути -- ищем другую машину, или меняем вышедшую из<br>> строя запчасть.<br>> > Если провести параллели, то с моей точки зрения мне вполне<br>> достаточно запчасти.<br>> > Вы предлагаете замену машины.<br>> <br>> Не так, я скорее рассматриваю одновременно все множество путей<br>> из точки А в точку Б для различных вариантов А и Б и различных<br>> внешних условий и стараюсь понять, какой именно автомобиль,<br>> с какими именно параметрами будет наиболее оптимальным<br>> решением для такой задачи - перемещения их точки А в точку Б.<br>> </div><div data-marker="__QUOTED_TEXT__">Вертолет и телепортацию не забудьте :)<br>Учитывая ваши слова "если абстрагироваться от затрат времени<br>и сил на реализацию решения..."<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br>> Вот как я уже говорил, задача построения VPN - если взять все<br>> множество<br>> таких задач, то в части случаев для построения VPN более оптимальным<br>> вариантом будет использование WireGuard, а в части случаев - OpenVPN.<br>> Именно потому, что WireGuard обладает некоторыми свойствами<br>> и качествами, которые отсутствуют в OpenVPN, и наоборот,<br>> потому что OpenVPN обладает некоторыми свойствами и качествами,<br>> которые отсутствуют в WireGuard. И поэтому в части случаев<br>> оказывается более оптимальным и целесообразным построение<br>> VPN с использованием WireGuard, а в некоторых случаях<br>> - более оптимальнныи и целесообразным оказывается<br>> построение VPN с использованием OpenVPN.<br>> <br></div><div data-marker="__QUOTED_TEXT__">И в части случаев оба они окажутся в равной степени не пригодны...<br>Да и там, где пригодны, далеко не всегда оптимальны по каким-то критериям.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">VPN технологий существуют десятки. Но вы почему-то в этом посте ограничились 2-мя.<br>А как же "все множество путей" ?<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Эти 2 достаточно удобны для решения большого круга задач -- это да, но это не отменяет достоинств других VPN-ов. </div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">> >> Получить потери можно в случае использования syslog<br>> >> и unix socket`ов - если читающая сторона не будет<br>> >> успевать читать данные из сокета - у nginx не останется<br>> >> иных варантов, кроме как дропать часть записей.<br>> >><br>> >> При записи логов в файлы - этот вариант исключен,<br>> >> если на разделе есть достаточное количество свободного места.<br>> >><br>> > О появились доп. условия -- место на разделе...<br>> <br>> Так ведь свободное место на разделе есть, с этим же нет проблем.<br></div><div data-marker="__QUOTED_TEXT__">Есть проблема. </div><div data-marker="__QUOTED_TEXT__">В исходной постановке (когда сия задача встала передо мной) задачи было пожелание обойтись имеющимся ресурсом.<br>Я задачу решил именно в этих начальных условиях.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">> </div><div data-marker="__QUOTED_TEXT__">> Если часто делать ротацию логов - его надо будет совсем не много.<br>> </div><div data-marker="__QUOTED_TEXT__">> Тем более, что можно включить компрессию логов на лету, если надо.<br>></div><div data-marker="__QUOTED_TEXT__">Повторюсь: я уже просто запись в файл счел лишним этапом, </div><div data-marker="__QUOTED_TEXT__">а уж сопутствующие этому затраты на компрессию-декомпрессию только в минус.<br>> >> Хотя бы даже одним только этим свойством запись логов в файлы<br>> >> намного лучше записи логов в unix socket`ы.<br>> <br>> > А как же место на разделе? Замена одной проблемы другой. Только и<br>> всего.<br>> <br>> У Вас разве есть проблемы со свободным местом на разделе?<br>> тогда включите компрессию логов на лету - свободного места<br>> потребуется меньше, ресурсов процессора будет использовано<br>> больше. Только и всего. Это не проблема, это лишь tradeoff.<br>> </div><div data-marker="__QUOTED_TEXT__">И еще раз повторюсь -- что мешает мне на концептуальном уровне <br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">просто изменить подход так, чтоб эта проблема даже на горизонте не маячила?<br><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br>> > Т.е. Проблему X -- расхождение при использовании сокета, вы меняете<br>> на проблему У -- достаточное количество места<br>> > и производительность системы ввода-вывода, просто с вашей точки<br>> зрения это как-бы и не проблема вовсе<br>> <br>> Количество свободного места на разделе - это не проблема, потому что<br>> Thin provisioning и все разделы виртуальных машин имеют логический<br>> размер в 50 TiB, - я бы сделал и больше, но Red Hat не рекомендует.<br></div><div data-marker="__QUOTED_TEXT__">Это тут вообще к чему? <br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">> <br>> > с моей точки зрения менять одну проблему на другую смысла нет<br>> <br>> использование места на диске - это не проблема, это необходимая плата<br>> за то, что запись в логи будет происходить без потерь информации,<br>> и что чтения и обработка информации из логов не обязаны быть<br>> такими синхронными и производительными, как в случае с unix<br>> socket`ами.<br>> </div><div data-marker="__QUOTED_TEXT__">Обязаны! и синхронными и производительными.<br>Если статистика будет накапливаться быстрее, чем обрабатываться, то данные никогда не будут актуальны.<br>Т.е. я сегодня увижу статистику за вчера, а за сегодня-- только через 2 дня, а к концу года буду видеть уже с отставанием в месяц??<br>И кому это будет интересно??<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br>> > Вот вам идея оптимального по большинству критериев решения --<br>> > Когда будете решать сходную задачу напишите свой модуль для nginx<br>> > Чтоб сразу считать все нужное "внутри" без посредников.<br>> > Я такое решение тоже рассматривал, отказался.<br>> > Лично мои трудозатраты по реализации такого подхода превосходят все<br>> разумные пределы.<br>> > Что и стало ключевым фактором "против".<br>> <br>> Такой модуль уже есть, Angie умеет экспортировать данные<br>> напрямую в Prometheus. Если бы у njs была возможность разделять<br>> данные между worker`ами, то можно был бы пряом через njs это делать.<br>> И скорее всего - это можно уже сейчас запрограммировать на lua,<br>> используя в качестве веб-сервера OpenResty, там есть доступ<br>> к разделяемой памяти. Или - просто парсить логи и все,<br>> это будет и быстрее и проще, чем unix socket`ы, IMHO.<br></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Нет там нужных мне метрик. И быть не может :)<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Метрика по параметру в GET/POST запросе, усредненная за 60 секунд...</div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Итоги разных экспериментов:<br>Исходные данные - CPU Xeon E5-26xx v4 CPU 2.2GHz<br>Для наглядности привожу данные по 1 вычислительному ядру.<br>Итак, на 1 вычислительное ядро</div><div data-marker="__QUOTED_TEXT__"> --- Существующий на данный момент бекэнд, куда nginx у меня проксирует запросы -- максимум около 2000 в секунду на одно ядро (вообще не моя епархия, но там точно НЕ php). </div><div data-marker="__QUOTED_TEXT__"> --- NGINX для теста, на который отзеркалированы запросы, вся его функция -- выдать ответ "200" и сообщение в лог записать, все, никакого проксирования или отдачи контента, <br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">никаких вычислений и т.д. Голый "200" + строка в лог-файле средствами nginx-а, ротация 10 секунд с удалением результата. --- максимум примерно 10 000 в секунду на 1 ядро<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"> --- парсинг данных из лога, накопленного за 60 секунд из расчета нагрузки 400тыс/сек, т.е. 24млн строк. -- на одном ядре от 8 минут. в зависимости от нагрузки на дисковую подсистему 8-9 минут. т.е. при среднем 500секунд 48 000 в секунду на одно ядро.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"> --- Обработка через юникс-сокет "на лету" python3.9 скриптом -- 43 000 в секунду на одно ядро 100% соответствие результатов, около 89-92% занятость ядра CPU.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Итого технически "самый быстрый" -- парсинг лога, но тянет за собой запись-чтение-удаление при относительном преимуществе 9-12% и </div><div data-marker="__QUOTED_TEXT__">зависимости результата от файлового ввода-вывода. <br></div><div data-marker="__QUOTED_TEXT__"> а по факту на общей нагрузке системы потенциальный выигрыш составляет 1,5-2% от производительности системы, т.к. это задача вторая, а первая -- проксирование, и она "кушает" гораздо больше парсинга.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Возможно оптимизацией парсинга можно добиться и повышя скорости, выигрыш составит еще 1,5%... <br>А из расчета загрузить сокет-питон на 100% и это преимущество теряется.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Таким образом единственный сколь-нибудь существенный бонус - потенциальная полнота данных для обработки перестает быть существенным, когда считаем <br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">усредненные данные на миллионных выборках.</div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Зеркалирование -- проигрывает по всем параметрам. </div><div data-marker="__QUOTED_TEXT__">код принимаюшей стороны должен быть эффективнее nginx-а (отвечающего всем "200") в 5 раз для реального выигрыша над юникс-сокет+питон. <br>Не знаю насколько эффективен будет Go. Но честно говоря даже не вижу смысла проверять.</div><div data-marker="__QUOTED_TEXT__">Он должен на поррядок превосходить какой-нибудь php, а по обнаруженным данным там разница в 3-5 раз, а надо минимум в 10 для того, чтоб это имело хоть какой-то смысл в данной конкретной задаче.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Могу и ошибаться.<br><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">> <br>> -- <br>> Best regards,<br>> Gena<br>> <br>> _______________________________________________<br>> nginx-ru mailing list<br>> nginx-ru@nginx.org<br>> https://mailman.nginx.org/mailman/listinfo/nginx-ru<br><br><br><br></div></div></body></html>