Используется во многих местах в компьютерной областитайникНапример, чтобы смягчить несоответствие скоростей процессора и памяти, мы часто добавляем кеш первого, второго и третьего уровня. , по принципу локальности программы в большинстве случаев попадет в кеш.
В настоящее время основные данные веб-приложений обычно хранятся вбаза данныхНапример, информация о пользователе, информация о заказе, информация о транзакции и т. д., при этом база данных и язык программирования не имеют значения.Посредством взаимодействия SQL программам, написанным на таких языках, как Java и Php, необходимо получить доступ к базе данных, выполнить бизнес-логику и отображать результаты для пользователей. нобаза данныхСуществуют определенные ограничения, такие как: 1. Подключения к базе данных являются очень «дорогими» ресурсами. Для повторного использования этих ресурсов в настоящее время используется технология пула подключений. 2. Количество подключений в пуле подключений ограничено. много пользователей, необходимо Подождать, 3. Требуется блокировка при чтении и записи данных.
Из приведенного выше введения мы знаем, что база данных в крупномасштабной системе часто становится узким местом, и мы не можем получить доступ к базе данных каждый раз, когда мы обращаемся, особенно в случае нескольких пользователей и большого параллелизма. Какой метод мы обычно используем в такой ситуации?Все проблемы компьютерной индустрии можно решить, добавив слой абстракции.. Тогда для узкого места базы данных мы можем добавить слой к прикладному слою и слою базы данных, то естьслой кэша.
Как реализовать кеширование
Если вы главный архитектор крупной компании, и сейчас компании нужно самостоятельно разработать систему кеширования, как вам ее спроектировать? Я думаю, что вы должны подумать над следующими вопросами перед проектированием:
- В каком формате данные хранятся в кеше?
- Как приложение (клиент) получает доступ к кешу?
- Что делать, если место в кеше занято приложением?
- Хотите ли вы поддерживать распределенное хранилище (шардинг данных) и как?
1. Данные какого формата хранятся в кеше?
В настоящее время распространенные форматы данных включают сериализованные объекты, XML, JSON, строки (ключ, значение) и базовые структуры данных.язык JavaЕсть сериализация и десериализация сериализованных объектов, а protobuf, разработанный Google, не зависит от языка, например, Python сериализует объект, а Java может десериализовать этот объект.
2. Как приложение обращается к кешу
Учитывая, что в компании много серверных команд и используются разные языки программирования, это требует, чтобы наша собственная система кэширования была независима от языков программирования.разработать пакет договоровдля поддержки различных языков. Как клиент использует этот протокол? Наиболее распространенной является модель клиент/сервер. Сначала сервер прослушивает запрос, затем клиент отправляет запрос и получает ответ, где запрос, отправленный клиентом, является протоколом, и, наконец, он обменивается данными на основе сокета. Например:set 'name' 'mukedada'
,get name
.
3. Что делать, если место в кеше закончилось?
При запуске кэш-сервера необходимо задать размер кэша, при заполнении кэша используется алгоритм LRU.
4. Внедрить распределенное хранилище
Для крупномасштабных серверов приложений одномашинный кэш-сервер не может его поддерживать. Затем кэш-сервер должен бытьГоризонтальное расширение(То есть добавление или удаление серверов, когда активность закончилась, нужно подумать об удалении серверов), то какой алгоритм используется для распределения данных по каждому серверу относительно равномерно? При этом этот алгоритм должен быть размещен на стороне клиента или на стороне сервера?
- Реализация клиентаОбратите внимание, что клиент здесь относится к службе веб-приложений, а информация о списке серверов передается черезконфигурационный файлполучить. При изменении количества узлов клиент должен быть проинформирован.
Типичное его применениеMemcached, Memcached используетПоследовательный алгоритм хеширования, прежде чем представить его, давайте посмотрималгоритм остатка. Для (ключа, значения), которое пользователь хочет сохранить, вычислите целочисленное хэш-значение ключа, а затем вычислите оставшуюся часть числа серверов, чтобы определить сервер хранения. С этим методом есть фатальная проблема:При изменении количества отправленных серверов изменится и остаток, поэтому для получения данных необходимо снова зайти в базу. Для того, чтобы углубить общее понимание, давайте рассмотрим конкретный пример: Допустим, есть 3 сервера 0, 1, 2, хеш-значения ключа1 и ключа2 равны 100, 99 соответственно, а соответствующие остатки равны 1 и 0, что означает, что они хранятся отдельно.В серверах с номерами 1 и 0, теперь если добавить сервер 3, соответственно изменятся и их остатки, 100% 4 = 0, 99% 4 = 3, но их нет на серверах 0 и 3. Соответствующие данные найти не удалось.
Для решения проблемы алгоритма остатка наши предки предложилиАлгоритм распределенного согласованного хеширования. Его идея состоит в том, чтобы максимально снизить воздействие при изменении количества серверов. Например: когда мы добавляем node5, затрагиваются только ключи в локальной области, а оставшийся алгоритм влияет на глобальную.
Однако у него также есть проблема неравномерного распределения, из-за которой некоторые серверы кэшируют больше данных, а некоторые меньше. Один из способоввиртуальный узел, то есть сделать сервер воплощенным в виде нескольких виртуальных узлов и распределить их по кольцу. Memcache использует этот подход.
Другой метод — слот Hash. Redis принимает этот метод, который будет подробно описан при вводе реализации маршрутизации.-
реализация проксиПрограмма-агент размещается на стороне сервера, и ее типичными случаями являются Twemproxy и Codis. Его основная идея: приложение отправляет запрос Прокси, Прокси вычисляет узел, с которого должны быть получены данные по определенному алгоритму, и возвращает ответ клиенту. Чтобы прокси-сервер не имел единой точки отказа, высокая доступность прокси-сервера может быть достигнута с помощью кластеризации и других методов.
-
Реализация маршрутизации Его типичный случай — Redis. Его основная идея заключается в том, что приложение может отправить запрос любому узлу. Когда узел содержит данные запроса, он напрямую возвращает ответ приложению. Когда узел не содержит данных запроса, ему будет предложено перейти к другие узлы для получения данных, где клиентской библиотеке необходимо разобрать соответствующие инструкции. Например: когда в узле1 нет данных, клиентской программе будет разрешен доступ к узлу3, что аналогично веб-сайту.перенаправить, недостаток:node1 должен знать данные других узлов, то есть node1 и другие узлы взаимодействуют друг с другом.
Во-первых, у него 16284 слота, каждый узел управляет слотом Hash, и каждый раз, когда приходит новый запрос, обрабатывается значение его ключа.CRC16(key)%16384
Остаток в конечном итоге попадет в слот в диапазоне от 0 до 16383.
Однако всякий раз, когда добавляется новый узел, хэш-слот должен быть получен от каждого исходного узла, что требуетперенос данныхпроцесс. Что делать, если есть запрос пользователя в процессе переноса данных? В настоящее время решение состоит в том, чтобы позволить узлу 1 и узлу 4 удерживать один и тот же слот, но устанавливать разные состояния.Например, состояние слота узла 1 установлено как миграция, а состояние узла 4 — импорт, первая передача запроса узлу 1, если есть данные в node1, они будут возвращены напрямую, если нет, они будут переданы в ndoe4. Как показано ниже.
В то же время мы заметили, что единую точку отказа имеют узел 1, узел 2 и т. д. Для повышения доступности мы используем режим master-slave для каждого узла. Данные сначала записываются на главный узел, а затем есть два способа.Первый способ - напрямую вернуть результат клиенту, а затем синхронизировать данные главного узла с подчиненным узлом.Преимущество этого в том, что период ответа короткий, а недостаток в том, что может быть В случае несогласованности данных, то есть после того, как мастер-узел возвращает результат клиенту, сбой происходит до того, как он успеет синхронизировать данные с подчиненным узлом , то эта часть данных будет потеряна. Метод 2: после того, как данные записаны на главный узел, данные должны быть успешно синхронизированы с подчиненным узлом, а затем результат возвращен клиенту.Этот метод обеспечивает надежную согласованность данных, но пользователю нужно ждать дольше.
Проблема с разбивкой кеша
Каждый раз, когда пользователь обращается к кешу, кеш не попадает, в результате каждый запрос на доступ к базе данных Это проблема поломки кеша, в этом случае кеш не работает, но увеличивает потребление системы. В ответ на эту проблему, как правило, такие события, как Double Eleven, предварительно сохраняют информацию о пользователе в кэше до начала события.
Добро пожаловать в общедоступную учетную запись WeChat: Mu Keda, все статьи будут синхронизированы в общедоступной учетной записи.