Тактика использования PHP на высоконагруженном сайте

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


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

Базы данных

На данный момент я планирую использовать функции MySQLi в PHP5. Однако как мне настроить базы данных по отношению к пользователям и контенту? Я действительно необходимость несколько баз данных? На данный момент все перемешано в одной базе данных - хотя я рассматривал возможность распространения пользовательских данных в одну, фактического контента в другую и, наконец, основного контента сайта (мастеров шаблонов и т. д.) В другую. Я считаю, что отправка запросов к разным базам данных снизит нагрузку на них, поскольку одна база данных = 3 источникам нагрузки. Также было бы это эффективно, если бы все они были на одном сервере?

Кеширование

У меня есть система шаблонов, которая используется для создания страниц и замены переменных. Основные шаблоны хранятся в базе данных, и каждый раз, когда шаблон вызывается, вызывается его кэшированная копия (HTML-документ). На данный момент у меня в этих шаблонах есть два типа переменных - статическая и динамическая. Статические переменные обычно представляют собой такие вещи, как имена страниц, имя сайта - вещи, которые не часто меняются; динамические вары - это вещи, которые меняются при каждой загрузке страницы.

Мой вопрос по этому поводу:

Скажем, у меня есть комментарии к разным статьям. Что является лучшим решением: хранить простой шаблон комментария и отображать комментарии (из вызова БД) каждый раз, когда страница загружается, или сохранять кешированную копию страницы комментариев как страницу html - каждый раз, когда комментарий добавляется / редактируется / удаляется. страница повторно открыта.

Ну наконец то

Есть ли у кого-нибудь советы / указатели для запуска сайта с высокой нагрузкой на PHP. Я почти уверен, что это подходящий язык для использования - Facebook и Yahoo! уделяйте этому большое внимание - но есть ли какие-то переживания, которых я должен остерегаться?

Спустя 3,5 года, я даже не могу вспомнить, над чем работал, хотелось бы знать, что мне показалось таким крутым :)

Ross 09.12.2011 06:28

Пусть это будет вам уроком о преждевременной оптимизации :)

Rimu Atkinson 13.12.2012 10:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
247
2
23 907
23
Перейти к ответу Данный вопрос помечен как решенный

Ответы 23

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

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

Во-первых, как мне кажется, сказал Кнут: «Преждевременная оптимизация - корень всех зол». Если вам не нужно заниматься этими проблемами прямо сейчас, не делайте этого, сначала сосредоточьтесь на предоставлении того, что работает правильно. При этом, если оптимизация не может ждать.

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

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

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

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

RequiredFullQuote: «Мы должны забыть о небольшой эффективности, скажем, примерно в 97% случаев: преждевременная оптимизация - корень всех зол»

Alister Bulman 12.09.2011 13:05

RequiredReallyFullQuote: «Программисты тратят огромное количество времени на размышления или беспокойство о скорости некритичных частей своих программ, и эти попытки повышения эффективности на самом деле имеют сильное негативное влияние, когда рассматриваются отладка и обслуживание. Мы должны забыть о небольшой эффективности, говорят примерно в 97% случаев: преждевременная оптимизация - корень всех зол. Тем не менее, мы не должны упускать наши возможности в этих критических 3% ».

cHao 21.05.2013 14:18

Я работал над несколькими сайтами, которые получают миллионы обращений в месяц при поддержке PHP и MySQL. Вот некоторые основы:

  1. Кеш, кеш, кеш. Кэширование - один из самых простых и эффективных способов снизить нагрузку на ваш веб-сервер и базу данных. Кэшируйте содержимое страницы, запросы, дорогостоящие вычисления, все, что связано с вводом-выводом. Memcache чрезвычайно прост и эффективен.
  2. Используйте несколько серверов, когда вы исчерпали себя. У вас может быть несколько веб-серверов и несколько серверов баз данных (с репликацией).
  3. Уменьшите общее количество запросов к вашим веб-серверам. Это влечет за собой кеширование JS, CSS и изображений с использованием заголовков с истекшим сроком действия. Вы также можете переместить свой статический контент в CDN, что ускорит взаимодействие с пользователем.
  4. Измерение и эталон. Запустите Nagios на производственных машинах и выполните нагрузочный тест на сервере dev / qa. Вам нужно знать, когда ваш сервер загорится, чтобы вы могли его предотвратить.

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

