数据库和缓存的更新方式

1.先更新数据库,再更新缓存
2.先更新缓存,再更新数据库
3.先更新数据库,再删除缓存
4.先删除缓存,再更新数据库
5.使用canal更新缓存

一、先更新数据库,再更新缓存

1
2
db.update(key,val)
cache.setex(key,ttl,val)
  • 1.如果数据库更新成功,缓存设置失败,结果数据库是新数据,缓存是旧数据,导致数据不一致
  • 2.高并发场景下,A线程更新数据库status=1成功后卡住,B线程更新数据库status=2,并更新缓存成功,然后A线程恢复,把缓存刷成status=1,此时数据库status=2和缓存status=1数据不一致
    结论:不推荐

二、先更新缓存,再更新数据库

1
2
cache.setex(key,ttl,val)
db.update(key,val)
  • 1.如果缓存更新成功,数据库设置失败,结果数据库是旧数据,缓存是新数据,导致数据不一致
  • 2.高并发场景下,A线程更新缓存status=1成功后卡住,B线程更新缓存status=2,并更新数据库成功,然后A线程恢复,把数据库刷成status=1,此时数据库status=1和缓存status=2数据不一致
    结论:不推荐

三、先更新数据库,再删除缓存

1
2
db.update(key,val)
cache.del(key)
  • 1.如果数据库更新成功,缓存删除失败,结果数据库是新数据,缓存是旧数据,导致数据不一致
  • 2.高并发场景下,A线程更新数据库status=1成功后卡住,B线程更新数据库status=2,并删除缓存成功,然后A线程恢复,删除缓存,此时不影响数据一致性
    结论:不推荐

四、先删除缓存,再更新数据库

1
2
cache.del(key)
db.update(key,val)
  • 1.如果缓存删除成功,数据库更新失败,此时不影响数据一致性

  • 2.高并发场景下,A线程删除缓存后卡住,B线程删除缓存,并更新数据库status=2,然后A线程恢复,更新数据库status=1,此时不影响数据一致性
    结论:可以接受

    五、使用canal更新缓存

    canal 主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费

主从复制

工作原理
canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议
MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
canal 解析 binary log 对象(原始为 byte 流)

  • 1.异步执行,数据最终一致
  • 2.高并发场景下,会产生短暂的不一致,但是数据会最终一致
    结论:若对实时一致性要求不高推荐