开源实践 | 携程在OceanBase的探索与实践
写在前面:选型考虑
携程于1999年创立,2016-2018年全面推进应用 MySQL 数据库,前期线上业务、前端技术等以 SQL Server 为主,后期数据库逐步从 SQL Server 转到开源 MySQL 数据库。随着技术多元化以及业务的不断发展,MySQL 逐渐无法满足携程需求,主要体现在:业务数据模型呈现多元化,在异地多活部署、运维成本、资源弹性管理以及应用稳定性等方面对数据库技术提出了新的要求,MySQL 方案在单机性能瓶颈表现明显,同时分库分表方案带来运维复杂度和维护成本也随之增加。于是从2018年开始,携程开始引入 Mongo、HBase 等技术栈,同时探索通过OceanBase 社区版方案来替换原有MySQL方案。
经前期测试与后期实践,事实证明OceanBase技术特性及架构相对符合携程项目需求。OceanBase的异地多机房多写、大促弹性扩容、高可用切换对业务影响小都非常符合携程需求。同时在性能和成本方面取得了不错的收益:在性能方面,OceanBase 方案读性能平均提升 2 倍,写性能平均提升 3 倍;在成本方面,OceanBase 方案节省 2/3 存储资源,很大程度上降低了硬件成本。
本文内容主要分享携程在OceanBase社区版的探索,将从以下三个方面展开分析:OceanBase 自动化部署、MySQL 实例迁移 OceanBase 以及 OceanBase 方案收益。
一、基于OBD工具自动化部署环境
OBD (OceanBase Deployer)是 OceanBase 开源软件的安装部署工具,同时也是包管理器,可以用来管理 OceanBase 所有的开源软件。一开始,携程利用 OceanBase 开发的OBD 组件快速进行了部署,由于业务需要非常灵活的运维操作,比如需要扩容 OBServer 时,该操作需要通过命令行执行 ALTER 语句实现,暂不支持通过 OBD 来完成集群扩容,同时综合业务自身需求:
1、携程有自己的运维监控平台,需要将OceanBase的元数据、监控数据、以及任务流很好地融入到携程监控平台、自动运维平台中;
2、携程有着完整的企业dal层、数据库多环境(开发、测试、生产)上传发布流程和部署平台,OceanBase需要兼容甚至还需要和MySQL互相巧妙的兼容,而OBD当前版本无法支持。
为此,携程选择了基于OBD自动化工具进行二次开发,形成符合业务需求的部署方案,基于两个方面的考虑:开发语言易上手,二次开发成本低。OBD工具是Python写的程序,源码简单易懂,可以直接调试源码并进行二次开发自动化部署程序,大大降低了OceanBase运维嵌入携程平台的难度;融入个性化设置。OBD工具虽然方便,但是一些配置不够灵活,携程的安全策略以及服务器环境限制可能和OBD有所冲突。集群的元数据合并到携程的运维平台至关重要,而二次开发的自动化程序,可以直接定义安装的用户、目录,将服务器、IP、Zone等基础信息直接落到运维平台,为后续自动化运维打下了坚实的基础,和携程运维平台契合的更紧密。
以下是携程基于 OBD 部署工具二次开发的部署运维平台示意图:

在环境部署这里特别提一点,OceanBase的命令可以将整个参数放在启动命令中,包括OBServer和OBProxy。集群部署好后会在OBServer/etc目录下生成一个配置文件OBServer.config.bin,将所有集群信息记录在文件中,这样后续启动或者重启OBServer时,就不需要再带参数启动。OBProxy也是一样,在OBProxy/etc下也会生成OBProxy_config.bin文件,再次启动可以不带参数启动,这点对使用者非常友好,避免不带参数再次启动时,出现参数回滚问题。
二、MySQL实例迁移OceanBase实践
在部署工具改造工作完成之后,正式进入业务和数据的迁移环节。该部分主要从以下几个方面来介绍携程的迁移工作:集群架构设计、迁移准备工作(包括兼容性测试、业务模式评估、回退方案等)、应用迁移以及性能优化。
1、OceanBase 架构如何设计?
在实际环境中,需要根据自身 IDC 机房的部署,匹配适用 OceanBase 的架构设计。 OceanBase 在携程的部署架构如下,当前是一地三中心部署方案:

2、迁移准备工作
1)SQL事务兼容性测试
在携程开始使用时,OceanBase社区版完全兼容MySQL 5.6版本,而实际携程应用的是5.7版本。为此,将MemTable Trace抓取出来的语句在OceanBase上进行兼容性测试,发现大部分都相互兼容。这里需要注意的是:OceanBase不支持主键的删除,主键的修改、跨数据类型的字段的类型修改,但新增字段,扩容字段,没有任何影响。
2)对MySQL实例特点和业务模式进行分析
最值得关注的是,可以直接用MySQL创建表结构的语句在OceanBase 建表,后期简单做下优化和微调就可以,对使用者非常友好。
3)分区表结构改造
在OceanBase里,一张表即使没做分区也默认为分区表,即一个大的分区。使用分区表一方面可以基于数据分区来做集群层面的数据扩展, 另外一方面可以更充分的支持 SQL 并行执行, 充分利用资源,提升集群的性能。同时,好的分区设计机制跟业务息息相关。在实际环境中,MySQL实例的分区机制相对特殊,大量分区表的分区维护需要依赖自动化脚本,因此迁移到 OceanBase 环境前,表结构需要进行改造。换言之,更好地分析与设计OceanBase分区表,可以充分地发挥 OceanBase 的优势。基于以上考虑,对业务表结构进行如下改造:
- 去掉 Max分区:由于OceanBase不支持Max分区的Reorganize,所以MySQL的range分区表转到OceanBase后需要去掉Max分区,直接预留和保留一些分区来保证所有数据落在分区中,风险点是当数据超出分区范围则会导致写入失败。
- 本地索引改造:分区表的分区增加和删除机制,是由脚本自动维护的。在分区维护的时候,删除分区耗时比MySQL要长很多,经过分析研究,原因是表结构在OceanBase创建后二级索引默认是Global索引,在维护分区的时候会重建全局索引,所以耗时比较久。解决方法:创建表结构的时候,二级索引指定为Local,这样在维护分区时可以瞬间完成。
- TableGroup 解决跨 zone 访问:小表到底要不要做分区?根据 OceanBase 开源社区技术专家的意见:小表不建议做分区。为了解决join时候跨zone跨机器查询,rpc count过大导致性能下降问题,比较小的表、做key分区的表join查询比较频繁的表等可以做TableGroup,这样小表或者相同key的数据会在一起,不会跨zone跨机器查询。
4)回退方案
在OceanBase社区版3.1.0版本中,回退的方案并没有很多,针对社区版不支持OMS组件的情况,携程有两种解决办法:
方法一是应用双写,这也是最常用的一种方法。即在业务数据迁移完成之后,业务在写入 MySQL 环境的同时也会写入 OceanBase 环境。经过一段时间的线上验证,确认 OceanBase 方案在性能和稳定上满足业务要求之后,会断开业务写 MySQL 环境的链路,业务读写流量全部接入 OceanBase 环境。双写的缺点是增加开发成本,开发要介入。在社区版 3.1.2 版本中,将会开源的数据同步工具 OMS(OceanBase Migration Service)是 OceanBase 提供的一站式数据传输产品, 提供 MySQL 到 OceanBase 以及 OceanBase 到 MySQL 数据同步能力,数据迁移将会变的更加简单和快捷。
方法二是备份恢复。备份恢复是 OceanBase 数据库高可用特性的核心组件,主要用于保障数据的安全,包括预防存储介质损坏和用户的错误操作等。如果存储介质损坏或者用户误操作而导致了数据丢失,可以通过恢复的方式恢复用户的数据。从社区版3.1.1 开始, 社区版支持物理备份与恢复, 备份和恢复的性能得到大幅提升,可以快速的完成线上数据的全量和增量备份以及在异常情况下的数据恢复,非常好用。
三、上线迁移以及性能优化
1、从 MySQL平滑迁移至 OceanBase
携程自研设计架构是三个IDC,对应着三个IDC机房,也就是物理的机房,其中一个是开源的集群。由于后续资源紧张,对集群进行弹性扩容,每个Zone从最初的一台机器扩容到了两台机器。在 OBProxy 这一层,为了防止访问过于集中以及考虑到高可用问题,多个 OBProxy 做了负载均衡,应用通过负载均衡设备可以将流量平均打在多个OBProxy。还有另外一个方法,即应用通过DNS直接访问,但这种方法用得很少。
如何实现应用安全并且平滑的从MySQL转到OceanBase?携程也做了很多工作和预案。比如,OceanBase的连接串有租户的配置,那么用MySQL的账号直接访问OceanBase是不行的,需要提前在MySQL创建一个带租户的账号,uapp@tt01权限和之前的账号一样,只要修改应用的连接串配置,开发无需重新发布,后续将连接数据库的配置直接切换到OceanBase,几乎可以实现完全兼容。只要在迁移前验证确保所有的应用全部使用临时账号,就可以万无一失。
2、性能优化
在SQL优化方面,迁移之前应用大批次写入 MySQL 环境,单个批次数据量范围在1000条至10000条不等,写入性能不佳。同等数据量时,在 OceanBase 环境中数据写入更快。此外,可以对 SQL 语句进行优化,比如减少多张表的 join查询,SQL语句带上分区条件缩小范围查询,避免跨分区查询。
业务数据大量写入的时候,可以通过调整一些内存相关参数、日志清理参数来保证集群运行的稳定。在这里介绍3个非常有用的参数以及实际操作说明供参考学习:
- enable_merge_by_turn控制是否开启轮转合并。在凌晨做大合并的时候,开启轮转合并是逐个zone进行合并操作,先把Leader切走再做合并,做完再做下一个,切Leader会影响到业务。关闭该参数即所有的zone一起操作,可能会出现大事务冲突问题,携程一般会选择业务低峰期,或者业务影响很小的时候进行合并,保证合并顺利完成的同时尽量缩短用时。
- minor_freeze_times 用于设置多少次小合并触发一次全局合并。在实际业务中,频繁的全局合并可能会影响集群整体性能,通过该参数设置转储条件,尽量减少触发大合并的次数,保证集群性能稳定。
- writing_throttling_trigger_percentage参数用来控制内存限流阀值,在MEMStore占用内存达到该参数默认阀值时,会开启写入限速。针对写入频繁的高写入业务场景可能出现的内存耗尽导致OOM 问题,通过该参数配合writing_throttling_maximum_duration 参数(通过控制内存分配进度来控制写入速度,即指定在触发写入限速后,剩余 memstore 内存分配完所需的时间,默认一小时)使用。如果内存使用在默认值一小时之内达到限流阈值大小,剩下的内存会按照默认一小时平均分配。默认一小时之后内存没有释放,OceanBase 会拒绝应用建立新连接。这是一个保护措施,保证携程的集群在写入量很大时,集群运行依旧稳定。
3、慢SQL优化
在实际业务测试中,出现执行时间很长的 SQL 语句,仔细排查原因发现是因为查询所需的数据分布在不同节点或者机器上,所以 SQL 请求的数据需要跨机器或者跨 zone访问,网络交互次数增加,影响 SQL整体执行时间,在这里介绍一个典型慢 SQL 优化案例。
慢 SQL 信息:
select a.c1,a.c2 from table1 a left join table2 b on a.c0 = b.c0 where b.c1 is null and a.c1 = “XXXXX”;
查看系统表得到该SQL 执行信息:
select * from gv$sql_audit;

