
OceanBase 社区版从 3.1.2 版本开始,除 SQL 服务端访问模式外,还提供 Key-Value 的方式,即通过 Table API 帮助应用跨过 OceanBase SQL 引擎,以更快的方式直接与存储引擎和事务引擎进行交互,从而大幅提高数据的访问效率。
Table API 的诞生源自蚂蚁内部大量 HBase 应用的迁移,每年的双 11,应用都会面临访问流量的指数级增长,这是一个非常容易发生尖刺的特殊时期。一旦发生尖刺,HBase 会产生 GC 并且导致垃圾回收内存,延迟大幅增加甚至冲击业务系统的稳定性,这也是很多互联网公司投入大量的研发力量去优化 HBase Java GC 问题的原因。
自从 OceanBase 开始提供 Table API 接口,过去每年双 11 遇到的 Java GC 问题得到很好的解决。基于 OceanBase KV 接口能力,存储成本、性能和稳定性均得到大幅优化。
大数据领域中,基于 HBase 的 KV 存储引擎涌现出各种灵活的多模模式,比如 Apache Phoenix 提供 SQL 引擎,OpenTSDB 提供时序数据库访问,Apache Solr 提供搜索检索能力。随着 OceanBase 的 KV 能力落地,开始出现越来越多类似大数据领域的多模模式,涌现出基于 OceanBase KV 存储引擎能力实现分布式时序数据库 CeresDB 等。OceanBase 天然的弹性扩展、高可用、高性能等核心特性,相信在不远的将来会不断涌现出更多充满想象力的应用。

为什么选择 Table API
OceanBase 经过蚂蚁核心系统和双 11 大促连续 9 年的检验,在 OceanBase 上支持Table API,直接拥有 OceanBase 久经考验的架构优势:
• 高可用:单服务器故障能够自愈,支持跨城多机房容灾,数据零丢失,可满足金融行业 6 级容灾标准(RPO=0,RTO<30s);
• 高性能:准内存级数据变更操作,独创的编码压缩技术,结合线性水平扩展,TPC-C 测试达到 7.07 亿 tpmC,TPC-H 达到 1526 万 QphH@30000GB;
• 高扩展:Share-Nothing 架构,自动负载均衡,按需在线扩/缩容,对应用透明;集群规模可达数千节点,数据量可达 PB 级,单表记录万亿行;
• 低成本:不依赖于特定的高端硬件,降低用户的硬件成本;使用编码和通用压缩算法,全面对数据进行压缩,且不影响性能,降低用户存储成本;
• 多租户:通过租户实现资源隔离,数据库实例之间无须相互感知。并通过权限控制确保不同租户数据的安全性。多租户与 OceanBase 数据库强大的可扩展性相结合,能够提供安全、灵活的 DBaaS 服务;
• 云原生:为云而设计,满足多云需求,消除单云锁定限制,可部署在各种公有云环境;
• 生态丰富:可直接使用 OceanBase 备份恢复、自动部署、导入导出、OCP 云平台管控等生态配套工具。

“1 + 1 > 2”的架构提升
OceanBase 社区版对 Table API 不是简单的支持,而是要达到“1 + 1 > 2”的架构提升效果:
• 更高的性能,scan 性能是 HBase 的 2.42 倍,insert 是 HBase 的 1.7 倍;

• Table API 和 SQL 可以同时操作同一份数据而发挥各自优势;API 提供灵活的业务模型和极高的访问性能,SQL 提供强大的表达能力,例如 JOIN、ORDER BY、GROUP BY 等 API 无法描述的语义;
• 让 NoSQL 数据模型拥有了 ACID 事务能力和严格的一致性模型(一般的 NoSQL 数据库只提供行级事务和最终一致性);
• 同一个 OceanBase 租户可以同时支持 API 和 SQL,有 OceanBase 的环境就可以使用 Table API,极大缩减成本,提高交付效率;
• Table API 共享 OceanBase 的生态体系,包括离线处理能力、高可用能力、极致性能、极优成本;
• NoSQL 数据模型拥有 SQL 一样强大的数据类型表达能力,拥有存储端(相对于应用端)高效计算能力;
• 借助 OceanBase SQL 强大的 OLAP 分析能力,未来将可以直接分析 NoSQL 生成的在线业务数据;
• 同一个业务或相关业务的关系数据模型和 NoSQL 模型数据都存储在同一个OceanBase 集群内,可以统一资源管理和调度,统一运维。降低运维人员学习不同系统的成本,提升全栈的稳定性。

