Компания
46,12
рейтинг
22 октября 2013 в 17:47

Разное → Как сделать CDN для своего сайта и почему это полезно для высоконагруженных проектов

Главная задача отдела эксплуатации Sports.ru и Tribuna.com — масштабирование сетевой инфраструктуры в условиях постоянного роста трафика (за 1,5 года трафик и кол-во запросов в секунду выросло в два раза), регулярных пиковых нагрузок и аудитории, распределенной по разным странам. Для решения этой задачи мы используем разные технологии; одна из них — создание собственной CDN (сети доставки контента), которая позволяет сократить нагрузку, усилить защиту от DDoS-a и ускоряет загрузку сайта в удаленных регионах. Мы решили поделиться своим опытом в этой области и составили краткое практическое руководство для системных администраторов по разворачиванию и эксплуатации своей CDN.


I. Теория.


1. Терминология.

Сеть доставки (и дистрибуции) контента (англ. Content Delivery Network или Content Distribution Network, CDN) — географически распределённая сетевая инфраструктура, позволяющая оптимизировать доставку и дистрибуцию контента конечным пользователям в сети Интернет. Использование контент-провайдерами CDN способствует увеличению скорости загрузки интернет-пользователями аудио-, видео-, программного, игрового и других видов цифрового контента в точках присутствия сети CDN.

Так говорит нам всезнающая wikipedia. Но как же устроена эта CDN? Давайте сразу определимся со склонениями. CDN — это бла-бла-бла сеть. Сеть — женского рода, соответственно склоняем аббревиатуру в женском роде.

С точки зрения как это работает, можно написать следующую формулу:

CDN=anycast+proxy.

О anycast можно прочитать здесь ru.wikipedia.org/wiki/Anycast, если кому-то нужно вспомнить что такое Proxy-server, пробелы в знаниях можно восполнить тут: ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D0%BA%D1%81%D0%B8-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80

Фактически это технология сводится к анонсированию сетевого адреса, в который резолвится сайт, помещенный в CDN, из этих “географически распределённых мест” и проксированию запросов к условному одному серверу.

Какой профит из этого можно получить?
Размещая данные ближе к клиенту, вы получаете меньшую задержку в ответе для пользователя, сокращаете нагрузку на свой сервер, защита от DDoS… бла-бла-бла — читаем описание любой коммерческой CDN-сети.

Кажется сложным и непонятным? На самом деле это проще чем кажется, ниже всё будет описано более подробно.

2. Почему свой CDN, а не консалтинг.

Возникает вопрос, а для чего же делать свою CDN? Много прекрасных CDN-сетей, используй.
Во-первых, это не наш метод ;)
Во-вторых, эти сети уже построены, и не факт, что они подходят вам по распределенности на все сто. В случае своей CDN мы вольны где угодно размещать её узлы.
В-третьих, мы вкладываем деньги в свою инфраструктуру, а не в чужую.
В-четвёртных, настроить свою CDN мы можем как угодно. Кешировать можно не только статические данные, но и динамические, например, данные для аннонимусов или общие данные. Такой гибкости нам ни одна коммерческая сеть в полном объёме не даст.

3. Профит от использования.

Итак, что же конкретно можно получить от своей CDN-сети:

Скорость загрузки/сокращение трафика.
Размещая данные ближе к пользователю можно рассчитывать на то, что эти данные он быстрее получит. Логично. Что с сокращением трафика? Кеширование данных на узлах, позволяет сократить число обращений к “главному серверу”. Плюс, мы можем всегда передавать сжатые данные от главного сервера к узлу CDN, в keepalive-соединениях. Можно настроить узел CDN так, чтобы конкурирующий запросы, которые мы кешируем, не выполнялись параллельно. Это тоже позволяет экономить трафик и процессорное время на “главном сервере”. В случае sports.ru это всё в сумме позволяет сократить число запросов и трафик в 3,5 раза к “главному серверу”.
Так же узел CDN является прекрасным местом для размещения DNS-slave сервера. Собственно, по тем же причинам.

II. Практика.


4. Необходимые условия.

