79 lines
8.9 KiB
Markdown
79 lines
8.9 KiB
Markdown
---
|
||
aliases:
|
||
- кэш
|
||
- кэша
|
||
- кеш
|
||
tags:
|
||
- maturity/🌱
|
||
date:
|
||
- - 2024-05-24
|
||
zero-link:
|
||
- "[[../../meta/zero/00 HighLoad|00 HighLoad]]"
|
||
parents:
|
||
linked:
|
||
---
|
||
Для каждого ресурса критичной для пользователя является такая характеристика, как [[Latency|время отклика]] сервера. Увеличение времени отклика сервера приводит к оттоку посетителей. Следовательно, необходимо минимизировать [[Latency|время отклика]]: для этого необходимо уменьшать время, требуемое на формирование ответа пользователю, при этом для формирования ответа пользователю необходимо получить данные из каких-то внешних ресурсов ([Бэкенд](Бэкенд.md)).
|
||
|
||
|
||
> [!TIP] Работа без кэша
|
||
> Хорошая система должна уметь выдерживать нагрузку и без кэша. Задача кэша ускорить ответ, а не держать нагрузку.
|
||
|
||
Сами данные можно разделить на несколько категорий:
|
||
- **Можно потерять**. К этой категории относятся кэши выборок из базы данных. Потеря таких ключей не так страшна, потому что мы можем легко восстановить их значения, обратившись заново к backend’у. Однако частые потери кэшей приводят к излишним обращениям к БД.
|
||
- **Не хотелось бы потерять**. Здесь можно упомянуть счетчики посетителей сайта, просмотров ресурсов и т.п. Хоть и восстановить эти значения иногда напрямую невозможно, но значения этих ключей имеют ограниченный по времени смысл: через несколько минут их значение уже неактуально, и будет рассчитано заново.
|
||
- **Совсем не должны терять**. Кэш удобен для хранения сессий пользователей. Однако содержимое сессий не хотелось бы терять никогда – иначе пользователей на сайте будет «разлогинивать». Как попытаться избежать? Можно кластеризовать систему кэширования, так вероятность потери снижается.
|
||
|
||
==Системы используемые для кэширования обычно не являются надежными, так что не следует хранить только там какие-то важные данные.==
|
||
## Уровни кэширования
|
||
![](../../meta/files/images/Pasted%20image%2020240617195054.png)
|
||
|
||
![[../../meta/files/images/Pasted image 20241103033544.png]]
|
||
|
||
Уровни кэширования:
|
||
- [Кэширование на стороне браузера](highload/Кэширование%20на%20стороне%20браузера.md). Ответы HTTP могут кэшироваться браузером. При первом запросе данных по HTTP они возвращаются с политикой истечения срока действия в заголовке HTTP. При повторном запросе данных клиентское приложение сначала пытается получить их из кэша браузера.
|
||
- [Кэширование на стороне Nginx](../devops/nginx/Кэширование%20на%20стороне%20Nginx.md)
|
||
- [Content Delivery Network](highload/Content%20Delivery%20Network.md). CDN кэширует статические веб-ресурсы. Клиенты могут получать данные с ближайшего узла CDN.
|
||
- **Балансировщик нагрузки**: Балансировщик также может кэшировать ресурсы.
|
||
- [Кэширование в приложении](Кэширование%20в%20приложении.md). В сервисах есть несколько уровней кэша. Если данные не находятся в кэше процессора, сервис пытается получить их из памяти. Иногда в сервисе есть вторичный уровень кэша для хранения данных на диске.
|
||
- **Распределённый кэш**: Распределённые кэши, такие как Redis, хранят пары ключ-значение в памяти для множества сервисов. Это обеспечивает значительно лучшую производительность чтения и записи по сравнению с базой данных.
|
||
- **База данных**: Даже в базе данных есть различные уровни кэша
|
||
|
||
**Виды кэширования:**
|
||
- Сквозное. Все запросы проходят через кэш. [Схема](../../meta/files/images/Pasted%20image%2020240617194731.png).
|
||
- Кэширование на стороне сервиса. [Схема](../../meta/files/images/Pasted%20image%2020240617194759.png).
|
||
- Опережающее. Кладем данные в кэш заранее. [Схема](../../meta/files/images/Pasted%20image%2020240617194938.png).
|
||
|
||
Чаще всего кэш реализуется на основе [[../fundamental/structure/Хеш-таблица|хеш-таблиц]] и использует [принцип локальности](../fundamental/Принцип%20локальности.md). Для работы с хеш-таблицей вам необходим [[highload/Ключ кэширования|ключ кэширования]] и сами данные. По ключу данные кладутся и забираются из таблицы.
|
||
|
||
Для хранения результатов кэширования я обычно использую JSON. Использую для этого библиотеку [[../../../../knowledge/dev/java/other/Jackson|Jackson]], но есть один [[../snippet/Преобразование Json из коллекции в Java объект при помощи Jackson|нюанс при работе с коллекциям]], который стоит учитывать.
|
||
|
||
При желании результат кэширования можно сжать используя [[../algorithm/GZIP|GZIP]]. Однако, приходится использовать [[../other/Base64|Base64]], чтобы преобразовать байты полученные от gzip в строку, и уже в таком виде положить в Redis. Не смотря на то, что Base64 увеличивает размер строки на 33% все равно получается намного компактнее, чем просто JSON.
|
||
|
||
Рано или поздно исходные данные изменяются, и кэш перестает быть валидным. Часто важно, чтобы кэш сбрасывался сразу же за изменением. За это отвечает [[highload/Инвалидация кэша|Инвалидация кэша]].
|
||
|
||
![[../../meta/files/images/Pasted image 20241103035011.png]]
|
||
***
|
||
## Мета информация
|
||
**Область**:: [[../../meta/zero/00 HighLoad|00 HighLoad]]
|
||
**Родитель**::
|
||
**Источник**::
|
||
**Автор**::
|
||
**Создана**:: [[2024-05-24]]
|
||
### Дополнительные материалы
|
||
- [[highload/Оценка эффективности кэша|Оценка эффективности кэша]]
|
||
- [Старт с холодным кэшем](highload/Старт%20с%20холодным%20кэшем.md)
|
||
### Дочерние заметки
|
||
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
|
||
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
|
||
- [[CacheMissRate]]
|
||
- [[Content Delivery Network]]
|
||
- [[Инвалидация кэша]]
|
||
- [[Ключ кэширования]]
|
||
- [[Кэширование на стороне браузера]]
|
||
- [[Оценка эффективности кэша]]
|
||
- [[Перестройка кэша]]
|
||
- [[Старт с холодным кэшем]]
|
||
- [[Кэширование в приложении]]
|
||
- [[Кэширование на стороне Nginx]]
|
||
<!-- SerializedQuery END -->
|