Table API 整体架构
应用层有两种方式访问到 OceanBase Server:Table API 和 SQL,分别对应 NoSQL 和 SQL 模式。NoSQL 模式下,客户端接口 JavaClient 通过 RPC 协议直接与 OceanBase Server 通信,同时客户端支持丰富多样的操作函数,功能上基本可以满足大部分场景的需求。
相比于 SQL,整体流程上 Table API 并没有复杂的 SQL 语法语义等繁琐的解析以及生成执行计划等过程,但却具有与 SQL 几乎同等的事务以及存储能力,使用起来相对简单。整体流程图如下:

Table API 提供了对表模型数据的操作接口。同时,在内部,Table API 定义了客户端和数据库服务端之间的一组通用的交互协议。
Table API 处理逻辑

客户端
分布式数据库的每个表甚至每个表的不同分区都可能存放在不同的机器上,想要对表进行读写,必须先要定位到数据所属的表或是分区的位置。特别是对于 Table API,OceanBase Server 当前并不会做路由转发,只在本地执行,路由错误会读写非预期的数据。因此每一轮操作,客户端都会先根据 table name,rowkey 算出具体的分区号 partition id,进而根据分区号反向计算得出执行该指令的 OceanBase Server 具体位置,然后再把 request 请求发送到对应 OceanBase Server 节点。因此,客户端除了要保证基本的读写功能外,还承担着路由计算的重大使命。需要注意的是,当前Table API 没有跨分区事务。
传输层(RPC 框架)
Table API 使用 OceanBase 自定义的 RPC 协议进行通信,这个协议是标准的 Request-Response 模型。不同的 Request 之间互相独立,Server 端会并发处理多个请求。同一个客户端和 Server 端之间可以建立多个 TCP 连接接。这层模型由 Libeasy 封装。在 Libeasy 的包内包括 OceanBase RPC 包的包头和数据。数据经过 RPC 层传递后到服务端后,需要再经过 Decode 模块对数据包进行解析,OceanBase Server 最后从 pkg 请求包种解析出消息类型以及数据体。
服务端
OceanBase Server 服务端使用生产者消费者模型,来处理客户端的 Table API 消息请求。客户端并发消息的最大个数取决于队列的长度以及 Server 的处理速度。当服务端接收到客户端请求后,由独立线程把 Request 消息放到消息队列中,并且由工作线程从队列中取出消息体并处理。为了区分不同类型的消息,OceanBase Server 采用优先级队列,对不同类型的消息(MySQL,RPC等)进行分层处理,这样可以保证某些优先级比较高的请求不会因为超时而被饿死。
另外,Table API 与 OceanBase SQL采用相同的事务框架以及存储引擎。存储引擎是两级分区表+LSM 树,两级分区表支持哈希分区、Range 分区、以及哈希和 Range 的各种组合,能够通过自动 Range 分区和自动分区负载均衡来解决分区热点问题和机器热点问题,对用户完全透明。
*附存储引擎链接:https://open.oceanbase.com/docs/community/oceanbase-database/V3.1.1/lsm-tree-architecture
性能优势
OceanBase 采用分区表结构,主分区可以分布在不同的 OceanBase Server 上,对于不同副本的写操作会分布到不同的数据节点,从而实现数据多点写入,提高系统整体写入吞吐;数据存储采用 LSM-Tree 模型,业务数据可直接写入内存,获得接近内存数据库的写入性能;为了提高访问性能,OceanBase 设计了多种缓存结构,如块缓存、行缓存,另外设有布隆过滤器、查询优化等,最大限度地提高访问性能;相比于 SQL 模式,Table API 从宏观上绕过 SQL 复杂的语法语义解析,直接提供从客户端到服务端的访问,大大简化了访问路径;通过支持弱读能力,优化跨地域部署 OceanBase 数据库的查询操作,降低跨地域场景下的访问延时。

