![]() |
Подключение к базе данных в php
Добрый день, вот такой вот вопрос: существует php приложение в котором реализовано частое обращение к базе данных (mySQL, Firebird, Oracle). Вопрос вот в чем - при загрузке и работе проекта на сервере как лучше поступить:
1. Открыть один дескриптор (подключение) к БД и отправлять через него все SQL запросы на протяжении всего времени сессии пользователя; 2. Открывать и закрывать подключение к БД при каждом выполнении любого SQL запроса? Помнится мне, что в Delphi подключение к базе выполняется один раз (при запуске программы) но это пример клиентского приложения, ..хотелось бы знать - как эта задача правильно решается в серверных приложениях! Благодарю за внимание! Немного уточню: В моем случае php сервер участвует в проекте в роли интерфейса между flash на стороне клиента и БД на стороне сервера. Сессия в моем случае необходима только для проверок активности пользователя на странице (session_id() дает понять что клиент активен). Php отдает на сторону клиента данные привязанные к пользовательскому session_id(). Я наверное немного не правильно поставил вопрос, вот это наверное будет более правильная формулировка: насколько (приблизительно) сильна будет нагрузка на БД сервер, если PHP при каждом выполнении SQL запроса сначала будет: 1. Авторизироваться с БД; 2. Выполнять запрос; 3. Закрывать соединение с БД после выполнения запроса; > Является ли такой метод корректным? Или более правильная реализация будет - создание только одного подключения PHP к БД и отправлять/принимать через него результаты SQL запросов на протяжении всей активной работы сессии? |
На PHP Вы в каждый момент времени работаете с одним пользователем.
Если Вы создадите для него постоянный коннект в рамках его сессии, а запросы придут от 100 пользователей, будет 100 постоянных коннектов. Выход не в оптимизации коннекта к базе, а в организации кэша приложения, который принципиально снизит нагрузку на базу. |
Я подумываю вот что - 100 подключений из 100 пользователей будет в любом случае. Ссылку на базу (точнее это object класс возвращающий Resource на базу (соответственно - с destructor`ом)) привязываю к сессии! Т.е. коннект к базе делается только один раз, во время запуска сессии и активна во все время активности сессии. Может все же лучше выполнять sql запросы через одно постоянное подключение, чем многоразовое подключение при каждом sql запросе? ...вот как бы это меня волнует.
|
А мужики-то не знают :)
|
...ну, не знают так не знают :) У меня эта реализация уже работает, вроде пока не жалуюсь. Но вот жду ситуации что бы посмотреть что будет когда к одному подключению обратятся два разных sql query запроса... или выполнятся поочередно, или будет crash.
|
два запроса в рамках одного соединения встанут в очередь и выполнятся.
краша тут вообще не видно просто какой-то очередной пользователь при открытии приложения вместо соединения к базе получит false. это если общее количество соединений будет превышено. |
Re: два запроса в рамках одного соединения встанут в очередь и выполнятся.
краша тут вообще не видно Это обнадежило! Re: просто какой-то очередной пользователь при открытии приложения вместо соединения к базе получит false. это если общее количество соединений будет превышено. А вот тут хотелось бы знать по подробней! Это как то фиксировано в php сервере (я подключаюсь к Firebird базе данных (ibase_connect))? Или кол-во соединений фиксирует сама database? ....ну как бы хочется понять о каких именно соединениях идет речь! Если речь идет о БД, то вот результат некоторых тестов: Код:
Машина для тестирования: intel сервер с 16Гб памяти, 2 процессора |
ERrorMAKros, :)
Вы идете по пути, по которому прошли уже сотни и тысячи программеров. Для самого среднего приложения в соцсети со среднесуточной посещаемостью около 20 тыс., в онлайне всегда будет в среднем 700 пользователей, а в отдельные моменты в пике и 1000. Продвинутые приложения имеют и 800 тыс. пользователей в сутки, т.е., в онлайне может быть 30-40 тысяч. Писать сервер на постоянных коннектах к БД, на мой взгляд, просто бессмысленно. Ну, разве что из каких-то научных целей. Логика построения таких серверов в принципе другая. С клиентом взаимодействует сервер приложения (пул серверов), который берет на себя всю нагрузку и держит у себя в кэше всю основную игровую информацию. А уже этот сервер приложения в свою очередь обращается к серверу БД. При этом количество запросов "клиент->сервер приложения" несопоставимо больше, чем "сервер приложения->сервер БД". |
mikhailk, вы не представляете как вы кстате с вашим опытом, потому как ...я еще к этому всему ползу. Хочу чуть чуть рассказать - специфика моего приложения не является дополнением к соц. сети, мое приложение и является - соц. сетью (вот захотелось мне такое написать).
1. Firebird SQL database - хранит настройки GUI объектов и контент (она же определяет права доступа к контенту (в основном все на хранимых процедурах, таблиц совсем не много) + языковые пакеты для multilang реализации); 2. PHP - интерфейс между БД и клиентом; 3. Клиент - GUI Flash .swf оболочка, загружающая .swf объекты для управления контентом, окошки, менюшки и т.п. (это работает так: клиент -> запрашивает объект у базы база -> определяет где находится физическое тело (.swf) и имеет ли пользователь права доступа к нему, php -> отправляет тело клиенту; клиент -> обрабатывает .swf и уже этот самый .swf при успешной загрузке у клиента - загружает из БД (опять через php) языковой пакет и свои настройки) ...так же он может вызывать и другой объект или контент. В целом это все будет представлять из себя информационную систему, картинки, заметки, mp3 проигрывание музыки. Физически сам контент разбросан по разным интернет адресам, БД хранит в себе только ссылки на них и отдает их Flash`у в случае если удовлетворяются права доступа. Flash обрабатывает и отображает контент в том виде в котором нужно (.jpg в картинки, .flv в видео и т.д.). На основе типа контента Flash обращается на сервер и получает объект (.swf`ку) который будет отображать этот вид контента. До этого момента для меня моя разработка была ясна как день, пока вы не дали мне понять что ...у меня очень слабая работа с БД :( Подскажите где можно прочитать о том, как правильно построить соц. сеть или, что еще лучше, буду признателен если вы поделитесь опытом и парой советов по организации архитектуры БД в моем случа, потому как похоже что я вам в этом плане доверяю! |
Ну, к социальным сетям я отношения не имею, могу лишь поделиться тем, как сделано сейчас у меня.
Сервер приложения написан на PHP, для хранения кэша приложения применяется MemCache. В кэше хранится информация, готовая к отдаче клиенту без какой-либо обработки. В момент, когда от клиента идет запрос, скрипт php проверяет актуальную информацию в кэше и, если она есть, тут же ее отдает. Если ее нет, он лезет в базу, производит необходимую обработку и отдает, параллельно записывая в кэш. Когда клиент вносит изменения в базу, соответствующие данные в кэше должны быть сброшены. Тогда они при следующем запросе автоматически вычислятся заново и будут записаны в кэш. Собственно, это все. Основная сложность - обеспечение актуальности данных в кэше. Ошибки программирования, когда какие данные изменены в базе, но не сброшены в кэше, приводят к нарушению целостности информации и глюкам приложения. Иногда забавным, иногда не очень. P.S. А вообще-то Вы взялись за достаточно серьезную разработку. Вы в курсе? :) |
Не надо из мемкеша ничего выбрасывать, нужно изменять одновременно с данными в базе. А актуальность и синхронизация данных будет обеспечена прямыми руками. Если оные не есть прямые, тут ничего уж не поделаешь.
|
2mikhailk: Да, что работа серьезная - осознаю! Хочется на этом получить достойный опыт. За модель кеширования - спасибо! Есть над чем подумать!
2etc: Будьте добры - дискуссировать объективней? Я понимаю что у вас руки прямые, но я здесь с вами не руками меряюсь! Задача (на данный момент) одна - найти достойное решение обеспечивающее стабильную работу БД при превышении 850 кол-ва коннектов! |
Цитата:
Теперь по логике работы. Допустим, в кэше хранится профиль фермы пользователя в виде объекта. Пользователь купил ослика. От клиента поступил запрос на покупку ослика, по итогам которого сервер отдал клиенту обновленную информацию - добавленное жывотное, обновленная сумма на счету, обновленный рейтинг, клиент получил эти данные и у себя их учел. Параллельно с отправкой данных клиенту мы должны обеспечить целостность данных. Я сбрасываю профиль фермы из кэша, он будет автоматически заполнен при следующем обращении к ней методом, который указан в первом абзаце. Имею незначительную избыточность в вычислениях, но простоту и надежность. В Вашей реализации Вы, на сколько я понимаю, обновляете объект профиля фермы и записываете его заново. Т.е., Вы немного экономите на вычислениях, но имеете более сложный сервер. Вопрос выбора. Кстати, я тут подумал, что мне пришлось пойти своим путем и по вполне объективным причинам. Иногда есть потребность одновременно внести изменения, скажем, в тысячу-другу профилей ферм. Например, в стойла вернулись арендованные на сутки ослики. Пересчитывать все эти профили одной задачей - достаточно трудоемко. Проще их сбросить, чтобы потом они постепенно обновились в кэше по мере того, как они будут запрошены. |
mikhailk, о том, что надо проверять, никто не спорит. Но я предпочту снизить нагрузку на базу.
|
вставлю тоже пару слов.
Лично на мой взгляд кеширование, этот Memcache не нужная и не удобная штуковина вообще. Кто-то ещё ставит базу ключ=значение, да тот же MemcacheDB. Сидят там пару процентов производительности поднимают. Ломать себе мозг, как отыграть немного производительности у сервера, в наше время это лишние проблемы. Ещё можно программный код ужимать, а то у нас винчестеры 250кб. Да максимум поставил сверху Апачи Nginx, поднастроил БД, оптимизировал запросы и оптимизировал таблицы. Ну если проект большой, сразу арендовал один сервер. За 5 000 в месяц можно нормальный найти. Стало мало места, вынес базу данных на отдельный сервер. Дальше вынес все изображения на отдельный. Можно вообще базу по серверам отмасштабировать. Если вообще всё плохо то настроил "Ферму" на Nginx, или разнёс проект по модульно. Да 100 вариантов есть. |
У нас без мемкеша сервер загибается за 10 минут. Это при том, что запросы примитивны.
|
У Вас проекты такого плана с которыми я к сожалению не работал.
Там 25 000 нубов в TimeZero режет крысу, или 10 000 человек в destiny-online передаёт свои координаты местоположения. Наверно у меня проекты, где люди не так часто запросами кидаются. |
Я так понимаю, если мемкэш обеспечивает прирост в 2% производительности, то это очень интересное и необычное использование мемкэша.
membrilius, автор топика социальную сеть сделать собирается. Вам известны движки социальных сетей без кэширования? |
А мы вот apc выбрали все-таки, он удобнее.
Вообще всю статику в любом проекте, где предполагается хоть какая-то более ли менее нагрузка надо кешировать данные, собирать в байт-код пхп, картинки отдавать на всякие nginxы и т.п. |
mikhailk, я просто высказал своё мнение.. я не считаю что мемкэш это минус.
Просто если в конторе работает допустим 20 программистов... да было бы хорошо, если бы они на достойном уровне знали PHP и JavaScript. Вообще моя статистика из 100 человек на собеседование, только 10 видят PHP, JavaScript, HTML глазами хакера. Не в ту степь я пошёл ) Я читал много Ваших постов, Вы всеми руками за производительность - ценный сотрудник. А я человек которому проще вкладывать деньги в железо. И за такие понятия как Шардинг, Репликация (хоть это и ужасно, но иногда выручает), Партиционирование, Балансировка, Nginx фермы. Масштабировать я люблю ) |
А мужики-то не знают :)
|
Для многих людей мемкеш*—*это какое-то магическое заклинание. Когда я делал Лицемер для вконтакта (а он пробил отметку в 40 тыс запросов в минуту), то никакого мемкеша у нас вовсе не было, потому что не нужен он был.
И вообще, люди очень часто пытаются вместо решения проблемы (например, заменить медленный мускль на быстрый постгрес и заплатить единожды админу за правильную настройку всех опций в конфиге), закрывать проблему мемкешом. Самое главное, что это не очень помогает. Мемкеш очень сложный в работе инструмент, потому что он опасен рассинхронизацией данных с БД. Самое хреновое начинается, когда его начинают использовать как кеш по первичному ключу и ходить к нему, вместо базы за выборкой по select * from users where id = .. |
Я недавно был вынужден посмотреть в сторону memcache, ...конечно полностью полагаться на него не стоит, но как страховочный трос - пригодиться, да и вариаций его применения многовато ))) ...так что (пока только теоретически) считаю эту штукенцию полезной в хозяйстве, ...как только нарвусь на проблемы при реализации - ...но надеюсь что не нарвусь )))
|
| Часовой пояс GMT +4, время: 09:51. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.