Для того, чтобы сделать свой сервер CDN нам понадобится сам сервер, своя AS ru.wikipedia.org/wiki/%D0%90%D0%B2%D1%82%D0%BE%D0%BD%D0%BE%D0%BC%D0%BD%D0%B0%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_(%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BD%D0%B5%D1%82) и свободный ip-routenum, в котором мы и будем размещать свой CDN. Свободных IPv4 — сетей уже практически не осталось, но никто не мешает использовать эту статью для IPv6 истории :)

Нужно ещё будет как-то проксировать и сохранять ответы приходящих запросов.
Отказоустойчивость будем решать тем фактом, что Proxy и Anycast будем собирать на одном сервере. Если по каким-то причинам он отключится, это никак не повлияет на всю CDN в целом. Естественно, таких серверов должно быть как можно больше ;)

5. How To.

Для реализации всего задуманного потребуется потребуется сервер с несколькими физическими ядрами для распределение нагрузки сетевой карты на каждое ядро. Достаточное количество оперативной памяти для помещения всего кеша в рамдиск. Мы же не хотим нагружать диски на сервере за тридевять земель? ;) Сетевая карта с поддержкой распределения нагрузки на разные ядра процессора, для того чтобы иметь большую пакетную производительность. И RAID1 на SATA дисках для пущей надёжности.

А ещё это дело надо правильно настроить, чтобы заставить работать в полною силу. Тюнингу под большие веб-нагрузки и выжиманию всех соков из железа хорошо подходит FreeBSD 9.x. Можно использовать и Linux, но в плане прозрачноcти и простоты настройки, единого типа конфигов в моём личном рейтинге выигрывает FreeBSD.
Чтобы не повторятся приведу примеры дельных рекомендаций по настройки FreeBSD под аналогичный тип нагрузки:

dadv.livejournal.com/139170.html
serverfault.com/questions/64356/freebsd-performance-tuning-sysctls-loader-conf-kernel

или погууглить на соответствующую тему.

Анонсируемую сеть или часть этой сети я предлагаю разместить на интерфейсе локальной петли:

добавляем строчки в /etc/rc.conf:
ifconfig_lo0_alias0=«inet <ip-адрес CDN1>/32»
ifconfig_lo0_alias1=«inet <ip-адрес CDN2>/32»


и, конечно, не забыть включить маршрутизацию:

добавляем строчки в /etc/sysctl.conf:
net.inet.ip.forwarding=1


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

добавляем строчки в /boot/loader.conf:
tmpfs_load=«YES»


и /etc/fstab:
tmpfs /mnt/tmpfs tmpfs rw,mode=777 0 0


Анонсировать сеть CDN будем через OpenBGP:
www.freshports.org/net/openbgpd

Он обладает всем необходимым функционалом и просто настраивается. Скупая информация о нём в интернете нивелируется подробным Man-ом. Так же он может интегрироваться с пакетным фильтром PF, если нам захочется использовать его. Вот простой конфиг, который будет делать всё, что необходимо:

/usr/local/etc/bgpd.conf:
AS <номер нашей AS>
router-id <router-id>
network <анонсируемая сеть>
group «Uplink» {
neighbor <адрес провайдера> {
remote-as <AS провайдера>
descr «Uplink»
announce self
}
}
deny from any
deny to any
allow from <адрес провайдера>
allow to <адрес провайдера> prefix <анонсируемая сеть>


Перейдём к настройке Nginx. Фактически нам необходимо настроить на Nginx кешируюший статику proxy-сервер c агрегацией и сжатием остальных запросов и кеширумых данных.

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