Также ознакомьтесь с моим сообщением в блоге о масштабируемости, в нем есть много ссылок на презентации о масштабировании с использованием нескольких языков и платформ: http://www.ryandoherty.net/2008/07/13/unicorns-and-scalability/

+1 Здесь много полезной информации. В последнее время я больше исследую эту тему, и ваш ответ согласуется со всем, что я прочитал. Memcache, кеширование, CDN для статического контента, сокращение запросов; все хорошее. Я бы также добавил, генерируйте хеши для файлов статического содержимого (если вы находитесь за CDN / кешем) на стороне сервера, чтобы обновленные файлы имели уникальную подпись в кеше. Кроме того, комбинируйте статические исходные файлы (css, javascript) на лету (и кешируйте их с помощью хешей файлов), чтобы сократить количество запросов. Кроме того, динамически генерируйте превью (и сохраняйте их в кеше)

Evan Plaice 14.02.2011 14:58

Google создал модуль apache под названием mod_pagespeed, который может обрабатывать все конкатенации файлов, минификацию, переименование файлов для включения хеша и т. д. Для всего статического контента. Первоначально он должен лишь добавить небольшие накладные расходы на обработку на серверы, пока кеши (и CDN) не будут заполнены большей частью контента. Кроме того, в целях безопасности, как правило, не рекомендуется помещать общедоступные (пользователям) таблицы в ту же базу данных, что и таблицы, а не обрабатывать серверную часть (если по какой-то причине одна из таблиц должна быть взломана).

Evan Plaice 14.02.2011 14:58

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

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

Также очень поможет любой вид кеша опкодов для PHP (например, APC или один из многих других).

Ответ принят как подходящий

Нет двух одинаковых сайтов. Вам действительно нужно получить такой инструмент, как jmeter и тест, чтобы увидеть, где будут ваши проблемные точки. Вы можете потратить много времени на догадки и улучшения, но вы не увидите реальных результатов, пока не измерете и не сравните свои изменения.

Например, в течение многих лет кеш запросов MySQL был решением всех наших проблем с производительностью. Если ваш сайт работал медленно, эксперты MySQL предложили включить кеш запросов. Оказывается, если у вас высокая нагрузка записи, кеш на самом деле портит. Если бы вы его включили без тестирования, вы бы никогда не узнали.

И не забывайте, что масштабирование никогда не заканчивается. Сайт, который обрабатывает 10 запросов / с, потребует изменений для поддержки 1000 запросов / с. И если вам повезло, и вам нужно поддерживать 10 000 запросов / с, ваша архитектура, вероятно, также будет выглядеть совершенно иначе.

Базы данных

  • Не используйте MySQLi - PDO - это «современный» уровень доступа к базе данных объектно-ориентированного программирования. Самая важная функция, которую следует использовать, - это заполнители в ваших запросах. Достаточно умен, чтобы использовать подготовку на стороне сервера и другие оптимизации за вас.
  • Вероятно, вы не хотите сейчас разбивать свою базу данных. Если вы обнаружите, что одна база данных не режет, существует несколько способов масштабирования в зависимости от вашего приложения. Репликация на дополнительные серверы обычно работает хорошо, если у вас больше операций чтения, чем записи. Шардинг - это метод разделения ваших данных на множество машин.

Кеширование

  • Вероятно, вы не хотите кэшировать в своей базе данных. База данных обычно является вашим узким местом, поэтому добавление в нее дополнительных операций ввода-вывода обычно плохо. Есть несколько PHP-кешей, которые выполняют похожие вещи, например, БТР и Zend.
  • Измерьте свою систему с включением и отключением кеширования. Бьюсь об заклад, ваш кеш тяжелее, чем прямое обслуживание страниц.
  • Если создание ваших комментариев и данных статей из базы данных занимает много времени, интегрируйте кэш памяти в свою систему. Вы можете кэшировать результаты запроса и сохранять их в экземпляре memcached. Важно помнить, что получение данных из кэша памяти должно быть быстрее, чем их сборка из базы данных, чтобы получить какие-либо преимущества.
  • Если ваши статьи не являются динамическими или у вас есть простые динамические изменения после их создания, подумайте о том, чтобы записать html или php на диск. У вас может быть страница index.php, которая ищет на диске статью, если она там есть, она передает ее клиенту. Если это не так, он создает статью, записывает ее на диск и отправляет клиенту. Удаление файлов с диска приведет к перезаписи страниц. Если к статье добавлен комментарий, удалите кешированную копию - она ​​будет сгенерирована заново.

