7天用Go动手写/从零实现分布式缓存GeeCache

目录

谈谈分布式缓存

第一次请求时将一些耗时操做的结果暂存,之后遇到相同的请求,直接返回暂存的数据。我想这是大部分童鞋对于缓存的理解。在计算机系统中,缓存无处不在,好比咱们访问一个网页,网页和引用的 JS/CSS 等静态文件,根据不一样的策略,会缓存在浏览器本地或是 CDN 服务器,那在第二次访问的时候,就会以为网页加载的速度快了很多;好比微博的点赞的数量,不可能每一个人每次访问,都从数据库中查找全部点赞的记录再统计,数据库的操做是很耗时的,很难支持那么大的流量,因此通常点赞这类数据是缓存在 Redis 服务集群中的。html

商业世界里,现金为王;架构世界里,缓存为王。node

缓存中最简单的莫过于存储在内存中的键值对缓存了。说到键值对,很容易想到的是字典(dict)类型,Go 语言中称之为 map。那直接建立一个 map,每次有新数据就往 map 中插入不就行了,这不就是键值对缓存么?这样作有什么问题呢?git

1)内存不够了怎么办?github

那就随机删掉几条数据好了。随机删掉好呢?仍是按照时间顺序好呢?或者是有没有其余更好的淘汰策略呢?不一样数据的访问频率是不同的,优先删除访问频率低的数据是否是更好呢?数据的访问频率可能随着时间变化,那优先删除最近最少访问的数据多是一个更好的选择。咱们须要实现一个合理的淘汰策略。golang

2)并发写入冲突了怎么办?数据库

对缓存的访问,通常不多是串行的。map 是没有并发保护的,应对并发的场景,修改操做(包括新增,更新和删除)须要加锁。浏览器

3)单机性能不够怎么办?缓存

单台计算机的资源是有限的,计算、存储等都是有限的。随着业务量和访问量的增长,单台机器很容易遇到瓶颈。若是利用多台计算机的资源,并行处理提升性能就要缓存应用可以支持分布式,这称为水平扩展(scale horizontally)。与水平扩展相对应的是垂直扩展(scale vertically),即经过增长单个节点的计算、存储、带宽等,来提升系统的性能,硬件的成本和性能并不是呈线性关系,大部分状况下,分布式系统是一个更优的选择。服务器

4)...架构

关于 GeeCache

设计一个分布式缓存系统,须要考虑资源控制、淘汰策略、并发、分布式节点通讯等各个方面的问题。并且,针对不一样的应用场景,还须要在不一样的特性之间权衡,例如,是否须要支持缓存更新?仍是假定缓存在淘汰以前是不容许改变的。不一样的权衡对应着不一样的实现。

groupcache 是 Go 语言版的 memcached,目的是在某些特定场合替代 memcached。groupcache 的做者也是 memcached 的做者。不管是了解单机缓存仍是分布式缓存,深刻学习这个库的实现都是很是有意义的。

GeeCache 基本上模仿了 groupcache 的实现,为了将代码量限制在 500 行左右(groupcache 约 3000 行),裁剪了部分功能。但整体实现上,仍是与 groupcache 很是接近的。支持特性有:

  • 单机缓存和基于 HTTP 的分布式缓存
  • 最近最少访问(Least Recently Used, LRU) 缓存策略
  • 使用 Go 锁机制防止缓存击穿
  • 使用一致性哈希选择节点,实现负载均衡
  • 使用 protobuf 优化节点间二进制通讯
  • ...

GeeCache 分7天实现,天天完成的部分都是能够独立运行和测试的,就像搭积木同样,天天实现的特性组合在一块儿就是最终的分布式缓存系统。天天的代码在 100 行左右。

附 推荐阅读

原文地址: 7天用Go从零实现分布式缓存GeeCache - 极客兔兔

相关文章
相关标签/搜索