Чотири рівні кешування в мережі: клієнтський, мережевий, серверний і рівень додатка


Дізнайтесь більше про нові кар'єрні можливості в EchoUA. Цікаві проекти, ринкова оплата, гарний колектив. Надсилайте резюме та приєднуйтеся до нас.

У цій статті ми розглянемо один із секретів високої масштабованості й продуктивності сайтів. З блогу про архітектуру Flickr, на серверах якого розміщується понад 5 000 000 фотографій, ми дізналися, що кешування і оперативна пам’ять відіграють провідну роль у масштабованості й продуктивності сайту.

Сайт може зберігати дані для прискорення обробки подальших запитів на чотирьох рівнях:

  • клієнтський;
  • мережевий;
  • серверний;
  • рівень додатка.

Різні сторінки веб-сайту часто обмінюються тими самими ресурсами. Користувач повинен повторно використати ресурси під час навігації. Зображення, скрипти і стилі можна зберігати в кеші місяцями, а сама сторінка документа може кешуватися протягом декількох хвилин у клієнтському браузері.

Кеш на клієнтському рівні

Заголовки HTTP відповідають за визначення можливості кешування відповіді й за визначення терміну зберігання даних. Наведений нижче приклад заголовка Cache-control вказує, що відповідь може знаходитися в кеші протягом 7 днів. Браузер відправить повторний запит на зберігання даних, якщо термін зберігання сплине або користувач цілеспрямовано оновить сторінку.

Запит і відповідь, які можуть бути кешовані протягом 604800 сек.

Відповідь також може включати заголовок Last-Modified чи Etag. Ці заголовки потрібні для перевірки можливості повторного використання даних. Статус відповіді 304 вказує, що вміст не змінився і повторне завантаження не потрібне. Зверніть увагу на парні заголовки Last-Modified і If-Modified-Since, а також на дати:

Відповідь із заголовком “Last-Modified” і подальшим запитом з його використанням

Заголовок Etag використовується з If-None-Match аналогічним чином для обміну кодами відповіді при визначенні змін в контенті, якщо вони є.

Сайт з продуманими HTTP-заголовками набуде більшого успіху у користувачів. Крім того, браузер заощадить час і пропускну спроможність.

Кеш на мережевому рівні

У Вікіпедії наведено визначення: Мережа доставки контенту (CDN) – географічно розподілена мережева інфраструктура, що дозволяє оптимізувати доставку і дистрибуцію контенту кінцевим користувачам у мережі Інтернет. Інакше кажучи, CDN – це розподілене зберігання і використання кеша.

Директива HTTP- заголовка Cache-control: public дозволяє різним частинам мережі кешувати відповідь. За допомогою заголовка Cache-Control: public, max-age=31536000 знаходять ресурси, які зберігаються протягом року.

Можливо, Ви вже знайомі з іншими директивами заголовків. Є також ще один потужний заголовок, для обробки аутентифікованих та інших видів динамічних відповідей.

Кеш на серверному рівні

Крім налаштування правильних заголовків відповіді і обробки заголовків запиту, є багато різних моментів, які Ви могли б поліпшити на стороні сервера і додатка.

Перший підхід до швидших відповідей та економії ресурсів – налаштування кеш-сервера між додатком і клієнтом.

Клієнти, що просять одно і те ж вміст на проксі-сервері.

Такі інструменти, як Varnish, Squid і nginx кешують зображення, скрипти та інший вміст, який потрібен користувачам. Наступне налаштування nginx збирає кеш, спираючись тільки на HTTP-заголовки в додатку.

