Обнаружена блокировка сессий в PHP

1 23
iHead
На сайте с 25.04.2008
Offline
137
#21

Отсутствие блокировок в phpredis - это скорее баг, чем фича.

Вот народ просит как раз добавить блокировки

https://github.com/phpredis/phpredis/issues/37

alexeyymanikin, могли бы вы пояснить, почему вы считаете, что этим нужно гордиться и как у вас происходит разделение двух и более клиентов хостинга, использующих redis?

Рекомендуемый хостинг партнер 1С-Битрикс (https://www.ihead.ru/bitrix/), PHP-хостинг (https://www.ihead.ru/php/), доверенный партнер RU-CENTER (https://www.ihead.ru/news/573.html), официальный представитель REG.RU в Кирове (https://www.ihead.ru/news/851.html)
Aisamiery
На сайте с 12.04.2015
Offline
302
#22
ENELIS:
Интересно, а в Redis как эта блокировка обходится? Если изменение не будет атомарным, то будут коррапт данные или что еще хуже возможна утечка данных. Разница только в том, что Redis как и memcache держат это в памяти. Такие проблемы говорят о медленной ФС и дисках под ФС, раз IO заставляет ждать так долго.

Вам же сказали, что это не php блокировки, а блокировка файловая на запись. Тут не в скорости ФС дело, а дело в том, что вы файл открыли на запись и начали делать бэкап, так вот пока бэкап не сделается (вы же не закрыли дескриптор файла), то система не отдаст блокировку.

Сессии в php в своем стандарте очень примитивны, просто пишет в файл, а так в большинстве случаев достаточно сложить их в БД, главное реализовать очистку протухших сессий, но редис тоже вполне пойдет. Либо не дергать session_start для каждого хита.

Тут больший вопрос к самой архитектуры движка, а не к хостингу.

Разработка проектов на Symfony, Laravel, 1C-Bitrix, UMI.CMS, OctoberCMS
ENELIS
На сайте с 29.08.2008
Offline
194
#23

Так оно и в Редисе должно держать лок на сессию все время. Пока сессия открыта, в нее писать по идее не должно. Иначе коррапшн будет.

С Уважением, ServerAstra.ru (https://serverastra.com) - VPS и выделенные сервера в Будапеште по выгодным ценам!
Aisamiery
На сайте с 12.04.2015
Offline
302
#24
ENELIS:
Так оно и в Редисе должно держать лок на сессию все время. Пока сессия открыта, в нее писать по идее не должно. Иначе коррапшн будет.

Многое зависит от кейса, в сессию многое не складывают, авторизацию, какую то юзерскую инфу и тогда получается что в сессию вы пишите при авторизации, для чего вам постоянно писать и каким должен быть кейс чтоб побить данные при одновременном чтении и записи сессии одного юзера?

Вы же в стандарте тут блочите сессию не в момент записи в неё, а в момент открытия, то есть когда вызван session_start и до момента session_write_close. В этот промежуток вы можете ничего не делать с сессией, но у вас например какой нибудь ajax запрос ресурсоемкий повесит все остальные ajax запросы на странице при это никак не работая с сессией вообще. Тут корапшен как вы говорите будет только в одном случае, если ваш кейс пишет в чужие сессии, ну или чистит чужие сессии, ну вообщем при воздействии из вне. Я работаю на достаточно больших ИМ и хз, какой кейс может побить сессию в редисе если честно. Ну а скорости конечно прибавляется, так как сессия используется на каждом хите и не мучается дисковая подсистема, хотя можно под сессии выделить и виртуальную папочку в оперативке, кому как интереснее.

A
На сайте с 20.09.2008
Offline
131
#25
iHead:

alexeyymanikin, могли бы вы пояснить, почему вы считаете, что этим нужно гордиться и как у вас происходит разделение двух и более клиентов хостинга, использующих redis?

Мы используем не стандартный хандлер redis - а свой. В случае если редис не доступен сессии работают с файлами. Так же добавили модуль который пишет в лог где, на какой строке, какой URL вызывался и сколько времени была блокировка. Не могу сказать, что это было сложно сделать - но в момент внедрения проблем мы получили не мало.

теперь как устроенно разделение. У каждого пользователя в docker работает свой экземпляр redis со своим настройками памяти, конфигами. Работает от имени суб-пользователя привязанного к основному пользователю (для сбора статистики стандартными средствами)


doom2 : ~ [0] # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ebc582349435 registry.beget.ru/docker/service-redis:master "/sbin/minit" 6 days ago Up 21 hours service-LOGIN___redis_nzevv2
1f4063887879 registry.beget.ru/docker/service-sphinx:master "/init" 8 days ago Up 3 days service--LOGIN___sphinx_edo6y4
60a702ce3d15 registry.beget.ru/docker/service-redis:master "/sbin/minit" 8 days ago Up 3 days service--LOGIN___redis_jyogku
2680ca6c1e81 registry.beget.ru/docker/service-redis:master "/sbin/minit" 2 weeks ago Up 3 days service--LOGIN___redis_hlkgew
862f203728ee docker.beget/service-memcache:latest "/sbin/minit" 4 weeks ago Up 3 days service--LOGIN___memcached_gq0123
0975ffe4830e docker.beget/service-tarantool:latest "/sbin/minit" 5 weeks ago Up 21 hours service--LOGIN___tarantool_29bg4o
6ef10ca98e16 registry.beget.ru/docker/service-redis:master "/sbin/minit" 5 weeks ago Up 3 days service--LOGIN___redis_ywnlce
0d50a4676be7 registry.beget.ru/docker/service-redis:master "/sbin/minit" 5 weeks ago Up 3 days service--LOGIN___redis_0lgm1a

далее в iptables прописываем правила, их для каждого пользователя может быть много


-A OUTPUT -m comment --comment BASERULE -j BEGET_SERVICES_OUTPUT
-A BEGET_SERVICES_OUTPUT -m beget_owner --uid-owner 3100 -j service-aalangow

:ext-service-aalangow - [0:0]
:service-aalangow - [0:0]
-A BEGET_SERVICES_OUTPUT -m beget_owner --uid-owner 3100 -j service-aalangow
-A service-aalangow -d 127.0.0.1/32 -p tcp -m tcp --dport 6380 -m comment --comment redis_ywnlce -j DNAT --to-destination 172.17.0.1:6379
-A service-aalangow -d 127.0.0.1/32 -p tcp -m tcp --dport 6379 -m comment --comment redis_ywnlce -j DNAT --to-destination 172.17.0.1:6379
:service-aalangow - [0:0]
-A BEGET_SERVICES_OUTPUT -m beget_owner --uid-owner 3100 -j service-aalangow
-A service-aalangow -d 172.17.0.1/32 -p tcp -m tcp --dport 6380 -m comment --comment redis_ywnlce -j ACCEPT
-A service-aalangow -d 172.17.0.1/32 -p tcp -m tcp --dport 6379 -m comment --comment redis_ywnlce -j ACCEPT

Там два правила для локальных подключений и для внешних - это можно все настроить с панели управления. И получается, фактически когда пользователь стучится на 127.0.0.1:6379 его запрос перенаправляется внутрь контейнера, другие запросы внутрь контейнера попасть не могут.

Это позволяет поднимать приватные экземпляры redis, memcache, sphinx, mysql, postgress - да в принципе всего чего угодно в рамках виртуального хостинга.

Скажите почему возникает очень много блокировок сессий на связке HostCMS и бегет. Т.е в шаблоне или самой CMS косяк?
Если я перенесу сайт на другой хостинг блокировка останется, 100% вероятность?

Если честно я с HostCMS не разу не работал, в код не лазил, подсказать по этому вопросу не могу. Блокировки - это не к хостингу это больше к PHP. Только мы решили сообщать об этой проблеме, так как иногда это помогает.

---------- Добавлено 27.10.2017 в 04:59 ----------

пс. надеюсь пользователь aalangow не сильно обидеться что я указал его логин в примере...

-- С Уважением Алексей Маникин.
ENELIS
На сайте с 29.08.2008
Offline
194
#26
Aisamiery:
Многое зависит от кейса, в сессию многое не складывают, авторизацию, какую то юзерскую инфу и тогда получается что в сессию вы пишите при авторизации, для чего вам постоянно писать и каким должен быть кейс чтоб побить данные при одновременном чтении и записи сессии одного юзера?

Вы же в стандарте тут блочите сессию не в момент записи в неё, а в момент открытия, то есть когда вызван session_start и до момента session_write_close. В этот промежуток вы можете ничего не делать с сессией, но у вас например какой нибудь ajax запрос ресурсоемкий повесит все остальные ajax запросы на странице при это никак не работая с сессией вообще. Тут корапшен как вы говорите будет только в одном случае, если ваш кейс пишет в чужие сессии, ну или чистит чужие сессии, ну вообщем при воздействии из вне. Я работаю на достаточно больших ИМ и хз, какой кейс может побить сессию в редисе если честно. Ну а скорости конечно прибавляется, так как сессия используется на каждом хите и не мучается дисковая подсистема, хотя можно под сессии выделить и виртуальную папочку в оперативке, кому как интереснее.

Эх ПХП, ПХП... По идее если в редисе лок не ставиться на всю сессию на весь период, то скрипт выполняется в бекграунде до конца и пишет в сессию кривые данные, когда пользователь от злости обновил страницу и его новый скрипт пишет уже другие данные, на основании других записей, называется race condition, для этого и используются локи/семафоры/спины/мъютексы, в случае с файлами это как раз эксклюзивный лок на файл (который на самом деле не эксклюзивный на многих ОС), в случае с редисом - это (по идее) лок на запись в БД. В БД лок должен вестись сессионно и это отличает его от ФС, т.к. в ФС нет сессий, в БД пользователь сделал рефреш страницы, старая страница закрыла соединение с БД и соответственно транзакция откатилась, однако в случае скрипта пишущего в бекграунде Redis ничем не поможет, т.к. транзакция все равно будет завершаться, неважно сделал ли пользователь рефреш или нет.

Такой принцип работы мало отличается от ZFS (также существует транзакция, лок всего лишь запись в БД) и возможно BTRFS (не знаком), так что на новых ФС это дело не нужно (если только для кластеризации).

K
На сайте с 26.02.2016
Offline
38
#27

кто то мне из beget та походу за сообщение /ru/forum/comment/15306445

минусунул ((((

S4
На сайте с 26.07.2007
Offline
183
#28
Koan:
кто то мне из beget та походу за сообщение
минусунул ((((

Вы себе льстите.

Проверенные KVM NVMe VPS ( https://hosthatch.com/a?id=200 ) в Нидерландах, Швеции, Норвегии, Австрии и США с гарантированным ресурсом CPU - от $2,5/м за 1GB RAM, 10GB NVMe SSD Пожалуй, лучший веб-хостинг в России ( https://beget.com/p415216 ) (30 дней на тест)
1 23

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий