这篇文章主要介绍王泽林老师分享的 《OceanBase 的基础架构和开发技巧》。如果您看过第一篇文章的对应视频,会发现整个系列主要分为 MiniOB 和 OceanBase 两个系列,本篇文章就是 OceanBase 系列的开篇,所以文章中会有很多 OceanBase 的概念和特点介绍,作为开篇文章为大家普及一些基础知识。
一、基础架构
首先 了解一下数据库基础架构,我们通过下面这种图,来看一下数据库普遍存在的需求:
最最重要的应属“稳定性”了,然后在稳定性基础上,增加了扩展性、高可用、高性能、低成本、兼容性等需求。如果单谈稳定性的话,作为一款新兴数据库无法提供太多有力的证据自证其词,只能通过大量的测试来佐证;要么就是通过数据库的发展历史,所以这里王泽林老师先介绍了一下 OceanBase 的发展历史。
- 2010年,OB 起源于淘宝收藏夹业务,当时还是分布式 NoSQL 存储;
- 2013年~2016年,OB 增加了 SQL 引擎的支持,支持了三副本高可用;到2016年支持了蚂蚁金服的所有核心业务;
- 2017~2019年,增加了分布式事务和强一致性支持;并做了很多外部银行案例;
- 2020年,成立商业化公司独立运营;
- 2021年6月1日,开源并大力发展社区生态,支持社区共建。
通过上面历史的介绍,我们不难发现,OB 经历了几个大的阶段,每个阶段都会发生较大的架构调整,比如从早期的 分布式 NoSQL 存储跃升为 NewSQL 分布式数据库,再比如2022年 4.0 版本小鱼发布的单机一体化架构;每一次架构的变更都是一次顺应数据库历史发展的考量。历史发展的一些重要场景,也能充分证明 OB 的能力,比如对双十一的支持、一些世界第一打榜的结果等,这里就不展开说了,网上相关的文章太多了。
接下来就是其他架构在稳定性基础上的其他特点,包括 zone、rs、paxos 等概念,zone可以类比为一个城市、机房或者机架,同一集群尽量做到概念在一个水平线上;rs是rootservice的缩写,是集群的总控服务;paxos是副本一致性协议。
在同一个 zone 里面扩展机器可以达到提高 OB 集群性能的目的,但是扩展 zone 的数量并不能提高集群的性能而只能提高高可用性。据官方说法,TPCC测试时,集群规模有1500个节点。
针对“高可用”特点,OB提供双中心的架构,是一种逻辑复制的主备库模式,这种模式下,一些集群的动作,比如创建表操作,是通过 RS 的同步完成的,两边的 RS 各为其主;分区数据是 clog 的异步同步。
另外还有可用性更高的6副本两地三中心架构和5副本的三地五中心架构:
“高性能”的特点往往值得大书特书,王泽林老师通过 OB 典型的读写场景给大家做了介绍:
-
Read 分为本地读、远程读和分布式读,适应各种情况;对于读操作有以下优化手段:
- 降低响应时间
- obproxy 部署在 app 本地 - 可以将网络降低到1跳
- prepared statement 及协议优化 - 可以减少很多硬解析的过程
- fast parameterize & plan cache - 通过执行计划缓存快速命中执行计划
- CBO 查询优化器
- 一阶段分布式/并行执行计划生成
- 来自大量生产实践打磨的重写规则
- block cache & row cache - 存储引擎相关
- fused_row cache & bloom filter - 存储引擎相关
- static type expression - 静态类型的执行语法
- vectorized execution engine - 向量化执行引擎
- Px 并行执行
- 避免不必要的 RPC:三类执行计划
- 提升吞吐率
- MVCC 快照读
- 水平扩展
- 降低响应时间
-
Write 也分为本地写、远程写和分布式写;写操作也存在很多优化方法:
- 降低响应时间
- 内存级写入性能,小事务执行过程不落盘
- 局部索引避免分布式事务
- 轮转合并提升大压力下写入性能
- PDML - DML 并行
- 提高吞吐率
- Transaction Set Consistency
- 行级锁
- 多种隔离级别
- 降低响应时间
-
高效事务提交
- 降低响应时间
- 避免分布式事务:分区 vs 行 vs 块
- 全局时间戳服务优化
- 2 PC 一阶段优化
- 一体化设计的 clog 避免分布式状态机分层开销
- 使用 PL/SQL 减少交互次数
- 提升吞吐率
- 一致性协议 multi-paxos vs raft
- clog 日志组提交
- 锁模型:悲观锁 vs 乐观锁
- 热点行:提前解行锁,不需要到多数派提交,事务写下去就提前解行锁
- 降低响应时间
在“低成本”方面,通过多副本和多租户上的不同组合方案,达到降本的目的:
二、开发技巧
“工欲善其事,必先利其器” 这一部分,介绍了一些 OceanBase 开发技巧。这一部分包括以下内容:
- OBD 部署 OceanBase
- 使用源代码编译 OceanBase
- 设置开发 IDE
- 代码编写风格与自动化风格格式工具
- 代码调试
- 如何用自己的二进制部署 OceanBase
- 编写 mysqltest
- 编写 unittest
- 如何向 OceanBase 贡献代码
2.1 OBD 部署 OceanBase
该操作可以参考:https://github.com/oceanbase/obdeploy
另外可以通过 obd 命令帮助信息进行一些操作的了解:obd -h
, obd cluster -h
2.2 使用源代码编译 OceanBase
源码编译可以参考:https://github.com/oceanbase/OceanBase/wiki/Build-from-source-code
下图展示了当前兼容的操作系统和 CPU 架构,可以看到 MacOS 还是不支持的,其他大多数主流操作系统均得到了支持。
操作步骤中一些步骤的作用解释如下:
- sh build.sh --init - init操作是为了下载一些平台依赖,可以帮助大家更顺滑的准备编译环境; ash build.sh
- debug --init --make - 其中的 debug 或 release 相当于 cmake 操作
2.3 设置开发 IDE
IDE 设置可以参考:https://github.com/oceanbase/oceanbase/wiki/how_to_set_ide_with_ccls
在源码开发过程中,推荐的几款 IDE 分别为:Vim、Visual Studio Code 和 CLion。
推荐安装 ccls 插件,方便函数之间的跳转。
还要注意将生成的 compile_commands.json 文件 移动到项目根目录下面。
2.4 代码编写风格与自动化风格格式工具
代码风格这部分,可以参考文档:https://www.oceanbase.com/docs/community-code-style-cn-10000000000018872 ,这里面论述的很详细,建议每个人都好好的看看。
另外,源码中提供了一个 format.sh,在目录 sh tools/scripts/format.sh
下,使用方法及其他 IDE 如何配置请参考网页:https://github.com/oceanbase/oceanbase/wiki/How_to_set_code_format
2.5 代码调试
代码调试,可以参考文档:https://github.com/oceanbase/oceanbase/wiki/how_to_debug 。
文档里面有很多代码调试的方法,最建议的还是使用 gdb 进行调试。
最传统的方式是通过 gdb attach 上去调试,也可以使用 obd,如下:
$ ./obd.sh gdb -h
>>> obd tool command --help
Usage: obd tool command <deploy name> <command> [options]Options:-c COMPONENTS, --components=COMPONENTSThe components used by the command. The firstcomponent in the configuration will be used by defaultin interactive commands, and all available componentswill be used by default in non-interactive commands.-s SERVERS, --servers=SERVERSThe servers used by the command. The first server inthe configuration will be used by default ininteractive commands, and all available servers willbe used by default in non-interactive commands.-h, --help Show help and exit.-v, --verbose Activate verbose output.
2.6 如何用自己的二进制部署 OceanBase
用自己的二进制部署的话,可以采用 obd 来 change repo 的方式,参考命令 obd cluster change-repo
进行。
另外大家也可以使用 tools/deploy/obd.sh
进行配置部署,例如:
sudo ./obd.sh prepare
sudo ./obd.sh deploy -c single.yaml
如果出现以下问题,说明权限不够,请使用 sudo
权限:
$ ./obd.sh prepare
./obd.sh: line 8: /tools/deploy/activate_obd.sh: No such file or directory
>>> obd devmode enable
./obd.sh: line 14: //deps/3rd/usr/bin/obd: No such file or directory
Exec obd cmd failed. If your branch is based on 3.1_opensource_release, please go to the deps/3rd directory and execute 'bash dep_create.sh all' to install obd.
grep: /tools/deploy/.obd/.obd_environ: No such file or directory
如果出现以下问题,可能是 LD_LIBRARY_PATH 设置有问题,可以参考如下解决方法:
$ ./obd.sh deploy -c distributed-with-proxy.yaml
Deploy name: distributed-with-proxy
/home/chris/OceanBase/oceanbase/tools/deploy/bin/observer not found
# chris @ ob-allinone in ~/OceanBase/oceanbase/tools/deploy on git:master x [15:09:47]
$ /home/chris/OceanBase/oceanbase/tools/deploy/bin/observer
/home/chris/OceanBase/oceanbase/tools/deploy/bin/observer: error while loading shared libraries: libmariadb.so.3: cannot open shared object file: No such file or directory# chris @ ob-allinone in ~/OceanBase/oceanbase/tools/deploy on git:master x [15:10:18] C:127
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/chris/OceanBase/oceanbase/deps/3rd/usr/local/oceanbase/deps/devel/lib/mariadb/# chris @ ob-allinone in ~/OceanBase/oceanbase/tools/deploy on git:master x [15:10:40]
$ /home/chris/OceanBase/oceanbase/tools/deploy/bin/observer
/home/chris/OceanBase/oceanbase/tools/deploy/bin/observer
其实上面主要就是判断已存在的 observer 为什么没法执行,发现是缺少 so 文件,所以重设了一下环境变量就可以了。
或者也可以直接使用 ./observer
指定参数的方法来执行,可以参考官方文档中的手动安装 observer 并初始化部分。
2.7 编写 mysqltest
mysqltest 部分章节主要参考文档:https://github.com/oceanbase/oceanbase/wiki/Run-mysql-test 。
当我们写了一些比较复杂的功能时,可以通过 mysqltest 来测试一下编写的是否存在问题。这个过程需要写一个 test和一个result结果集文件。通过 obd test mysqltest xxxx
来进行测试,对比结果是否在预期范围内。当然要注意写对位置哦。
2.8 编写 unittest
编写 unittest 可以参考文档:https://github.com/oceanbase/oceanbase/wiki/Run-unit-test。如果要进行 unittest,需要先编译。
正常编译 oceanbase 不会编译 unittest,所以这里有一个手工编译的动作。
编译完成后,可以通过 ./run_tests.sh
运行所有单元测试,或者自己编写一个单独的测试,然后执行。
2.9 如何向 OceanBase 贡献代码
贡献代码部分就比较简单了,注意以下几点:
- 首先签署 CLA;
- 可以给 OB 提 issue;
- 如果功能改变比较大,可以开 discussion,然后 OB 的开发会与大家一起讨论;
- 如果要提交 pr 的话,需要提前做好 mysqltest 和 unittest;
- 也可以在一些 pr 上进行评论;
- 也可以做一些代码 review 的操作。
参考文档:https://github.com/oceanbase/oceanbase/wiki/Contribute-to-OceanBase。
今天的内容大概就这些~
最后的最后,如果大家感兴趣,可以多关注和参与 OB 的活动:https://ask.oceanbase.com/t/topic/35601006。