Pegasus系统的整体架构如下图所示,一共分为四个部分:

ReplicaServer主要负责数据存储和存取,以replica为单位进行服务:
MetaServer采用一主多备模式(one master, multiple backups),所有的状态都会持久化到Zookeeper上;同时通过Zookeeper进行选主。当master故障后,另一台backup立即抢到锁,然后从Zookeeper上恢复状态,成为新的master。MetaServer负责的功能包括:
Zookeeper主要有两个功能:
ClientLib对用户提供数据存储接口,特点:
LaserDB 主要包括三大核心组件:Laser Server, Laser Client 和 Laser Control, 此外还有适配 Redis 协议的 Laser Proxy 以及满足数据批量导入的 Laser Transform。在具体部署时用户可以根据自己的需求选择部署 Laser Proxy 和 Laser Transform

LaserDB 的存储服务核心组件,负责接收 thrift 请求并且处理对应的请求。除了负责对外的服务请求处理以外,还负责具体的数据存储、数据分片、数据同步等功能
负责集群数据表、数据表配置以及集群分片信息的管理,提供分片可视化、动态扩容、动态缩容
主要是负责和 Server 进行接口交互,并且实现 LaserDB 整体请求路由机制,对 Server 端提供的 API 接口进行封装,实现 mget, mset 等批量操作的客户端层并行化, 目前提供 C++, Golang 版本的 SDK 可以直接 与 Laser server 交互获得更好的性能,其他语言的业务可以选择 Laser Proxy 代理,最终通过 redis 客户端操作
Laser Proxy 主要是负责实现 Redis 协议的大部分常用命令支持,Proxy 通过调用 Laser Client 与 Laser Server 交互,对于 Proxy 来说是一个完全无状态的服务,可以将 Proxy 当做一个存储容量特别大的 Redis server 来看 。对于原有业务是 Redis 的,获取不方便直接使用 Laser Client SDK 调用的业务场景可以选用 Laser Proxy
Laser Transform 主要是负责实现数据的批量导入功能,对于有数据快速批量导入的需求,需要部署 Laser Transform 服务,并且 Laser Server 环境需要有 hdfs 客户端支持,Transform 服务主要负责定时调度提交 MapReduce 任务,将原始格式的数据转化为 Laser Server 可以识别的数据
Laser 为了解决不同业务场景不同的需求,从底层就支持了多租户的设计。Laser 引入了数据库、数据表的概念,通过对不同数据库、数据表进行不同的配置来应对不同的业务场景。实现了多租户特性 Laser 就可以有针对性的在热点流量时进行弹性扩容,合理的利用资源。