@ запись на диск. Вы даже можете отказаться от index.php и позволить Apache делать всю работу за вас, чтобы index.php вызывался только в том случае, если путь не существует. Для этого вы должны использовать mode_rewrite.

troelskn 29.09.2008 14:47

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

user42092 20.01.2009 04:50

-1, PDO значительно медленнее, чем MySQLi или даже расширение MySQL.

Alix Axel 10.09.2009 04:15

PDO был намного медленнее, чем mysqli, и для меня не работал с вложенными запросами. Mysqli также поддерживает параметры подготовки и привязки на стороне сервера, как и PDO.

Daren Schwenke 14.10.2009 07:23

Не могу поверить, что это было принято в качестве ответа. Это не очень хорошо.

symcbean 26.03.2010 19:05

about: caching - изображения, css, html и js помогут, отключите куки и на изображениях!

Talvi Watia 01.07.2010 03:53

@ Гэри

Don't use MySQLi -- PDO is the 'modern' OO database access layer. The most important feature to use is placeholders in your queries. It's smart enough to use server side prepares and other optimizations for you as well.

В данный момент я слежу за PDO, и похоже, что вы правы - однако я знаю, что MySQL разрабатывает расширение MySQLd для PHP - я думаю, что преуспеть в MySQL или MySQLi - что вы об этом думаете?


@ Райан, Эрик, tj9991

Спасибо за совет по расширениям кэширования PHP - не могли бы вы объяснить причины их использования? Я слышал много хорошего о memcached через IRC, но никогда не слышал об APC - что вы думаете о них? Я полагаю, что использование нескольких систем кэширования довольно контрэффективно.

Я обязательно разберусь с некоторыми тестировщиками профилирования - большое спасибо за ваши рекомендации по ним.

Конечно, pdo хорош, но имеетбылнемного спорят о его производительности по сравнению с mysql и mysqli, хотя сейчас это кажется исправленным.

Вам следует использовать pdo, если вы предполагаете переносимость, но если нет, то вам следует использовать mysqli. У него есть объектно-ориентированный интерфейс, подготовленные операторы и большая часть того, что предлагает pdo (кроме, ну, ну, переносимости).

Кроме того, если производительность действительно необходима, подготовьтесь к (родному для mysql) драйверу MysqLnd в PHP 5.3, который будет гораздо более тесно интегрирован с php, с лучшей производительностью и улучшенным использованием памяти (и статистикой для настройки производительности).

Memcache хорош, если у вас есть кластерные серверы (и нагрузка, подобная YouTube), но сначала я бы тоже попробовал БТР.

Похоже, Я был неправ. MySQLi все еще находится в разработке. Но, согласно статье, в PDO_MySQL теперь участвует команда MySQL. Из статьи:

The MySQL Improved Extension - mysqli - is the flagship. It supports all features of the MySQL Server including Charsets, Prepared Statements and Stored Procedures. The driver offers a hybrid API: you can use a procedural or object-oriented programming style based on your preference. mysqli comes with PHP 5 and up. Note that the End of life for PHP 4 is 2008-08-08.

The PHP Data Objects (PDO) are a database access abstraction layer. PDO allows you to use the same API calls for various databases. PDO does not offer any degree of SQL abstraction. PDO_MYSQL is a MySQL driver for PDO. PDO_MYSQL comes with PHP 5. As of PHP 5.3 MySQL developers actively contribute to it. The PDO benefit of a unified API comes at the price that MySQL specific features, for example multiple statements, are not fully supported through the unified API.