nginx.conf:
worker_processes auto;
http {
include mime.types;
proxy_temp_path /mnt/tmpfs/tmp;
proxy_cache_path /mnt/tmpfs/cache/site_cache levels=1:2 keys_zone=site:128m max_size=<размер кеша> inactive=<время, которое хранятся данные а кеше>;
gzip on;
gzip_disable «msie6»;
gzip_comp_level 4;
gzip_types text/plain text/html application/xml application/x-javascript text/javascript text/css application/json text/xml application/rss+xml;
gunzip on;
server {
listen 80 default;
server_name localhost;
location / {
proxy_cache_use_stale updating timeout http_500 http_502 http_504;
proxy_cache site;
proxy_cache_key $uri$is_args$args;
proxy_pass frontend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
}
location ~* \.(3gp|7z|avi|bmp|css|doc|docx|gif|gz|jpg|jpeg|js|mov|mp3|mp4|ogg|png|ppt|pptx|rar|tar|tiff|torrent|ttf|svg|swf|wma|xls|xlsx|xsl|xslt|zip)$ {
proxy_cache_use_stale timeout updating http_500 http_502 http_504;
proxy_cache site;
proxy_cache_key $uri$is_args$args;
proxy_cache_valid <время на которое кешируем статику>;
proxy_pass frontend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
}
}
upstream frontend {
server <адрес фронтенда>;
}


Если по каким-то причинам не нужно кешировать динамические запросы на сайте, выключаем кеширование в секции location /. Раскешировать статические данные можно, изменив в них GET-парамметр, например, указывая номер ревизии.

Bind.
Тут всё просто, устанавливаем и добавляем строчки в named.conf:

zone «site.ru» {
type slave;
file "/etc/namedb/slave/site.ru";
masters {
<ip-адрес днс-мастер-сервера>;
};
};


Не забываем разрешить скачивание всей DNS-зоны c мастер-сервера.

That’s all! CDN-сервер настроен. Немного будет переделок, если захочется CDN-нить ещё несколько сайтов ;)
Автор: @forwardfly
Sports.ru
рейтинг 46,12

