美团万亿级 KV 存储架构与实践

KV 存储做为美团一项重要的在线存储服务,承载了在线服务天天万亿级的请求量。在 2019 年 QCon 全球软件开发大会(上海站)上,美团高级技术专家齐泽斌分享了《美团点评万亿级 KV 存储架构与实践》,本文系演讲内容的整理,主要分为四个部分:第一部分讲述了美团 KV 存储的发展历程;第二部分阐述了内存 KV Squirrel 架构和实践;第三部分介绍了持久化 KV Cellar 架构和实践;最后分享了将来的发展规划和业界新趋势。算法

美团点评 KV 存储发展历程

美团第一代的分布式 KV 存储以下图左侧的架构所示,相信不少公司都经历过这个阶段。在客户端内作一致性哈希,在后端部署不少的 Memcached 实例,这样就实现了最基本的 KV 存储分布式设计。但这样的设计存在很明显的问题:好比在宕机摘除节点时,会丢数据,缓存空间不够须要扩容,一致性哈希也会丢失一些数据等等,这样会给业务开发带来的不少困扰。后端

随着 Redis 项目的成熟,美团也引入了 Redis 来解决咱们上面提到的问题,进而演进出来如上图右侧这样一个架构。你们能够看到,客户端仍是同样,采用了一致性哈希算法,服务器端变成了 Redis 组成的主从结构。当任何一个节点宕机,咱们能够经过 Redis 哨兵完成 Failover,实现高可用。但有一个问题仍是没有解决,若是扩缩容的话,一致性哈希仍然会丢数据,那么这个问题该如何解决呢?缓存

这个时候,咱们发现有了一个比较成熟的 KV 存储开源项目:阿里 Tair 。2014年,咱们引入了 Tair 来知足业务 KV 存储方面的需求。Tair 开源版本的架构主要分红三部分:上图下边是存储节点,存储节点会上报心跳到它的中心节点,中心节点内部有两个配置管理节点,会监控全部的存储节点。当有任何存储节点宕机或者扩容时,它会作集群拓扑的从新构建。当客户端启动时,它会直接从中心节点拉来一个路由表。这个路由表简单来讲就是一个集群的数据分布图,客户端根据路由表直接去存储节点读写。针对以前 KV 的扩容丢数据问题,它也有数据迁移机制来保证数据的完整性。服务器

可是,咱们在使用的过程当中,还遇到了一些其余问题,好比中心节点虽然是主备高可用的,但实际上它没有相似于分布式仲裁的机制,因此在网络分割的状况下,它是有可能发生“脑裂”的,这个也给咱们的业务形成过比较大的影响。另外,在容灾扩容时,也遇到过数据迁移影响到业务可用性的问题。另外,咱们以前用过 Redis ,业务会发现 Redis 的数据结构特别丰富,而 Tair 还不支持这些数据结构。虽然咱们用 Tair 解决了一些问题,可是 Tair 也没法彻底知足业务需求。毕竟,在美团这样一个业务规模较大和业务复杂度较高的场景下,很难有开源系统能很好地知足咱们的需求。最终,咱们决定在已应用的开源系统之上进行自研。微信

恰好在2015 年, Redis 官方正式发布了集群版本 Redis Cluster。因此,咱们紧跟社区步伐,并结合内部需求作了不少开发工做,演进出了全内存、高吞吐、低延迟的 KV 存储 Squirrel。另外,基于 Tair,咱们还加入了不少自研的功能,演进出持久化、大容量、数据高可靠的 KV 存储 Cellar 。由于 Tair 的开源版本已经有四五年没有更新了,因此,Cellar 的迭代彻底靠美团自研,而 Redis 社区一直很活跃。总的来讲,Squirrel 的迭代是自研和社区并重,自研功能设计上也会尽可能与官方架构进行兼容。后面你们能够看到,由于这些不一样,Cellar 和 Squirrel 在解决一样的问题时也选取了不一样的设计方案。网络