Please stop using the first MySQL driver for PHP ever published: ext/mysql. Since the introduction of the MySQL Improved Extension - mysqli - in 2004 with PHP 5 there is no reason to still use the oldest driver around. ext/mysql does not support Charsets, Prepared Statements and Stored Procedures. It is limited to the feature set of MySQL 4.0. Note that the Extended Support for MySQL 4.0 ends at 2008-12-31. Don't limit yourself to the feature set of such old software! Upgrade to mysqli, see also Converting_to_MySQLi. mysql is in maintenance only mode from our point of view.

Мне кажется, что статья тяготеет к MySQLi. Полагаю, я предвзято отношусь к PDO. Мне очень нравится PDO над MySQLi. Это прямо для меня. API намного ближе к другим языкам, на которых я программировал. Интерфейсы базы данных OO, кажется, работают лучше.

Я не встречал каких-либо конкретных функций MySQL, которые не были бы доступны через PDO. Я был бы удивлен, если бы когда-нибудь это сделал.

Re: PDO / MySQLi / MySQLND

@ Гэри

Вы не можете просто сказать «не используйте MySQLi», поскольку у них разные цели. PDO почти похож на уровень абстракции (хотя на самом деле это не так) и разработан, чтобы упростить использование нескольких продуктов баз данных, тогда как MySQLi специфичен для соединений MySQL. Неверно говорить, что PDO является современным уровнем доступа в контексте сравнения его с MySQLi, потому что ваше утверждение подразумевает, что прогресс был mysql -> mysqli -> PDO, что не так.

Выбор между MySQLi и PDO прост - если вам нужно поддерживать несколько продуктов баз данных, вы используете PDO. Если вы просто используете MySQL, вы можете выбирать между PDO и MySQLi.

Так почему бы вам выбрать MySQLi вместо PDO? Смотри ниже...

@ross

Вы правы насчет MySQLnd, новейшей библиотеки уровня ядра MySQL, однако она не заменяет MySQLi. MySQLi (как и PDO) остается тем способом, которым вы бы взаимодействовали с MySQL через свой PHP-код. Оба они используют libmysql в качестве клиента C, стоящего за кодом PHP. Проблема в том, что libmysql находится вне ядра PHP-движка, и именно здесь появляется mysqlnd, то есть это собственный драйвер, который использует внутренние внутренние компоненты PHP для максимальной эффективности, особенно когда речь идет об использовании памяти.

MySQLnd разрабатывается самим MySQL и недавно попал в ветку PHP 5.3, которая находится в стадии тестирования RC и готова к выпуску в конце этого года. После этого вы сможете использовать MySQLnd с MySQLi ... но не с PDO. Это даст MySQLi повышение производительности во многих областях (не во всех) и сделает его лучшим выбором для взаимодействия с MySQL, если вам не нужны такие абстракции, как возможности PDO.

Тем не менее, MySQLnd теперь доступен в PHP 5.3 для PDO, и поэтому вы можете получить преимущества повышения производительности от ND до PDO, однако PDO по-прежнему является общим уровнем базы данных, и поэтому будет вряд ли сможет извлечь из улучшений ND столько же, сколько MySQLi.

Некоторые полезные тесты можно найти здесь, хотя они с 2006 года. Вы также должны знать о таких вещах, как этот вариант.

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

Не так просто выбрать, что лучше, потому что у каждого из них есть свои преимущества и недостатки. Вам нужно прочитать ссылки, которые я предоставил, и принять собственное решение, затем протестировать его и выяснить. Я использовал PDO в прошлых проектах, и это хорошее расширение, но для чистой производительности я выбрал бы MySQLi с скомпилированной новой опцией MySQLND (когда будет выпущен PHP 5.3).

Я перешел с PDO на mysqli, и обычные запросы стали выполняться ровно в 2 раза быстрее.

serg 16.11.2008 22:50

@serg: не забудьте опубликовать несколько тестов, чтобы подтвердить это? Потому что я серьезно сомневаюсь, что простое переключение с PDO на mysqli даст вам такой прирост скорости.

Stann 12.03.2011 22:28

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

Thanks for the advice on PHP's caching extensions - could you explain reasons for using one over another? I've heard great things about memcached through IRC but have never heard of APC - what are your opinions on them? I assume using multiple caching systems is pretty counter-effective.

