«Эта статья участвовала в мероприятии Haowen Convocation Order, щелкните, чтобы просмотреть:Двойные заявки на внутреннюю и внешнюю стороны, призовой фонд в 20 000 юаней ждет вас, чтобы бросить вызов!"
Поиск по общедоступным номерам Wechat [Программа Юань Сяочжуан], Ленивый человек не может наслаждаться отдыхом~
предисловие
Поскольку высокий параллелизм и высокая производительность кэша широко используются в различных проектах, кэш чтения в основном согласован и, вероятно, работает в соответствии с процессом, показанным на следующем рисунке:
Но с точки зрения кеша обновлений, обновляется ли он для обновления базы данных и удаления кеша напрямую? Или сначала удалить кеш и обновить базу? На этом этапе стоит обсудить.
Схема консистенции
В реальной разработке проекта необходимо убедиться, что данные в базе данных и кеше непротиворечивы, иначе люди перезаряжают 100 юаней, а он все равно показывает 0,01 юаня, не стыдно? отТеоретически установка времени истечения срока действия кеша является наилучшим решением для обеспечения согласованности данных., если эта схема принята, все операции записи основаны на базе данных.Если база данных успешно записана, но обновление кеша не удается, пока срок действия кеша истекает, а кеш читается позже, новое значение будет считано в базе данных а потом обновил кеш. Основное направление следующего обсуждения — как обеспечить согласованность данных, не полагаясь на время истечения срока действия, установленное для кеша. Вот три основных варианта:
①Сначала обновите базу данных, затем обновите кеш.
②Сначала удалите кэш, затем обновите базу данных.
③ Сначала обновите базу данных, затем удалите кеш.
Сначала обновите базу данных, а затем обновите кеш.
Это решение вообще противоположно (в моем сознании~), почему? Почему против этого плана? Есть две основные причины, пожалуйста, выслушайте меня подробно:
Во-первых, с точки зрения безопасности данных, если есть запрос на A и запрос на B для работы в одно и то же время, A сначала обновляет часть данных в базе данных, а затем B немедленно обновляет часть данных. , но это может быть связано с задержками в сети и другими причинами. Что происходит, когда кэш обновляется первым? Данные в кэше не являются последними данными, обновленными B, что приводит к несогласованности данных.
Во-вторых, с точки зрения бизнес-сценариев, если это бизнес, который записывает больше баз данных и читает меньше баз данных, если это решение будет принято, данные будут часто обновляться до того, как кэш будет прочитан, что является пустой тратой производительности.
Принимая во внимание два вышеупомянутых аспекта, эта схема решительно проходит. Следующие два решения являются двумя наиболее противоречивыми решениями: сначала удалить кеш, а затем обновить базу данных, или сначала обновить базу данных, а затем удалить кеш?
Сначала удалите кэш, а затем обновите базу данных.
Если одновременно есть запрос А на операцию обновления и запрос Б на операцию запроса, то может случиться так, что кеш будет удален до запроса А на операцию записи.Запрос Б просто придет в это время и обнаружит, что кеш пуст, и запрос B будет запрашивать базу данных.Если в это время операция записи, запрошенная A, не была завершена, а запрос B запрашивает старое значение или старое значение будет записано в кеш, а A запрашивает запись нового значения в базу данных, что приведет к несогласованности данных.Проблема в том, что если вы не примете стратегию установки срока действия для кеша, данные всегда будут быть грязными данными.
Чтобы решить эту ситуацию, вы можете использоватьОтсроченное двойное удалениеСтратегия состоит в том, чтобы удалить кеш перед обновлением базы данных, а затем записать в базу данных.После завершения обновления базы данных снова удалить кеш.Цель состоит в том, чтобы удалить грязные данные в кеше, которые могут быть вызваны запросом на чтение .Перед удалением кеша во второй раз можно Sleep на несколько секунд Разработчики могут оценить трудоемкость бизнес-логики чтения данных в своих проектах, а затем добавить к затратам времени несколько сотен мс. цель этого состоит в том, чтобы гарантировать, что запрос на чтение завершается, а запрос на запись может удалить запрос на чтение, что приводит к грязным данным. Если MySQL принимает архитектуру разделения чтения-записи, данные могут быть несогласованными из-за задержки ведущий-ведомый.После завершения операции записи вы можете некоторое время спать в соответствии со временем задержки ведущий-ведомый, а затем удалить кеш. Псевдокод для отложенного двойного удаления выглядит следующим образом:
# 伪代码
def delay_delete():
redis.delete('name') # 更新数据库之前先删除缓存
sql = 'update info set name='lili' where id=1;' # 更新数据库
cursor.execute(sql)
time.sleep(1) # 如果mysql是主从架构则休眠主从延时的时间再多几百ms
redis.delete('name') # 再次删除缓存
Не будет ли ошибки при удалении кеша во второй раз? Если второе удаление не удастся, это все равно вызовет проблему несоответствия кеша и базы данных, как ее решить? Давайте рассмотрим следующий вариант.
Сначала обновите базу данных, а затем удалите кеш
Иностранец предложилСхема обновления кэша, в статье упоминалось, что приложение должно получать данные из кеша. Если получение прошло успешно, оно вернется напрямую. Если получение не удалось, оно будет получено из базы данных. После успеха оно будет помещено в кеш. При обновлении данных данные должны быть сначала сохранены в базе данных. После успешного обновления кеш следует сделать недействительным. ** Исходный текст ниже
If an application updates information, it can follow the write-through strategy by making the modification to the data store, and by invalidating the corresponding item in the cache.
When the item is next required, using the cache-aside strategy will cause the updated data to be retrieved from the data store and added back into the cache.
Приведет ли эта схема к несогласованности данных? Например следующая ситуация:
Есть два запроса A и B. Запросы A и обновления B. Предположим, что происходит следующее:
① Кэш просто не работает в это время
② Запрос A будет запрашивать базу данных, чтобы получить старое значение.
③ Запросить B записать новое значение в базу данных
④ Удалите кеш после успешной записи запроса B.
⑤ Запрос A на запись найденного механизма в кеш, генерирующий грязные данные...
Если говорить о вышеописанной ситуации, то действительно будет несогласованность данных, но XDM задумайтесь, какова вероятность этого? Если этот результат должен быть получен первым, должно быть условие, то есть время операции запроса B очень короткое. Насколько время работы запроса B на запись в базу данных быстрее, чем время запроса A на читать данные из базы данных.Быстро (поскольку redis очень быстрый, поэтому время работы redis можно пока не учитывать), только в этом случае ④ может говорить первым, чем ⑤, но операция чтения базы данных происходит намного быстрее чем операция записи, иначе выполняется разделение чтения и записи. Так что вероятность этого очень, очень, очень мала, но что, если пациент с обсессивно-компульсивным расстройством должен быть излечен? Можно установить срок действия кэша или применить стратегию отложенного двойного удаления второй схемы, чтобы гарантировать выполнение операции удаления после завершения запроса на чтение.
последний вопрос
Есть еще проблема, то есть окончательное решение крайне низкой вероятности несогласованности данных, которая может возникнуть в третьем решении, заключается в использовании стратегии отложенного двойного удаления второго решения, но она также упоминается во втором решении. Что делать, если не удается удалить кэш? Не будет ли по-прежнему проблемы с несогласованностью данных? Как решить эту проблему? Вотмеханизм повторной попытки, если удаление не удалось, повторите попытку. Вот схема повторной попытки.
① Обновите базу данных
②Кэш не удалось удалить по разным причинам.
③ Поместите кеш, который не удалось удалить, в очередь сообщений
④Бизнес-код получает ключ для удаления из очереди сообщений
⑤ Продолжайте пытаться удалить операцию, пока она не завершится успешно.
Эпилог
Статья была впервые опубликована в публичном аккаунте WeChat.Ченг Юань Сяочжуан, синхронизировано сНаггетс.
Кодировать слова непросто, объясните, пожалуйста, источник перепечатки, а маленькие друзья, которые проходят мимо, протягивают свои милые пальчики и ставят лайк перед уходом (╹▽╹)