这两个存储其实都是 KV 存储领域不一样的解决方案。在实际应用上,若是业务的数据量小,对延迟敏感,咱们建议你们用 Squirrel ;若是数据量大,对延迟不是特别敏感,咱们建议用成本更低的 Cellar 。目前这两套 KV 存储系统在美团内部天天的调用量均已突破万亿,它们的请求峰值也都突破了每秒亿级。数据结构

内存 KV Squirrel 架构和实践

在开始以前,本文先介绍两个存储系统共通的地方。好比分布式存储的经典问题:数据是如何分布的?这个问题在 KV 存储领域,就是 Key 是怎么分布到存储节点上的。这里 Squirrel 跟 Cellar 是同样的。当咱们拿到一个 Key 后,用固定的哈希算法拿到一个哈希值,而后将哈希值对 Slot 数目取模获得一个Slot id,咱们两个 KV 如今都是预分片16384个 Slot 。获得 Slot id 以后,再根据路由表就能查到这个 Slot 存储在哪一个存储节点上。这个路由表简单来讲就是一个 Slot 到存储节点的对照表。多线程

KV 数据分布介绍

接下来说一下对高可用架构的认知,我的认为高可用能够从宏观和微观两个角度来看。从宏观的角度来看,高可用就是指容灾怎么作。好比说挂掉了一个节点,你该怎么作?一个机房或者说某个地域的一批机房宕机了,你该怎么作?而从微观的角度看,高可用就是怎么能保证端到端的高成功率。咱们在作一些运维升级或者扩缩容数据迁移的时候,可否作到业务请求的高可用? 本文也会从宏观和微观两个角度来分享美团作的一些高可用工做。架构

Squirrel 架构

上图就是咱们的 Squirrel 架构。中间部分跟 Redis 官方集群是一致的。它有主从的结构, Redis 实例之间经过 Gossip 协议去通讯。咱们在右边添加了一个集群调度平台,包含调度服务、扩缩容服务和高可用服务等,它会去管理整个集群,把管理结果做为元数据更新到 ZooKeeper。咱们的客户端会订阅 ZooKeeper 上的元数据变动,实时获取到集群的拓扑状态,直接在 Redis 集群进行读写操做。并发

Squirrel 节点容灾

而后再看一下 Squirrel 容灾怎么作。对于 Redis 集群而言,节点宕机已经有完备的处理机制了。官方提供的方案,任何一个节点从宕机到被标记为 FAIL 摘除,通常须要通过 30 秒。主库的摘除可能会影响数据的完整性,因此,咱们须要谨慎一些。可是对于从库呢?咱们认为这个过程彻底不必。另外一点,咱们都知道内存的 KV 存储数据量通常都比较小。对于业务量很大的公司来讲,它每每会有不少的集群。若是发生交换机故障,会影响到不少的集群,宕机以后去补副本就会变得很是麻烦。为了解决这两个问题,咱们作了 HA 高可用服务。

它的架构以下图所示,它会实时监控集群的全部节点。无论是网络抖动,仍是发生了宕机(好比说 Redis 2 ),它能够实时更新 ZooKeeper ,告诉 ZooKeeper 去摘除 Redis 2 ,客户端收到消息后,读流量就直接路由到 Redis 3上。若是 Redis 2 只是几十秒的网络抖动,过几十秒以后,若是 HA 节点监控到它恢复后,会把它从新加回。

Squirrel—节点容灾

若是过了一段时间,HA 判断它属于一个永久性的宕机,HA 节点会直接从 Kubernetes 集群申请一个新的 Redis 4 容器实例,把它加到集群里。此时,拓扑结构又变成了一主两从的标准结构,HA 节点更新完集群拓扑以后,就会去写 ZooKeeper 通知客户端去更新路由,客户端就能到 Redis 4 这个新从库上进行读操做。

经过上述方案,咱们把从库的摘除时间从 30 秒下降到了 5 秒。另外,咱们经过 HA 自动申请容器实例加入集群的方式,把宕机补副本变成了一个分钟级的自动操做,不须要任何人工的介入。

