задний план
Кэширование — очень полезная концепция в разработке программного обеспечения, а кэширование базы данных — неизбежный сценарий в проекте. В интервью неоднократно задавали вопрос о гарантии согласованности кеша Вот краткое изложение, чтобы выбрать правильную схему согласованности для различных требований.
что такое кеш
Есть разница в скорости хранения. Кэширование — это технология временного хранения результатов низкоскоростного хранения в высокоскоростном хранилище.
Как показано на рисунке, хранилище над пирамидой можно использовать в качестве кэша для хранилища под ним.На этот раз мы обсуждаем в основном сценарий кэширования базы данных, и в качестве примера мы возьмем Redis в качестве кэша MySQL.
Зачем нужно кэширование
Хранилище, такое как mysql, обычно поддерживает все функции ACID. Из-за таких факторов, как надежность и долговечность, производительность, как правило, невысока. Большое количество одновременных запросов будет оказывать давление на mysql и вызывать нестабильность системы базы данных. Он также подвержен задержкам. В соответствии с принципом локальности 80% запросов будут приходиться на 20% горячих данных.В сценарии большего чтения и меньшего количества записи добавление слоя кеша очень полезно для повышения пропускной способности и надежности системы.
Существует проблема
Сохраненные данные могут меняться со временем, а данные в кэше будут несогласованными. Конкретное допустимое время несогласованности требует специального анализа конкретного бизнеса, но обычный бизнес должен быть в конечном итоге непротиворечивым.
Redis как кеш mysql
В обычном режиме разработки в качестве хранилища используется mysql, а в качестве кэша для ускорения и защиты mysql используется redis. Однако, когда данные mysql обновляются, как Redis поддерживает синхронизацию.
Стоимость синхронизации строгой согласованности слишком высока.Если преследуется цель строгой согласованности, то нет необходимости использовать кеш, и можно использовать напрямую mysql. Что обычно считается возможной согласованностью.
решение
Вариант первый
Через время истечения ключа, при обновлении mysql, redis не обновляется. Этот метод прост в реализации, но время несоответствия будет очень большим. Если запросы на чтение очень часты, а время истечения относительно велико, будет сгенерировано много долговременных грязных данных.
преимущество:
- Низкая стоимость разработки и простота реализации;
- Стоимость управления низкая, и вероятность проблем будет относительно небольшой.
недостаточный
- Это полностью зависит от времени истечения срока действия. Если время слишком короткое, кеш будет часто аннулироваться. Если оно слишком длинное, будет длительная задержка обновления (несогласованность).
Вариант 2
Расширение на основе схемы 1, для получения итогового результата используется время истечения ключа, а при обновлении mysql одновременно обновляется и redis.
преимущество
- По сравнению со схемой 1 задержка обновления меньше.
недостаточный
- Если обновление mysql прошло успешно, а обновление redis завершилось неудачно, схема выродится до первой;
- В сценариях с высокой степенью параллелизма бизнес-серверу необходимо одновременно подключаться к mysql и redis. Таким образом, ресурсы соединения удваиваются, и легко вызвать проблему слишком большого количества соединений.
третье решение
Оптимизируйте синхронную запись Redis в решении 2, увеличьте очередь сообщений, передайте операцию обновления Redis в kafka и обеспечьте надежность очереди сообщений, а затем создайте службу потребителя для асинхронного обновления Redis.
преимущество
- Очередь сообщений может использовать дескриптор, и многие клиенты очереди сообщений также поддерживают отправку в локальный кэш, что эффективно решает проблему слишком большого количества соединений во втором решении;
- Используйте очередь сообщений для достижения логической развязки;
- Сама очередь сообщений надежна и может быть использована для повторного использования хотя бы один раз путем отправки вручную.
недостаточный
- Проблема таймингов до сих пор не решена.Если несколько бизнес-серверов обрабатывают два запроса на одну и ту же строку данных, например, a=1;a=5;, если первый в mysql выполняется первым, а тот, что входит в kafka Порядок таков, что второй выполняется первым, тогда данные будут несогласованными.
- Вводится очередь сообщений, и в то же время сообщение о потреблении услуг необходимо увеличивать, а стоимость высока.
Вариант 4
Обновите Redis, подписавшись на binlog, используйте потребительскую службу, которую мы создали как ведомую для mysql, подпишитесь на binlog, проанализируйте обновленное содержимое, а затем обновите его до Redis.
преимущество
- В случае низкого давления mysql задержка невелика;
- Полностью отделен от бизнеса;
- Исправлены проблемы со временем.
недостаток
- Чтобы построить отдельную службу синхронизации и внедрить механизм синхронизации binlog, стоимость относительно высока.
Суммировать
Выбор схемы
- Во-первых, подтвердите требования к задержке продукта.Если требования чрезвычайно высоки и данные могут измениться, не используйте кэш.
- Вообще говоря, достаточно решения 1. Автор проконсультировался с 4 или 5 командами, и они в основном используют решение 1. Поскольку можно использовать решение кэширования, обычно это сценарий большего чтения и меньшего написания, и в то же время, у бизнеса есть определенная терпимость к задержкам. Вариант 1 не требует затрат на разработку и на самом деле более практичен.
- Если вы хотите повысить оперативность обновления, выберите вариант 2, но нет необходимости делать гарантии повторных попыток и тому подобное.
- Вариант 3 и вариант 4 предназначены для сервисов с относительно высокими требованиями к задержке, один из них — режим push, а другой — режим pull, а решение 4 имеет более высокую надежность, поскольку они готовы тратить время на логику обработки сообщений, лучше сделать это в один шаг, используйте вариант 4.
в заключении
В общем, варианта 1 достаточно. Если требования к задержке высокие, выберите вариант 4 напрямую. Если это сцена интервью, от простого к сложному, интервьюер будет поэтапно задавать вопросы, мы понемногу выведем, а гости и ведущие получат удовольствие.