66 lines
8.3 KiB
Markdown
66 lines
8.3 KiB
Markdown
---
|
||
aliases:
|
||
tags:
|
||
- зрелость/🌱
|
||
date:
|
||
- - 2024-05-24
|
||
zero-link:
|
||
- "[[00 Архитектура ПО]]"
|
||
- "[[00 HighLoad]]"
|
||
parents:
|
||
linked:
|
||
---
|
||
Для каждого ресурса критичной для пользователя является такая характеристика, как время отклика сервера ([Latency](Latency.md)). Увеличение времени отклика сервера приводит к оттоку посетителей. Следовательно, необходимо минимизировать время отклика: для этого необходимо уменьшать время, требуемое на формирование ответа пользователю, при этом для формирования ответа пользователю необходимо получить данные из каких-то внешних ресурсов ([Бэкенд](Бэкенд.md)).
|
||
|
||
Ускорить сложные запросы может кэширование: мы помещаем результат вычислений в некоторое хранилище (например, [Memcached](Memcached.md) или [Redis](Redis.md)), которое обладает отличными характеристиками по времени доступа к информации. Теперь вместо обращений к медленным, сложным и тяжелым backend’ам нам достаточно выполнить запрос к быстрому кэшу.
|
||
|
||
![](Pasted%20image%2020240617184722.png)
|
||
|
||
Система должна уметь выдерживать нагрузку и без кэша. Задача кэша ускорить ответ, а не держать нагрузку.
|
||
|
||
Кэширование основывается на [принципе локальности](Принцип%20локальности.md).
|
||
|
||
==Системы используемые для кэширования обычно не являются надежными, так что не следует хранить только там какие-то важные данные.== Данные можно разделить на несколько категорий:
|
||
- «**Можно потерять**». К этой категории относятся кэши выборок из базы данных. Потеря таких ключей не так страшна, потому что мы можем легко восстановить их значения, обратившись заново к backend’у. Однако частые потери кэшей приводят к излишним обращениям к БД.
|
||
- «**Не хотелось бы потерять**». Здесь можно упомянуть счетчики посетителей сайта, просмотров ресурсов и т.п. Хоть и восстановить эти значения иногда напрямую невозможно, но значения этих ключей имеют ограниченный по времени смысл: через несколько минут их значение уже неактуально, и будет рассчитано заново.
|
||
- «**Совсем не должны терять**». Кэш удобен для хранения сессий пользователей. Однако содержимое сессий не хотелось бы терять никогда – иначе пользователей на сайте будет «разлогинивать». Как попытаться избежать? Можно кластеризовать систему кэширования, так вероятность потери снижается.
|
||
|
||
Уровни кэширования:
|
||
- [Кэширование на сервере](Кэширование%20на%20сервере.md)
|
||
- [Кэширование на стороне Nginx](Кэширование%20на%20стороне%20Nginx.md)
|
||
- [Кэширование на стороне клиента Nginx](Кэширование%20на%20стороне%20клиента%20Nginx.md)
|
||
- [Кэширование в браузере](Кэширование%20в%20браузере.md)
|
||
|
||
Виды кэширования:
|
||
- Сквозное. Вс
|
||
## Ключ кэширования
|
||
Ключ кэширования должен обладать следующими свойствами:
|
||
- При изменении параметров выборки, которую мы кэшируем, ключ кэширования должен изменяться (чтобы с новыми параметрами мы не «попали» в старый кэш).
|
||
- По параметрам выборки ключ должен определяться однозначно, т.е. для одной и той же выборки ключ кэширования должен быть только один, иначе мы рискуем понизить эффективность процесса кэширования, создавая несколько кэшей для одной и той же выборки.
|
||
|
||
Можно использовать следующий вариант (пример для PHP): если существует некоторая точка в коде, через которую проходят все обращения к БД, а любое обращение полностью описывается (содержит все параметры запроса) в некоторой структуре `$options`, можно использовать следующий ключ:
|
||
|
||
```php
|
||
$key = md5(serialize($options))
|
||
```
|
||
|
||
Такой ключ удовлетворяет первому условию% при изменении `$options` будет обязательно изменен `$key`, но и второе условие будет соблюдаться, если мы будем все типы данных в $options использовать «канонически», т.е. не допускать строки `"1"` вместо числа `1`. Функция `md5` используется для «сжатия» данных.
|
||
|
||
## Инвалидация
|
||
Если мы закэшировали какие-то данные от backend’а, например, выборку из БД, рано или поздно исходные данные изменяются, и кэш перестает быть валидным. Причем очень желательно, чтобы кэш сбрасывался сразу же за изменением.
|
||
|
||
Один из подходов это инвалидация по времени. Для кэшированных данных устанавливается TTL, и по прошествию времени кэш удаляется. Такое вариант подходит для редко изменяемых данных, устаревание которых не приводит к серьезным проблемам в бизнес-логике, например словари. При таком варианте важно подобрать оптимальное время жизни кэша, слишком маленькое время жизни будет давать плохую производительность, слишком большое ухудшит опыт пользователей.
|
||
|
||
Первый вариант не подходит. Некоторые чуствительные данные нужно инвалидировать их сразу при изменении. Тут может помочь тегирование ключей.
|
||
|
||
Инвалидация:
|
||
- По истечению срока жизни - TTL
|
||
- Принудительный вызов команды инвалидации
|
||
- Алгоритмы вытеснения
|
||
|
||
Алгоритмы вытеснения:
|
||
- Алгоритм Белади. Несуществующий идеальный алгоритм. Храним только нужную информацию, не нужную не храним.
|
||
- [Least Recently Used](Least%20Recently%20Used.md)
|
||
- [Most Recently Used](Most%20Recently%20Used.md)
|
||
- [Last Frequently Used](Last%20Frequently%20Used.md)
|
||
- [Adaptive Replacement Cache](Adaptive%20Replacement%20Cache.md) |