Подтвердить что ты не робот

Что такое кеширование?

Я постоянно слышу о человеке, у которого была проблема с производительностью x, которую они решали посредством кэширования.

Или, как выполнение x, y, z в коде программы может повредить вашу способность кэширования.

Даже в одном из последних подкастов Джефф Этвуд рассказывает о том, как они кэшируют определенные значения для быстрого поиска.

Кажется, есть некоторая неопределенность в терминах "кеш" и "кеширование", и это привело меня к путанице в этом смысле в разных случаях. Независимо от того, ссылаетесь ли вы на кеширование приложений или баз данных, процессор и т.д. И что это значит.

Что такое кеширование и какие разные типы?

Из контекста я могу понять это, для хранения некоторого полученного значения в основной памяти и быстрого просмотра доступ к нему. Однако, что это такое на самом деле?

Это слово, по-видимому, используется во многих разных контекстах с немного иным значением (cpu, database, application и т.д.), и я действительно хочу его очистить.

Есть ли разница между тем, как кеширование работает в ваших приложениях против кэширования вашей базы данных?

Когда кто-то говорит, что они нашли часть кода, которая повредила бы кеширование и после того, как они исправили его, он улучшился скорость их приложения, каковы они говорить о?

Является ли программа кешированием чего-то это делается автоматически? Как вы позволяете кэшировать значения в вашем программы? Я часто читал этот сайт говорит, что они кэшировали значение в их применении я сижу здесь и интересно, что они означают.

Кроме того, что это действительно означает, когда кто-то говорит о базе данных кэширование? Это просто функция они включаются в их базу данных? Делать вы должны явно кэшировать значения или база данных выбирает, какие из них кэш для вас?

Как начать кэширование элементов самостоятельно для повышения производительности?

Можете ли вы привести несколько примеров того, как я могу начать кешировать значения в моих приложениях? Или снова, это то, что уже сделано, под капотом, и мне просто нужно написать свой код определенным образом, чтобы разрешить "кэширование"?

Как насчет кэширования базы данных, как мне начать? Я слышал о таких вещах, как memcache. Этот тип утилиты необходим для кэширования в базах данных?

Я ищу, чтобы получить хорошее различие между кешированием в приложениях и базами данных, их использованием и тем, как оно реализовано в обоих случаях.

4b9b3361

Ответ 1

Кэширование - это просто практика хранения данных и извлечения данных из высокопроизводительного хранилища (обычно памяти) либо явно, либо неявно.

Позвольте мне объяснить. Память быстрее доступна, чем файл, удаленный URL (обычно), база данных или любой другой внешний накопитель необходимой вам информации. Поэтому, если действие использования одного из этих внешних ресурсов значительно, вы можете извлечь выгоду из кеширования для повышения производительности.

Кнут однажды сказал, что преждевременная оптимизация - это корень всего зла. Ну, преждевременное кэширование - это корень всех головных болей, насколько мне известно. Не решайте проблему, пока у вас не будет проблема. Каждое принятое вами решение происходит за счет стоимости, которую вы заплатите, чтобы реализовать ее сейчас, и заплатить за нее, чтобы впоследствии изменить ее, поэтому чем дольше вы можете отложить создание демиконов и изменить свою систему, тем лучше.

Итак, сначала определите, что у вас действительно есть проблема, и где она. Профилирование, протоколирование и другие формы тестирования производительности помогут вам здесь. Я не могу достаточно подчеркнуть, насколько важен этот шаг. Количество раз, когда я видел, что люди "оптимизируют" то, что не является проблемой, поражает.

Итак, у вас проблема с производительностью. Скажите, что ваши страницы запускают запрос, который занимает много времени. Если он читается, у вас есть несколько вариантов:

  • Запустите запрос как отдельный процесс и поместите результат в кеш. Все страницы просто обращаются к кешу. Вы можете обновлять кешированную версию так часто, как это уместно (один раз в день, один раз в неделю, один раз в 5 секунд, независимо от того, что подходит);
  • Кэш прозрачно через поставщика персистентности, ORM или что-то еще. Конечно, это зависит от того, какую технологию вы используете. Hibernate и Ibatis, например, поддерживают кэширование результатов запроса;
  • Попросите страницы выполнить запрос, если результат не находится в кеше (или он "устарел", что означает, что он рассчитан дольше, чем указанный "возраст" ) и помещает его в кеш. У этого есть проблемы concurrency, если два (или более) отдельных процесса все решают, что им нужно обновить результат, чтобы вы в конечном итоге выполняли один и тот же (дорогой) запрос восемь раз подряд. Вы можете справиться с этой блокировкой кеша, но это создает еще одну проблему с производительностью. Вы также можете вернуться к concurrency методам на вашем языке (например, API Java 5 concurrency).