Abase2 的整体架构主要如上图所示,在用户、管控面、数据面三种视角下主要包含 5 组核心模块。
线上一个集群的规模大约为数千台机器,为管理各个集群,我们研发了 RootServer 这个轻量级组件。顾名思义,RootServer 拥有全集群视角,它可以更好地协调各个集群之间的资源配比,支持租户在不同集群之间的数据迁移,提供容灾视图并合理控制爆炸半径。
Abase2 是多租户中心化架构,而 MetaServer 则是整个架构的总管理员,它主要包括以下核心功能:
管理元信息的逻辑视图:包括 Namespace,Table,Partition,Replica 等状态和配置信息以及之间的关系;
管理元信息的物理视图:包括 IDC,Pod,Rack,DataNode,Disk,Core 的分布和 Replica 的位置关系;
多租户 QoS 总控,在异构机器的场景下根据各个租户与机器的负载进行副本 Balance 调度;
故障检测,节点的生命管理,数据可靠性跟踪,在此基础上进行节点的下线和数据修复。
DataNode 是数据存储节点。部署时,可以每台机器或者每块盘部署一个 DataNode,为方便隔离磁盘故障,线上实际采用每块盘部署一个 DataNode 的方式。
DataNode 的最小资源单位是 CPU Core(后简称 Core),每个 Core 都拥有一个独立的 Busy Polling 协程框架,多个 Core 共享一块盘的空间与 IO 资源。
一个 Core 包含多个 Replica,每个 Replica 的请求只会在一个 Core 上 Run-to-Complete,可以有效地避免传统多线程模式中上下文切换带来的性能损耗。
Replica 核心模块如下图所示,整个 Partition 为 3 层结构:
数据模型层:如上文提到的 String, Hash 等 Redis 生态中的各类数据结构接口。
一致性协议层:在多主架构下,多点写入势必会造成数据不一致,Anti-Entropy 一方面会及时合并冲突,另一方面将协调冲突合并后的数据下刷至引擎持久化层并协调 WAL GC。
数据引擎层:数据引擎层首先有一层轻量级数据暂存层(或称 Conflict Resolver)用于存储未达成一致的数据;下层为数据数据引擎持久化层,为满足不同用户多样性需求,Abase2 引设计上采用引擎可插拔模式。对于有顺序要求的用户可以采用 RocksDB,TerarkDB 这类 LSM 引擎,对于无顺序要求点查类用户采用延迟更稳定的 LSH 引擎。
Client 模块是用户侧视角下的核心组件,向上提供各类数据结构的接口,向下一方面通过 MetaSync 与 MetaServer 节点通信获取租户 Partition 的路由信息,另一方面通过路由信息与存储节点 DataNode 进行数据交互。此外,为了进一步提高服务质量,我们在 Client 的 IO 链路上集成了重试、Backup Request、热 Key 承载、流控、鉴权等重要 QoS 功能。
结合字节各类编程语言生态丰富的现状,团队基于 Client 封装了 Proxy 组件,对外提供 Redis 协议(RESP2)与 Thrift 协议,用户可根据自身偏好选择接入方式。此外,为了满足对延迟更敏感的重度用户,我们也提供了重型 SDK 来跳过 Proxy 层,它是 Client 的简单封装。
DTS 主导了 Abase 生态系统的发展,在一二代透明迁移、备份回滚、Dump、订阅等诸多业务场景中起到了非常核心的作用,由于篇幅限制,本文不做更多的详细设计叙述。
Client 模块是用户侧视角下的核心组件,向上提供各类数据结构的接口,向下一方面通过 MetaSync 与 MetaServer 节点通信获取租户 Partition 的路由信息,另一方面通过路由信息与存储节点 DataNode 进行数据交互。此外,为了进一步提高服务质量,我们在 Client 的 IO 链路上集成了重试、Backup Request、热 Key 承载、流控、鉴权等重要 QoS 功能。
DTS 主导了 Abase 生态系统的发展,在一二代透明迁移、备份回滚、Dump、订阅等诸多业务场景中起到了非常核心的作用。
参考:Abase2:字节跳动新一代高可用 NoSQL 数据库
主要组成:


参考GitHub - OpenAtomFoundation/pika: Pika is a nosql compatible with redis, it is developed by Qihoo's DBA and infrastructure team 首发丨360开源的类Redis存储系统:Pika - 墨天轮
Client接入层
RedKV集群部署完成后,通过公司内部提供的Service Mesh组件做服务发现,对Client提供服务。
Proxy
Proxy层由一个无状态CorvusPlus进程组成。它兼容老的Redis Client,扩缩容、升级对无Client和后端集群无感,支持多线程、IO多路复用和端口复用特性。对比开源版本,CorvusPlus增强了自我防护和可观测特性,实现了可在线配置的功能特性:
RedKV Server配置多个IO线程同时监听一个端口来接受连接请求,每个线程上的连接数目会随机均衡。每个线程只解析自己连接上的请求,并将解析出的报文通过key挂到对应的请求队列上,每个队列由一个Worker线程处理。这样同一个key/同一个slot上的请求都会落到同一根Worker线程上处理,避免了对key进行加锁,减少锁冲突和线程切换。Worker线程中会对数据进行重编码,存储到Rocksdb本地存储引擎。

参考:小红书自研KV存储架构如何实现万亿量级存储与跨云多活 - 知乎