NoSQL 应用的现状
什么是 NoSQL?我们知道关系型数据库强调 CAP 理论:Consistency,Availability 和 Partition Tolerance,这三者不可兼得。谈到 NoSQL,我们会引入 BASE 概念:
- Basically Available:分布式系统在出现故障时允许损失部分可用性,以保证核心功能可用。比如在电商场景中,有时交易付款出现了问题,但用户仍可以正常浏览商品。
- Soft State:由于不要求强一致性,BASE 允许系统中存在一种不影响系统可用性的中间状态,比如订单支付中、数据同步中等,在数据达到最终一致的状态后才改为成功。
- Eventually Consistent:指经过一段时间后所有节点的数据将会达到一致。比如最终支付中的状态会变成支付成功或者支付失败;订单的状态和实际交易的过程达成一致;但这个过程有一定的时间延迟。
BASE 理论是对 CAP 中 AP 理论的扩展,通过牺牲强一致性获得可用性。当出现故障时,允许部分不可用,但能保证核心功能可用;允许数据在一段时间内不一致,但最终要达到一致。NoSQL 大致可以分为以下几类:
- KV 类:以 Redis 为代表;
- 文档型:以 MongoDB 为代表;
- 列存:以 HBase 为代表;
- 图、时序等新兴的数据库也都属于 NoSQL 范畴。
如今 NoSQL 在字节跳动有非常广泛的应用:数万 NoSQL 应用实例,10W+ 台物理服务器资源,字节跳动超过 90% 的在线服务都是 NoSQL 系统提供的。
NoSQL 产品矩阵
上图是字节跳动 NoSQL 的产品矩阵。我们对内对外提供了生态类产品,包括 Redis、HBase、MongoDB 和 InfluxDB。此外自研的平台上提供了 ByteGraph 和 ABase,这两者和字节跳动的业务息息相关,也是内部业务重度依赖的两大产品。
字节跳动 NoSQL 的最新实践
字节跳动的大部分业务数据可归纳为以下几种类型:
- 用户之间的关系:比如关注好友等;
- 内容:视频、文章、广告等;
- 用户和内容的连接:用户发布内容之后的评论、点赞、转发等,自媒体还会关注广告点击及分成收益等数据。
这三种数据关联到一起就会形成图状结构。
自研分布式图数据库
为了满足内部 social graph 在线增删改查的场景,字节跳动自研了分布式图存储数据库 ByteGraph。针对刚才提到的图状数据结构,ByteGraph 支持有向属性的图数据模型、Gremlin 查询语言以及丰富的写入和查询接口,具有海量存储和吞吐能力,单体集群可达万亿条边,支持百万 QPS 图上多度读写。ByteGraph 也支持 Super Node 热点访问,单个过亿出度节点 10K 量级 QPS 毫秒级读写。
目前 ByteGraph 基本支持了字节跳动全系产品,除核心数据管理之外,BytrGraph 也支持以下典型场景:
- 风控反作弊:在风控场景,业界以前的常用做法是使用 HBase 加上一个计算引擎。实际上图计算对于风控反作弊的异常识别和风险检测更适合。
- 推荐模型:图训练系统也支持推荐的核心模型,这也是字节跳动的的一个核心场景。
目前 ByteGraph 在字节跳动内部的使用量有多大?这里列举一组数据:
- 服务 2000+ 内部用户(这里的用户指一个业务线或者一个小的 App)
- 1000+ 图数据库集群
- 日均运行 1000+ 图计算任务
- 服务器规模 1W+ 台。
字节跳动为什么要自研这样一个庞大的系统?作为业内最大的图生态之一,现有的一些开源解决方案还不能满足字节跳动对图场景的需求。所以在 2018-2019 年,字节跳动就尝试自研分布式图数据库,最初是为了解决抖音关系的多度在线查询(约百万 QPS),当时最主要的功能是支持定制点和边的接口。在 2019 年-2021 年,ByteGraph 已经支持了属性图模型和 Gremlin 语法,也在公司内部广泛落地,集群数量快速扩张,并逐步标准化。
目前字节跳动在图数据库方面的多篇论文已被 VLDB 等数据库顶会收录,ByteGraph 预计在今年年底也将通过火山引擎提供给更多用户。
图计算系统
从图数据库又引申出来一个非常大的概念——图计算。举个例子,在 Google 上搜索时,需要基于网页的链接关系计算每个页面的 page rank,从而对页面进行排序。页面的链接关系其实就是一张图,基于网页链接关系的 page rank 计算,就是在这张图上运行一个图算法,即图计算。
小规模的图可以通过单机来进行计算,但如今随着业务数据量的增大,一般都需要引入分布式计算系统来解决问题,并且需要系统能高效运行各类图算法,做大规模的数据处理。
字节跳动早期时有不少业务使用 MapReduce 和 Spark 来实现图算法。得益于批处理系统的广泛使用,业务同学能够快速上线算法逻辑。但批处理(batch processing)本身是为处理并行数据而设置的,能轻易将工作负载分散到不同机器上,并行处理大量的数据。
MapReduce 的过程是 Map 先切割,然后并行处理,再进行 Reduce。但是图数据比较特殊,天生就有关联性,无法像以前常用的行式数据一样直接切割。
如果用批处理系统来运行图的算法,就需要引入大量 shuffle 操作来实现关系的连接。但 shuffle 操作非常重,不仅会导致任务的运行时间变长,还会浪费非常多的计算资源。
为了解决这一系列的问题,字节跳动引入了图计算系统。目前该系统支持超大规模图万亿点边规模上的计算训练,支持动态超高吞吐(百万吞吐级别)的训练和推理,同时支持内存/SSD 混合介质的数据处理及 fault-tolerance,十亿点边超大图的处理仅在分钟级。
为了让用户使用更方便,我们提供了一站式的图数据分析与管理平台,集成图计算、图训练的产品能力,广泛对接公司内核心业务场景。字节跳动在风控、电商、搜索、推荐等领域的典型图分析应用方案都沉淀在该平台,能做到开箱即用。
ABase
ABase 是字节跳动自研的 KV 存储服务,具有大容量、高吞吐、高可用(容灾)、多地域、低延时、易使用、低成本的特点。随着字节跳动的业务规模不断扩张,急剧增长的数据量在可用性和性能、跨地域同步、同城容灾能力、资源和成本优化等方面对 KV 存储系统提出了更高的要求。我们希望 ABase 能支持的场景包括:
- 持久化 KV
- 兼容 Redis 协议,提供比 Redis 更大容量的缓存
- Redis 复杂命令
- 数据生态同步:支持数据的备份/回滚,FaaS 数据订阅,支持 ABase to Hive, Hive to ABase,方便用户在线查询和分析的转换
- 跨地区同步:支持多活
- 边缘存储:给边缘机房提供近地读写服务
对于上述这些要求,第一代的 ABase 无法完全满足,所以我们引入了 ABase 第二代无主架构,实现多点写入,从高可用达到了极高可用。机器硬件或网络都会有一定的故障率,常见的高可用方案是使用多副本、热备的形式。常见的主从架构有一个写入点,主节点故障时,系统通过 HA 策略自动切换到热备的从节点,这样一般就成为高可用了。
但在生产环节有两个问题:
- 主节点故障需要一系列的检测机制,工业界的实现一般在 1s 以上, 而 ABase 的用户最长只能接受毫秒级别的延时,秒级别的切主还是会造成整个过程的写失败。
- 传统的主故障探测对于慢节点的自动检测和快速处理比较困难。
Abase 第二代采用无主架构来解决这两个问题,支持任意点写入,没有主节点故障后需要的切主时间,也不会受到单一慢节点影响,因此任何单一节点故障对可用性零影响,同时可规避慢节点,缩短 P99 延时。
ABase 核心流程架构
传统的 qourum 无主架构修复数据一般需要构建 Merkle tree,会造成海量 KV 场景数据达成一致的时间非常长,理论上有时可能是周级别。数据一致性依赖读 qourum,读吞吐的能力又非常浪费。
ABase 自研的无主快速一致算法借鉴了有主架构的同步方式,限制了写入流的数,只在必要情况下乱序同步,这样大幅度提高了数据达到一致的速度,数据修复不必再依赖读取,也可充分发挥整个系统的读性能。
另一方面,为了解决冲突,ABase 将数据的 HLC 时间戳编码在 key 结构上,这样用户冲突就可以自然解决了。然而引入这种机制之后,要找同一个 Key 的所有版本中时间戳最大的一个,这样点查询的性能会恶化。
为了解决这个问题,我们引入了双引擎结构:多版本只存在 log engine 中。当完成冲突处理之后,单版本写入 KV engine,这样绝大部分的查询都是点查询,不再需要查看所有版本。log engine 中的索引是全内存的,这样多版本查询就不会影响性能。
以上就是 ABase 第二代引入无主架构所做的 trade-off。ABase 现状经过优化后,ABase 目前可用性和性能上都大大提升。
- 极高可用:直接屏蔽慢节点,无主从切换不可用时间,可一直写入。
- 全球化部署:快速的一致性算法;支持 Zset,List 等复杂数据结构的 CRDT 方案。
- 支持高性能架构:包括 RunToComplete 架构、KV 分离/全内存索引、FIFO log 优化。
- 支持 Serverless 存储:多租户 QoS 保证、多维度的负载均衡调度、极致的资源利用率。
字节跳动目前已有 5000+ 业务在使用 ABase,服务器超过 5W 台,请求量达到百亿级,数据规模百 PB 级,在 30+ 地域多地部署。
NoSQL 技术未来发展趋势
最后我们对 NoSQL 技术的未来发展趋势做一个简单的预判。我们重新再来回答一下什么是 NoSQL。我认为 NoSQL 不仅是 not only SQL 也不仅是没有 SQL 语言,我对 NoSQL 的定义是高性能弹性存储+可扩展性动态计算的数据库。
现在我们从数据 Schema 维度审视,NoSQL 代表了半结构化和非结构化的数据处理。“处理”既包括计算,也包含存储。从 CAP 理论维度来看,NoSQL 强调的是“最大化” P,也就是弹性规模化能力,在 C 和 A 上不同的场景各有不同权衡。
最后再看看未来的机遇。根据 Gartner 的统计,2025 年全球会有 175ZB 的数据需求,其中大部分是非结构化/半结构化数据,并且会大量沉淀在 TOS/S3 等存储产品中,这些数据的存储和计算都蕴含大量的机遇。当然机遇与挑战并存,谁能解决数据的处理(存储+计算)问题,谁就能立于不败之地。
我认为 NoSQL 未来会有两个极致的方向:一个是极致的高性能 KV 系统,以 Redis 为代表;另一个就是海量大规模的 KV 系统,以前文介绍的 ByteGraph 和 ABase 为代表。对于字节跳动的 NoSQL 来说,我们在朝着以下方向努力:
- 利用 Cloud Native、Serverless 能力,实现极致弹性和性价比、精细化的资源调度;
- 强调数据增值能力和数据共享,对计算(包括分析和 AI)的需求越来越重;
- 融合多样化的非结构/半结构数据 Schema,统一存储,统一计算;
- 软硬件结合,带来数量级革命的技术升级;
- 产品界面标准化,增强 Redis 生态能力建设与 SQL 生态能力建设。
我认为 NoSQL 在接下来几年里最大的发展趋势是能存下所有数据,并且能够又快又好地计算出来,让用户看到数据存储的价值。
现在 NoSQL 和关系型数据库的界限变得越来越模糊了,所以数据库在不断形成各种分支的同时,也在不停地融合,这就是今天技术发展的趋势和方向。