Squirrel 跨地域容灾

咱们解决了单节点宕机的问题,那么跨地域问题如何解决呢?咱们首先来看下跨地域有什么不一样。第一,相对于同地域机房间的网络而言,跨地域专线很不稳定;第二,跨地域专线的带宽是很是有限且昂贵的。而集群内的复制没有考虑极端的网络环境。假如咱们把主库部署到北京,两个从库部署在上海,一样一份数据要在北上专线传输两次,这样会形成巨大的专线带宽浪费。另外,随着业务的发展和演进,咱们也在作单元化部署和异地多活架构。用官方的主从同步,知足不了咱们的这些需求。基于此,咱们又作了集群间的复制方案。

如上图所示,这里画出了北京的主集群以及上海的从集群,咱们要作的是经过集群同步服务,把北京主集群的数据同步到上海从集群上。按照流程,首先要向咱们的同步调度模块下发“在两个集群间创建同步链路”的任务,同步调度模块会根据主从集群的拓扑结构,把主从集群间的同步任务下发到同步集群,同步集群收到同步任务后会扮成 Redis 的 Slave,经过 Redis 的复制协议,从主集群上的从库拉取数据,包括 RDB以及后续的增量变动。同步机收到数据后会把它转成客户端的写命令,写到上海从集群的主节点里。经过这样的方式,咱们把北京主集群的数据同步到了上海的从集群。一样的,咱们要作异地多活也很简单,再加一个反向的同步链路,就能够实现集群间的双向同步。

接下来咱们讲一下如何作好微观角度的高可用,也就是保持端到端的高成功率。对于 Squirrel ,主要讲以下三个影响成功率的问题:

  • 数据迁移形成超时抖动。
  • 持久化形成超时抖动。
  • 热点 Key 请求致使单节点过载。

Squirrel 智能迁移

对于数据迁移,咱们主要遇到三个问题:

  • Redis Cluster 虽然提供了数据迁移能力,可是对于要迁哪些 Slot,Slot 从哪迁到哪,它并无论。
  • 作数据迁移的时候,你们都想越快越好,可是迁移速度过快又可能影响业务正常请求。
  • Redis 的 Migrate 命令会阻塞工做线程,尤为在迁移大 Value 的时候会阻塞特别久。

为了解决这些问题,咱们作了全新的迁移服务。

下面咱们按照工做流,讲一下它是如何运行的。首先生成迁移任务,这步的核心是“就近原则”,好比说同机房的两个节点作迁移确定比跨机房的两个节点快。迁移任务生成以后,会把任务下发到一批迁移机上。迁移机迁移的时候,有这样几个特色:

  • 第一,会在集群内迁出节点间作并发,好比同时给 Redis 一、Redis 3 下发迁移命令。
  • 第二,每一个 Migrate 命令会迁移一批 Key。
  • 第三,咱们会用监控服务去实时采集客户端的成功率、耗时,服务端的负载、QPS 等,以后把这个状态反馈到迁移机上。迁移数据的过程就相似 TCP 慢启动的过程,它会把速度一直往上加,若出现请求成功率降低等状况,它的速度就会下降,最终迁移速度会在动态平衡中稳定下来,这样就达到了最快速的迁移,同时又尽量小地影响业务的正常请求。

接下来,咱们看一下大 Value 的迁移,咱们实现了一个异步 Migrate 命令,该命令执行时,Redis 的主线程会继续处理其余的正常请求。若是此时有对正在迁移 Key 的写请求过来,Redis 会直接返回错误。这样最大限度保证了业务请求的正常处理,同时又不会阻塞主线程。

Squirrel 持久化重构