Комментарии (26)

  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      В этом нет необходимости: при помощи bgp мы и так получаем ближайший cdn и, соответственно, dns сервер. Плюс bgp, в отличии от Geo-IP, в случае каких-любо изменений в сети перенастроит всё самостоятельно.
      • +1
        А как насчет того, что при anycast балансировке вы имеете погрешность на определение конечного пользователя из-за того, что он использует «далекий» резолвер?
        • 0
          Для наших текущих рынков (Россия и Украина) такая ситуация на практике крайне маловероятна. Возможно, в дальнейшем что-то придётся придумывать дополнительно.
          • +1
            Тогда к чему для такого маленького разброса сегмента делать CDN?!
            • +1
              1. Уменьшение времени отклика.
              2. Сокращение нагрузки за счёт ещё одного уровня во всей системе (вертикальное масштабирование).
              2. Защита от DDoS.
              3. Обкатывание технологий. Есть планы по развитию :)
        • 0
          Вы имеете в виду случай, если пользователь прописал у себя, например, гугловский днс?
          Тогда как раз схема с GeoIP будет страдать — т.к. она всех будет считать находящимся совсем в других местах и будет предлагать далекое «зеркало».
          В данном случае у всех все резолвится одинаково, но трафик идет на более близкое зеркало — за этим следит NOC провайдера.
          • 0
            У GeoIP есть много своих проблем, не спорю. Как вы боретесь с тем, что по anycast вы определяете клиента на базе адреса резолвера, а не клиента?
            • 0
              Не очень понял вас.
              С использованием anycast мне не нужно определять клиента — все клиенты получают один и тот же ip-адрес сайта, условно говоря 1.2.3.4.
              Но этот адрес физически «размазан» по разным ДЦ. Клиент об этом не знает никак.
              Он просто отправляет запрос на этот ip 1.2.3.4, оборудование провайдера думает где этот ip находится и видит, что в сеть 1.2.3.0/24 можно попасть разными маршрутами. Идет ближайшим и попадает на зеркало сайта.

              То есть определение куда направить пользователя происходит не по адресу использованного им резолвера, а по его реальному ip адресу.
              • 0
                >Но этот адрес физически «размазан» по разным ДЦ.
                Скорее уж логически…

                Советую вам более детально изучить данный вопрос, так как это работает несколько не так как вы описали. Клиент для доступа к сайту первоначально обращается не к вам, а к резолверу своего провайдера или любому другому, который у него прописан. Резолвер в свою очередь идет на ваш anycast адрес, который один для всех. Ваш сервер принимает адрес резолвера за адрес клиента — точность позиционирования ломается. Не забывайте, что у вас только DNS Anycast, а не HTTP сервер. У вас был практический опыт использования TCP Anycast, о котором вы рассказали в своем примере.
    • 0
      Будут большие проблемы в регионах. Тот же Мегафон растянул свою ASку на всю страну, но, т.к. белых адресов мало, они в течение суток «мигрируют» с востока на запад страны. И как тут GeoIP пользоваться?
  • 0
    Если не секрет, какой минимальный размер блока IP под это дело? (/24? /22?)

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

    Заранее спасибо!

    • +1
      BGP AS минимально /24.
    • +1
      /24 минимально

      Основная задача — это выдавать контент целевому пользователю как можно быстрее. Наша CDN помогает реализовать эту задачу следующими методами:
      1. Кеширование максимально больше данных ближе к пользователю.
      2. Уменьшить нагрузку на основные сервера, соответственно выделить больше процессорных ресурсов на пользователя.
      3. Снизить последствия DDoSа и, как следствие, недоступности сервиса.
  • +3
    краткое содержание статьи:

    1, 2, 3, 4. какие клёвые технологии, почитайте про них тут, тут и тут;
    5. клёвое железо; минимальный конфиг openbgp, nginx, bind.

    интересно, 23 человека, плюсанувших статью, прочитали её вообще?
    • 0
      Все сложные вещи состоят из простых :) Вся сложность в их сочетании.
  • +1
    Интересно было почитать. Статья вызвала двоякие чувства.

    Статья безусловно полезная если
    1) основной траффик идет с одного региона
    2) у вас есть BGP, но нету денег на нормальное железо
    3) нужна специфическая статистика доступа по статике или Вы считаете, что сдн должна и динамика кэшировать
    4) не проблема поднятие нескольких каналов с BGP линками
    5) вы не интересны людям, способным сделать (D)DOS

    Если же хотя бы два из этих условий не выполняется — предложенный метод не есть оптимальным.
    По пунктно аргументация:
    1) если трафик с разных регионов — то даже при наличии своих трансатлантических каналов (ого ;) задержки выше, чем с локального датацентра
    Вывод: GeoIP + BIND + несколько серверов на разных континентах эффективнее. У компаний, которые предоставляют CDN сервисы датацентры расхоложены в о всех основных узлах связанности интернет, они как правило включены в группы обмена траффиком, у них BIND привязан даже не к GeoIP а к BGP info
    2 PPS этого решения несравненно ниже железных решений с использованием человеческих раутеров и Content Service Switch, что есть уровень в выше.
    3 Если не нужна специфическая статистика — то как правило себестоимость эксплуатации специализированых сервисов CDN ниже при одинаковом качестве
    4) вроде и так понятно
    5) Каналы входят на прямую, и не используется никаких программных или аппаратных решений по защите от DOS.

    По мотивации:
    Во-первых, это не наш метод ;) — ну кто бы спорил ;)
    Во-вторых, эти сети уже построены, и не факт, что они подходят вам по распределенности на все сто. — ну разве что случай, если у вас большая часть посетителей находится в компактном регионе.
    Фраза «В случае своей CDN мы вольны где угодно размещать её узлы.», это конечно отлично, но получить 2 AS сейчас с мотивацией «нам нужен СДН» это из области трудновыполнимого, а для одной AS
    В-третьих, мы вкладываем деньги в свою инфрастурктуру, а не в чужую. — достойный аргумент. По этому у меня есть собственная AS.
    В-четвёртных, настроить свою CDN мы можем как угодно. Кешировать можно не только статические данные, но и динамические, например, данные для аннонимусов или общие данные. Такой гибкости нам ни одна коммерческая сеть в полном объёме не даст.
    — аргумент понятен
    Но, если честно я бы переобозвал статью. То что Вы описали — это не совсем CDN.
    • 0
      1) Трафик действительно идёт с одного региона (Евразия). Городить несколько ЦОДов пока нет смысла.

      2) PPS этого решения на практике один узел CDN выдерживает гигабитную нагрузку (как раз после матча Россия-Азербайджан испытали очередной рекорд) и pps был в районе 80к пакетов в секунду (в одну сторону) при загрузке процессора менее 10%. Используются вот эти карточки ark.intel.com/ru/products/69655/Intel-Ethernet-Converged-Network-Adapter-X520-T2

      3) На данном этапе да, но по нашим планам роста такой вариант даст свой профит в будущем.

      4) А какие могут быть проблемы?

      5) Вот как раз это решение и помогло нам выдержать несколько DDoS-ов на практике.

      Немного не понял, зачем две AS? Мы пользуемся одной, что мы делаем не так? :)
      • 0
        Я пару дней подумал в фоне над вопросом. И всё-таки решил полностью согласится, что для ваших условий выбранный способ оптимальный. А смысла вести терменологический спор на супертонкостях определений нет.

        Немного не понял, зачем две AS? Мы пользуемся одной, что мы делаем не так? :)
        Для UDP все просто великолепно. Для TCP считалось, что при anyroute их нужно несколько в зависимости от основной топографии сети для того чтобы исправить проблемы на подобии следующих: Есть площадки А, Б. Клиенты, у которых исходящий трафик балансируется таким образом, что часть пакетов маршрутизируется в А, а часть в Б. В результате аолучается ситуация, когда TCP линк устанавливается с узлом, на который пришел syn (к примеру А), но получилось много ретранзмитов, изза того, что часть трафика ушла на Б. Легко посмотреть процент подобного паразитного трафика и ретранзмитов по каунтерам системя (извините в БЗД не знаю как, но уверен, что от линухов отличия мало).

        В сети не редко встречаются ситуации, когда часть пакетов одной и той-же TCP сессии бегает через разные линки. К примеру больше года наблюдал как на www.asx.com.au часть трафика бегала через японию, а часть через филипины.К сожалению сейчас ситуацию повторить не смог.

        Знакомый кошковед сказал мне, что я отстал от жизни, и сейчас никто робином не балансирует пакеты, балансируют либо по хешам сессий либо по хешам сетей. Так что сейчас вполне можно использовать anyroute для TCP. И однной AS достаточно.

        По поводу DDOS,
        С использованием умных железяк о них можно особо не беспокоится, но и без них тоже можно прожить. Атаки уровней 1-6 страшны (свякие синкфлуды, и прочее детство лечатся настройкой оси) только 0-day (чего никак не исправишь), Атаки 7 уровня по прежнему страшны. HTTPs у Вас нет, для защиты от slow-clients (что сейчас особенно популярно) community.qualys.com/blogs/securitylabs/2011/11/02/how-to-protect-against-slow-http-attacks, даже медленную отдачу боди можно детектить. По остальным типам — тоже можно найти средства.

        Снимаю шляпу. Было полезно почитать и поучится еще одной альтернатиые.
  • 0
    Вы крутые :) сразу подошли к вопросу роста трафика радикально, это правильно.

    У меня вопросы.

    1. Вы рассматривали готовые CDN для ваших задач? NGENIX, например.

    2. У вас только картинки и текст или ещё и видео-контент раздаётся? Видел у вас ссылки на Ютюб только, может пропустил чего.
    • +1
      Отвечаю:

      1. Рассматривали. Они не очень хорошо подходят по наши планы. + Два узла мы разместили прямо в своём ЦОДе, снизив вероятность заДДоСивания его самого.

      2. Картинки, стили, тексты и прочая статика + общие данные и данные для анонимов — тексты и JSON-ы.
  • 0
    Ясно, спасибо.
  • 0
    А как быть с нагрузкой на MySQL?
    Если так же использовать CDN, то как быть с различной информацией на серверах, ведь в реальном времени не получится всё синхронизировать?
  • 0
    Если вы фанат BSD, то советую varnish вместо nginx.

    nginx таки скорее сервер, а не кэш.

    Много клевых фич — в планэ кэш-акселлератора nginx до него далеко.
    • 0
      Особенно клево для принудительного кэширования динамических страниц. Повырезать из запросов левые заголовки — куки, языки, кодировку и т.п., чтобы не было отдельной одного и того же в кэше.
  • 0
    Вот интересно, как вы решали задачу пофайлового сброса кэша при использование proxy_cache, который хранит по ключам, а не по URL? Вам же не только статику, но и динамику сбрасывать (или на динамику вы, в конечном итоге, забили?).
    Такое ощущение, что вы наступили на большое количество граблей, но не стремитесь это рассказывать. Тот же Anycast может «страдать» потерей пакетов из-за перекидывания IP-адресов, в этом плане GeoIP все же надежнее. Или вы нашли какой-то идеальный Anycast?
    Спрашиваю не из праздного интереса: Айри.рф строили, исходя из почти те же предпосылок, но решение оказалось технически другим, и, скорее всего, выигрывает перед вашим по функциональности / стоимости.

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

Самое читаемое Разное