阳江网红酒店无边泳池,长春网站优化平台,视频网站文案,品牌传播推广方案如何基于OceanBase构建应用和数据库的异地多活
前言 OceanBase是一个通用的分布式的关系型数据库#xff0c;有很多独特的特点。比如数据库的多租户、高可用、极致弹性伸缩能力。如果把OceanBase当作单库使用#xff0c;就没有把OceanBase的分布式优势发挥到极致。
本文主要…如何基于OceanBase构建应用和数据库的异地多活
前言 OceanBase是一个通用的分布式的关系型数据库有很多独特的特点。比如数据库的多租户、高可用、极致弹性伸缩能力。如果把OceanBase当作单库使用就没有把OceanBase的分布式优势发挥到极致。
本文主要分享一个基于分布式架构的应用把OceanBase数据库的分布式优势发挥到极致所需要了解的OceanBase基础这也是理解蚂蚁金服的基于OceanBase构建的三地五中心异地多活架构的基础。 分布式数据库开发相关问题 好的性能首先是设计出来的应用如果追求极致的性能就需要关注OceanBase里数据的相关事情。如 数据如何分布 数据如何读写 存储容量瓶颈怎么办 访问性能瓶颈怎么办 数据库出故障时数据可用性和可靠性具体怎样应用需要做什么特殊处理么 数据库扩展时应用需要迁移数据么数据迁移的时候对应用有什么影响
这些问题对理解OceanBase的分布式特点很有帮助。后面我们逐步看看OceanBase是如何应对。 OceanBase集群外观 首先简介一下OceanBase集群的外观。 OceanBase是以集群形式运行的由一堆服务器组成。上图是「三副本」部署机器会分为三组每组一个区域称为Zone各个机器通过网络互相访问。没有光纤交换机、共享存储以及直连网线等。
服务器通常建议CPU、内存和磁盘尽可能的大磁盘建议用普通SSD盘。普通服务器的好处是便宜劣势是可靠性和性能可能不如小型机那么高。也就是说OceanBase可以部署在一组可靠性和性能不是特别高的普通服务器上却提供了高性能、高可用和高可靠、弹性伸缩等多项能力。
以上是一个OceanBase集群的外观和能力但是提供给业务的并不是这个集群的全部资源和能力而是其子集即租户Tenant。 OceanBase多租户特性
OceanBase定义了一些基本的资源规格Resource unit config如4CPU8Gmem500Gdisk等然后选取某类资源规格创建一组资源池Resource Pool此时集群资源就有一部分被分配出去了。最后将这个资源池关联到一个新建租户则租户就可以使用这个资源池的能力。
OceanBase默认有个sys租户管理整个集群。用户租户必须在sys租户内部创建。
如下示例就是创建租户的过程。
#sys租户登录方法
$mysql -hxxx.xx.11.11 -urootsys#obdemo -P2883 -proot oceanbase -A
#资源规格UnitConfig create resourceunit S0_uc max_cpu2,max_memory5G,…
资源单元Unit create resourcepool Pool_01 unitS0_uc,unit_num2,...
租户Tenant create tenant test_ins resource_pool_list (Pool_01),...
OceanBase兼容了大部分MySQL连接协议和语法租户的使用体验跟MySQL实例很像。研发可以在租户里创建数据库Database、表Table。还包括分区表等。
OceanBase里描述数据的最小粒度是分区。普通的表非分区表就是一个分区分区表则包含多个分区。
租户的示意图如下。租户之间数据是绝对隔离资源有一定程度隔离。研发可以将业务先垂直拆分为多个独立的子业务分别使用不同的租户或者集群。 OceanBase资源单元 租户里并不知道数据具体在哪个机器上也可以说没必要知道。只是租户的性能还取决于运维为租户规划的资源池分布情况所以了解一下资源单元的分布特点对性能规划也是有意义的。
资源池Resource Pool是由一组资源单元Resource Unit组成。资源单元数量默认跟Zone的数量一致或者是它的倍数可以配置具体分布在哪些Zone以及每个Zone里的Unit数量。如下图 资源单元具备一定的资源能力是数据的容器。租户拥有的资源单元规格和数量决定了这个租户最大性能。资源单元可以在同一个Zone的不同节点之间自由迁移OceanBase借此来维持各个节点的资源利用率尽可能维持一个均衡状态。 OceanBase拆分设计 数据库拆分
数据库拆分有两种。
一是垂直拆分。即按业务模块拆分到不同的实例或库里。为了模块之间互不影响拆分到不同的实例比较好。在OceanBase里实现时可以是拆分到同一个集群里不同租户或者不同集群里的租户都可以取决于业务规模和数据库集群规模。垂直拆分很好理解后面不再赘述。
一是水平拆分。即按某个业务维度将数据拆分到多个分片。这些分片可以是在一个库或者不同库或者不同实例的不同库下。水平拆分实现又有两类常用的选择。如下 分库分表。将一个业务表拆分到N个相同结构的物理表中。中间件做业务表逻辑表到分表物理表的映射路由以及其他相关操作如结果聚合计算等。这个N个物理表可以在不同实例的不同分库中。分库的维度和分表的维度可以不一样比较灵活。 分区表。将一个物理表设计为分区表拆分到N个分区。分区表的各个分区结构是数据库内部保证一致。OceanBase选择的是分区表的水平拆分方式并且支持二级分区表即有2个不同的拆分维度叠加使用。
水平拆分示意图如下 上图是分库分表和分区表同时结合使用。业务表order先经过中间件拆分为100个分表存在10个分库里每个分表在OceanBase内部又是一个分区表100个分区。分库分表的维度和分区表分区的维度都是一致的根据用户ID。
分库分表和分区各有利弊。
分库分表的好处是各个分表的结构一致性是在中间件层保证比较好控制比较适合灰度变更允许部分分表结构不一致最终必须全部一致。此外更大的好处是分库分表是实现异地多活单元话架构的必不可少的条件。缺点是中间件的SQL支持范围有限。
分区的好处是在数据库内部解决了拆分问题。针对分区表的SQL功能是数据库SQL引擎的本质工作相关特性全局索引、二级分区等会持续开发完善。 分区
分库分表架构设计需要确定机器数、实例数、分库数和分表数的拓扑性能理论上限取决于主实例所处的机器节点数。此后要做扩展就要调整这四个元素的数目及其联系。这种扩展很可能涉及到分表数据的迁移需要借助外部工具或产品实现。
分区架构设计研发确定分区策略和分区数运维确定租户的资源单元数量OceanBase确定资源单元Unit在哪些机器节点上以及分区Partition在哪些资源单元里。同一个分区不能跨节点存储。如下图。此后要做扩展就是调整资源单元的规格、数量。
OceanBase在确定Unit里的分区的位置时会尽量让每个节点的负载维持均衡。这个负载的计算方式比较复杂会综合考虑OB节点内部CPU、内存和空间利用率等。分区随意分布对应用性能很可能有负面影响。当业务上有联系的两个表的分区分布在不同的资源单元里同时也分布在不同的节点里这两个表的连接就难以避免跨节点请求数据网络上的延时会影响这个连接的性能。 注 t1(p0) 表示表t1的0号分区。
每个分区在集群里数据实际有三份即三副本Replica。图中忽略了Zone2和Zone3的细节。三副本之间的数据同步靠把Leader副本的事务日志同步到其他Follower副本中。Paxos协议会保障这个事务日志传输的可靠性事务日志在一半以上成员里落盘剩余成员最终也会落盘同时还有个以分区为粒度的选举机制保障Leader副本不可用的时候能快速从现有两个Follower副本里选举出新的Leader副本并且数据还绝对不丢。这里就体现了故障切换时两个重要指标RPO0 RTO30s。 Locality
图5中t0和t1业务上是有联系的表如主表和详情表两者都是分区表分区策略和分片数都相同OceanBase提供了一个表属性“表分组”TableGroup。设置为同一个表分组的不同表的分区数一定一样并且同号分区组成一个“分区分组”PartitionGroup。同一个分区分组的分区一定会分配在同一个资源单元Unit内部也就是会在同一个节点内部彼此的连接逻辑就避免了跨节点请求。另外一个效果是如果一个事务同时修改两个有业务关联的分区使用分区分组也可以规避跨节点的分布式事务。这个表分组属性的设置就是OceanBase的Locality特性之一——影响相关分区的分布。
实际上每个分区都有三副本Replica, 本文例子图5中省略了t0(p0)和t1(p0)的其他两个副本都分别会在同一个Unit里分配。不仅如此每个分区的三副本里都会有leader副本默认提供读写服务。leader副本是选举出来的。t0(p0)和t1(p0)的leader副本也一定会在同一个Unit里即在同一个Zone里。这样才彻底的避免了连接的时候跨节点请求。
OceanBase的Locality特性还可以指定租户/数据库/表的默认Zone这样下面的表的leader副本会优先被选举为这个Zone里副本。
如下面例子数据库和表会继承租户的默认设置当然也可以自己修改primary_zone或者locality属性覆盖上层设置。
create tenant obtrans0primary_zonehz1;
create table item (…)locality Fhz1, Fhz2, Fhz3,R{all_server}hz1, R{all_server}hz2, R{all_server}hz3
注F表示全功能副本R表示只读副本。
设置primary_zone后单个租户的所有表的读写都集中到一个Zone里该租户在其他zone里的Unit就没有读写压力。通常这样做是源于业务应用的要求。如应用的请求都是来自于这个Zone为了规避应用跨Zone读写数据性能下降。不过primary_zone更大的意义在于当集群里有很多租户的时候可以将不同业务租户的读写压力分摊到不同Zone的机器这样集群整体资源利用率提升所有应用的总体性能也得到提升。后面要介绍的异地多活架构就充分利用OceanBase这个特性在数据库层面将拆分的表的业务读写点尽可能分散到所有Zone的所有机器上。
除了表与表之间可能有联系业务模块之间也可能有联系。一个业务过程可能会横跨多个业务模块前面这些模块的数据被垂直拆分到多个租户里。OceanBase的Locality特性“租户分组”TenantGroup还可以设置不同租户之间的联系。如下租户交易订单和支付订单在业务上是先后发生。
create tenantgroup tgtrade tenant_array(obtrade0, obpay0);
租户分组的意义依然是为了在分布式架构下尽可能将一个业务流程内多次数据库请求都约束在同一个Zone或者Region注OceanBase将地域相邻的Zone定义为一个Region里。 OceanBase异地多活架构 异地多活概念
异地多活的概念一直都有只是内涵不断变化。以双机房多活为例应用通常都是无状态的可以多地部署。数据库有状态传统数据库只有主库可以提供读写备库最多只能提供只读服务如ORACLE的Active Dataguard 1. 应用双活数据库A地读写B地不可读写。这种只有应用多活数据库是异地备份容灾无并发。 2. 应用双活数据库A地读写B地只读。这种也是应用双活数据库读写分离实例级并发。 3. 应用双活数据库双活两地应用同时读写不同表。这种数据库双向同步应用同时错开写不同的数据表级并发。 4. 应用双活数据库双活两地应用同时读写相同表不同记录。这种数据库双向同步应用同时错开写不同的数据行级并发。 5. 应用双活数据库双活两地应用同时读写相同表相同记录。这种数据库双向同步应用同时写相同的数据最终会因为冲突一方事务回滚行级并发写冲突
上面第1种情形B地应用是跨地域远程读写数据库。两地距离较大的时候性能会很不好。2的B地应用是本地访问数据库。345三种情形两地数据库都提供读写服务对应用而言是本地访问数据库但到分布式数据库内部其要读写的数据是否正好在本地就取决于业务和数据库的拆分设计。有这么一种情形B地应用访问B地数据库实例请求的数据的写入点恰好是A地这样会走分布式数据库内部路由远程A地实例中拿到数据性能上会有些下降而业务可能不知道为什么。 OceanBase水平拆分方案
为了避免在分布式数据库OceanBase内部发生跨Zone请求应用的请求流量的水平拆分规则和数据的水平拆分规则要保持一致并联动就可以实现真正的应用向本地实例请求读写的数据恰好就是在本地实例种。这就是Locality的用途所在。 首先业务架构层面能根据用户IDuid做拆分将用户拆分为100分。x和y是用户直接相关的表都根据uid拆分为100个分表分布在5个不同的租户里。x[00-19]表示20个分表。每个租户的Leader分别分布在不同的Zone。uid:00-19表示 分到这20个分片的用户数据和用户流量。
应用层面在某个环节能根据UID将用户请求转发到对应的机房Zone应用服务之间的请求信息都有这个UID信息后面应用请求都在本机房流转并且访问数据库时通过分库分表中间件DBP和OceanBase的反向代理OBProxy就路由到本机房的业务租户上。
实际使用这个架构时有几个隐含的前提Zone1和Zone2是同城双机房Zone3和Zone4是同城双机房两个城市靠的比较近Zone5 实际很远所以一般不提供写入。为节省空间Zone5里的副本放的是日志副本。 应用异地多活架构
上面要实现OceanBase在每个Zone的应用写入都是恰好是本地访问关键点就是应用流量水平拆分规则跟数据水平拆分规则保持一致。而应用要维持这样一个规则需要很多产品都要支持水平拆分等。如下图 图中流量接入层的“负载均衡”环节负责调整用户流量到对应的机房Zone此后的应用之间的请求就都是本地访问。
能使用这个解决方案的业务都是能按用户维度做水平拆分。有些业务的拆分维度跟用户维度是冲突的或者有些业务的数据只支持集中写入等不能做到上面这种多活但也可以使用OceanBase实现单点写入多点读取的功能。
OceanBase在异地容灾和多活架构方案中的价值就是支持水平拆分规则的定义、解决了多个机房间数据同步和一致性问题、始终具备高可用和弹性伸缩能力等。 原文链接 本文为云栖社区原创内容未经允许不得转载。