Redis 主从同步时会生成 RDB。生成 RDB 的过程会调用 Fork 产生一个子进程去写数据到硬盘,Fork 虽然有操做系统的 COW 机制,可是当内存用量达到 10 G 或 20 G 时,依然会形成整个进程接近秒级的阻塞。这对在线业务来讲几乎是没法接受的。咱们也会为数据可靠性要求高的业务去开启 AOF,而开 AOF 就可能因 IO 抖动形成进程阻塞,这也会影响请求成功率。对官方持久化机制的这两个问题,咱们的解决方案是重构持久化机制。

上图是咱们最新版的 Redis 持久化机制,写请求会先写到 DB 里,而后写到内存 Backlog,这跟官方是同样的。同时它会把请求发给异步线程,异步线程负责把变动刷到硬盘的 Backlog 里。当硬盘 Backlog 过多时,咱们会主动在业务低峰期作一次 RDB ,而后把 RDB 以前生成的 Backlog 删除。

若是这时候咱们要作主从同步,去寻找同步点的时候,该怎么办?第一步仍是跟官方同样,咱们会从内存 Backlog 里找有没有要求的同步点,若是没有,咱们会去硬盘 Backlog 找同步点。因为硬盘空间很大,硬盘 Backlog 能够存储特别多的数据,因此不多会出现找不到同步点的状况。若是硬盘 Backlog 也没有,咱们就会触发一次相似于全量重传的操做,但这里的全量重传是不须要当场生成 RDB 的,它能够直接用硬盘已存的 RDB 及其以后的硬盘 Backlog 完成全量重传。经过这个设计,咱们减小了不少的全量重传。另外,咱们经过控制在低峰区生成 RDB ,减小了不少 RDB 形成的抖动。同时,咱们也避免了写 AOF 形成的抖动。不过,这个方案由于写 AOF 是彻底异步的,因此会比官方的数据可靠性差一些,但咱们认为这个代价换来了可用性的提高,这是很是值得的。

Squirrel 热点 Key

下面看一下 Squirrel 的热点 Key 解决方案。以下图所示,普通主、从是一个正常集群中的节点,热点主、从是游离于正常集群以外的节点。咱们看一下它们之间怎么发生联系。

当有请求进来读写普通节点时,节点内会同时作请求 Key 的统计。若是某个 Key 达到了必定的访问量或者带宽的占用量,会自动触发流控以限制热点 Key 访问,防止节点被热点请求打满。同时,监控服务会周期性的去全部 Redis 实例上查询统计到的热点 Key。若是有热点,监控服务会把热点 Key 所在 Slot 上报到咱们的迁移服务。迁移服务这时会把热点主从节点加入到这个集群中,而后把热点 Slot 迁移到这个热点主从上。由于热点主从上只有热点 Slot 的请求,因此热点 Key的处理能力获得了大幅提高。经过这样的设计,咱们能够作到实时的热点监控,并及时经过流控去止损;经过热点迁移,咱们能作到自动的热点隔离和快速的容量扩充。

持久化 KV Cellar 架构和实践

下面看一下持久化 KV Cellar 的架构和实践。下图是咱们最新的 Cellar 架构图。

跟阿里开源的 Tair 主要有两个架构上的不一样。第一个是OB,第二个是 ZooKeeper。咱们的 OB 跟 ZooKeeper 的 Observer 是相似的做用,提供 Cellar 中心节点元数据的查询服务。它能够实时与中心节点的 Master 同步最新的路由表,客户端的路由表都是从 OB 去拿。 这样作的好处主要有两点,第一,把大量的业务客户端跟集群的大脑 Master 作了自然的隔离,防止路由表请求影响集群的管理。第二,由于 OB 只供路由表查询,不参与集群的管理,因此它能够进行水平扩展,极大地提高了咱们路由表的查询能力。另外,咱们引入了 ZooKeeper 作分布式仲裁,解决我刚才提到的 Master、Slave 在网络分割状况下的“脑裂”问题,而且经过把集群的元数据存储到 ZooKeeper,咱们保证了元数据的高可靠。

Cellar 节点容灾