Если это обновление (или обновления происходят, которые необходимо отразить в вашем кеше чтения), то это немного сложнее, потому что не имеет хорошего значения старого кеша и более нового значения в базе данных, так что тогда предоставить вашим страницам непоследовательное представление данных. Но в широком смысле есть четыре подхода к этому:

  • Обновите кеш и затем оставьте запрос на обновление соответствующего хранилища;
  • Запись через кеширование: поставщик кэша может предоставить механизм для сохранения обновления и блокировки вызывающего абонента до тех пор, пока это изменение не будет выполнено; и
  • Кэширование с обратной записью: то же самое, что и кэширование с записью, но оно не блокирует вызывающего. Обновление происходит асинхронно и отдельно; и
  • Стойкость как модель обслуживания: это предполагает, что ваш механизм кэширования поддерживает некоторую наблюдаемость (например, прослушиватели событий кэша). В принципе, совершенно отдельный процесс - неизвестный вызывающему абоненту - прослушивает обновления кеша и сохраняет их по мере необходимости.

Какая из перечисленных выше методологий будет зависеть от ваших требований, используемых вами технологий и целого ряда других факторов (например, требуется поддержка кластеризации и восстановления после отказа?).

Трудно быть более конкретным, чем это, и дать вам указания о том, что делать, не зная много более подробно о вашей проблеме (например, есть ли у вас проблема).

Ответ 2

Скорее всего, вы прочтете о кешировании в контексте веб-приложений. Из-за природы Интернета кеширование может сильно отличаться.

Рассмотрим следующее:

Запрос веб-страницы попадает на веб-сервер, который передает запрос на сервер приложений, который выполняет некоторый код, который отображает страницу, и который должен обращаться к базе данных для динамического извлечения данных.

Эта модель плохо масштабируется, поскольку по мере того, как количество запросов на страницу увеличивается, сервер должен делать то же самое снова и снова, для каждого запроса.

Это становится еще более серьезной проблемой, если веб-сервер, сервер приложений и база данных находятся на другом оборудовании и обмениваются данными по сети друг с другом.

Если у вас есть большое количество пользователей, попавших на эту страницу, имеет смысл не пропустить весь путь до базы данных для каждого запроса. Вместо этого вы прибегаете к кешированию на разных уровнях.

Кэш результатов

Кэширование результатов - это сохранение результатов запроса базы данных вместе с запросом в приложении. Каждый раз, когда веб-страница генерирует запрос, приложения проверяют, уже ли кешируются результаты, а если они есть, вытаскивает их из набора данных в памяти. Приложение все еще должно отображать страницу.

Кэш-память компонентов

Веб-страница состоит из разных компонентов - страниц или любого другого, что вы можете назвать. Стратегия кэширования компонентов должна знать, какие параметры были использованы для запроса компонента. Например, небольшая панель "Последние новости" на сайте использует географическое местоположение пользователя или предпочитает показывать локальные новости. Следовательно, если новости для местоположения кэшируются, компонент не нужно отображать и вытаскивать из кеша.

Кэш страницы

Одной стратегией кэширования целых страниц является сохранение строки запроса и/или параметров заголовка вместе с полностью визуализированным HTML. Файловая система достаточно быстро для этого - для веб-сервера еще дешевле читать файл, чем делать вызов на сервер приложений для отображения страницы. В этом случае каждый пользователь, который отправляет ту же строку запроса, получит тот же кешированный контент.

Интеграция этих стратегий кэширования - единственный способ создать действительно масштабируемые веб-приложения для большого количества одновременных пользователей. Как вы можете видеть, потенциальный риск здесь заключается в том, что если часть содержимого в кеше не может быть однозначно идентифицирована с помощью ключа, люди начнут видеть неправильный контент. Это может стать довольно сложным, особенно когда у пользователей есть сеансы и есть контекст безопасности.