针对这个场景尝试两种优化方法:
第一种:使用TableGroup 方式,将查询所需的数据放在一起,查询速度提升明显
Step1:创建 tablegroup
mysql> CREATE TABLEGROUP IF NOT EXISTS tg_1;
Step2:添加对应的表
mysql> ALTER TABLE TABLE1 SET TABLEGROUP tg_1;
mysql> ALTER TABLE TABLE2 SET TABLEGROUP tg_1;

第二种:手工把两个表迁移到同一个节点,效果一样但是相对麻烦
Step1:switch replica
mysql> ALTER SYSTEM SWITCH REPLICA PARTITION_ID='0%0@100000' source='x.x.x.x:2882';
Step2:move replica
mysql> ALTER SYSTEM MOVE REPLICA PARTITION_ID='0%0@100000' source='x.x.x.x::2882';
Step3:避免分区自动在Unit之间重新均衡
mysql> ALTER SYSTEM SET ENABLE_REBALANCE = 'false' [TENANT='tenantname'];
通过以上两种优化方式,RPC_count 从 23331降低至 1 次,优化效果显著。
四、OceanBase 方案在性能和成本方面收益明显
在使用 OceanBase 方案之后,携程在性能和成本方面取得了不错的收益:
1、性能方面,相比 MySQL,OceanBase 方案读性能平均提升 2 倍,写性能平均提升 3 倍,性能提升明显;
2、成本方面,基于数据编码以及存储引擎自带多级压缩技术,使得 OceanBase 方案相比 MySQL 节省 2/3 存储资源,很大程度上降低了硬件成本。
读性能对比:
| OceanBase 读性能 | MySQL 读性能 |
|---|---|
![]() |
![]() |
写性能对比:
| OceanBase 写性能 | MySQL 写性能 |
|---|---|
![]() |
![]() |
写在最后:未来规划
在携程与OceanBase短暂的磨合期内,携程各项测试表明,OceanBase原生分布式数据库的各方面性能均可满足携程的业务需求。当前携程的风控业务系统、会员用户画像等多个业务在测试 OceanBase 社区版。携程非常感谢OceanBase的所有技术支持人员,期待在后续合作中,OceanBase能发挥出更优越的表现。
开源实践 | 携程在OceanBase的探索与实践的更多相关文章
- 携程实时计算平台架构与实践丨DataPipeline
文 | 潘国庆 携程大数据平台实时计算平台负责人 本文主要从携程大数据平台概况.架构设计及实现.在实现当中踩坑及填坑的过程.实时计算领域详细的应用场景,以及未来规划五个方面阐述携程实时计算平台架构与实 ...
- 转:携程App的网络性能优化实践
http://kb.cnblogs.com/page/519824/ 携程App的网络性能优化实践 受益匪浅的一篇文章,让我知道网络交互并不是简单的传输和接受数据.真正的难点在于后面的性能优化 下面对 ...
- 携程App的网络性能优化实践
首先介绍一下携程App的网络服务架构.由于携程业务众多,开发资源导致无法全部使用Native来实现业务逻辑,因此有相当一部分频道基于Hybrid实现.网络通讯属于基础&业务框架层中基础设施的一 ...
- 美团 iOS 端开源框架 Graver 在动态化上的探索与实践
近些年,移动端动态化技术可谓是“百花齐放”,其中的渲染性能也是动态化技术一直在探索.研究的课题.美团的开源框架 Graver 也为解决动态化框架的渲染性能问题提供了一种新思路:关于布局,我们可以采用“ ...
- 解密国内BAT等大厂前端技术体系-携程篇(长文建议收藏)
1 引言 为了了解当前前端的发展趋势,让我们从国内各大互联网大厂开始,了解他们的最新动态和未来规划.这是解密大厂前端技术体系的第四篇,前三篇已经讲述了阿里.腾讯.百度在前端技术这几年的技术发展. 这一 ...
- 敏捷之旅--携程行程&订单团队
转自本人运营的公众号“ 携程技术中心PMO”(ID:cso_pmo) 关于我们 我们面临的挑战 敏捷开发是以用户的需求进化为核心,采用迭代.循序渐进的方法进行软件开发.先把一个大项目分 ...
- 携程Android App插件化和动态加载实践
携程Android App的插件化和动态加载框架已上线半年,经历了初期的探索和持续的打磨优化,新框架和工程配置经受住了生产实践的考验.本文将详细介绍Android平台插件式开发和动态加载技术的原理和实 ...
- 携程酒店DevOps测试实践
作者简介 王幸福,携程酒店研发部高级测试经理,负责无线自动化测试相关工作.在测试框架和平台研发.移动测试.DevOps等领域有着丰富的经验. 如今很多大型互联网公司.创新型企业都在积极地进行DevOp ...
- 携程React Native实践
React Native(下文简称 RN)开源已经一年多时间,国内各大互联网公司都在使用,携程也在今年 5 月份投入资源开始引入,并推广给多个业务团队使用,本文将会分享我们遇到的一些问题以及我们的优化 ...
随机推荐
- Servlet(4):一个简单的注册页面
一. 注册要求 1. 一个注册页面 username (文本框) password:密码 (密码框) passwordYes :再次输入密码(密码框) hobby (多选框) sex (单选框) in ...
- git 使用https方式进行 pull、push代码免密
由于网络原因我用ssh方法拉取代码每次都提示远程服务连接失败,因此我用了https方式去拉去代码. 这种方式拉取代码每次操作都要输入密码,为了解决这个问题做了一下操作: 在命令行输入 git conf ...
- Linux下部署Java项目(jetty作为容器)常用脚本命令
startup.sh #!/bin/bash echo $(basename $(pwd)) "jetty started" cd jetty nohup java -Xmx8g ...
- angular关于select的留白问题
Angular select留白的问题 小白的总结,大神勿喷:需要转载请说明出处,如果有什么问题,欢迎留言 总结:出现留白说明你的ng-model的值在option的value中没有对应的值: 一.直 ...
- Linux 文件权限、系统优化
目录 Linux 文件权限.系统优化 1.文件权限的详细操作 1.简介: 2.命令及归属: 3.权限对于用户和目录的意义 权限对于用户的意义: 权限对于目录的意义: 4.创建文件/文件夹的默认权限来源 ...
- Explain的详细使用
官方文档 https://dev.mysql.com/doc/refman/5.7/en/explain-output.html explain俩种类型 explain extended 会在 exp ...
- idea秘钥集成docker
目录 docker开启远程访问 docker安全远程访问 服务端 客户端 修改权限 修改docker配置 IDEA集成docker部署项目 1. 新建DockerFile,配置启动服务 2. Dock ...
- 第四届“传智杯”全国大学生IT技能大赛题解
目录 A B C D E F G 今年题目难度普遍偏低.只有 D,F 还好. A 按题目给的公式计算即可.注意应在最后的答案中去掉小数部分. B 按照题意模拟即可.注意答案要与 \(0\) 取 \(\ ...
- Django记录操作日志、LogEntry的使用
LogEntry是在后台开发中经常用到的模块,它在admin是默认开启的. 可以使用LogEntry模块记录所有用户的操作记录.一方面可以用来监督,另一方面可以用来做回滚. 1. 使用LogEntry ...
- java 图形化工具Swing 颜色文件选择器 ;JColorChooser;JFileChoose
使用JColorChooser: JColorChooser用于创建颜色选择器对话框,该类的用法非常简单,该类主要提供了如下两个静态方法: (1),showDialog(Component compo ...