介绍完总体的架构,咱们看一下 Cellar 怎么作节点容灾。一个集群节点的宕机通常是临时的,一个节点的网络抖动也是临时的,它们会很快地恢复,并从新加入集群。由于节点的临时离开就把它完全摘除,并作数据副本补全操做,会消耗大量资源,进而影响到业务请求。因此,咱们实现了 Handoff 机制来解决这种节点短时故障带来的影响。

如上图所示 ,若是 A 节点宕机了,会触发 Handoff 机制,这时候中心节点会通知客户端 A节点发生了故障,让客户端把分片 1 的请求也打到 B 上。B 节点正常处理完客户端的读写请求以后,还会把本应该写入 A 节点的分片 1&2 数据写入到本地的 Log 中。

若是 A 节点宕机后 3~5 分钟,或者网络抖动 30~50 秒以后恢复了,A 节点就会上报心跳到中心节点,中心节点就会通知 B 节点:“ A 节点恢复了,你去把它不在期间的数据传给它。”这时候,B 节点就会把本地存储的 Log 回写到 A 节点上。等到 A 节点拥有了故障期间的全量数据以后,中心节点就会告诉客户端,A 节点已经完全恢复了,客户端就能够从新把分片 1 的请求打回 A 节点。

经过这样的操做,咱们能够作到秒级的快速节点摘除,并且节点恢复后加回,只需补齐少许的增量数据。另外若是 A 节点要作升级,中心节点先经过主动 Handoff 把 A 节点流量切到 B 节点,A 升级后再回写增量 Log,而后切回流量加入集群。这样经过主动触发 Handoff 机制,咱们就实现了静默升级的功能。

Cellar 跨地域容灾

下面我介绍一下 Cellar 跨地域容灾是怎么作的。Cellar 跟 Squirrel 面对的跨地域容灾问题是同样的,解决方案一样也是集群间复制。如下图一个北京主集群、上海从集群的跨地域场景为例,好比说客户端的写操做到了北京的主集群 A 节点,A 节点会像正常集群内复制同样,把它复制到 B 和 D 节点上。同时 A 节点还会把数据复制一份到从集群的 H 节点。H 节点处理完集群间复制写入以后,它也会作从集群内的复制,把这个写操做复制到从集群的 I 、K 节点上。经过在主从集群的节点间创建这样一个复制链路,咱们完成了集群间的数据复制,而且这个复制保证了最低的跨地域带宽占用。一样的,集群间的两个节点经过配置两个双向复制的链路,就能够达到双向同步异地多活的效果。

Cellar 强一致

咱们作好了节点容灾以及跨地域容灾后,业务又对咱们提出了更高要求:强一致存储。咱们以前的数据复制是异步的,在作故障摘除时,可能由于故障节点数据还没复制出来,致使数据丢失。可是对于金融支付等场景来讲,它们是不允许数据丢失的。面对这个难题,咱们该怎么解决?目前业界主流的解决方案是基于 Paxos 或 Raft 协议的强一致复制。咱们最终选择了 Raft 协议。主要是由于 Raft 论文是很是详实的,是一篇工程化程度很高的论文。业界也有很多比较成熟的 Raft 开源实现,能够做为咱们研发的基础,进而可以缩短研发周期。

下图是如今 Cellar 集群 Raft 复制模式下的架构图,中心节点会作 Raft 组的调度,它会决定每个 Slot 的三副本存在哪些节点上。

