Четири нива на кеширане на ниво мрежов клиент, мрежа, сървър и приложение
В тази статия ще разгледаме една от тайните на високата мащабируемост и производителност на сайта. От архитектурния блог Flickr, който съдържа над 5 000 000 снимки, научихме, че кеширането и RAM играят ключова роля в скалируемостта и производителността на сайта.
Сайтът може да съхранява данни за ускоряване на обработката на последващи заявки на четири нива:
- клиент;
- мрежа;
- сървър;
- ниво на приложение.
Различните страници на уебсайт често споделят едни и същи ресурси. Потребителят трябва да използва повторно ресурсите, докато навигира. Изображения, скриптове и стилове могат да бъдат кеширани с месеци, а самата страница на документа може да бъде кеширана за минути в клиентски браузър.
Кеш на ниво клиент
HTTP заглавките са отговорни за определянето дали отговорът може да бъде кеширан и за определянето колко дълго се съхраняват данните. Следният пример за заглавка за контрол на кеша показва, че отговорът може да бъде кеширан за 7 дни. Браузърът ще изпрати отново заявката за съхранение на данни, ако съхранението изтече или потребителят целенасочено опреснява страницата.
Заявка и отговор, които могат да бъдат кеширани за 604800 секунди.
Отговорът може също да включва заглавка Last-Modified или Etag. Тези заглавки са необходими за проверка на повторното използване на данните. Състояние на отговор 304 показва, че съдържанието не е променено и не е необходимо презареждане. Обърнете внимание на сдвоените заглавки Last-Modified и If-Modified-Since, както и датите по-долу:
Отговор със заглавка „Последна промяна“, последвана от заявка с негоизползване.
Заглавката Etag се използва с If-None-Match по подобен начин за обмен на кодове за отговор при определяне на промени в съдържанието, ако има такива.
Сайт с добре обмислени HTTP хедъри ще има по-голям успех сред потребителите. В допълнение, браузърът ще спести време и честотна лента.
Кеш на мрежово ниво
Според Wikipedia мрежата за доставка на съдържание (CDN) е географски разпределена мрежова инфраструктура, която оптимизира доставката и разпространението на съдържание до крайните потребители в Интернет. С други думи, CDN е разпределено съхранение и използване на кеш.
Директивата Cache-control: public HTTP header позволява на различни части на мрежата да кешират отговора. Използвайте заглавката Cache-Control: public, max-age=31536000, за да намерите ресурси, които се съхраняват за една година.
Може вече да сте запознати с други директиви за заглавки. Има и друг мощен хедър за обработка на удостоверени и други видове динамични отговори.
Кеш на ниво сървър
В допълнение към настройването на правилните заглавки на отговора и обработката на заглавките на заявката, има много други неща, които можете да подобрите от страна на сървъра и приложението.
Първият подход за по-бързи отговори и спестяване на ресурси е да се настрои кеш сървър между приложението и клиента.
Клиенти, изискващи същото съдържание от прокси сървър.
Инструменти като Varnish, Squid и nginx кешират изображения, скриптове и друго съдържание, което потребителите изискват. Следната настройка на nginx събира кеша въз основа само на HTTP заглавките в приложението.
Има друга директива, наречена proxy_cache_lock, която позволява на прокси сървъра да делегира само първия отподобни клиентски заявки в даден момент за приложението. Ако директивата е зададена, клиентите ще получат отговор, когато бъде върната първата заявка.
Множество клиенти изискват едно и също съдържание едновременно.
Този прост, но мощен механизъм избягва бъркотията от страна на приложението, когато има много заявки, когато съдържанието изтече.
Идеята на последния, но не на последно място подход е, че прокси сървърът може да подобри устойчивостта на приложението. Има флагове на директива proxy_cache_use_stale за доставяне на изтекло съдържание, когато приложение върне състояние на грешка или когато комуникацията между прокси сървъра и приложението не работи правилно.
Вижте ръководството Кеширане с NGINX и NGINX Plus за повече подробности и опции за конфигуриране.
Кеш на ниво приложение
Кеширането на приложения намалява времето за изпълнение на определени операции. Примерите включват сложни изчисления, заявки за данни към други услуги или споделени данни, използвани в същите заявки.
запомняне
Кодът на Ruby по-горе използва прост метод за запаметяване, който запазва цената на продукта, за да избегне допълнителни изчисления. Тази функция ще съхранява данните в екземпляра на обекта и ще пести ресурси по време на обработката на заявката.
Тази функция може да бъде извикана от всяко място в кода. Използването на тази техника обаче създава определени проблеми. Важно е да запомните, че вашите данни няма да имат срок на валидност. Тоест глобалното запаметяване на кода ще остане в паметта по време на целия цикъл на приложение.
Интелигентно кеширане в паметта
Много библиотеки предоставят този модел,но паметта на приложението не е безкраен ресурс. Например мениджърът на кеша за Node не управлява количеството памет, което консумира. Също така може да се превърне в проблем, ако вашето приложение кешира данни в големи количества, консумирайки цялата налична памет.
Кеширането на данни на Rails интелигентно свива съхранените данни, когато те надхвърлят размера на разпределената памет, премахвайки отдавна неизползвани записи. Това позволява постоянните данни да бъдат кеширани, без да се указва дата на изтичане.
Споделено кеширане
Способността да се обработва нарастващ брой потребители и заявки е важен обект на уеб разработката. Един от начините за мащабиране на приложение е добавянето на екземпляри на приложението (хоризонтално мащабиране). Както може би се досещате, обикновеният кеш в паметта не може да се използва от множество екземпляри.
Прилагането на дванадесетте фактора, методологията на софтуера като услуга (SaaS), показва, че приложението никога не трябва да приема, че всички данни, кеширани в паметта или на диска, ще бъдат достъпни при следващи заявки – при голям брой разнородни процеси, следващата заявка вероятно ще бъде обработена от друг процес.
Хранилище за ключ-стойност като Memcached или Redis може да се използва за споделяне на кеш данни между екземпляри на приложения. Тези инструменти имат различни алгоритми за намаляване на количеството кеширани данни. Кеш хранилищата също могат да бъдат устойчиви на грешки с репликация и съхранение на данни. Алгоритмите са толкова различни, че Netflix създаде свой собствен инструмент.
Друг важен аспект при използване на кеш хранилища е състоянието на състезание, което възниква при достъп на различни екземпляри на приложениянекеширани данни едновременно. API за кеширане на заявки на Rails съдържа свойството race_condition_ttl за минимизиране на този ефект.
Предотвратяването на условия на състезание за кешове с множество екземпляри на приложения е предизвикателство. Оптималното решение в този случай е да актуализирате кешираните данни извън нишката на приложението и да използвате кешираните данни в самото приложение. В архитектура на микроуслуга е възможно да се защити комуникацията между приложението и услугата с помощта на nginx, както е описано по-горе.