PolygonStore,一款“业务驱动”而生的 NoSQL 多模数据库产品
蚂蚁具有丰富的业务生态,产生了海量的多样化的数据。例如,金融业务产生的交易数据;搜广推业务产生的人群数据;风控业务产生的行为数据和关系网络数据;AI 业务产生的训练数据;小程序云业务产生的社交数据和移动应用数据;短视频业务产生的多模态内容数据;监控业务产生的指标数据等。
这些数据不能全部存储于传统关系型数据库中,从而催生了多样化的非关系型数据库,例如 KV 数据库、宽表数据库、文档数据库、图数据库、时序数据库等。
01.
数据库类型介绍
◾️ 关系型数据库
关系模型之父 Edgar F. Codd 于 1970 年在论文《A Relational Model of Data for Large Shared Data Banks》中介绍了关系模型,是关系型数据库理论的开山之作。论文中提出了一种通过关系来表达数据关系的方法,并以集合论为理论基础介绍了几种应用于关系的算子。
随后出现了大量基于该模型的数据库系统,包括 Oracle、MySQL、SQL Server、PostgreSQL 等,这些产品至今依然在 DB-Engines 排行榜上占据了绝对优势。
总结一下关系型数据库的典型特征:
关系模型的基本结构是关系,其表现形式是表格、元组、属性,并满足完整性约束
关系型数据库通过 SQL 访问和操作,SQL 相当完备,具有强大的表达能力,除了基本的增删改查,还支持复杂语义,例如 Join、聚集、排序等操作,也能够支持非关系模型(XML、JSON)
支持复杂的事务模型,及延伸出的 ACID 特性,适用于金融、电信等 business-critical 的业务场景
◾️ NoSQL 数据库
2009 年兴起的 NoSQL 运动,起源于两篇论文,《Bigtable: A Distributed Storage System for Structured Data》和《Dynamo: Amazon’s Highly Available Key-value Store》。这两者分别致力于解决不同的课题,从而提供了不同的价值。
Bigtable 由 Google 创建,用于网络爬虫场景,不断写入抓取到的大量网页数据,然后由 MapReduce 系统创建索引,所以 BigTable 提供了高效的查询能力,原生支持 MapReduce 计算框架,适用于大数据的实时查询和分析场景。
Dynamo 由 Amazon 创建,用于其内部的收藏夹场景,在数据中心故障情况下依然能够提供写入和读取服务,是一个分布式、内置容错能力的 KV 存储,适用于 OLTP 场景。
社区受这两篇论文启发,生机盎然的兴起了一众数据库项目,并展开了激烈讨论。NoSQL 这个词语首创于 90 年代末的一款开源数据库产品 Strozzi NoSQL,并在 2009 年一场由 Johan Oskarsson 发起的聚会中再次使用,随后像野火一样流行起来。
NoSQL 并未有过权威机构进行定义,通过对这一时期兴起的数据库产品的特征进行归纳总结,具备以下特征的数据库产品可以认为是 NoSQL 数据库:
不使用关系模型
运行于多台服务器组成的集群上
开源
首先服务于 21 世纪早期的互联网产业
无需预先定义表结构
目前市场主要围绕着几款 NoSQL 数据库产品:MongoDB、Redis、Cassandra 和 HBase。
Cassandra 是 Dynamo 的开源实现,综合采用了 Dynamo 的分布式架构 和 BigTable 的数据模型。Cassandra 从设计之初致力于解决复制和可扩展性,从而提供一个高性能、高可靠性的数据库,这成为了 Cassandra 赢得流行的原因。
HBase 是 BigTable 的开源实现,BigTable 构建于 GFS 之上,HBase 受此影响构建于开源分布式文件系统 HDFS 之上。
HBase 和 HDFS 的协作配合体现了 Hadoop 生态体系的巧妙设计:HDFS 侧重于系统吞吐量,提供了大文件高效写入的能力,但不提供随机查找能力;而 HBase 则提供了应用数据写入和 KV 随机查找的能力,及行级事务的能力;通过 HDFS,HBase 融入了 Hadoop 生态,从而与 MapReduce、Spark、Hive 等框架形成了协作。HBase 的 高性能、高扩展性、及与 Hadoop 生态的无缝融合成为其赢得流行的原因。
MongoDB 是一款文档型数据库,支持文档模型,例如 JSON、BSON 等。文档模型是一种对开发非常友好的存储模型,其 JSON 存储格式最接近于真实的业务对象模型,且具备 schema-free 的特性,无需提前设计统一的格式,极大减少开发的工作,从而快速开发迭代。
MongoDB 具备丰富的应用特性,例如地理位置索引用于构建 O2O 应用、全文索引用于搜索场景,从而简化应用复杂度。MongoDB 的开发友好性成为其赢得流行的原因。
◾️ 总结
综上所述,关系型数据库诞生于上世纪 70 年代,ACID 和 SQL 是其最显著的特性,ACID 支持完整的事务语义,SQL 具有复杂的语义表达能力,适合 business-critical 的业务场景,例如 ERP、CRM、交易、记账 等。
NoSQL 数据库诞生于 2000 年后,BASE 和 schema-free 是其最显著的特性,具备极好的水平扩展性( 此时的关系型数据库还不具备水平扩展性,后来出现的 NewSQL 改变了这点,例如 Spanner、OceanBase,使得关系型数据库也具备了水平扩展性 )、及放松的一致性语义,其最大优点是灵活性,可以不用预先定义表结构(关系型数据库先定义表结构再写入数据),对应用开发友好。
非关系型数据库一般通过简单的 API 接口访问(例如 put、get、scan、delete 等),Session 轻量化,但缺乏复杂的语义表达能力。NoSQL 数据库是对关系型数据库一个很好的补充,两者提供了各自不同的价值。
02.
对 NoSQL 场景的思考
业务数据的多样性催生了 NoSQL 数据库的蓬勃发展,这些数据库产品简化了开发模式,在传统关系型数据库以外有了更多的选择,可以更加灵活、准确的对应用建模,增加了数据库的易用性。
但应用开发者需要在“事务”和“易用性”之间纠结,或者基于“多边形架构”来满足各种数据的存储需求。例如开发一个电子商务应用,使用关系型数据库存放客户信息;使用文档数据库保存半结构化数据,例如商品历史信息;使用 KV 数据库存放购物车;图数据库存放高关联数据,例如商品推荐功能。
多边形架构带来了数据冗余、数据一致性问题、应用架构复杂性,及对应用开发者不直接感知的运维成本、存储成本、稳定性等问题。
多边形架构带来了以下复杂度:
增加了开发成本:不同的数据库产品具有不同的数据模型和访问接口,应用开发者需要理解并运用到应用程序中去,并且可能产生了跨数据库事务,增加了开发成本。随着业务流量的增加和业务 Workload 的变化,数据库产品可能会产生性能瓶颈,需要深入学习并调优
产生了数据孤岛:同一个业务系统的数据在多个数据库产品中存在,引入了一致性和可用性的问题,打破了数据的 “Single Source of Truth” 的特性
增加了数据冗余:同一份数据使用于不同需求场景时(例如 TP 和 AP),往往使用不同数据库产品处理对应的 Workload,带来了数据冗余,极大增加了存储成本
增加了维护复杂度:技术风险是一个体系活,包括到数据库产品的稳定性、成本、安全、运维效能、建站效能等方方面面,多套数据库产品意味着复杂度的非线性增加
Our view is that we are entering a world of Polyglot Persistence where enterprises, and even individual applications, use multiple technologies for data management. As a result, architects will need to be familiar with these technologies and be able to evaluate which ones to use for differing needs.—— 《NoSQL Distilled》 by Pramod J. Sadalage and Martin Fowler [1]
2017 年,Gartner 对数据库未来的发展趋势做了预测,其中很重要的一项就是多模数据库,多模数据库是指在单个数据库产品中同时支持结构化和非结构化在内的多种数据模型。多模数据库能够简化应用存储架构,显著降低运维成本和存储成本。
Nearly all vendors in this market offer in-memory capabilities, multimodel, cloud (dbPaaS or a hosting model, or both) and HTAP programming capabilities. ——《Gartner Magic Quadrant for Operational Database Management Systems, 2017》[2]
所以,结合应用数据存储痛点和数据库发展趋势,蚂蚁场景需要一款什么样的 NoSQL 数据库产品呢?
首先,必须是一款多模数据库,能够兼具关系模型的 business-critical 特性(主要包括 ACID 特性和 SQL 语句的强大表达能力),及非关系型的易用性。结合蚂蚁的业务场景,多模型需要能够包括 KV 模型、表模型、宽表模型、文档模型等。
其次,结合蚂蚁的金融特性,必须具备强一致性。一致性包括两层含义,一层是读写一致性(也可以称为写后读一致性,即写完数据之后马上读,能够读到最新的数据,而不是老的数据),对比我们前面介绍的 Dynamo 和 Cassandra,则是提供了最终一致性。另一层是容灾一致性,无论是单节点故障、还是机房故障和城市故障,切换后不存在数据丢失,因此能够使得应用代码尽可能简单,无需嵌入各种复杂补偿机制。
再次,需要具备齐全的生态能力以适配蚂蚁架构,包括同城无损容灾、异地无损容灾、极低成本、大促弹性、快速建站、Serverless 等能力。
以快速建站为例,随着蚂蚁集团业务合规改造及蚂蚁国际小站点的展开,快速部署成为了一项基本能力。对比我们前面介绍的 Bigtable 和 HBase 类产品,建站部署时需要先部署一套分布式文件系统,无形中增加了建站成本和降低了交付效能。
最后,也是最重要的,将业务数据存储到该数据库产品上只是第一步,后续需要能够陪伴业务一起成长。随着业务场景的拓展,数据库产品需要同步丰富自身特性,从而让业务简单,让业务能够更加专注于业务。
03.
PolygonStore 介绍
面向蚂蚁在线业务场景,我们提供了一款名为 PolygonStore 的 NoSQL 数据库产品。PolygonStore 的定位是面向在线业务场景的低成本、功能丰富、易用的多模数据库,支持 KV 、表、宽表、文档等数据模型,以简化业务研发为使命。
“Polygon” 一词有多边形的寓意,对应我们前文介绍的多边形存储架构,希望能够集多种数据库的能力于一身,简化业务存储架构、提升业务开发层次、提升业务数据存储的总体 ROI 。
PolygonStore 另一个目标是希望能够提供演进式能力,解决蚂蚁业务场景遇到的各种难题,从而更好的服务于蚂蚁业务场景。
PolygonStore 的整体架构如下图所示:
◾️ 多模型能力
PolygonStore 的首要任务是提供多模型能力,能够兼具关系模型的 business-critical 特性和非关系型的易用性。
调研了业界多款多模数据库产品,架构实现上分为三类:
多种接口访问一份数据:底层依赖同一个存储引擎,支持事务、二级索引、多级一致性 等特性,上层适配多种数据模型。本质是一份数据多种数据模型。
多种存储港,内置数据的异步流动以支持多种应用需求,应用写入一份数据,异步生成其他存储格式,例如列存用于 AP,例如倒排索引用于全文检索。本质是多份存储格式的数据以支持多种应用场景,难点在于实时性和稳定性之间的权衡,数据存储成本也会大大增加。
同时支持结构化、半结构化、非结构化的统一管理,适用于内容管理场景,例如金融影像平台。本质是多种存储引擎的统一管理,难点在于数据的一致性。
PolygonStore 采用了“多种接口访问一份数据”的实现方式,由 OBKV 提供行存能力,上层适配多种数据模型。这也是多款 NoSQL 数据库的通用实现方式,例如 BigTable、HBase、Cassandra、DynamoDB、FoundationDB、YugaByteDB:数据以行的方式进行存储及索引,然后基于行键进行分片,将他们分布到集群中;列可以被定义在行中,从而可以提供 schema-free 的能力。
这里的“行”不同于关系模型中的“行”,关系模型中的“行”表示一个实体。而这里的“行”根据不同数据模型有不同的含义,例如对于宽表模型,“行”又被称为 Cell,相同 Rowkey 的所有 Cell 组成一个完整的实体。
正如经典博文《 Why are NoSQL Databases Becoming Transactional?》中所述:底层核心引擎构建事务、高性能、跨地域部署等能力,并基于该引擎在上层实现多种数据模型,是一种历久弥坚的真正创新。这也是对 PolygonStore 架构设计的最好诠释。
the real innovation in database software will come from building a core engine that can easily handle multiple data models without compromising on the core guarantees of transactions, high performance and geo-distribution. This in turn ensures that your operational database infrastructure is not only fit-for-purpose on day 1 but is also future-proof for years to come. —— Why are NoSQL Databases Becoming Transactional? [3]
存储层
PolygonStore 基于 OBKV 构建存储能力。OBKV 基于 OceanBase 的存储引擎提供了存储能力和事务能力,并通过 API 的方式对外提供数据访问能力,无需通过 OceanBase 的 SQL 层。
OceanBase 的存储引擎可分为两层,底层的分布式部分实现了线性扩展、Paxos 复制、分布式事务等分布式特性从而达到持续可用。上层的单机部分融合了传统关系数据库以及内存数据库的一些技术从而达到极致性能。
存储引擎的单机部分采用分层 LSMTree 结构,数据分为两部分:基线数据和增量数据。基线数据是持久到磁盘上的数据,一旦生成就不会再修改,称之为 SSTable。增量数据存在于内存,应用写入都是先写到增量数据,称之为 MemTable,同时通过 RedoLog 来保证事务性。这部分对上层模块提供 ACID 能力。
存储引擎的分布式部分采用数据分区和多副本技术以达到“高扩展性和高可靠”,对应于我们上文提到的 Cassandra 通过极佳的复制和可扩展性从而赢得流行。
数据冗余有多个副本(例如,同城三副本部署架构为 3 个,三地五副本部署架构为 5 个),分布于多个 OceanBase 节点上。
事务提交时 RedoLog 利用 Paxos 协议在多个副本间达成多数派提交,从而维护副本之间的一致性。当少数派节点发生异常时可以保证数据的完整性,并在较短的时间内恢复数据访问,达到 RPO=0、RTO<30 秒的 SLA。应用无需感知数据所在的位置,客户端会根据应用请求来定位数据所在的位置,从而将读写请求发送给 Leader 进行处理,对应用仍然展现为单机数据库。
通过数据分区的方式以达到水平扩展性,支持 hash 分区和 range 分区。支持二级分区,例如对于海量交易场景,单表数据量庞大,一级按用户分区,二级按时间分区,从而很好的解决大用户扩展性的问题,如果要删除过期数据,可以通过删除分区实现。也支持生成列分区,生成列指这一列由其他列计算所得,该功能能够满足期望将某些字段进行一定处理后作为分区键的需求。
对分区表查询进行了优化,对于查询中包含分区键或者分区表达式的查询,能够准确的计算出该查询对应的分区,称为分区裁剪;对于多分区查询,能够使用分区间并行查询、分区间排序消除、partition-wise join 等技术,从而大大提升查询性能。
基于以上介绍,OceanBase 的存储引擎非常接近于传统关系型数据库的单机引擎特性,一个数据分区的所有数据(基线数据 + 增量数据 + 缓存数据 + 事务日志)全部存在于同一个 OceanBase 节点中,因此针对一个数据分区的读写操作不会有跨机操作(除了事务日志通过 Paxos 协议形成多数派同步,因此对于事务提交会增加一次网络延迟),再加上准内存数据库及多级 Cache 机制,从而能够提供低延迟、高吞吐的极致性能。
OBKV 还支持多种复杂类型,例如 XML、JSON、GIS、LOB 等数据类型。正是这些与时俱进的新特性,使得基于 OBKV 构建上层多模型服务是一件水到渠成的事情,也能让更多人一起参与建设 OceanBase 的大生态。在蚂蚁内部,除了 PolygonStore,还有 Ceresdb、Ketch(ETCD on OBKV) 也是基于 OBKV 构建的。
OceanBase 作为一款商业数据库,能够积极支持这些从蚂蚁场景洞察挖掘出来的需求,从而“让数据管理和使用更简单”。OceanBase 与时俱进的特性支撑了生态的蓬勃发展,感谢 @远智 带领的 OceanBase 深圳研发中心给予的鼎力支持。
OBKV 通过 API 的方式对外提供数据访问能力,我们称之为 TableAPI,相比 SQL 具有如下优点:
TableAPI 越过 SQL 层,直接访问存储层,数据访问路径短,相同功能时性能更优。且语义简单,易于优化
API 接口使用简单,直接提供实体语义,不需要复杂的 ER 映射
使用 RPC 协议,没有传统 JDBC/ODBC 接口的“重”连接,几乎不受连接数的限制
RPC 协议格式自定义,可以基于业务场景和需求,灵活便捷的增加新功能
OBKV 的数据也支持通过 SQL 语句访问,从而在享受到 API 接口诸多优点的同时,也能享受到 SQL 接口的强大表达能力。
模型层
PolygonStore 支持三种数据模型,分别是关系表模型、宽表模型、文档模型,并提供访问这三种模型的 API,分别是 TableAPI、HBaseAPI、MongoAPI。KV 模型本质是一种简化的关系表模型,同样通过 TableAPI 访问。
- 关系表模型
关系表模型,数据是强 schema 的,应用需要通过 SQL 的 DDL 语句定义表结构。表需要包含一个主键和若干强类型的列,还可以定义二级索引和唯一性约束。创建二级索引后,所有 TableAPI 的写入操作都会同步更新索引。
使用 Query 接口,可以使用二级索引进行查询扫描。很多 NoSQL 数据库只支持主键查询,应用不得不自己在应用层维护一个索引表,不仅增加了应用数据层的复杂度,而且索引和主表的一致性很难保证,PolygonStore 的表模型原生支持二级索引,极大简化了应用逻辑。
除了 Query 接口外,TableAPI 支持通过主键对行数据进行读写,简称行接口,支持的操作类型有 retrieve/get、insert_or_update/put、delete、insert、update、replace、increment、append 等。TableAPI 还支持 QueryAndMutate 的 CAS 原子操作。
TableAPI 提供的 Query 接口功能无法和 SQL 同日而语,只能提供 get、scan、limit、offset 等有限功能,如果需要聚合、排序等复杂功能,可以使用 SQL 接口进行访问。这也是 PolygonStore 的架构优势所在 — 多种接口访问一份数据。
KV 模型本质上是一种简化的关系表模型,建表时只有 K 和 V 两列,并按照 K 或者 K 的生成列进行分区,此处不再赘述。
- 宽表模型
宽表模型,也叫做 column family store 模型,不需要预先定义表结构,并且提供对历史多版本的读取能力。基于 tableAPI 提供的基本接口,PolygonStore 实现了兼容 Hbase API 的 JAVA SDK,兼容 hbase 0.94 版本的特性,我们称之为 HBaseAPI 。
HBaseAPI 支持 scan、delete、filter、increment、checkAndPut 等 HBase 语义,基于 HBaseAPI 可以方便的使用宽表模型对业务数据建模。HBaseAPI 完全兼容 HBase 接口,业务无需改造。该模型采用 K、Q、T、V 四列表示一个 Cell ,支持 hash 分区、range 分区、基于前缀的生成列的 key 分区、及各种分区方式的组合。
对于宽表模型与数仓的数据流动,支持全量数据入仓、增量数据实时入仓,及数仓数据导入,从而较好的支持需要与大数据生态联动的业务场景。
- 文档模型
文档模型,通过 JSON/BSON 格式存储数据,每个文档都由键值对组成。其中的值可以是简单的值,也可以是复杂的元素,例如列表和子文档。文档可以通过主键进行检索,也可以通过在内部健值上创建的索引进行检索,以提升检索的性能。
PolygonStore 基于 OBKV 的 JSON 数据类型支持文档模型,可以方便的使用文档模型对业务数据建模。PolygonStore 支持多种协议访问,包括 HTTP、HTTPS、MongoDB 原生协议,从而可以复用生态,减少应用接入成本。
PolygonStore 提供多语言 SDK,包括 Java、Python、Golang、PHP、Node.js,从而更好的服务于主站业务和小程序云业务。
◾️ 扩展特性
PolygonStore 的定位是面向蚂蚁在线业务场景的多模数据库,以简化业务开发为使命。所以业务数据存储到 PolygonStore 上只是第一步,更重要的是能够跟随业务场景的拓展而不断丰富自身特性,让业务开发更简单更专注。
这一原则是 PolygonStore 的立项根本,并每年把 PolygonStore 的边界往外扩展一点点。这些年我们陆续上线了热点更新、向量、Serverless 等特性,还有实时推送、轻量 AP 等特性正在规划中。
热点更新
通过悲观锁串行更新保证高并发下更新的准确性和连续性,同时导致单行的处理能力下降,称为热点。热点是电商的经典难题之一,面对瞬时大量用户的秒杀请求,对全链路提出了非常高的并发需求。
近年来随着直播电商市场竞争的白热化,对支付平台单账号的支付能力提出了越来越高的要求。某种程度上,单账号的秒级支付能力成为了支付平台的核心竞争力之一。
综上所述,小红书“裁长补短”、美团“砥砺深耕”、东方甄选“自立门户”,不同平台征战直播电商的策略不同,这样差异化的逻辑构成了不同的利剑,为直播电商后浪抢食抖音、快手、淘宝直播电商市场份额提供了强劲的攻击力,直播电商市场竞争越来越刺激了。——《小红书、美团、东方甄选加码,直播电商生变?》[4]
单账号支付能力给数据库提出了技术挑战:热点行更新。由于数据库在执行行更新操作时,会加悲观锁,造成在同一行上更新操作的串行化。由于并发请求量极大,造成行锁争抢,进而队列积压,数据库工作线程或者应用工作线程卡住而造成业务雪崩。
业务上有多种优化方式,例如拆分热点账号、缓冲记账、汇总记账等,这些优化手段是业务层的,对业务代码侵入很大,需要人工维护热点账号,且可能带来资损风险。为此我们基于 PolygonStore 的关系表模型提供了热点更新的特性,通过 group increment + 多表 batch + 提前解行锁的技术提高单账号秒级更新能力:
group increment:在服务端对热点行的更新做聚合,避免每一次操作都需要执行申请行锁、释放行锁的操作,从而优化行锁的竞争等待时间。
多表 batch:通过 TableAPI 的 batch 接口实现单机多表事务操作,支持业务语义的多次操作通过一次 RPC 完成,减少应用程序和数据库交互的网络开销。
提前解行锁:由于事务提交过程中会持续持有行锁,三地五中心部署时由于事务提交存在跨城延迟导致热点能力退化,PolygonStore 引入了 OceanBase 的提前解行锁功能,从而避免热点行能力因部署架构而退化。
我们在方案设计的过程中,遵循通用性的设计原则,避免应用逻辑的侵入。通用性使得方案能够适用于更多业务场景,从而提升研发的 ROI。也避免了应用逻辑改动所带来的数据库的发布和升级,降低基础设施的稳定性。
PolygonStore 的热点能力目前正在权益资产场景联调。权益资产中的券/红包/立减/通兑等在使用过程中均需要控制发放预算、支付预算等。因此,对于某一个营销活动,所有用户的预算扣减流量会打到同一个预算模版上,从而形成热点。业务原来的热点能力为 6k tps,目前基于 PolygonStore 的方案已经优化到 3w tps,依然持续优化中。
向量检索
在现实世界中,很大比例的数据都是以非结构化数据存在的,例如我们上文提到的“短视频场景产生的多模态内容数据”,包括音频、视频、图片等。为了处理这些非结构化数据,通常会基于人工智能技术提取这些非结构化数据的特征以生成特征向量,然后对这些特征向量进行分析和检索以实现对非结构化数据的处理。
因此对数据库产生了存储和检索特征向量的需求。向量检索有着非常丰富的应用领域,例如人脸识别、推荐系统、图片搜索、语音处理、自然语言处理、文件搜索等。
PolygonStore 的文档模型提供了向量检索的特性,应用程序把生成的向量数据写入到 JSON 格式的字段中,用户基于该字段建立向量索引。PolygonStore 的向量引擎抽取该字段的数据离线构建向量索引,并提供 topK 的查询能力。
PolygonStore 的向量引擎基于 Facebook 开源的 Faiss 库构建。基于 HNSW 算法构建索引,支持多种相似度检索方式,包括欧式距离、点积、余弦。向量检索能力预计将于 8 月底发布。
◾️ 丰富生态
PolygonStore 仅仅在多模型能力上的创新是远远不够的,还必须建设齐全的配套生态,解决“易用性”的课题。PolygonStore 的底层存储依赖于 OBKV,直接继承了 OceanBase 在蚂蚁多年的“易用性”沉淀:
极致性能:每年双十一大促,OceanBase 都会提出性能优化的目标,PolygonStore 共享 OceanBase 的存储引擎,天然能够享受性能优化的红利
容灾架构:PolygonStore 具备跟蚂蚁业务架构完全匹配的同城无损能力和异地无损容灾能力,且 RPO=0,RTO < 30 秒。且配备能力完备的容灾中控平台,负责容灾巡检、容灾演练自动化、容灾决策、容灾保鲜等职责,从而具备容灾的无人值守能力。
大促弹性:通过只读副本的方式,支持分钟级弹出弹回能力,业务无感知。
数据安全:数据安全是数据库最重要的事情,PolygonStore 具备多级数据安全能力,包括数据备份、立体回收站(六级回收站:数据库主机、集群、租户、库、表、行)、异地数据热备。
高可用保障:OAS 为 PolygonStore 的稳定性保驾护航,提供异常检测、故障自愈、根因定位、自动修复等能力,同时兼顾运维效能和数据安全。
历史库平台:历史库平台负责冷热数据分级存放,大幅降低在线存储的成本,提高在线场景的查询性能。
除了以上直接继承于 OceanBase 的“易用性”能力,我们还针对 PolygonStore 建设了 Serverless 能力和低成本能力。
Serverless
Serverless 正在成为一个新的基础设施,其提供了一种全新的计算模式——“来了就用,功能齐全,用完即走”,让开发人员关注代码运行而不需要管理任何基础设施。正如 《Serverless Architectures》中所述:基于 Serverless 技术,移动应用可以直接使用云端数据库 (e.g., Parse, Firebase),鉴权服务 (e.g., Auth0, AWS Cognito),从而避免自己开发这些功能,能够更加专注于业务本身。
Serverless was first used to describe applications that significantly or fully incorporate third-party, cloud-hosted applications and services, to manage server-side logic and state. These are typically “rich client” applications—think single-page web apps, or mobile apps—that use the vast ecosystem of cloud-accessible databases (e.g., Parse, Firebase), authentication services (e.g., Auth0, AWS Cognito), and so on. These types of services have been previously described as “(Mobile) Backend as a Service", and I use "BaaS" as shorthand in the rest of this article. ——《Serverless Architectures》[5]
PolygonStore 提供了 Serverless 特性,从而服务于蚂蚁的小程序云场景。Serverless 特性具有以下能力:
全托管:PolygonStore 提供了灵活的管控 API 和读写 API,应用可以自由的创建表和读写数据,而不需要关心数据库的创建和维护,从而把应用开发者从管理硬件、升级软件、配置集群的负担中释放出来。PolygonStore 的 全托管特性负责了齐全的透明提供(Transparent Provisioning )能力,包括容量托管、故障恢复、数据备份、版本升级,及全托管服务所需要的其他能力。
极致弹性:PolygonStore 提供了多租户的能力,多个实例的表部署于同一个节点上,同一个实例的表可以跨节点部署。通过应用流量度量、资源预留、预设 Quota、监控水位、分时复用等技术,从而在达到极好隔离性的同时,提供极致的弹性能力,使得用户的实例容量随着应用流量无感扩容。该特性依赖了 OAS 的容量管家能力,容量管家提供了容量画像和容量预测的能力,从而可以通过灵活调度达到分时复用的效果。
按使用量付费:PolygonStore 提供了请求量和数据量的计量能力,从而按照用户的使用量计费。通过极致弹性能力,使用同等资源的费用低于友商产品。
低成本
作为归属于技术风险的的数据库团队,我们对成本极其敏感,所以低成本是 PolygonStore 致力于提供的核心价值之一。PolygonStore 的产品设计从多个层面降低成本:
部署架构:蚂蚁全域的核心应用都需要具备异地容灾能力,PolygonStore 提供了三地五中心的部署方式,从而具备了 RPO=0、RTO < 30 秒的无损容灾能力。该部署方式下,需要 4 份全副本和 1 份日志副本,共计 4.2 份数据。同样容灾能力的开源 HBase 产品,一共需要 8 份数据,从而能够大幅降低存储成本。
数据压缩:PolygonStore 的分布式架构提供了轮转合并的能力,由于轮转合并的引入,用户请求流量与合并过程错峰,正在合并的 Zone 的 CPU 和磁盘 IO 可以大量用于复杂的数据编码/压缩,并选择最优的编码算法,并且对应用数据写入零影响。高压缩率极大的节省了存储空间,压缩后的数据量只占原数据量的 20% 。而传统关系型数据库原地更新数据,与应用流量叠加,在“高压缩率”和“低资源消耗”两者之间只能选择后者,甚至建议用户谨慎使用该功能。
极致弹性:PolygonStore 在小程序云场景探索了极致弹性的能力。极致弹性的核心设计在于两点,首先对应用的流量精确度量,从而可以准确的进行资源预留和预设 Quota;然后通过 OAS 的容量能力,对业务流量进行画像和预测,从而达到分时复用、按需扩容的效果。该能力目前仅适用于小程序云,后续将引进主站场景。
共享配套:PolygonStore 与 OceanBase 共享配套设施,包括变更系统、高可用系统、离线链路、数据备份系统,而不需要额外的硬件成本。从而能够节省整体的建站成本,同时也能够提升建站效能。甚至 PolygonStore 可以与 OceanBase 共用同一套集群,从而进一步降低建站的总体成本。
◾️ 高度自治
随着上线业务增多,机器规模化和场景多样化带来的复杂度会显著提升,从而对稳定性和效能提出了极大挑战。在 PolygonStore 逐步发展的过程中,我们在一线不断解决稳定性、效率、安全性等各种问题。在付出极大人力成本的同时,我们积极思考并沉淀了一套自治系统 OAS,使得 PolygonStore 具备了高度自治的能力,从而能够接受更加复杂场景的挑战。
OAS 是基于机器学习和专家经验实现的数据库自感知、自修复、自运维、自调优、自安全的一站式数据库自治服务,提供稳定性、运维效能、安全等价值。
OAS 包括异常检测、故障自愈、告警自治、容量托管、智能应急、风险回归等子系统。产品设计遵循 发现问题->诊断问题->恢复问题 的一站式流程,从而提供自感知、自修复、自运维、自调优等数据库自治能力,让用户更加平稳的使用到 PolygonStore 提供的数据库服务。
04.
应用场景
经过数年的产品能力打磨,PolygonStore 在蚂蚁已经支持了众多的业务场景。丰富的业务场景对 PolygonStore 提出了多样化的特性诉求,我们对此进行了归纳总结,并产出了应用场景的最佳实践。
◾️ 基本 KV 场景
KV 是最基本的非关系型场景,具备以下特征:
强 schema:需要根据应用场景灵活定义联合主键和若干强类型字段,而不是朴素的 KV 模型和 HBase 模型
海量容量:需要支持容量横向扩展;session 轻量化,避免连接数瓶颈
容灾架构:容灾是基本的需求,例如单机、单机房、城市等级别的故障,最好数据零丢失,而传统主备架构很难做到
高性能读写:读写一般以简单的 put、get 为主,通过 API 接口即可,而不需要较重的 SQL 接口
二级索引:支持二级索引 或 唯一索引,避免应用系统通过多张表的方式维护二级索引
范围查询:需要支持基于索引 或 索引最左前缀 的范围查询
复杂查询:轻量 AP 场景,例如 join、聚合、排序等复杂查询,API 接口对这类复杂查询无能为力
离线导入:部分业务数据由数仓产品产生并导入到在线产品供在线应用访问,需要支持离线导入
热点更新:部分业务的秒杀场景,需要数据库提供较高的热点行更新能力
PolygonStore 的关系表模型支持以上特性需求。需要强调的是,同一份数据既能支持 API 接口访问,又能支持 SQL 接口访问。API 接口访问路径短,及 session 轻量化,相比较于 SQL 接口,提高 30% ~ 50% 的吞吐量,且 RT 更低,同时还避免了 SQL 接口的连接数瓶颈。
SQL 接口支持复杂查询,例如 join、聚合、排序等,从而满足业务的轻量 AP 场景。避免业务在数据库选型上的纠结,及同一份数据存放于多种不同类型的数据库产品而引入的数据一致性问题和成本增加。
目前已上线的典型业务有 数据上下文、AntQ Index 、IoT 人脸识别、消息推送、权益资产 等业务。
◾️ 资金场景
资金场景是金融行业最重要的场景,数据一致性是其最基本的诉求,具备以下特征:
数据零丢失:资金场景与金钱相关,任何容灾情况下的数据零丢失是最基本的需求,传统主备架构难以做到在主库故障下的备库数据零丢失。例如在主站容灾演练时,有些业务由于不能容忍数据丢失而需要提前切换,从而导致容灾演练的效果大打折扣
原子写入:需要支持业务上的多张表的原子写入能力,或者全写入,或者全不写入,例如资金汇总表和资金明细表,如果出现中间状态,就会引起用户困惑,甚至投诉;例如幂等场景,幂等表和资金表放在一个批次中写入,如果幂等表写入失败,则资金表也写入失败
条件写入:非关系型场景多为基于主键的写入,通过 API 方式即可,简单高效,但存在写入时需要判断条件的场景,例如异步更新的幂等和保序需求,例如乐观锁更新
复杂查询:需要支持各种维度的范围查询,尤其是存在大 C 场景的情况下,会引入很大的数据扫描量,对查询性能提出了较高要求
PolygonStore 的关系表模型和宽表模型通过事务和 CAS 特性支持原子写入和条件写入,通过流式接口和丰富的 Filter 算子以支持高效的范围查询,目前已上线的典型业务有资金资产、资产账等,消费记录和商家账单正在接入中。
◾️ 行情场景
行情是指市场上商品的实时价格,多用于金融市场,例如 期货行情、外汇行情、证券行情等。一般由写应用拉取渠道数据写入,读应用支持用户读取实时报价进行交易。该类业务具备以下特征:
写少读多:渠道数据写入,用户读取,由于写入由渠道驱动,而读取由海量用户驱动,故读扩展能力是强需求
弱读延迟可控:读取的行情数据需要尽量新,不能有太大延迟
数据过期能力:行情数据,一般保留最近一段时间,或者最近若干版本即可,需要数据过期能力,否则会造成数据膨胀,造成成本问题和性能问题
PolygonStore 的宽表模型支持以上特性需求:
通过只读副本以支持读扩展,只读副本由 PolygonStore 原生提供, 区别于通过外部组件搭建的备副本,稳定性和延迟性更能够得到保证
通过有界旧一致性以保证弱读的数据延迟总在一定范围内,如果该副本与 Leader 的延迟大于配置的参数值,将读取应用所在地的其他副本,如果所有副本都不能满足要求,则将应用请求路由到 Leader 副本,此时可能会产生跨城请求,需要根据业务敏感度谨慎的配置该参数
通过 TTL 以支持数据过期能力,支持基于时间和版本数的过期方式
目前已上线的典型业务有证券行情、外汇行情等业务
◾️ 计算场景
实时计算场景,存储计算系统的实时状态信息,从而容灾场景下用于构建实时快照。应用攒批写入,在批次结束时一次性将所有数据序列化并写入。读取由事件驱动,读取相应作业的状态数据。该类业务具有以下特征:
单表数据量大,达到 T 级别
业务流量具有突发性和批量性,例如 batch 请求和 single 请求混合负载,batch 请求成批到达,容易出现大请求阻塞小请求的情况,导致 P999 RT 不理想
由于存储作业的状态,存在大字段,甚至出现大字段的 append 操作,最大可能达到几兆单条记录,极大消耗内存和网卡资源
作业动态生成和消亡,很容易产生热点机器,热点机器容量水位较高,可能导致作业抖动
PolygonStore 针对以上挑战进行了诸多深度优化:
由于应用数据量非常大,通过编码+压缩的方式对数据进行压缩,压缩率为 0.2,相比压缩前存储数据量大幅降低。高压缩比得益于多副本+轮转合并的架构,从而可以消耗大量 CPU 用于压缩而不用担心影响业务流量。而传统数据库由于刷脏页动作与业务流量叠加,高压缩比和低 CPU 消耗不能同时兼得。
业务流量的问题,最主要的问题是请求队列等待,在业务上表现为长尾 RT,P999 RT 达到数百 ms,为平均 RT 的 30~50 倍,进而导致业务流量剧烈波动。PolygonStore 提供了优先级队列的解决方案,即业务可以指定每个请求的优先级,不同优先级在 PolygonStore 内部有不同的请求队列和不同的工作线程,从而做到大请求与小请求的全链路隔离。例如对于批量写和单点读的混合场景,可以对读请求设置为高优先级,对写请求设置为正常优先级,从而避免成批到达的写请求对读请求的影响。在实时流计算引擎业务上,我们最终将 P999 RT 优化到 33ms。
针对业务大字段的问题,我们从两方面解决,一是降低写入量,二是扩大内存池,具体的方案有:1)上线自动负载均衡方案,根据分区写入量做负载均衡,将写入量均匀打散到所有的机器上;2)机型定制化,提高事务日志盘的大小;3)在客户端进行数据压缩,大幅度降低写入数据量;4)对事务日志进行压缩,减少事务日志同步的数据量。
针对热点机器,我们引入了实时负载均衡系统。普通的负载均衡场景,基本上基于一个变量进行负载均衡就能符合生产需要,例如同业务的不同分表位所对应的租户,这些租户具有相似的负载量,再根据某个不均衡变量负载均衡就可以。而单租户多分区场景,不同的分区之间毫无规则可言,并且流量特征迥异甚至动态变化,必须考虑三个变量,内存、CPU 和 磁盘数据量,才能设计出符合生产需要的负载均衡系统。
目前该场景已经上线的业务有实时流计算引擎、Ceresdb 等业务。
◾️ 非结构化场景
非结构化场景,特指通过 JSON/BSON 结构存储数据的业务场景,一般用文档模型支持。文档模型具备 schema-free 的特征,及丰富的应用数据类型,从而对开发非常友好。
该业务场景的典型特征,具有不可预测的使用模式。例如社交业务和移动业务,包括在线游戏、照片共享、位置感知应用程序等,随时可能像病毒一样传播开来。该类业务对数据库提出了高容量、开发友好的能力诉求。
文档模型给应用开发带来了极大的便利:
所见即所得的存储模型,以更低的成本(学习、开发)支持业务快速迭代,从而快速开发市场
应用需求多变,数据模型无法确定,且需要快速迭代开发。例如内嵌文档、内嵌数组等特性便于查询、更新
应用需要特定的数据类型,例如地理位置查询
强大的索引能力,支持单字段索引、复合索引、多 key 索引等索引类型,从而提高查询效率
便利的多维度查询能力,支持丰富的 aggregate 算子、正则表达式查询,支持各种对象的操作符
PolygonStore 通过文档模型支持该场景,支持动态索引,支持多种协议访问,支持多语言 SDK。目前该场景已上线的业务有研发效能、法律合规、多媒体、语雀、小程序云等业务。
05.
历史回顾 & 展望
2017 年 11 月 Gartner 提出数据库未来需要在几个方面进行创新,其中有一项就是“多模数据库”。因此我们于 2018 年 2 月立项了 OBKV 项目,致力于打造一款蚂蚁自己的多模数据库产品。
我们首先在 OceanBase 关系型的基础上拓展了访问接口,通过 API 越过 SQL 层直接访问存储引擎中的数据。然后在 API 之上适配了 Table 模型和宽表模型,使得 OBKV 具备了多模型能力。通过对主站研发效能和前端的业务洞察,我们于 2021 年 8 月适配了文档模型。
2022 年 12 月我们通过对小程序云的业务调研,开始建设 Serverless 能力,并随后被确定为小程序上的主力数据库产品。2023 年 2 月依托于小程序云场景建设的 Serverless 能力,我们进行了产品升级,并命名为 PolygonStore。
产品升级的目的是对这些年打磨的能力进行总结,并在新环境新场景下对产品定位进行重新思考和强化,更好的迈向未来,正所谓“追风赶月莫停留,平芜尽头是春山”。在已有能力的基础上,继续深入业务前线,洞察需求,演进能力,解决蚂蚁业务遇到的各种课题,更好的服务于蚂蚁。
PolygonStore 是由“业务驱动”而诞生的,同时“业务驱动”也是 PolygonStore 不断前进的动力。
相关资料
[1] https://martinfowler.com/books/nosql.html
[2] https://www.gartner.com/en/documents/3823563
评论