你们能够看到 Slot 1 在存储节点 一、二、4 上,Slot 2 在存储节点二、三、4上。每一个 Slot 组成一个 Raft 组,客户端会去 Raft Leader 上进行读写。因为咱们是预分配了 16384 个 Slot,因此,在集群规模很小的时候,咱们的存储节点上可能会有数百甚至上千个 Slot 。这时候若是每一个 Raft 复制组都有本身的复制线程、 复制请求和 Log等,那么资源消耗会很是大,写入性能会不好。因此咱们作了 Multi Raft 实现, Cellar 会把同一个节点上全部的 Raft 复制组写一份 Log,用同一组线程去作复制,不一样 Raft 组间的复制包也会按照目标节点作整合,以保证写入性能不会因 Raft 组过多而变差。 Raft 内部实际上是有本身的选主机制,它能够控制本身的主节点,若是有任何节点宕机,它能够经过选举机制选出新的主节点。那么,中心节点是否是就不须要管理 Raft 组了吗?不是的。这里讲一个典型的场景,若是一个集群的部分节点通过几轮宕机恢复的过程, Raft Leader 在存储节点之间会变得极其不均。而为了保证数据的强一致,客户端的读写流量又必须发到 Raft Leader,这时候集群的节点流量会很不均衡。因此咱们的中心节点还会作 Raft 组的 Leader 调度。好比说 Slot 1 存储在节点 一、二、4,而且节点 1 是 Leader。若是节点 1 挂了,Raft 把节点 2 选成了 Leader。而后节点 1 恢复了并从新加入集群,中心节点这时会让节点 2 把 Leader 还给节点 1 。这样,即使通过一系列宕机和恢复,咱们存储节点之间的 Leader 数目仍然能保证是均衡的。

接下来,咱们看一下 Cellar 如何保证它的端到端高成功率。这里也讲三个影响成功率的问题。Cellar 遇到的数据迁移和热点 Key 问题与 Squirrel 是同样的,但解决方案不同。这是由于 Cellar 走的是自研路径,不用考虑与官方版本的兼容性,对架构改动更大些。另外一个问题是慢请求阻塞服务队列致使大面积超时,这是 Cellar 网络、工做多线程模型设计下会遇到的不一样问题。

Cellar 智能迁移

上图是 Cellar 智能迁移架构图。咱们把桶的迁移分红了三个状态。第一个状态就是正常的状态,没有任何迁移。若是这时候要把 Slot 2 从 A 节点迁移到 B节点,A 会给 Slot 2 打一个快照,而后把这个快照全量发到 B 节点上。在迁移数据的时候, B 节点的回包会带回 B 节点的状态。B 的状态包括什么?引擎的压力、网卡流量、队列长度等。A 节点会根据 B 节点的状态调整本身的迁移速度。像 Squirrel 同样,它通过一段时间调整后,迁移速度会达到一个动态平衡,达到最快速的迁移,同时又尽量小地影响业务的正常请求。

当 Slot 2 迁移完后, 会进入图中 Slot 3 的状态。客户端这时可能还没更新路由表,当它请求到了 A 节点,A 节点会发现客户端请求错了节点,但它不会返回错误,它会把请求代理到 B 节点上,而后把 B 的响应包再返回客户端。同时它会告诉客户端,须要更新一下路由表了,此后客户端就能直接访问到 B 节点。这样就解决了客户端路由更新延迟形成的请求错误。

Cellar 快慢列队

下图上方是一个标准的线程队列模型。网络线程池接收网络流量解析出请求包,而后把请求放到工做队列里,工做线程池会从工做队列取请求来处理,而后把响应包放回网络线程池发出。

咱们分析线上发生的超时案例时发现,一批超时请求当中每每只有一两个请求是引擎处理慢致使的,大部分请求,只是由于在队列等待太久致使总体响应时间过长而超时了。从线上分析来看,真正的慢请求占超时请求的比例只有 1/20。

咱们的解法是什么样?很简单,拆线程池、拆队列。咱们的网络线程在收到包以后,会根据它的请求特色,是读仍是写,快仍是慢,分到四个队列里。读写请求比较好区分,但快慢怎么分开?咱们会根据请求的 Key 个数、Value大小、数据结构元素数等对请求进行快慢区分。而后用对应的四个工做线程池处理对应队列的请求,就实现了快慢读写请求的隔离。这样若是我有一个读的慢请求,不会影响另外三种请求的正常处理。不过这样也会带来一个问题,咱们的线程池从一个变成四个,那线程数是否是变成原来的四倍?其实并非的,咱们某个线程池空闲的时候会去帮助其它的线程池处理请求。因此,咱们线程池变成了四个,可是线程总数并无变。咱们线上验证中这样的设计能把服务 TP999 的延迟下降 86%,可大幅下降超时率。

