- Поисковые системы
- Практика оптимизации
- Трафик для сайтов
- Монетизация сайтов
- Сайтостроение
- Социальный Маркетинг
- Общение профессионалов
- Биржа и продажа
- Финансовые объявления
- Работа на постоянной основе
- Сайты - покупка, продажа
- Соцсети: страницы, группы, приложения
- Сайты без доменов
- Трафик, тизерная и баннерная реклама
- Продажа, оценка, регистрация доменов
- Ссылки - обмен, покупка, продажа
- Программы и скрипты
- Размещение статей
- Инфопродукты
- Прочие цифровые товары
- Работа и услуги для вебмастера
- Оптимизация, продвижение и аудит
- Ведение рекламных кампаний
- Услуги в области SMM
- Программирование
- Администрирование серверов и сайтов
- Прокси, ВПН, анонимайзеры, IP
- Платное обучение, вебинары
- Регистрация в каталогах
- Копирайтинг, переводы
- Дизайн
- Usability: консультации и аудит
- Изготовление сайтов
- Наполнение сайтов
- Прочие услуги
- Не про работу
Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий
Столкнулся с неприятной проблемой.
На одном из серверов происходит что-то странное.
Объясняю. Откручивается рекламная строчка. Количество показов записывается в файле var/stat.php, который формируется простейшим var_export из массива.
Количество просмотров не слишком и большое, но приличное: около 100 тыс. в сутки.
Так вот, периодически из файла пропадает ЧАСТЬ массива 8-/
Кто сталкивался с подобным поведением и куда копать?
копать тут -> http://ru.php.net/flock , применяйте вдумчиво, иначе будет только хуже:)
p.s.: "нагрузка на чтение/запись файлов" в php абсолютно не при чем. это стандартное поведение файлов, когда с ними работают без блокировки. файл-то один, а конкурентов пытающихся в него инфу скинуть куча. если Вы не управляете очередностью записи, то получаете то, что получаете.
edogs, разве информация при file_put_contents не целиком пишется?
Это не блокирущая запись.
Я не вполне понимаю... то есть вы хотите сказать, что может быть ситуация, когда в момент записи файла (то есть она ещё не вполне завершилась), файл может прочитаться другим скриптом, пока он ещё не полностью сформирован?
В общем да. Даже более того, если у Вас не используется блокировка, то если один скрипт у Вас пишет файл, и второй тоже начинает, а тут еще третий тоже начинает писать, то на выходе может быть абсолютная жуть.
Блокировка файлов единственный способ это контроллировать. И это относится не только к php, а в принципе к работе с файлами. Плюс обязательно прочтите про особенности flock в мануале php, там есть неочевидные вещи типа "all accessing programs have to use the same way of locking or it will not work" и "On some operating systems flock() is implemented at the process level. When using a multithreaded server API like ISAPI you may not be able to rely on flock() to protect files against other PHP scripts running in parallel threads of the same server instance!" и пара других.
Значит ли это, что для использования блокировки придётся отказываться от удобнейших file_get_contents и file_put_contents? В мануале сказано:
Да, прийдется! Даже более того, в мануале сказано "all accessing programs have to use the same way of locking or it will not work". То есть все другие способы не использующие flock обломятся.
Я, кстати, файлы вообще не открываю. Эта сгенерированная статистика инклюдится, там в файле сразу массив в переменной.
Имхо: мемкэшед, временные таблицы mysql, sqllite - как вариант если не хочется возиться с файлами непосредственно. Плюс в первых 2 случаях скорость может оказаться выше.
p.s.: и еще замечание. сериализация работает быстрее чем var_export. и проще отлавливаются ошибки, если файл не полный.
edogs, разве информация при file_put_contents не целиком пишется?
Я не вполне понимаю... то есть вы хотите сказать, что может быть ситуация, когда в момент записи файла (то есть она ещё не вполне завершилась), файл может прочитаться другим скриптом, пока он ещё не полностью сформирован?
BrokenBrake добавил 28.10.2009 в 06:16
Ой, вы ответили уже, оказывается.
Тема не обновляется, когда правите сообщение.
Я вас понял, спасибо. Но понял не вполне :)
Значит ли это, что для использования блокировки придётся отказываться от удобнейших file_get_contents и file_put_contents? В мануале сказано:
Я, кстати, файлы вообще не открываю. Эта сгенерированная статистика инклюдится, там в файле сразу массив в переменной.
BrokenBrake добавил 28.10.2009 в 06:23
И ещё очень важный момент из мануала:
В некоторых операционных системах flock() реализован на уровне процессов. При использовании многопоточных серверных API, таких как ISAPI, вы не можете полагаться на flock() для защиты ваших файлов от дугих PHP-скриптов, которые работают в параллельном потоке на том же сервере!
Если несколько пользователей открыли один и тот же PHP-файл, который пишет в другой файл... наверно, блокировка не поможет? Не понимаю :(
BrokenBrake добавил 28.10.2009 в 06:28
Имхо: мемкэшед, временные таблицы mysql, sqllite - как вариант если не хочется возиться с файлами непосредственно. Плюс в первых 2 случаях скорость может оказаться выше.
Я про временные таблицы даже не знал ничего.
Изучу этот вопрос, спасибо!
p.s.: и еще замечание. сериализация работает быстрее чем var_export. и проще отлавливаются ошибки, если файл не полный.
Сперва именно сериализацию и делал, но было хуже.
Огромное спасибо за помощь Edogs, и Aktuba, а также моим клиентам, которые провели экстремальное тестирование. Сегодня я устранил проблему. Если кто-то работает с данными в файлах, настоятельно рекомендую ознакомиться вот с этой заметкой - http://airbase.ru/computers/php/flock/ (в данный момент недоступна)
Главное оттуда:
Это работает без сбоев месяцами при тысячах обращений к файлу в день.
Следует также помнить, что читать файл нужно только через fopen() (можно fopen(..","r")) НО НЕ ЧЕРЕЗ file() или readfile(). Может считаться полузаписанный файл. Т.е. если это только для разового чтения и сбой не страшен, то пожалуйста. Если же требуется что-то прочитать, изменить и записать, то всё надо делать в одно открытие файла, как в приведённом выше примере.
Блокировка не нужна если есть атомарная операция переименования файла.
Создаете новый файл с кешем, не стирая старый и делаете rename(). Полностью избавляет от необходимости ставить блокировки чтения.
Впрочем, нужно помнить, что на windows-хостинге rename не удаляет старый файл с тем же именем автоматически. Но таким хостингом никто из пхпшников не пользуется.
Блокировка не нужна если есть атомарная операция переименования файла.
Создаете новый файл с кешем, не стирая старый и делаете rename(). Полностью избавляет от необходимости ставить блокировки чтения.
Да, это альтернативный метод, я изучал его. И, хоть это было совсем недавно, не помню почему отказался. Но были какие-то весомые причины.
Советую для вышеописанных целей использовать memcached (http://ru.wikipedia.org/wiki/Memcached), для Ваших целей как в плане экономия ресурсов, так и в плане скорости подойдет идеально.
stack, для моих целей вообще не подойдёт, так как продукт должен ставиться пользователем с минимальной подготовкой на максимальное количество всевозможных серверов. Думаю, Memcached не везде есть.
BrokenBrake, а никаких минусов нет, кроме windows. Если вспомните - напишите.
насколько я изучил документацию, можно использовать LOCK_EX в int file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] )
Описано это так:
LOCK_EX Acquire an exclusive lock on the file while proceeding to the writing.
слушайте netwind'а )
у флока минусов по-больше, чем с временным файлом и переименовыванием)