Собственно, многие используют APC и memcached вместе ...

PDO также очень медленный, а его API довольно сложен. Никто в здравом уме не должен использовать его, если переносимость не вызывает беспокойства. И давайте посмотрим правде в глаза, в 99% всех веб-приложений это не так. Вы просто придерживаетесь MySQL или PostrgreSQL или того, с чем вы работаете.

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

У меня есть веб-сайт с 7-8 миллионами просмотров страниц в месяц. Не очень много, но достаточно, чтобы наш сервер почувствовал нагрузку. Решение, которое мы выбрали, было простым: Memcache на уровне базы данных. Это решение хорошо работает, если ваша основная проблема - загрузка базы данных.

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

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

Теперь все, что вам нужно сделать, это решить, может ли запрос использовать кешированные (и, возможно, устаревшие) результаты или нет. Большинство запросов, выполняемых пользователями, теперь выбираются непосредственно из Memcache. Исключение составляют обновления и вставки, которые для основного веб-сайта происходят только из-за регистрации. Эта довольно простая мера снизила нагрузку на наш сервер примерно на 80%.

Как бы то ни было, кеширование в PHP ГРОМКО ПРОСТО, даже без дополнительных / вспомогательных пакетов, таких как memcached.

Все, что вам нужно сделать, это создать выходной буфер с помощью ob_start().

Создайте функцию глобального кеширования. Вызовите ob_start, передайте функцию как обратный вызов. В функции найдите кешированную версию страницы. Если существует, служите ему и закончите.

Если его нет, скрипт продолжит обработку. Когда он достигнет соответствующей ob_end (), он вызовет указанную вами функцию. В это время вы просто получаете содержимое буфера вывода, помещаете его в файл, сохраняете файл и завершаете работу.

Добавьте некоторое истечение срока действия / сборку мусора.

И многие люди не понимают, что вы можете вкладывать вызовы ob_start() / ob_end(). Поэтому, если вы уже используете выходной буфер, например, для синтаксического анализа рекламы или выделения синтаксиса или чего-то еще, вы можете просто вложить еще один вызов ob_start/ob_end.

+1 потому что это похоже на интересную идею. Я не знаю, насколько хорошо это работает с точки зрения производительности

Sylverdrag 22.04.2009 16:06

+1 потому что это интересная идея. Эти обратные вызовы могут вызвать для меня мой класс кеширования!

Xeoncross 06.12.2009 23:24

Посмотрите на mod_cache, кэш вывода для веб-сервера Apache, аналогичный кэшированию вывода в ASP.NET.

Да, я вижу, что это все еще эксперимент, но когда-нибудь он станет финальным.

Общий

  • Не пытайтесь оптимизировать, пока не увидите реальную нагрузку. Вы могли догадаться, но если нет, вы зря потратили время.
  • Используйте jmeter, xdebug или другой инструмент для тестирования сайта.
  • Если загрузка начинает вызывать проблемы, вероятно, будет задействовано кэширование объекта или данных, поэтому обычно читайте о параметрах кэширования (memcached, параметры кеширования MySQL)

Код

  • Профилируйте свой код, чтобы знать, где находится узкое место, и в коде ли оно или в базе данных.

Базы данных

  • Используйте MYSQLi, если переносимость на другие базы данных не важна, в противном случае - PDO
  • Если тесты показывают, что проблема в базе данных, проверьте запросы, прежде чем начинать кэширование. Используйте ОБЪЯСНЯТЬ, чтобы увидеть, где ваши запросы замедляются.
  • После того, как запросы оптимизированы и база данных каким-либо образом кэширована, вы можете захотеть использовать несколько баз данных. Либо репликация на несколько серверов, либо сегментирование (разделение данных на несколько баз данных / серверов) может быть подходящим, в зависимости от данных, запросов и типа поведения чтения / записи.