Table API 操作类型
Table API 支持四种不同的操作类型,分别是 login,execute,batch_execute 和query(查询扫描)。操作类型的实现背后,是分别使用四个不同的处理 Processor 类进行管理。每一种类型通过继承和派生衍生出对应的 process 处理函数,分别处理不同的 RPC 消息请求。
• 登录请求:OceanBase TableLoginRequest,需要提供和 SQL 一样的 OceanBase 租户和用户名密码用于认证。认证成功才可以使用其他 Table API ;
• Table API 单次处理请求:OceanBase TableOperationRequest,例如 insert、update、delete、replace、retrieve、increment、append 等;
• Table API 批处理请求:OceanBase TableBatchOperationRequest,单处理的集合;
• Table API 流式查询请求:OceanBase TableQueryRequest,例如针对某 primary key 范围的 scan range。
基本操作类型
单处理(Single Operation)
Insert | 插入一行记录 | · 插入成功,则返回标记该操作影响的行数,简称为 affect_rows(下同),插入成功时返回1 · 插入失败,affected_rows 为0 · 主键冲突(行存在)则插入失败 |
Get | 取回一行记录 | · 若行存在,则返回该行记录,否则,返回空集 |
Delete | 删除一行记录 | · 若行记录被成功删除,返回 affected_rows 为1 · 行不存在,则返回 affected_rows 为0 |
Update | 更新一行记录 | · 该行记录被成功更新时返回 affected_rows 为1 · 若行不存在,返回 affected_rows 为0 |
Insert or update | 插入或修改一行记录 | · 若行不存在,则插入记录,返回 affected_rows 为1 · 若行存在(主键冲突),则更新这行记录,成功返回 affected_rows 为1 · 特别的,如果插入有唯一索引冲突,则也执行更新操作 |
Replace | 替换一行记录 | · 如果这行不存在,则插入记录,返回 affected_rows 为1 · 若行存在(主键冲突),则删除原记录,然后再插入这行记录,成功返回 affected_rows 大于1(包含被删除的行) · 特别如果有唯一索引冲突,则删除所有引起冲突的行,然后再插入这行记录,返回 affected_rows 大于1(包含被删除的行) |
Increment | 把指定列的值原子地增加(可以为负数)某个增量值(OceanBase 1.4.75开始新增特性) | · 支持操作整型列类型,含 tinyint,smallint,mediumint,int,bigint 及对应的无符号列类型,其他列类型报错 · 如果计算结果溢出列类型的值域,则报错 · 若行不存在,则插入,把增量值设置为初值(等价于原值为0) · 若行存在,但指定列的值为 NULL,则把增量值设置为初值(等价于原值为0) |
Append | 把指定列的值原子地追加某个串。(OceanBase 1.4.75开始新增特性) | · 支持操作支持 varchar/varbinary 类型,其他列类型报错 · 如果计算结果溢出列的长度,则报错 · 行不存在,则插入,把增量值设置为初值(等价于原值为空串) · 若行存在,但是指定列的值为 NULL,把增量值设置为初值(等价于原值为空串) |
批操作 (Batch Operation)
批操作为单操作的集合,因此想了解批处理的具体表现,可以参考上一节内容,在这里不做赘述。特别的,为了加速批操作流程,在针对只读批操作集合的处理上,OceanBase Server 做了只读事务的优化,使得批操作中的只读操作集合,相比于读写批操作,在性能上的表现会更好。关于 Batch 的实现,可以参考客户端使用。
*附链接:https://github.com/oceanbase/obkv-table-client-java/tree/master/example
查询操作(Query)
支持根据主键或者主键的前缀进行范围扫描,也可以不指定主键,根据索引或者索引前缀范围进行扫描查询。Query 操作类型可以指定多段范围进行扫描。现阶段,在一次 query 的 RPC 消息交互过程中,最大能从服务端返回 64M 的结果数据集合(可调整)。关于 Query 的实现,可以参考客户端使用。
*附链接:https://github.com/oceanbase/obkv-table-client-java/tree/master/example
Table API支持的值类型
Table API 支持 OCEANBASE SQL 支持的所有值类型。包括:
• NULL
• Tiny Int,Unsigned Tiny Int
• Small Int,Unsigned Small Int
• Medium Int,Unsigned Medium Int
• Int,Unsigned Int
• Big Int,Unsigned Big Int
• Float,Unsigned Float
• Double,Unsigned Double
• Decimal,Unsigned Decimal
• Datetime,Timestamp
• Date,Time,Year
• Varchar,Char (支持两种collation:utf8mb4_general_ci和utf8mb4_bin)
• Varbinary,Binary
• Tiny Text,Text,Medium Text,Long Text
• Tiny BlOceanBase ,BlOceanBase ,Medium BlOceanBase ,Long BlOceanBase
• Bit






