*作者介绍:振飞(高德地图总裁)、炳蔚(高德技术服务平台负责人)、福辰(高德服务端架构师)
PolarDB
Lindorm
OB
ES
MongoDB
...
1.1 OceanBase 基础属性信息
1.2 多方权衡后,为什么选择 OceanBase?
需要提前规划好分片规则,一旦定好规则就难以移动,扩展困难
分得太细会浪费资源,分得太粗会导致二次拆分
数据迁移困难
2.1 云原生数据库的发展历程
单机:传统单机数据库、依赖高端硬件、系统难以扩展、成本高。
PG-XC:基于中间件的分布式数据库(TDDL)。待解决全局一致性、跨库事务、复杂的 SQL 等问题。
NewSQL:高可用、水平扩展、分布式事务,全局一致性、复杂 SQL、自动负载均衡、OLAP 等。
Sharding on MySQL:一般我们可以在应用侧或者代理层做分片来管理多个 MySQL 物理库,以解决单机容量和性能不足的问题。现在正在使用的 TDDL 就是该架构,虽然计算存储资源可扩展,但在扩展和数据迁移时,业务系统层面需要做不少改造和业务数据的灰度,为了保证业务不停机会产生比较大的改造成本和数据迁移的风险。(PG-XC风格)
NewSQL:国内以 TiDB 和 OceanBase 为代表的原生支持分布式的关系型数据库,主要也是为了解决 MySQL 的问题。和 Sharding on MySQL 不同的是,NewSQL 将分片功能作为数据库的一部分来实现,并提供了动态扩缩容的能力,且对上层业务透明,具备透明可扩展性。
Cloud Native DB:云原生数据库国内以 PolarDB 为代表,具备池化的资源,也可以实现存储资源的动态扩缩容,其一般采用的主备方式来实现高可用,同时其扩容和主备探活等功能需要大量依赖外部系统。(PG-XC风格)
Share-Nothing:架构的每个节点有独立的计算和存储功能并且节点之间不共享数据
无状态 SQL 计算节点,无限水平扩展
远程存储,共享存储节
强 SQL 支持( 系统自动扩展路由 )
和单机一样的事务支持
跨数据中心故障自动恢复
无限的弹性水平扩展
Share-Everying:也叫 Share-Storage,即 Share-Disk,架构是在存储层做了统一和共享,但计算节点是独立节点
F1 设计的目标
无限弹性水平扩展
跨数据中心故障自愈
事务的 ACID 一致性
全面的 SQL 支持,支持索引
Spanner 设计的目标
管理跨数据中心复制的数据
重新分片和平衡数据的能力
跨数据中心迁移数据
2.2 OceanBase 的技术内幕
一、 OceanBase 存储引擎
低成本,自研行列混存的压缩算法,压缩率较传统库提高 10+ 倍。
易使用,支持活跃事务落盘来保证大事务的正常执行和回滚。多级转储和合并来平衡性能和空间。
高性能,提供多级缓存保证低延时。OLAP 操作提供向量化支持。
高可靠,全局合并时多副本比对和主表与索引表比对校验和来保证用户数据正确性。
数据缓存:
Bloom Filter Cache:维护缓存静态数据的 Bloom Filter,快速过滤无需访问的数据。当一个宏块上的空查次数超过某个阈值时,就会自动构建 BloomFilter Cache。
Row Cache:数据行缓存,在进行单行或多行访问时构建并命中。
Block Index Cache:描述对每个宏块中所有的微块的范围,用于快速定位微块。
Block Cache:微块缓存,在对数据块访问是构建和命中。
Fuse Row Cache:数据在多 SSTable 中的融合结果。
···
Metadata缓存:
Partition Location Cache:用于缓存 Partition 的位置信息,帮助对一个查询进行路由。
Schema Cache:缓存数据表的元信息,用于执行计划的生成以及后续的查询。
Clog Cache:缓存 Clog 数据,用于加速某些情况下 Paxos 日志的拉取。
改进底层 SSTable 的存储结构,通过宏和微块的模式,解决写放大的问题,而且可以随时调整 Compact 时机,在挪移 Parttion 的时候,底层数据存储单元非常适合快速移动。
本身 OceanBase 也会对底层存储进行监控,控制 Compact 时机,不会导致前端请求收到影响,在 Compcat 也会针对数据进行对比,防止静默导致数据错乱,而且压缩比高,整体体积很小。
讲解存储和为什么 MySQL 不能 Online DDL 等。 主要介绍 B+Tree 和 LSM 的存储区别。
二、数据复制-Paxos
三、数据复制-延展
四、分布式事务
五、向量化+并行执行引擎
六、 空间优化
七、OLAP 场景支撑
支持列存和行存
支持向量化
支持并行计算
支持数据压缩,根据不同的类型压缩类型也不同
八、OceanBase 更多场景支持
OceanBase 正常模式
OceanBase Key-Val模式
OceanBase NoSQL模式
OceanBase 纯列存模式
OceanBase Serverless模式
强一致金融场景的业务落地
海量数据,多点写入场景落地
中心写单元读场景落地
3.1 强一致金融场景落地实践
财务结算服务作为与 B 端商家合作的钱款计算的一环,对数据一致性有极高的要求,不能出现因数据不一致或最终一致而导致钱款计算错误的情况。
财务结算服务业务逻辑复杂,需要降低迁移改造成本,最好能完整兼容原业务所使用的 SQL 协议,平滑替换底层数据库,不需要业务过多的改造。
为了提升财务结算系统的数据强一致性,优先选择了三机房的部署架构。
三、为什么选择 OceanBase?
解题设计核心要点:
五、部署架构
采用同地三机房部署
OceanBase 原生支持能力,多份数据同时写入,无同步延时问题
提升存储稳定性,高可用和容灾能力,跨地域级别的容灾能力。
强一致的存储保证,对于结算财务类的数据,保障较高的一致性,而非用最终一致性的妥协换取其他方面的能力。
提升扩展性,提升数据库弹性扩缩容的能力,存储横向扩展对上层系统透明,极大降低数据迁移的风险。
数据压缩,减少数据占用的存储容量,OceanBase 使用的 LSM-tree 结构存储最大可压缩数据至原大小的 35%,降低存储费用成本。
平衡升级:迁移 OceanBase 后仍然可使用 MySQL 原生驱动,使用 MySQL 5.7 版本的 SQL 进行业务功能开发,兼容原有存储(XDB)的协议,极大降低业务系统改造成本。
整理压测结果
3.2 海量数据多点写入场景落地实践
四、可行性分析
从成本上,针对云同步的结构化的海量数据,其"低成本存储的高级压缩技术",数据文本压缩+行列存储数据特性压缩,将成本压缩到极致,且数据量越大优势越大。
从原理上,LSM-Tree 的底层数据结构,内存处理增、删、改与批量顺序的磁盘写入极大提高了写入性能,足以支持了数万级 TPS 的数据写入,其 B+ 树的索引支撑了数十万 QPS 的业务读请求。
从架构上,其多单元同步链路,OMS 的秒级数据同步能力,保障了多机房数据同步低延迟支撑了多机房多活的可行性。
从业务上
分布式原生数据库从本质解决了业务研发需要考虑的分库分表问题。
业务特性为多端数据同步,可用 ID 作为分区键,所有操作在单分区内完成极大提升读写性能。
多语言 SDK,支撑各类业务系统,极大简化对接成本;同时支持 SQL 形式,更换配置无业务入侵。
五、落地方案
DAO 层业务改造,使用 OceanBase Client 实现业务逻辑改造。
简单通用的 SDK,Java SDK 的流式编程,简单易用
业务无 SQL 语句配置
调用过程 SDK 封装业务无感
数据迁移:全量数据迁移,使用集团内部工具 DATAX 将 ID 分桶并发拉取,整体数千亿数据 2 天左右完成全量同步,采用 OceanBase 异地备份恢复能力,将数据同步到其他单元,天级完成。
数据比对:业务自研千亿级数据对比、更新、同步框架,实现千亿数据天级对比完成,通用框架,实现增量/全量对比/修复。
灰度迁移:数据双写,ID 维度白名单/灰度,支持比例控制,核心支持按 ID 随时回滚。
多点写入
三地读写
无网络延迟
同城双主库容灾,异地多活容灾
同城数据库侧容灾切流
三地业务侧容灾切流
三地六向数据同步
三地六向秒级同步
3.3 中心读写单元读架构落地实践
评价系统作为整体评价的入口,对于性能有极致的要求,整体 RT 必须控制在 15ms 以内。
为了提升读性能,整体采用用户就近接入,三单元读数据,中心写入数据,对于读数据需要异地容灾能力。
需要支持后续数据量的持续增长。
为什么选择中心写单元读?
为什么选择 OceanBase?
业务上,业务不断发展,数据量不断增长,需要解决数据存储的瓶颈,OceanBase 优异的横向扩容能力能很好的解决这个问题。
成本上,OceanBase 自研的基于行列混存结构/高效数字编码的存储压缩技术,将成本压缩到极致,能有效的降低评价数据的存储成本。
原理上,基于 LSM-Tree 的底层数据结构,极大提高了写入性能,足以满足评价场景的写入诉求。基于 B+ 树的索引,能满足评价场景大量读的查询诉求。
架构上,基于 OceanBase 主备库的架构,利用集群原生的复制能力,实现秒级同步,可靠性高。
三、部署架构图
中心写入
中心写单元读,架构更加简单,不用担心数据覆盖的问题
同城双主容灾,异地多活容灾
同城多机房容灾切流
三地读容灾切流
三地主备数据同步
利用集群间原生同步能力,秒级同步
张北中心主集群可读可写,实现强一致读。
上海和深圳为备集群,通过 OceanBase 原生的集群复制能力同步,秒级延迟,实现非强一致异构存储的高流量低耗时读业务。
实时:OceanBase 主备之间通过集群原生的同步能力,可靠性非常高,基本不需要担心。
离线:提供离线分析的兜底手段,通过 MAC 平台 T+1 分析监控数据一致性。
延迟监控:OceanBase 主备之间通过集群原生的主备同步延迟监控能力进行监控,集群级别的复制能力性能很高,正常的延迟都在秒级。
六、索引设计实践
partition by key(appraise_id) partitions 512
用户维度单个、批量查询(占比 75%)
通过评价 ID 查询(占比 15%)
评价对象维度查询/按时间分页查询(占比 10%)
partition by key(appraiser_id) partitions 512
PRIMARY KEY (`appraise_id`, `appraiser_id`),
KEY `idx_appraiser_id_gmt_create` (`appraiser_id`, `gmt_create`) BLOCK_SIZE 16384 GLOBAL,
KEY `idx_targetid_gmt_create` (`appraise_target_id`, `gmt_create`) BLOCK_SIZE 16384 GLOBAL,
KEY `idex_modified_status` (`gmt_modified`, `status`) BLOCK_SIZE 16384 GLOBAL
partition by key(appraiser_id)
评价者 ID 维度(appraiser_id)设置分区键
评价 ID(appraise_id)设置为主键查询
评价对象维度(appraise_target_id)设置全局索引查询
KEY `idx_appraiser_id_gmt_create` (`appraiser_id`, `gmt_create`) BLOCK_SIZE 16384 LOCAL,
新的数据库架构完全支撑整体评论体系的读写性能
分布式数据库,不用担心后续的海量数据增长导致重新分库分表
整体压测结果如下:读/写 2w,平均响应稳定在 1~2ms
4.1 关于为什么选择 OceanBase
4.2 OceanBase部署架构选择
一、架构选择-多点写入
用户就近接入,读写对应单元,无数据延迟
实现完美的异地多活,各单元异地容灾,机房故障,随时切流,用户无损
二、架构选择-中心写单元读
整体对于读支撑能力提供三倍,同时节省了网络耗时
主从架构为集群内部机制,自动同步,运维更简单
三、架构选择-同城多机房读写
用户请求到业务系统无法避免的物理延迟(30~50ms)
同城多机房灾备,无法媲美异地灾备能力
架构简单运维方便
四、关于多单元数据同步
五、架构选择结论
不用结构有不同的优劣,具体采用哪种架构要看业务需求,如果业务对读延迟没有强要求,可采用主备模式,否则选择多单元 OMS 同步模式,而针对本身就是单元化的云同步业务,多点写入是我们最好的选择。
六、多点写入系统的问题与解决方案
云同步系统是否业务一定要单元化?不单元化会有什么问题?
从成本考虑,已经单元化,三个单元是否可以不存全量数据?
单元化系统容灾切流是否会有问题?
1.云同步系统为什么要实现单元化
2. 单元化系统每个单元是否要存全量数据
3. 单元化系统容灾切流是否会有问题
七、切流态的数据缺失和覆盖解决方案
1. 什么情况下会有数据缺失
2.什么情况下会有数据覆盖
对于张北 OB 如果数据延迟:则 2 先进行,1 通过同步链路进行,最终数据,id = 1 name = 'a'。
对于深圳 OB:则 1 先进行,2 后进行,最终数据,id = 1 name = 'b'。
3. 解决方案是什么
业务侧保证禁写时间,同时要求 OMS 不能有长延迟。
OMS 数据同步时保证数据不被覆盖(目前 OMS 支持启停后重新追数据,会比较时间戳),所以我们在切流预案中集成了 OMS 的启停。
OMS 延迟越低,风险越小。
4. OMS同步怎么降低延迟
5. OMS 降低延迟效果
4.3 选择分区表,还是单表?
一、业务设计选择-分区表 or 单表
业务增长迅猛一定选择分区表。
注意目前 OceanBase 的分区数量最大 8192,且分区数在创建时即固定,不可自动分列。
二、业务设计选择-全局索引 or 局部索引
局部索引:索引和数据相同的分区规则,在同一机器上,可避免部分分布式事务。
全局索引:不管是全局分区索引还是全局不分区索引,其都可能导致索引和数据不在同一机器上,每次写入都是跨机分布式事务。换句话说全局索引会影响表数据写入性能。
1.使用全局索引的场景
有除主键外的全局唯一性的强需求,需要全局性的唯一索引。
查询条件没有分区谓词,无高并发写入。避免全局扫描,可构建全局索引,但一般限制在4条全局索引内。
2. 全局索引、局部索引性能对比
3. 局部索引读写注意事项
4. 全局索引使用的注意事项
三、业务设计选择-OBKV or OceanBase普通版本
四、业务设计选择-什么时候使用复制表?
六、业务设计选择-主键和分区键设置
4.4 业务落地的瓶颈
一、瓶颈-流量稍高,Client 明显报错超时
Java Client 代码问题,在发起请求处理链接,不合理使用 Synchronized。
升级最新包即可解决。
二、瓶颈-读写流量增加,业务超时明显
随着压测的增加,平均 RT 明显上涨,且失败超时明显增加。
原因:Proxy 侧性能瓶颈。
三、瓶颈-业务机器扩容失败,无法链接数据库
扩容失败提示无法连接数据库。
业务系统不断重试依然无法连接。
四、瓶颈解决-海量数据云上部署架构优化
五、业务落地-优化效果
4.5 当然我们也趟过一些坑
一、OBKV 版不支持 SQL 优化器,使用索引需要程序指定
TableQuery query = obTableClient.query(table).setScanRangeColumns("item_uid", "item_id");
for (String itemId : itemIdSet) {
query.addScanRange(new Object[]{uidStr, itemId}, new Object[]{uidStr, itemId});
}
QueryRESultSet rESults = query
.indexName(INDEX_UID_ITEM_ID)
.execute();
public TableQuery queryWithFilter(int uid, String table, ObTableFilterList filterList) {
return obTableClient
.query(table)
.setScanRangeColumns("uid")
.addScanRange(uid, uid)
.setFilter(filterList);
}
二、OMS clog丢失、OMS 同步明显延迟触发报警
三、主从架构高德评论库上海备集群缩容后无法提供服务
直接原因:集群缩容,把 SLB 切换到了不支持备集群的 OBProxy 版本上,导致服务不可用。
根本原因:公有云上 OceanBase 集群的 OBProxy 默认是和 OBServer 同机部署,3 月初为了配合支持主备库和 POC 测试,将 OBProxy 部署模式切到了独立支持主备库的实例和版本部署,但是元信息记录没有修改(仍然为混部模式)。导致本次缩容过程中,识别到混部模式后,认为需要修改 SLB 挂载的 OBProxy 信息,从而挂载到了现在的不支持主备库的版本,业务访问异常。
OBProxy 运维操作自动化优化:避免操作疏漏引入的后续问题,支持创建各版本 OBProxy 集群、SLB 绑定 OBProxy 等。
释放节点操作新增静默期:有问题可以马上回滚。
四、OBServer 部分节点 CPU 被打满
PRIMARY KEY (`feedback_id`, `id`),
KEY `idx_gmt_create_id` (`gmt_create`, `id`) BLOCK_SIZE 16384 LOCAL
partition by hash(feedback_id)
为解决大小 ID 查询性能不一致的问题,需要重构 idx_gmt_create_id 索引,增加 feedback_id 筛选列,避免全分区扫描。具体索引为 KEY `idx_feedback_id_gmt_create_id` (`feedback_id`, `gmt_create`, `id`) BLOCK_SIZE 16384 LOCAL。
OceanBase 侧做逆序排序优化,新版本已修复。
云原生(Cloud Native)其实是一套架构体系,说到体系其实就会衍生出方法论。Cloud 的含义是应用和数据都不在机房或者 IDC 中,而在 N 多机器组合的云中.Native 设计之初就是以云架构为基础,提供资源池化、弹性和分布式服务等核心能力。 非原生到云原生的转化路径为: 1、DevOps 迭代与运维自动化,弹性伸缩、动态调度 2、微服务,Service Mesh、声明式 API 3、容器化 4、持续交付
5.1 高德与 OceanBase 合作后续展望
因高德数据体量很大,后续会持续落地OceanBase( 常规结构化和非结构化版本)
探索 OceanBase 的 AP 能力,替换 ADB 方案
探索 Serverless 版本
一、海量数据项目 - 结构化数据
二、海量数据项目 - 非结构化数据
三、 探索 OceanBase 的 AP 能力,替换 ADB方案
四、Serverless 版本的探索
资源按需使用,规格动态升级
资源按需使用,底层存储空间扩容
5.2 极简架构建构云原生 Serverless 和组装式研发生态
组装式研发,乐高组件,动态编排,快速迭代提升人效,降低维护成本,快速迭代业务。
Serverless 生态建设,更加丰富的脚手架和工具落地,快速降本。
存储层面支持 Serverless,一个函数通杀所有,端云一体,语言无关,降低研发门槛。