В один прекрасный день ваш сайт стал «тормозить», хотя раньше буквально «летал». Казалось бы — виноват «хостер». В большинстве случаев это не так. Наиболее вероятно, что ваш проект переживает проблемы роста, через которые суждено пройти всем.
Разработчики сайтов, как и все люди, не склонны учиться на чужих ошибках. Результат — большинство сайтов вынуждены переживать проблемы роста. Как показывает практика, проблемы у всех одинаковы и даже опытные разработчики не могут их избежать.
Вместе с владельцами и разработчиками сайтов их проблемы переживает и «хостер». За долгие годы работы специалисты хостинговой компании «Экстмедиа» накопили большой опыт по решению подобных проблем. Мы постарались выделить наиболее характерные.
Многие удивляются — почему так получается, что в самом начале проекта сайт работал быстро, а через полгода-год стал отдавать страницы ощутимо медленнее? Почему так получается, что сайт работающий в реальных условиях на сервере в Интернет работает медленнее, чем на локальном компьютере разработчика или тестовом сервере?Причин подобного поведения сайтов может быть много, но наиболее характерные из них связаны именно с ростом проекта. В таких случаях сайты обычно начинают работать с каждым днем все медленнее и медленнее из-за накопления больших объемов информации в базах данных либо из-за роста числа посетителей сайта.
Когда разработчики создают и тестируют программное обеспечение для сайтов на своем компьютере или тестовом сервере то, очень часто они не отдают себе отчета в том, что сайт является системой предназначенной для одновременного доступа многих пользователей, а также не представляют себе каким объемом данных придется оперировать в будущем либо не понимают, что два разных запроса в базу данных имеющих одно и то же назначение могут требовать разных ресурсов.
Серверы баз данных (MySQL), веб-серверы (Apache) и серверы приложений (Tomcat), даже сами языки программирования (PHP, Java, Perl), которыми пользуются разработчики для создания своих проектов, устроены таким образом, что для обеспечения стабильной и быстрой работы с определенным объемом данных и определенным числом одновременно обращающихся пользователей требуются определенные аппаратные ресурсы, а чтобы ресурсов использовалось меньше приходится прибегать к специальным техникам, о которых начинающие разработчики вообще не имеют понятия (IPC, разделяемая память). Чем больше объем данных и чем большему числу пользователей необходимо обращаться к ним одновременно — тем больше требуется ресурсов.
Рост объемов информации в базах данных и аудитории сайта требует для нормальной и быстрой работы сайта все больше и больше вычислительных ресурсов и, когда их становится недостаточно, сайт начинает «тормозить». На компьютере разработчика или на тестовом сервере, куда обычно обращается не более одного пользователя одновременно, наиболее вероятно сайт будет работать достаточно быстро, что усложняет понимание проблем.
Решение подобных проблем, как водится, лежит на поверхности. Наращивание мощности серверов и аппаратной базы, вне всяких сомнений, помогает… но, часто, как показывает практика, весьма ненадолго, потому что в абсолютном большинстве случаев является лечением внешних симптомов, но не настоящих причин самой проблемы.
Медленная работа сайта часто является прямым следствием ошибок в архитектуре программного обеспечения сайта либо, что также случается достаточно часто, банальных ошибок, которые были допущены по невнимательности.
С самого начала проекта, когда его скромной аудиторией кроме имеющих непосредственное отношение к проекту являются только поисковые сервера, до того времени, когда сайт вырастает в большой информационный ресурс и его суточная аудитория составляет ощутимую долю от всех пользователей Интернет в стране, сайт проходит несколько этапов технической эволюции.
Этапы технической эволюции сайта прежде всего связаны с хостингом и аппаратной базой, которая обеспечивает его работу.
Часто сайты начинают свой рост с виртуального хостинга, когда ресурсы одного сервера или системы серверов используются совместно многими сайтами. Затем переходят на виртуальный сервер (VPS), где ресурсы одного сервера также используются несколькими подобными виртуальными серверами, но при этом каждому гарантируется определенный объем ресурсов. После переходят на выделенный физический сервер, где все ресурсы сервера используются только одним проектом.
VPS, кстати, в основном используется из соображений безопасности, а не из соображений быстродействия. Так может получиться, что сайт работал на виртуальном хостинге быстрее, потому что использовал большую долю ресурсов мощного сервера «хостера», а на VPS за счет ограничений сайт работает либо медленнее либо с перебоями. Поэтому этап эволюции сайта связанный с VPS при присутствии проблем роста обычно является кратковременным решением перед переходом к выделенному серверу.
Дальнейшие этапы эволюции сайта предусматривают системы уменьшения и распределения нагрузки различного уровня и стоимости, которые включают в себя множество выделенных физических серверов, а, возможно, и специальное оборудование для создания кластеров.
Не так важно с какого именно технического этапа начинает ваш сайт. Главное, что при появлении проблем роста вы встаете перед выбором — перейти на следующий технический уровень увеличив затраты на аппаратную базу, которые могут оказаться для вас неожиданными и весьма существенными, или все же приложить усилия на поиск и утранение узких мест в программном обеспечении сайта, ошибок допущенных в архитектуре или по невнимательности.
На каждом последующем этапе технической эволюции для владельцев проекта возрастают затраты хостинг и на все, что к нему относится — оборудование, каналы, электричество, поддержку. В следствие этого многие владельцы сайтов долго не понимают зачем им что-то менять, когда всего несколько месяцев назад все работало быстро. При этом речь о переходе на более затратный вид хостинга речь не идет. Разбираться в собственном программном обеспечении зачастую для них также сложная задача, потому что разработчик сайта может потребовать за это также немалых денег либо просто за полгода-год может скрыться с обозримого горизонта. В самых запущенных случаях клиент меняет хостинг, где его сайт поначалу даже может работать немного быстрее, но потом история повторяется вплоть до момента осознания необходимости действий, которые нужно предпринять самому владельцу сайта.
На практике, какой бы путь развития вы ни выбрали, если были допущены ошибки, то наращивание аппаратной базы обычно помогает на весьма короткий срок. Поэтому, все равно, рано или поздно придется заниматься улучшением программного обеспечения сайта и его архитектуры, если этого не было сделано изначально. Если ошибки были допущены по невнимательности, то позже будет много обиднее осознавать, что пришлось увеличить затраты, когда можно было этого избежать.
Конкретные проблемы, которые решаются на уровне программного обеспечения можно разделить по мерам, которые необходимо предпринять для их успешного разрешения.
Прежде всего, подобные проблемы можно разделить на такие, которые легко устраняются только за счет правильной настройки серверного программного обеспечения или оптимизации баз данных, или, другими словами, такие, которые обычно можно решить без внесения изменений в код сайта, и те, что для своего разрешения требуют модификации программного обеспечения сайта.
Проблемы правильной настройки серверного программного обеспечения мы опустим, потому что большинство хостинг провайдеров, которые работают на рынке давно и работают не только с сайтами уровня домашних страниц, но и с серьезными клиентами, настраивают серверы правильно с учетом того, чтобы обеспечить максимальную эффективность использования ресурсов сервера. Неоптимально сервер обычно настраивают только неопытные администраторы. У опытных администраторов оптимальные настройки выработаны многолетней практикой.
Наиболее частые проблемы, от которых страдает большинство сайтов — проблемы с базами данных, которые возникают по мере роста объемов хранимой информации.
Одной из самых распространненых проблем с базами данных является отсутствие правильного индексирования в таблицах. К счастью, эта наиболее частая проблема достаточно легко устраняется и не требует изменения в программном обеспечении.
Индексы — основное преимущество баз данных, которое облегчает и ускоряет поиск записей в таблицах. Данные в базах данных обычно хранятся на жестких дисках, которые являются достаточно медленными устройствами. При запросе в базу сервер читает данные одной или нескольких записей с жесткого диска в оперативную память. Без индексов поиск записей на диске возможен только с помощью перебора всех записей, особенно, при сложных запросах с использованием сортировки. Индексы, которые указывают положение определенных записей на диске, загружаются целиком или полностью в оперативную память, которая является устройством намного более быстрым, чем жесткие диски.
Что происходит на сервере, когда индексов в таблицах нет либо они построены неправильно? В таких случаях сервер баз данных вынужден для выполнения запроса перебирать на диске все записи в таблице. Когда в таблице записей не так много, то запросы без использования индексов не оказывают существенного влияния на производительность. Когда же число записей в базе возрастает уже до нескольких тысяч, а сам запрос выполняется достаточно часто и во многих потоках одновременно для многих пользователей, то это уже оказывает существенное влияние на производительность за счет перегрузок приходящихся на дисковую подсистему.
Большинство операционных систем вообще не предусматривают распараллеливания работы с диском, а более современные операционные системы обычно позволяют запускать не более одного-двух потоков одновременной работы с диском на каждый системный процессор. Именно из-за этого проблемные запросы в базы данных, которые не используют индексы, являются бичом для многих разработчиков сайтов.
Проблема с индексами в базах данных может возникнуть не только у начинающих разработчиков, но и опытных. Во время разработки многие таблицы создаются в спешке, а индексы для них строятся в процессе разработки на основе запросов, которые становятся известны только потом. Большая часть таблиц создаваемых большинством разработчиков имеет только один индекс — уникальный ключ по идентификатору записи. При переносе проекта с тестовой площадки на рабочий сервер о создании дополнительных индексов, как это часто бывает, забывают.
Например, этим летом у одного из наших клиентов — белорусского информационного портала с посещаемостью в районе 10.000 уникальных посетилей в сутки стал «тормозить» сайт, который размещается на выделенном сервере. По его просьбе увеличили память, но это помогло ненадолго и вскоре «тормоза» начались вновь. Клиент далеко не сразу понял, что проблема именно в его программном обеспечении, потому что «раньше все работало быстро».
Клиент обратился к нам за помошью и в результате того, что мы помогли ему составить правильные индексы показатель средней загрузки сервера снизился с 60 до уровня менее 1, а суммарное использование процессора его выделенного сервера в дневном пике теперь не превышает 20%.
Бывали в нашей практике и такие случаи, что по прошествии некоторого времени, например, через год или два, владелец сайта теряет контакт с разработчиками и остается с «тормозящим» сайтом один на один. В таких случаях, если проблемы не требуют изменений в коде сайта, хостер может помочь.
Случаи же, когда в архитектуре баз данных действительно делаются явные ошибки и требуется вмешательство в код, на сегодня редки. К счастью, существует достаточное количество документации, где подробно рассказано, как построить оптимальную базу данных.
К таким случаям относятся, например, действительно плохая архитектура баз данных когда использование основного преимущества индексов является невозможным (использование элементов, которые не могут быть проиндексированы), либо использование запросов которые в силу специфики баз данных и языков программирования засоряют оперативную память ненужной информацией (запросы вида “select * from table;” или хранение адресов IP в виде текста, а не в виде числа).
К слову очень многие программисты ленятся использовать SQL-запросы, которые выбирали бы только действительно необходимые данные. Написать запрос вида “select * from table;” — быстрее, чем выбирать нужные поля для каждого конкретного случая. Это приводит к тому, что при использовании таких запросов скрипты пользователя используют больше памяти и фактически в пустую.
В особенности это плохо для языков программирования, в которых не очень внимательная работа с переменными приводит к тому, что эта память не освобождается, а в памяти сервера накапливается мусор, что увеличивает размер оперативной памяти необходимой для обслуживания каждого пользователя. Например, в связке Apache+mod_php+PHP размер одного процесса за счет накапливаемого мусора достигает в среднем 15-20 мегабайт. В некоторых тяжелых случах каждый процесс занимает под 100 мегабайт.
Таким образом, зная, что для обслуживания одного клиента необходимо два одновременных соединения и два процесса Apache, мы получаем что для каждого пользователя нам нужно в среднем 30-40 мегабайт оперативной памяти. Сколько при этом клиентов одновременно сможет выдержать сервер с 1 гигабайтом памяти легко подсчитать.
К сожалению, далеко не все проблемы решаются с помошью правильной настройки сервера и оптимизации баз данных. Когда посещаемость сайта действительно растет — необходимо все больше и больше ресурсов. При этом улучшение и модификация кода — неизбежны.
Даже в случае, когда архитектура идеальна и софт способен обслуживать много пользователей. Часто оказывается, что программное обеспечение написано для архитектуры состоящей фактически из одного сервера. В таких случаях, в качестве скорой помощи, в зависимости от архитектуры программного обеспечения можно применить различные меры, которые связаны с созданием систем уменьшения и распределения нагрузки, что не приводит к необходимости вносить изменения код.
Дешевые системы уменьшения и распределения нагрузки, которые позволяют сайту созданному для работы на одном сервере принимать одновременно больше посетителей, могут быть установлены либо на тот же сервер либо на один или несколько обычных серверов.
Обычно в таких случаях дешевым решением являются специальные веб-серверы либо кэширующие «обратные» прокси-серверы (nginx, squid и т.п.), которые работают в режиме акселерации. Как показывает практика, подобные системы могут снизить нагрузку на основной сервер в 3-10 раз, но не более. Степень снижения нагрузки зависит от каждого конкретного сайта.
При этом имеет смысл использования не более нескольких кэширующих серверов с распределением нагрузки между ними в дешевом варианте через систему DNS в немногим более дорогом через аппаратные системы распределения нагрузки.
Основное преимущество таких систем — низкая стоимость решения, оплачиваются только дополнительные серверы. Система из двух-трех серверов будет стоить всего два-три раза дороже.
Когда уже и этих мер оказывается недостаточно, то мы снова стоим перед выбором. Единственным выходом доступным без изменения программного обеспечения сайта остается создание кластера.
Недостатком кластерных систем является относительно большая стоимость специального оборудования, которая на порядок или даже два превышает стоимость обычных серверов.
Так если нужен кластер на 2 узла, который выполняет задачи не только распределения нагрузки между узлами, но и обеспечивает полную постоянную доступность, обойдется в сумму в районе 50.000 долларов, а из 20 узлов — 120.000 долларов.
Кластеры же, которые строятся без специального оборудования малоэффективны, могут работать медленнее и имеют пределы масштабирования за счет узких мест в основном связанных с передачей данных от общего файлового хранилища, которое является непременным атрибутом кластерной системы.
Специальное оборудование для кластерных систем дает существенное ускорение в производительности общего файлового хранилища за счет использования множественных оптических каналов передачи данных, которые на порядок быстрее даже гигабитного ethernet. Так передача данных по обычной сети Ethernet ограничена скоростью 1 гигабит/c, а передача данных по оптическому волокну Fibre Channel превышает эту скорость в несколько раз.
Другим выходом является все же изменение программного обеспечения сайта с целью его большей масштабируемости. По такому пути, например, рассчитывая на маштабируемость и параллельную архитектуру, пошла компания Google.
В заключение хочется отметить, что, если с нагрузкой вашего сайта при посещаемости около 50.000-100.000 уникальных посетителей в сутки, не справляется один достаточно маломощный сервер, то вам стоит уделить время на его оптимизацию. На нашей практике древний, однопроцессорный сервер уровня Pentium III еще в 1998-1999 годах выдерживал нагрузку в 150.000 уникальных посетителей в сутки без особого напряжения.
Самые лучшие системы сайтов, которые сегодня выдерживают без напряжения огромные количества посетителей используют старый, добрый метод кэширования данных, которые изменяются достаточно редко. Например, CMS на сайте, где содержимое страниц меняют раз в месяц (пусть даже раз в сутки), вполне может генерировать статические страницы на жестком диске, потому что нет смысла каждую минуту динамически обращаться в базу данных за тем, что не изменяется годами.
Павел Новиков, директор сектора разработки ПО, хостинг-компания «Экстмедиа».
Жаль что их не было на di.by — в программе были я надеялся что они расскажут чего натестировали. а так провели круглый стол, а людям показать?