Как стать автором
Поиск
Написать публикацию
Обновить

Подводные камни при работе с файлами в Linux с примерами на Python

Уровень сложностиСредний
Время на прочтение4 мин
Количество просмотров5.7K
Всего голосов 24: ↑24 и ↓0+28
Комментарии14

Комментарии 14

Вообще держать лог открытым – плохая практика. Открыл – дописал строчку – закрыл.

Не соглашусь с вами. Открытие-закрытие - это накладные расходы. Писать мы можем часто - 100 строк в секунду или даже чаще, из разных потоков.

А ещё это может быть не просто текстовый лог, а, например, WAL-файл базы данных, который всё время открыт.

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

На мой взгляд, текстовый лог осмыслен тогда, когда его можно читать с консоли в реальном времени.

Снова не соглашусь с вами. И nginx тоже не согласится.

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

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

Синхронизация - да, это отдельная проблема, и это проблема. Надо выбирать - либо скорость, либо консистентность. nginx не очень заботится о том что потеряется пара секунд логов, это проблема админов.

А вот с базой данных все сложнее. Помню как на меня наорал DBA, когда я спросил почему нельзя ставить Oracle на виртуалку хотя бы в тестовых окружениях.

Любая система виртуализации имеет настройки кэширования, и они безопасны. Небезопасные режимы надо включать руками с приседаниями. Сделано специально с учетом среднего уровня специалистов :-)

Из того разговора я успел понять что Oracle - не просто любая база данных и они на <censored> вертели идею ловить непонятные ошибки в базе из-за того что какой-то <censored> с горы хочет сэкономить на железе.

Про logrotate - проблема описана правильная, но среди решений нет варианта "наорать на администратора и рассказать ему оcopytruncate", хотя в голосовании видно что автор знает об этом.

Если на сервере включено write caching на уровне диска/SSD, то fsync() может завершиться успешно, а данные — остаться в кэше контроллера и быть утеряны при сбое питания

Неверно. Этот os.fsync() это вызов функции операционной системы, а та при флашинге кэша активно отправляет записи с флагами PRE_FLUSH и FUA (force unit access) который соответственно сбрасывают кэши и пишут мимо кэша. То, что вы написали, бывает только если администратор умышленно стреляет себе в голову.

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

Как отследить это?

  • Проверяйте os.stat() и os.fstat() — если inode у файла изменился, лог был заменён.

  • Или используйте watchdog/inotify для мониторинга.

Зачем что-то проверять периодически внутри сервиса если есть механизм сигналов. Просто сделайте обработчик сгнала и в нем переоткрывайте логи. Так что если админ в какой-то момент переименует лог-файл то он же и пошлет сигнал на переоткрытие.

Я предлагаю не просто писать огромные логи с огромной скоростью в текстовые файлы, а еще их распечатывать мелко-мелко и отправлять голубем админу. А потом писать статьи как голуби, иногда, не долетают и что с этим делать.
ЗЫ: непонятно почему нельзя их писать в редис какой-нибудь...

Зарегистрируйтесь на Хабре, чтобы оставить комментарий