...

вторник, 22 октября 2013 г.

Как сделать 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-нить ещё несколько сайтов ;)


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers. Five Filters recommends:



Комментариев нет:

Отправить комментарий