Cellar 热点 Key

上图是 Cellar 热点 Key 解决方案的架构图。咱们能够看到中心节点加了一个职责,多了热点区域管理,它如今不仅负责正常的数据副本分布,还要管理热点数据的分布,图示这个集群在节点 C、D 放了热点区域。咱们经过读写流程看一下这个方案是怎么运转的。若是客户端有一个写操做到了 A 节点,A 节点处理完成后,会根据实时的热点统计结果判断写入的 Key 是否为热点。若是这个 Key 是一个热点,那么它会在作集群内复制的同时,还会把这个数据复制有热点区域的节点,也就是图中的 C、D 节点。同时,存储节点在返回结果给客户端时,会告诉客户端,这个 Key 是热点,这时客户端内会缓存这个热点 Key。当客户端有这个 Key 的读请求时,它就会直接去热点区域作数据的读取。经过这样的方式,咱们能够作到只对热点数据作扩容,不像 Squirrel ,要把整个 Slot 迁出来作扩容。有必要的话,中心节点也能够把热点区域放到集群的全部节点上,全部的热点读请求就能均衡的分到全部节点上。另外,经过这种实时的热点数据复制,咱们很好地解决了相似客户端缓存热点 KV 方案形成的一致性问题。

发展规划和业界趋势

最后,一块儿来看看咱们项目的规划和业界的技术趋势。这部份内容会按照服务、系统、硬件三层来进行阐述。首先在服务层,主要有三点:

  • 第一,Redis Gossip 协议优化。你们都知道 Gossip 协议在集群的规模变大以后,消息量会剧增,它的 Failover 时间也会变得愈来愈长。因此当集群规模达到 TB 级后,集群的可用性会受到很大的影响,因此咱们后面会重点在这方面作一些优化。
  • 第二,咱们已经在 Cellar 存储节点的数据副本间作了 Raft 复制,能够保证数据强一致,后面咱们会在 Cellar 的中心点内部也作一个 Raft 复制,这样就不用依赖于 ZooKeeper 作分布式仲裁、元数据存储了,咱们的架构也会变得更加简单、可靠。
  • 第三,Squirrel 和 Cellar 虽然都是 KV 存储,可是由于它们是基于不一样的开源项目研发的,因此 API 和访问协议不一样,咱们以后会考虑将 Squirrel 和 Cellar 在 SDK 层作整合,虽而后端会有不一样的存储集群,但业务侧能够用一套 SDK 进行访问。

在系统层面,咱们正在调研并去落地一些 Kernel Bypass 技术,像 DPDK、SPDK 这种网络和硬盘的用户态 IO 技术。它能够绕过内核,经过轮询机制访问这些设备,能够极大提高系统的 IO 能力。存储做为 IO 密集型服务,性能会得到大幅的提高。

在硬件层面,像支持 RDMA 的智能网卡能大幅下降网络延迟和提高吞吐;还有像 3D XPoint 这样的闪存技术,好比英特尔新发布的 AEP 存储,其访问延迟已经比较接近内存了,之后闪存跟内存之间的界限也会变得愈来愈模糊;最后,看一下计算型硬件,好比经过在闪存上加 FPGA 卡,把本来应该 CPU 作的工做,像数据压缩、解压等,下沉到卡上执行,这种硬件能在解放 CPU 的同时,也能够下降服务的响应延迟。

做者简介

泽斌,美团点评高级技术专家,2014 年加入美团。

招聘信息

美团基础技术部存储技术中心长期招聘 C/C++、Go、Java 高级/资深工程师和技术专家,欢迎加入美团基础技术部你们庭。欢迎感兴趣的同窗发送简历至:tech@meituan.com(邮件标题注明:基础技术部-存储技术中心)

阅读更多技术文章,请扫码关注微信公众号-美团技术团队!

相关文章
相关标签/搜索