Ответ 3

Есть два значения, о которых я знаю.


Один из них - кеширование приложений. Это когда, если данные медленнее, чтобы получить откуда-то (например, из-за сети) или медленнее, чтобы вычислить, тогда приложение кэширует копию данных (чтобы ему не нужно было ее снова или пересчитать: it уже кэширован). Реализация кэша требует немного дополнительного прикладного программного обеспечения (логики для использования кеша) и дополнительной памяти (в которой хранятся кэшированные данные).

Это "кеширование" используется при цитировании здесь:

Из контекста я могу понять это, сохранить сохраненное значение в основной памяти и получить быстрый доступ к нему.


Другим является кэширование процессора, которое описано в этой статье в Википедии. Кэширование процессора происходит автоматически. Если вы много читаете из небольшого объема памяти, тогда центральный процессор может выполнять большинство этих чтений из своего кеша. OTOH, если вы читаете из большого объема памяти, он не может все вписываться в кеш, и процессор должен тратить больше времени на работу с более медленной памятью.

Это "кеширование" используется при цитировании здесь:

Когда кто-то говорит, что они нашли фрагмент кода, который повредил бы кеширование, и после того, как они исправили его, он улучшил скорость своего приложения, о чем они говорят?

Это означает, что они нашли способ изменить свой код, чтобы вызвать меньше Кэш пропускает.


Что касается кэширования базы данных, я не знаю.

Ответ 4

Есть несколько проблем.

Один, это гранулярность. Ваше приложение может иметь очень точные уровни кэширования сверх того, что делает база данных. Например, база данных, вероятно, просто кэширует страницы данных, а не обязательно определенные строки.

Другое дело, что приложение может хранить данные в своем "родном" формате, тогда как БД, очевидно, кэширует только в своем внутреннем формате.

Простой пример.

Скажите, что у вас есть Пользователь в базе данных, который состоит из столбцов: 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, ваше приложение не "знает это", и, следовательно, кеш грязный.

Итак, тогда есть куча деталей в обработке этой связи, чтобы поддерживать синхронизацию приложения с БД.

Наличие большого количества кеша базы данных очень хорошо для больших запросов по "горячим" наборам данных. Чем больше у вас памяти, тем более "горячие" данные вы можете получить. До такой степени, что вы можете кэшировать всю БД в ОЗУ, вы исключаете задержку ввода/вывода (по крайней мере, для чтения) переноса данных с диска на буфер ОЗУ. Но у вас все еще есть расходы на транспортировку и сортировку.

Приложение может быть гораздо более избирательным, например, кэширование более ограниченных подмножеств данных (только DB-кеширование блоков), а наличие данных "ближе" к приложению значительно повышает производительность.

Нижняя сторона заключается в том, что не все кэшируется в приложении. База данных имеет тенденцию хранить данные более эффективно, в целом, чем приложение. Вам также не хватает языка запросов к кэшированным данным приложения. Большинство людей просто кэшируют через простой ключ и идут оттуда. Легко найти USER ID 123, сложнее для "ВСЕ ПОЛЬЗОВАТЕЛИ ИМЕНИ".

Кэширование базы данных имеет тенденцию быть "бесплатным", вы устанавливаете номер буфера, а СУБД обрабатывает остальные. Низкое воздействие, уменьшает общие задержки ввода-вывода и дисков.

Кэширование приложений, конечно же, относится к конкретным приложениям.

Он отлично работает для изолированных "статических" данных. Это очень легко. Загрузите кучу вещей в поисковые таблицы при запуске и перезапустите приложение, если они меняются. Это легко сделать.

После этого сложность начинает увеличиваться по мере добавления в "грязную" логику и т.д.

Что все сводится к тому, что до тех пор, пока у вас есть API данных, вы можете кэшировать постепенно.

Итак, до тех пор, пока вы вызываете getUser(123) везде, а не попадаете в БД, вы можете позже вернуться и добавить кеширование в getUser, не влияя на ваш код.

Итак, я всегда предлагаю какой-то уровень доступа к данным в каждом коде, чтобы обеспечить этот бит уровня абстракции и перехвата.

Ответ 5