Кеширование

  • Много написано о кэшировании кода, объектов и данных. Найдите статьи на БТР, Zend Optimizer, memcached, QuickCache, JPCache. Сделайте что-то из этого до того, как вам действительно понадобится, и вы будете меньше беспокоиться о том, чтобы начать неоптимизированный.
  • APC и Zend Optimizer - это кеши кодов операций, они ускоряют код PHP, избегая повторного анализа и перекомпиляции кода. Обычно установка проста, стоит заняться на ранней стадии.
  • Memcached - это общий кеш, который вы можете использовать для кеширования запросов, функций или объектов PHP или целых страниц. Код должен быть специально написан для его использования, что может быть сложным процессом, если нет центральных точек для обработки создания, обновления и удаления кэшированных объектов.
  • QuickCache и JPCache - это кеши файлов, в остальном похожие на Memcached. Основная концепция проста, но также требует кода и проще с центральными точками создания, обновления и удаления.

Разное

  • Рассмотрите альтернативные веб-серверы для высокой нагрузки. Такие серверы, как свет и nginx, могут обрабатывать большие объемы трафика при гораздо меньшем объеме памяти, чем Apache, если вы можете пожертвовать мощностью и гибкостью Apache (или если вам просто не нужны эти вещи, которые часто вам не нужны).
  • Помните, что в наши дни оборудование на удивление дешево, поэтому не забудьте потратить усилия на оптимизацию большого блока кода, а не на «давайте купим сервер-монстр».
  • Подумайте о добавлении тегов "MySQL" и "масштабирование" к этому вопросу.

Я не могу поверить, что никто уже не упомянул об этом: Модуляризация и Абстракция. Если вы думаете, что ваш сайт должен вырасти до большого количества машин, вы должен спроектируете его так, чтобы он мог! Это означает глупые вещи, например, не предполагать, что база данных находится на локальном хосте. Это также означает вещи, которые поначалу будут неудобными, например, написание уровня абстракции базы данных (например, PDO, но намного легче, потому что он делает только то, что вам нужно).

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

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

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

Кроме того, если вам может потребоваться балансировка нагрузки на сервер базы данных в будущем, Прокси MySQL вполне может помочь вам в этом.

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

Я ведущий разработчик на сайте с более чем 15 миллионами пользователей. У нас было очень мало проблем с масштабированием, потому что мы планировали это РАНО и тщательно масштабировали. Вот несколько стратегий, которые я могу предложить на основе своего опыта.

СХЕМА Во-первых, денормализуйте свои схемы. Это означает, что вместо того, чтобы иметь несколько реляционных таблиц, вы должны вместо этого выбрать одну большую таблицу. В общем, объединения - это пустая трата драгоценных ресурсов БД, потому что выполнение нескольких операций подготовки и сортировки сжигает дисковые операции ввода-вывода. По возможности избегайте их.

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

ИНДЕКСИРОВАНИЕ Убедитесь, что в ваших запросах используется хотя бы один индекс. Однако помните, что индексы будут стоить вам денег, если вы будете часто писать или обновлять. Чтобы избежать этого, есть несколько экспериментальных приемов.

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

Избегайте вычислительных запросов, как чумы. Если вам необходимо вычислить запрос, попробуйте сделать это один раз во время записи.

Кеширование Я очень рекомендую Memcached. Это было доказано крупнейшими игроками в стеке PHP (Facebook) и очень гибкое. Для этого есть два метода: один - кэширование на уровне БД, а другой - на уровне бизнес-логики.

Вариант уровня БД потребует кэширования результатов запросов, полученных из БД. Вы можете хэшировать свой SQL-запрос с помощью md5 () и использовать его в качестве ключа поиска перед переходом в базу данных. Плюс в том, что это довольно легко реализовать. Обратной стороной (в зависимости от реализации) является то, что вы теряете гибкость, потому что вы относитесь ко всему кешированию одинаково в отношении истечения срока действия кеша.

В магазине, в котором я работаю, мы используем кеширование бизнес-уровня, что означает, что каждый конкретный класс в нашей системе управляет своей собственной схемой кеширования и тайм-аутами кеширования. Это сработало для нас очень хорошо, но имейте в виду, что элементы, полученные из БД, могут не совпадать с элементами из кеша, поэтому вам придется обновлять кеш и БД вместе.

