阅读907 返回首页    go 阿里云


设置热点 Key__用户指南_云数据库 Memcache 版-阿里云

热点 Key 技术详情

背景信息

在分布式 K-V 存储系统中,对某个 key 进行读写时,会根据该 key 的 hash 计算出一台固定的 server 来存取该 K-V,如果集群不发生服务器数量变化,那么这一映射关系就不会变化。

云数据库 Memcache 版就是这样一种 K-V 缓存系统。因此在实际应用中,某些高峰时段,有的云数据库 Memcache 版用户会大量请求同一个 Key(可能对应应用的热卖商品、热点新闻、热点评论等),所有的请求(且这类请求读写比例非常高)都会落到同一个 server 上,该机器的负载就会严重加剧,此时整个系统增加新 server 也没有任何用处,因为根据 hash 算法,同一个 key 的请求还是会落到同一台新机器上,该机器依然会成为系统瓶颈。这个问题称为“热点key”问题。

现状

用户使用云数据库 Memcache 版就是为了提升业务性能,难免会触发“热点key问题”。但云数据库 Memcache 版做为公共云服务,在发现有热点的情况下,如果继续放任该热点无限激增,就会带来整个系统宕机。所以当前的做法会对每个用户在每台服务器上分配一定的 QPS 或带宽,当用户在某台服务器上的请求超过该用户的配额,我们就会对用户进行流控,服务端返回 TEMPORARY_FAILURE。该限制会影响用户正常请求,持续时间分钟级。

解决方案

云数据库 Memcache 版简单架构图如下。

proxy 是无状态层,上面做了些访问控制功能,用户客户端到 proxy 是随机的,不受固定算法(如 hash)控制。而 proxy 到 DataServer 的链路是根据 key 决定的,当用户访问热点 key 时,所有 proxy 上关于该 key 的请求都会落到同一台 DataServer。

所以解决热点问题,其核心思路是:每台 DataServer 对所有 key 进行采样、定位,实时计算出当前热点 key,将其反馈给 proxy 层,由 proxy 缓存备份。即负载压力由 DataServer 转向 proxy,因为 proxy 可以无状态扩容,而 DataServer 不可以。

DataServer如何发现热点?

每台服务器有个 HotKey 逻辑,让每个到达服务器的目标请求(可配置不同类型请求)经历三个流水阶段。流程图如下。

  • 采样阶段(根据配置设定采样次数 sample_max)

    本阶段输出:是否有热点现象,如果有热点,输出热点的桶号供下阶段使用。

  • 定位阶段(根据配置设定采样次数 reap_max)

    本阶段输出:热点 key(如果满足阈值)。 并添加到服务端的 LRU 链表。

  • 反馈阶段

    对到达服务器的目标请求,取出 key,然后查询 LRU 链表判断该 key 是否为热点 key。如果是热点,就会在请求结束后,向 proxy 发送一个 feedback 包,通知 proxy。至此,服务器 HotKey 逻辑结束。

发现热点后 proxy 怎么处理?

当 proxy 收到 DataServer 的热点反馈之后,会将该 key 写入到自己的 LRU-cache 里面。这样,热点的 key 就已经存在于与 proxy 中了,下次用户请求就可以直接返回了。

如何保证数据一致性呢?

下面讨论都是用户 client 已经触发了热点 key 问题,假设用户 client 跟每个 proxy 都建立了链接,并且每个 proxy 上都有对热点 key 的请求,那么理论上每个 proxy 的 LRU-cache 都有一份数据。

保证单条连接上的一致性

当用户 client 和 proxy1 建立连接,用户修改了一个 key(任何写操作),proxy1 上会在 LRU-cache 中同步删除该 key,新 key 就会写到 DataServer 上,然后在读数据的时候,由于 LRU-cache 不命中,就会 从DataServer 上拿到最新数据。

不同链接上只能提供弱一致性

如果这个时候用户从 proxy2 上读热点数据呢?理论上就会读到老数据,该数据将于100 ms之后从 proxy-cache 中过期淘汰掉,之后就会更新会最新数据,即不同连接间可能有100 ms 不一致。

怎样看待弱一致性

事实上,不开启热点 key 功能,在不同链接上也会存在弱一致。假设用户 client 建立了两条链接到云数据库 Memcache 版,在链接1上写 入key-value1,在链接1、2上分别读该 key。当链接1上用户 update 了 key-value2,这个请求需要一定的网络延迟才能写入到服务端,如果这个时候链接2上同时发起对 key 的读取操作,如果读请求先到服务端,它将读到的是 value1 的老值。

所以开启热点 key 功能,只是增加了不一致时间,且该功能为可选。控制权由用户掌握。

适用场景

开启热点 key功 能之后,只会对用户的读请求产生影响,该影响增加了不同链接上的弱一致性的时间。因此,该功能适合读多写少,且对强一致性要求不高的应用。收益整个方案核心是负载压力由 DataServer 转移到 proxy。好处如下:

  • 因为 DataServer 扩容也解决不了热点问题,而 proxy 可以无状态扩容,对用户来讲就极大提升了热点 key 访问的能力,不受单点制约。

  • 缩短了服务端处理链路,对用户平均 RT 也所降低。

  • 免除服务端热点流控的分钟级别影响。

操作步骤

开启热点 Key 模式,可以有效提升高峰业务时段的响应能力。

  1. 登录 Memcache 管理控制台

  2. 实例列表页面,定位到目标实例。

  3. 单击实例右侧的管理,进入到基本信息页面。

  4. 在左侧导航栏选择热点 Key 设置

  5. 选择开启热点 Key 模式。

最后更新:2016-12-14 14:57:00

  上一篇:go 免密码访问__用户指南_云数据库 Memcache 版-阿里云
  下一篇:go 监控与报警__用户指南_云数据库 Memcache 版-阿里云