proxy_cache_path /path/to/cache keys_zone=my _cache:10m;server { location /{ proxy_cache my_cache; proxy_pass http://aplication; }}

Є ще одна директива, яка називається proxy_cache_lock, вона дозволяє проксі-серверу делегувати тільки перший з подібних клієнтських запитів за один раз для додатка. Якщо директива встановлена, клієнти отримуватимуть відповідь при поверненні першого запиту.

Багато клієнтів, які запитують те саме одночасно

Цей простій, але потужний механізм дозволяє уникнути безладу на стороні додатка при великій кількості запитів, коли закінчується термін зберігання контенту.

Ідея останнього, але не менш важливого підходу полягає в тому, що проксі-сервер може поліпшити відмовостійкість додатка. Є прапори директиви proxy_cache_use_stale для доставки контенту із закінченим терміном актуальності, коли додаток повертає статус помилки або коли зв’язок між проксі-сервером і додатком не працює належним чином.

У керівництві по кешуванню з NGINX і NGINX Plus міститься детальніша інформація і параметри конфігурації.

Кеш на рівні додатка

Кешування додатка скорочує час виконання певних операцій. Як приклад можна навести комплексні обчислення, запити даних до інших служб або загальні дані, використовувані в однакових запитах.

Мемоізация

def price @price ||= Price.new (unit_price, category) end

У наведеному вище коді на Ruby використовується простий метод мемоізації, який зберігає ціну продукту, щоб уникнути додаткових обчислень. Ця функція збереже дані в екземплярі об’єкта і заощадить ресурси під час обробки запиту.

Цю функцію можна викликати з будь-якого місця коду. Проте використання такої техніки викликає певні проблеми. Важливо пам’ятати, що Ваші дані не матимуть терміну актуальності. Глобальна мемоізація коду залишатиметься в пам’яті протягом усього циклу роботи додатка.

Інтелектуальне кешування в пам’яті

cache.fetch ("category - tax -#{category_id}", expires _in: 1.minute) do CategoryTax.new (category_id)
end

У наведеному вище коді використовується API кешування Rails для зберігання і повторного використання мітки категорії протягом однієї хвилини під час обробки запитів. Ключем кеша для ідентифікації даних є category_id. Цей метод використовується для економії ресурсів, часу і зменшення об’єму запитів до зовнішньої служби міток категорій.

Багато бібліотек надають цей шаблон, але пам’ять додатка – не нескінченний ресурс. Наприклад, менеджер кеша для Node не управляє об’ємом споживаної пам’яті. Також це може стати проблемою, якщо Ваш додаток кешує дані у великих об’ємах, споживаючи всю доступну пам’ять.

Кешування даних Rails розумно скорочує дані, що зберігаються, коли вони перевищують виділений розмір пам’яті, видаляючи давно невживані записи. Це дозволяє кешувати постійні дані, не вказуючи терміну їх актуальності.

Спільне кешування

Вміння поводитися зі збільшуваною кількістю користувачів і запитів – важливий об’єкт веб-розробки. Один зі способів масштабування додатка – додавання екземплярів додатка (горизонтальне масштабування). Як Ви, напевно, здогадалися, простий кеш в пам’яті не може використовуватися декількома екземплярами.

Додаток дванадцяти чинників, методологія побудови програмного забезпечення як служби (SaaS), вказує на те, що додаток ніколи не повинен припускати, що всі кешовані в пам’яті або на диску дані будуть доступні при подальших запитах – з великою кількістю різнотипних процесів висока вірогідність того, що наступний запит буде оброблений іншим процесом.

Ще один важливий аспект при використанні сховищ кеша – це стан гонки, який відбувається, коли різні екземпляри додатка звертаються до некешованих даних одночасно. API кешування запитів Rails містить властивість race_condition_ttl для мінімізації цього ефекту.

Попередження стану гонки для кеша з декількома екземплярами додатків є складним завданням. Оптимальним рішенням у цьому випадку виступає оновлення даних кеша поза потоком додатка і використання кешованих даних у самому додатку. В архітектурі мікросервісу можна захистити зв’язок між додатком і сервісом за допомогою nginx, як це описано вище.

Висновок

Сподіваємося, що ця стаття допоможе Вам зрозуміти і вибрати кращу стратегію для Вашого додатка. HTTP- заголовки – це найпростіше, що Ви можете і повинні налаштувати для оптимізації кешування Вашого додатка. Використайте також інші стратегії, коли у Вас з’являться певні проблеми з продуктивністю, але пам’ятаєте, що передчасна оптимізація – корінь усіх бід.

Переклад статті “Client, Network, Server and Application Caching on the Web”

Київ, Харків, Одеса, Дніпро, Запоріжжя, Кривий Ріг, Вінниця, Херсон, Черкаси, Житомир, Хмельницький, Чернівці, Рівне, Івано-Франківськ, Кременчук, Тернопіль, Луцьк, Ужгород, Кам'янець-Подільський, Стрий - за статистикою саме з цих міст програмісти найбільше переїжджають працювати до Львова. А Ви розглядаєте relocate?


Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *