69 lines
7.4 KiB
Markdown
69 lines
7.4 KiB
Markdown
|
---
|
|||
|
aliases:
|
|||
|
- кэш
|
|||
|
tags:
|
|||
|
- maturity/🌱
|
|||
|
date:
|
|||
|
- - 2024-05-24
|
|||
|
zero-link:
|
|||
|
- "[[../../meta/zero/00 HighLoad|00 HighLoad]]"
|
|||
|
parents:
|
|||
|
linked:
|
|||
|
---
|
|||
|
Для каждого ресурса критичной для пользователя является такая характеристика, как [[Latency|время отклика]] сервера. Увеличение времени отклика сервера приводит к оттоку посетителей. Следовательно, необходимо минимизировать [[Latency|время отклика]]: для этого необходимо уменьшать время, требуемое на формирование ответа пользователю, при этом для формирования ответа пользователю необходимо получить данные из каких-то внешних ресурсов ([Бэкенд](Бэкенд.md)).
|
|||
|
|
|||
|
|
|||
|
> [!TIP] Работа без кэша
|
|||
|
> Хорошая система должна уметь выдерживать нагрузку и без кэша. Задача кэша ускорить ответ, а не держать нагрузку.
|
|||
|
|
|||
|
==Системы используемые для кэширования обычно не являются надежными, так что не следует хранить только там какие-то важные данные.== Чаще всего кэш реализуется на основе хэш-таблиц и использует [принцип локальности](../fundamental/Принцип%20локальности.md).
|
|||
|
|
|||
|
Сами данные можно разделить на несколько категорий:
|
|||
|
- **Можно потерять**. К этой категории относятся кэши выборок из базы данных. Потеря таких ключей не так страшна, потому что мы можем легко восстановить их значения, обратившись заново к backend’у. Однако частые потери кэшей приводят к излишним обращениям к БД.
|
|||
|
- **Не хотелось бы потерять**. Здесь можно упомянуть счетчики посетителей сайта, просмотров ресурсов и т.п. Хоть и восстановить эти значения иногда напрямую невозможно, но значения этих ключей имеют ограниченный по времени смысл: через несколько минут их значение уже неактуально, и будет рассчитано заново.
|
|||
|
- **Совсем не должны терять**. Кэш удобен для хранения сессий пользователей. Однако содержимое сессий не хотелось бы терять никогда – иначе пользователей на сайте будет «разлогинивать». Как попытаться избежать? Можно кластеризовать систему кэширования, так вероятность потери снижается.
|
|||
|
## Уровни кэширования
|
|||
|
![](../../meta/files/images/Pasted%20image%2020240617195054.png)
|
|||
|
|
|||
|
![](../../meta/files/images/Pasted%20image%2020240701115612.png)
|
|||
|
|
|||
|
Уровни кэширования:
|
|||
|
- [Кэширование на стороне браузера](highload/Кэширование%20на%20стороне%20браузера.md)
|
|||
|
- [Кэширование на стороне Nginx](highload/Кэширование%20на%20стороне%20Nginx.md)
|
|||
|
- [Content Delivery Network](highload/Content%20Delivery%20Network.md)
|
|||
|
- [Кэширование в приложении](Кэширование%20в%20приложении.md)
|
|||
|
|
|||
|
Виды кэширования:
|
|||
|
- Сквозное. Все запросы проходят через кэш. [Схема](../../meta/files/images/Pasted%20image%2020240617194731.png).
|
|||
|
- Кэширование на стороне сервиса. [Схема](../../meta/files/images/Pasted%20image%2020240617194759.png).
|
|||
|
- Опережающее. Кладем данные в кэш заранее. [Схема](../../meta/files/images/Pasted%20image%2020240617194938.png).
|
|||
|
## Ключ кэширования
|
|||
|
Ключ кэширования должен обладать следующими свойствами:
|
|||
|
- При изменении параметров выборки, которую мы кэшируем, ключ кэширования должен изменяться (чтобы с новыми параметрами мы не «попали» в старый кэш).
|
|||
|
- По параметрам выборки ключ должен определяться однозначно, т.е. для одной и той же выборки ключ кэширования должен быть только один, иначе мы рискуем понизить эффективность процесса кэширования, создавая несколько кэшей для одной и той же выборки.
|
|||
|
|
|||
|
Можно использовать следующий вариант (пример для PHP): если существует некоторая точка в коде, через которую проходят все обращения к БД, а любое обращение полностью описывается (содержит все параметры запроса) в некоторой структуре `$options`, можно использовать следующий ключ:
|
|||
|
|
|||
|
```php
|
|||
|
$key = md5(serialize($options))
|
|||
|
```
|
|||
|
|
|||
|
Такой ключ удовлетворяет первому условию: при изменении `$options` будет обязательно изменен `$key`, но и второе условие будет соблюдаться, если мы будем все типы данных в $options использовать «канонически», т.е. не допускать строки `"1"` вместо числа `1`. Функция `md5` используется для «сжатия» данных.
|
|||
|
|
|||
|
Если мы закэшировали какие-то данные от backend’а, например, выборку из БД, рано или поздно исходные данные изменяются, и кэш перестает быть валидным. Причем очень желательно, чтобы кэш сбрасывался сразу же за изменением. За это отвечает [[highload/Инвалидация кэша|Инвалидация кэша]]
|
|||
|
***
|
|||
|
## Мета информация
|
|||
|
**Область**:: [[../../meta/zero/00 HighLoad|00 HighLoad]]
|
|||
|
**Родитель**::
|
|||
|
**Источник**::
|
|||
|
**Автор**::
|
|||
|
**Создана**:: [[2024-05-24]]
|
|||
|
### Дополнительные материалы
|
|||
|
- [[highload/Оценка эффективности кэша|Оценка эффективности кэша]]
|
|||
|
- [Старт с холодным кэшем](highload/Старт%20с%20холодным%20кэшем.md)
|
|||
|
### Дочерние заметки
|
|||
|
```dataview
|
|||
|
LIST
|
|||
|
FROM [[]]
|
|||
|
WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link)
|
|||
|
```
|