кэширование берет результат длинного или интенсивного алгоритма и сохраняет ответ, так что вам не нужно снова запускать алгоритм, вы просто повторно используете результат.

Ответ 6

Концепция кэша здесь является перегруженным термином. Я не знаком с гайками и болтами кэширования базы данных.

В приложениях есть два использования термина.

Когда кто-то говорит, что они нашли часть кода, которая повредила бы кеширование и после того, как они исправили его, он улучшился скорость их приложения, каковы они говорить о?

В этом случае они ссылаются на кеш процессора.

Кэш CPU - это память на процессоре, которая намного быстрее, чем оперативная память, но у нее нет случайного доступа. То, что CPU решает загрузить в кеш, может немного усложниться. См. Ulrich Dreppers Что каждый программист должен знать о памяти для большого количества деталей.

Помните, что кеш-память процессора может быстро ускорить работу - вам просто нужно уделять больше внимания тому, где вещи будут размещаться относительно друг друга в физической памяти и когда они, вероятно, будут использоваться.

Один пример (также, вероятно, анти-шаблон для ремонтопригодности) состоит в том, что у вас есть массив структур, и вы делаете много циклов над членами структуры, вам может быть лучше, со структурой, где все поля массивы. Если данные, которые вы зацикливаете, соприкасаются в памяти, у вас есть больше шансов не нарушать кеш.

Всевозможные вещи могут влиять на эффективность использования вашего кеша - предсказание ветвлений для кода, загружаемого в кеш, размер и выравнивание структур данных и шаблонов доступа, где и когда объявлять локальные переменные, которые будут помещаться на стек.

Другое общее использование термина для программирования приложений может быть сделано с помощью memoization. Факторный пример на этой странице wikipedia объясняет вещи лучше, чем я бы сделал.

Ответ 7

Кэширование в базах данных, как правило, является функцией базы данных, и она автоматически управляется базой данных. Кэширование в приложениях будет варьироваться от одной платформы к другой.

Кэш объектов - это механизм, который можно использовать для размещения обычно используемых объектов в памяти, так что вам не нужно оплачивать затраты для извлечения данных и их воссоздания. Обычно это управляется с помощью кода и зависит от того, какое решение для кеширования вы используете.

Существуют распределенные решения для кеша, которые включают настройку служб на нескольких серверах, чтобы дать вам ферму кеша. Это обеспечивает масштабируемость и избыточность. Клиенты могут запрашивать кешированную информацию по сети. Опять же, это ручная процедура в вашем коде. Пример поставщика распределенного кэша memcached:

http://www.danga.com/memcached/

Примером конкретного кэширования может быть кеширование asp.net. Asp.net поддерживает несколько видов кеша. Существует традиционный кэш объектов (который может использоваться во всех видах приложений .net, а не только на веб-сайтах). Существуют также функции кэширования, которые позволяют настраивать страницы и пользовательские элементы управления для автоматического кэширования их вывода. Это не кэширует данные, он кэширует конечный результат (HTML страницы) и обслуживает его, когда пользователь запрашивает одну и ту же страницу с теми же строками строки запроса, что и предыдущий пользователь.

Ответ 8

Это, вероятно, легче, чем вы могли себе представить, и почему люди пытаются его закрыть.

Это просто означает хранить значения в вашей памяти, а не возвращаться к базе данных для них каждый раз.

Существует много способов сделать это, но сама концепция тривиальна.

Изменить: это может быть сделано на ЛЮБОЙ уровень - все, что занимает много времени, может быть кэшировано где-то, что вы можете получить быстрее.

Ответ 9

Кэширование необязательно относится только к значениям "из полученных", но к чему-либо, что вы можете сэкономить, уменьшив количество повторных вычислений. Простым примером, который приходит на ум, является вычисление последовательности фибоначчи. Простейшая рекурсивная реализация выглядит так (в psuedo-code):

function f(n)
    if n < 2 then
        return n;
    return f(n - 1) + f(n - 2)

Это можно улучшить с помощью кэширования, чтобы предотвратить повторное вычисление уже известных значений:

fib_cache = {}

function f(n)
    if n < 2 then
        return n;
    if fib_cache.contains(n) then
        return fib_cache[n]
    fib_cache[n] = f(n - 1) + f(n - 2)
    return fib_cache[n]