Есть пара вопросов.
Во-первых, это гранулярность. Ваше приложение может иметь очень хороший уровень кэширования сверх того, что делает база данных. Например, база данных, скорее всего, будет просто кэшировать страницы данных, а не обязательно конкретные строки.
Другое дело, что приложение может хранить данные в своем «родном» формате, тогда как БД, очевидно, кэширует только во внутреннем формате.
Простой пример.
Скажем, у вас есть пользователь в базе данных, которая состоит из столбцов: USERID
, FIRSTNAME
, LASTNAME
. Очень просто.
Вы хотите загрузить пользователя USERID=123
в ваше приложение. Какие шаги предпринимаются?
- Выдача вызова базы данных
- Разбор запроса (
SELECT * FROM USER WHERE USERID = ?
)
- Планирование запроса (т. Е. Как система собирается получать данные)
- Извлечение данных с диска
- Потоковая передача данных из базы данных в приложение
- Преобразование данных базы данных в данные приложения (то есть
USERID
в целое число, скажем, имена в строки.
Кэш базы данных, вероятно, будет кэшировать шаги 2 и 3 (это кэш операторов, поэтому он не будет анализировать или перепланировать запрос) и кэшировать фактические блоки диска.
Итак, вот ключ. Ваш пользователь, USER ID 123
, имя JESSE JAMES
. Вы можете видеть, что это не много данных. Но база данных кеширует дисковые блоки. У вас есть индексный блок (с 123
на нем), затем блок данных (с фактическими данными и всеми другими строками, которые умещаются в этом блоке). Итак, что номинально, скажем, 60-70 байт данных на самом деле имеет кеширование и влияние данных на БД, вероятно, 4K-16K (зависит от размера блока).
Светлая сторона? Если вам нужна другая строка, которая находится рядом (скажем, USER ID = 124
), шансы высоки, индекс и данные уже кэшированы.
Но даже с этим кешированием вам все равно придется платить за перемещение данных по проводам (и это всегда по проводам, если вы не используете локальную БД, тогда это зацикливание), и вы «неустрашимы» " данные. То есть преобразование его из битов базы данных в биты языка в биты приложения.
Теперь, когда приложение получает USER ID 123
, оно помещает значение в долгоживущую хэш-карту.
Если приложение когда-либо захочет его снова, оно будет искать на локальной карте, в кэше приложения и сэкономит на поиске, проводном транспорте и расходах на сортировку.
Темная сторона кэширования приложений - синхронизация. Если кто-то входит и делает UPDATE USER SET LASTNAME="SMITH" WHERE USERID=123
, ваше приложение не «знает об этом», и, следовательно, кэш грязный.
Итак, есть множество деталей в обработке этих отношений для синхронизации приложения с БД.
Наличие большого количества кэша базы данных очень удобно для больших запросов к «горячему» набору данных. Чем больше у вас памяти, тем больше «горячих» данных вы можете иметь. Вплоть до того, что вы можете кэшировать всю БД в ОЗУ, вы устраняете задержку ввода-вывода (по крайней мере, для чтения) перемещения данных с диска в буфер ОЗУ. Но у вас все еще есть расходы на транспорт и сортировку.
Приложение может быть гораздо более избирательным, например, кешировать более ограниченные подмножества данных (БД - это просто блоки кеша), а расположение данных «ближе» к приложению повышает эту производительность.
Недостатком является то, что не все кэшируется в приложении. База данных, как правило, хранит данные более эффективно, чем приложение. Вам также не хватает языка «запросов» для кэшированных данных вашего приложения. Большинство людей просто кешируют с помощью простого ключа и переходят оттуда. Легко найти USER ID 123
, сложнее для "ВСЕХ ПОЛЬЗОВАТЕЛЕЙ ИМЯ ДЖЕССА".
Кэширование базы данных имеет тенденцию быть «свободным», вы устанавливаете номер буфера, а СУБД обрабатывает все остальное. Низкое влияние, уменьшает общие затраты ввода-вывода и задержки диска.
Кэширование приложения, в частности, зависит от приложения.
Очень хорошо работает для изолированных «статических» данных. Это очень просто. Загрузите кучу вещей для поиска таблиц при запуске и перезапустите приложение, если они изменятся. Это легко сделать.
После этого сложность начинает увеличиваться по мере добавления «грязной» логики и т. Д.
Все это сводится к тому, что до тех пор, пока у вас есть API данных, вы можете кэшировать его постепенно.
Итак, до тех пор, пока вы вызываете getUser(123)
везде, а не нажимаете на БД, вы можете позже вернуться и добавить кеширование в getUser
без ущерба для вашего кода.
Итак, я всегда предлагаю какой-то уровень доступа к данным в коде каждого, чтобы обеспечить этот уровень абстракции и перехвата.