/images/avatar.jpg

Crazyfrank 的博客

Raft 协议

Raft算法深度解析 - 第一部分:问题的起源

为什么需要Raft?从单机到分布式的痛苦历程

1. 从单机开始:一切都很简单

想象你在开发一个简单的计数器服务:

// 单机版本 - 完美运行
type Counter struct {
    value int
    mu    sync.Mutex
}

func (c *Counter) Increment() {
    c.mu.Lock()
    c.value++
    c.mu.Unlock()
}

func (c *Counter) Get() int {
    c.mu.Lock()
    defer c.mu.Unlock()
    return c.value
}

单机的美好世界

缓存与数据库--一致性的取舍

今天讲讲旁路缓存策略。

概念介绍

一般来说我们在业务中引入缓存,涉及到三种操作数据库和缓存的方式:

  • 读穿:
    1. 应用读数据。
    2. 查 Redis。命中则返回。
    3. 未命中则查 MySQL。
    4. 从 MySQL 取到数据后,写入 Redis。
    5. 返回数据。
  • 写穿:
    1. 应用更新数据。
    2. 代码同时(或在同一个事务中)执行:
      • 更新 MySQL 数据库。
      • 更新(或失效)Redis 中的对应缓存。
  • 旁路缓存:
    • 读操作:采用 “读穿” 策略。
      • Cache Hit -> 返回缓存数据。
      • Cache Miss -> 从 DB 读,回填 Cache,再返回。
    • 写操作:先更新数据库,然后删除(失效)缓存。
      • 这是“旁路缓存”策略的精髓——“先更新数据库,再删缓存”。

对于读穿从上面的介绍也可以看出来它不是单独使用的,而写穿,目前没有一个中间件支持同时操作数据库,所以一般不使用,所以日常使用最多的也就说第三种方式:旁路缓存

技术选型

基本准则

从数据出发。

具体什么意思呢?很多时候,我们在没有进入企业化开发的时候,功能实现完、测试后基本上就算“完成”了。但从一个企业级的项目来说,编码结束,才是项目的开始。