РАЗДЕЛЕНИЕ ДАННЫХ Репликация только у вас. Раньше, чем вы ожидаете, ваши записи станут узким местом. Чтобы компенсировать это, убедитесь, что поддержка сегментирования данных поддерживается как можно раньше. Если вы этого не сделаете, вы, скорее всего, захотите застрелиться позже.

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

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

ОФФЛАЙН ОБРАБОТКА Не заставляйте пользователя ждать вашего бэкэнда, если ему это не нужно. Создайте очередь заданий и перенесите любую обработку, которую вы можете в автономный режим, выполняя отдельно от запроса пользователя.

+1 Несомненно, это должен быть принятый ответ. Интересно, что все, что я когда-либо читал о создании баз данных, всегда гласит: «Максимально нормализируйте все данные», не говоря уже о снижении производительности при объединении. Я всегда интуитивно чувствовал, что объединения (особенно множественные) добавляли много накладных расходов, но до сих пор не слышал, чтобы кто-то сказал об этом явно. Хотел бы я лучше понять, о чем вы говорите, когда MySQL вычисляет индексы, это звучит как очень интересный прием.

Evan Plaice 14.02.2011 15:10

Разделение данных необходимо для слишком больших баз данных. Google (компания, а не поисковая система) может сказать много интересного о реализации схем шардинга. Автономная обработка также имеет огромное значение, когда дело доходит до ограничения количества операций записи в базу данных (и ограничения количества повторных вычислений индексов таблицы). Я видел множество блогов (и я думаю, что даже Stack Overflow) использовали эту технику для своих пользовательских систем комментариев / отзывов.

Evan Plaice 14.02.2011 15:16

Спасибо за комментарии. Удивительно, что некоторые выступают за профилирование кода среднего уровня, когда время выполнения VAST тратится либо на ввод-вывод данных, либо на ввод-вывод клиент-сервер. Убер-сложная оптимизация, экономящая 20% времени выполнения процесса PHP, который занимает 40 мс, бессмысленна по сравнению с простой 5% -ной экономией на запросе к базе данных за 1 секунду.

thesmart 17.02.2011 02:01

Если вы работаете с большими объемами данных и кеширование их не сокращает, обратите внимание на Sphinx. У нас были отличные результаты с использованием SphinxSearch не только для лучшего поиска текста, но и в качестве замены поиска данных для MySQL при работе с большими таблицами. Если вы используете SphinxSE (плагин MySQL), он в несколько раз превзошел наш прирост производительности, который мы получили от кеширования, а реализация приложения - это грешник.

Точка зрения, касающаяся кеша, точна; это наименее сложная и самая важная часть создания эффективного приложения. Я хотел бы добавить, что, хотя memcached великолепен, APC примерно в пять раз быстрее, если ваше приложение находится на одном сервере.

В сообщении «Сравнение производительности кэша» в блоге о производительности MySQL есть несколько интересных тестов на эту тему - http://www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/.

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

Производительность не имеет значения, если сайт недоступен. А для доступности нужно горизонтальное масштабирование. Минимум, который вам может разумно сойти с рук, - это 2 сервера, на которых работают apache, php и mysql. Настройте одну СУБД как подчиненную по отношению к другой. Выполняйте все записи на главном сервере и все чтения в локальной базе данных (что бы это ни было) - если по какой-то причине вам не нужно считывать данные, которые вы только что прочитали (используйте мастер). Убедитесь, что у вас есть оборудование для автоматического продвижения раба и ограждения хозяина. Используйте циклический DNS для адресов веб-серверов, чтобы обеспечить большее соответствие подчиненному узлу.

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

Убедитесь, что у вас есть инструменты мониторинга и анализа данных для измерения производительности ваших сайтов и выявления узких мест. Большинство проблем с производительностью можно исправить, написав лучший SQL / исправив схему базы данных.

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

Используйте кеш-код операции.

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

Нажимайте на клиента как можно больше кэширования.

Используйте mod_gzip, чтобы сжать все, что вы можете.

С.

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

В общем, Просто быстро. Шаблоны замедляют работу. Базы данных замедляют вас. Сложные библиотеки замедляют работу. Накладывая шаблоны друг на друга, извлекая их из баз данных и анализируя их в сложной библиотеке -> временные задержки умножаются друг на друга.

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

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

Другие вопросы по теме