Большая PHP-сессия замедляет работу веб-приложения - PullRequest
8 голосов
/ 25 сентября 2011

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

Сейчас у меня есть сложная функция PHP, которая генерирует большую сессию PHP, создавая массивы файлов, к которым у пользователя есть доступ, либо в их организации, либо в их совместной работе, и объединяя эти массивы доступа. Когда эти файлы отображаются для пользователя, PHP проверяет этот массив, чтобы увидеть, есть ли у них доступ, и если они делают, он добавляет кнопку, чтобы открыть файл. Я делаю это таким образом, потому что выполнение запроса для проверки доступа для каждого отдельного файла в конечном итоге заняло слишком много времени при отображении длинных списков файлов, а PHP in_array () был значительно быстрее.

Проблема в ...

Сессия php стала настолько большой, что, кажется, замедляет работу простых функций веб-сайта, и мне нужно придумать новый способ сделать это.

Мой вопрос ...

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

Ответы [ 2 ]

6 голосов
/ 25 сентября 2011

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

Это поле будетсохраните json представление вашей структуры разрешений.Это потребует только одного обращения к базе данных, и большая часть обработки будет выполняться при синтаксическом анализе стороны сервера данных json (что не должно быть слишком много служебных данных).

Это стандартный способуменьшить размер информации о сеансе на стороне клиента.Хорошее практическое правило - помещать в таблицу Sessions что-либо, что раскрывает логику вашего приложения.

Обновление

Я бы сохранял только те файлы, которые они do имеют доступ в поле json.Можно предположить, что небытие запрещает им доступ к файлам.Это снова уменьшит нагрузку на производительность.

Это будет работать только в том случае, если нет сложной структуры разрешений (например, каждый файл имеет разрешения на чтение и запись).Если этого не произойдет, я бы сказал, что вы в чистоте.

0 голосов
/ 25 сентября 2011

Я не уверен, что вы многое можете сделать. Возможно, memcached может помочь, но я не использовал его (хотя, насколько я слышал, для этого он и используется).

Вы можете сохранить массив в файле, хотя, насколько я знаю, это именно то, что делают сессии.

Вы также можете попробовать использовать разделяемую память для сохранения пользовательских данных в памяти между запусками скриптов.

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


ОБНОВЛЕНИЕ: Другая идея.

Вы также можете предварительно рассчитать разрешения пользователя для каждого файла и сохранить их в базе данных. Таблица может называться FilesPermittedPerUser и иметь первичный ключ из двух столбцов userID / fileID. Это создаст индекс, который отсортирован сначала по userID, а затем по fileID. Ключ из двух столбцов также обеспечит уникальность записей.

Поскольку он будет проиндексирован пользователем, вы можете просто ORDER BY userID и LIMIT 10, 10 перечислить только файлы 10-20. Извлечение только частей списка через AJAX означало бы, что вы никогда не вызовете ужасную нагрузку на память, которую в настоящее время вызывают ваши скрипты.

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

Вы также можете организовать файловую систему по папкам. Нет никакого смысла просто бросать тонны файлов пользователям и постоянно поддерживать их. Попробуйте скинуть 10.000 файлов в Explorer / Finder / Nautilus и посмотрите, что произойдет, когда вы откроете эту папку. Ничего хорошего, и они сохраняют память - а с PHP вы этого не делаете.

Заключительная идея (хотя вам, вероятно, не нужно переходить к этим крайностям): переписать API файловой системы в нечто, отличное от PHP, и сохранить данные о правах доступа. Используйте PHP только для пересылки запросов на этот пользовательский сервер, который работает на другом сервере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...