暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

最佳实践6|分布式数据库HTAP混合负载最佳实践

巨杉数据库 2021-01-13
1088

01 前言

近年来,在金融科技的推动下,互联网金融业务蓬勃发展,金融行业数据处理呈现出新的特征,如数据量大、并发量高、处理性能高、类型繁多等。这就对海量数据的存储、并发访问及实时分析能力提出了新的要求。

另一方面来讲,“事后”分析已经不能满足快速的市场需求和业务变化,需要对海量客户行为数据的实时洞察提高营销精准度,如实时推荐等,并持续监测交易行为提高风险预警能力,如实时风控、反欺诈等。传统技术架构下的数据分析业务,其数据时效性面临着前所未有的挑战。

HTAP(混合事务/分析处理),是Gartner提出的一种新兴的应用框架,旨在打破事务处理和分析之间“壁垒”,在同一个数据库中,提供更高效的“实时业务”决策。

本次最佳实践,我们将为您展开讲解,如何利用巨杉分布式数据库SequoiaDB,实现HTAP混合事务/分析处理,实现OLTP与OLAP及资源平衡。

02 背景


2.1 业务需求变革

Gartner最新研究报告显示,操作型数据库(ODBMS),需要同时支持传统事务处理、分布式数据处理、事件/动态数据处理、交易与分析混合处理(增强型事务处理)等多种用例场景。报告中特别提到,将原有的操作和分析融合处理(HTAP)用例更改为增强型事务处理及可编程的HTAP功能,即:在维持高服务等级(SLA)事务处理的同时,嵌入分析处理(包括AI/ML)能力。
为了支撑大规模实时分析应用(如风控,实时推荐,实时数据看板,报表等),需要数据库能够同时具备OLTP和OLAP的混合负载能力。其中OLTP负载能力承载在线业务,而OLAP负载能力则直接对数据进行实时分析,以期大幅缩短决策周期,甚至提供跨业务线的综合实时分析能力。

2.2 传统OLTP/OLAP的痛点

目前在业内,实现HTAP混合负载,主要有三种技术方案:

• 单一系统同时承载混合负载(如DB2、Oracle、MySQL等)

• 使用不同系统组合+数据同步技术(如ETL、GoldenGate、CDC等)

• 同一存储不同计算引擎(如HBase+Spark等)

这些技术实现HTAP混合负载,无论何种方案,均存在一定的缺陷和短板。

  • 数据共享难题

传统技术使用Oracle、MySQL、DB2、Informix等数据库构建业务,分离部署,数据分散存储。要实现HTAP混合负载,需要构建多套数据库,并基于一系列的数据复制技术,或基于ETL进行数据加工、转换。这样一来,不但架构的复杂性大大增加,数据传输消耗了大量的网络带宽进行数据传输。即便如此,这种跨库实现的混合负载,数据的延迟得不到有效解决。

例如一个关联查询,往往需要在不同机构实现跨库数据查询。甚至,有些数据已经使用磁带落库的方式永久封存,数据远远没有发挥出其应有价值。如何能够打通各个业务系统,把数据盘活,解决复杂的数据复制,让数据能够给业务带来新的增长点,是现在面临比较棘手的问题。

图1 OGG+Kafka实现数据复制

  • 性能不能兼顾

事实上,传统数据库也能够实现混合负载的需求,但往往要在功能或性能上做出牺牲。对于交易场景,关注低延迟、高并发的数据增删改查,同时对ACID功能有严格的要求。这种场景一般需要使用行式存储,牺牲了海量数据访问能力,如Oracle、MySQL等。对于分析场景,主要是是大量数据扫描,甚至做聚合,对并发和延迟要求并不高,但更加关注吞吐量、容量、弹性伸缩能力,更倾向于采用列式存储,因此不得不牺牲实时更新、关联查询能力,如HBase、Oracle In-Memory等。因此,以往的HTAP混合负载技术,很难做到对交易能力和分析能力的兼顾。
  • 扩展性难题

核心系统普遍使用“传统数据库+小型机+集中式存储”架构,扩容难度大,扩容成本也很高。从运维来说,为了保证在线交易数据库的容量,只能不断把旧的生产数据卸载到历史库,甚至封存在磁带库中,日常的数据管理工作给运维人员带来不小负担。对于HTAP业务系统,一次扩容也必然要涉及到源端和目标端,工作量巨大。另一方面,分析业务往往需要横跨在线、历史数据,甚至多业务线的数据,更需要可扩展架构,来满足不断变化的业务迭代,以及不断提升的容量需求和性能要求。
  • 开发接口单一

以往的混合负载技术,其提供的SQL接口比较单一,一般只能提供一种SQL语法。另外,随着业务量的爆发式增长及无纸化的推进,数据库不仅仅需要保存文本数据,更多需要保存音频、影像类大对象数据。目前的技术架构,无法适应目前互联网多样化的应用、开发需求。
 
综上所述,以往的HTAP混合负载技术,存在明显的短板和不足。在这种条件下,具有支持多节点部署、多引擎、高扩展、高冗余等特性的分布式数据库架构,逐渐成为了HTAP技术的首选。

2.3 巨杉分布式数据库SequoiaDB的HTAP技术优势

一个HTAP数据库要实现混合负载,既要能满足上述多种技术要求,也需要能够保证不同业务之间的负载隔离。
巨杉数据库SequoiaDB,采用存算分离架构,通过统一的分布式数据库底座,融合不同的计算引擎,很好地解决了传统技术实现HTAP混合负载的各种难题:
• 轻松地在一个数据库内,提供HTAP支持,无需分库及跨库复制;
• 支持多种计算引擎,如MySQL、PostgreSQL、SparkSQL等;
• 支持跨引擎ACID,兼容标准SQL;
• 支持多种形式的负载隔离;
• 支持弹性扩展、多活容灾。
在SequoiaDB数据库中,用户可以利用复制组的多副本特性,在节点和会话等多个级别设定读写分离策略,使得不同类型的应用(联机交易、联机分析、数据中台等),采用各自的开发接口(例如 MySQL、PostgreSQL、SparkSQL等),进行数据的实时访问,且之间不产生负载干扰。

图2  SequoiaDB三副本实现HTAP

03 分布式数据库HTAP技术特性

3.1 副本

图3 巨杉数据库分布式架构
多副本机制:

• 数据分散存储在不同的数据组中;

• 主副本提供读、写服务,备副本提供只读服务;

数据组内,有多个副本,由数据库内部的一致性算法实现数据同步。

图4  数据一致性同步

3.2 负载隔离

在数据组内,设置读写访问优先级策略:
• 将MySQL、PostgreSQL引擎指向读写副本,实现高并发的数据增删查改,来承载联机交易业务;
• 将Spark引擎指向只读副本,实现数据分析、高并发查询,来承载联机分析业务;
• 为了更细化地实现隔离,还可以使SQL引擎连接到具体的某个副本上;

• 各个副本之间,没有任何负载干扰,完全实现了HTAP混合负载下的负载隔离。

图5  HTAP负载隔离

3.3 多种SQL引擎

分布式数据库支持多种SQL引擎,常见的有:

1、MySQL引擎

2、PostgreSQL引擎

3、Spark引擎

图6  三种解析器使用特征

各类引擎的特点如下:

SQL引擎

描述

适用场景

MySQL

引擎

适合精准查询、业务数据写入、柜面查询等场景

增删查改操作和普通MySQL完全一致

MySQL语法兼容度达到100%

OLTP

PostgreSQL

引擎

以复杂SQL语法和强大的SQL编程能力见长

支持增删查改等功能,和普通PostgreSQL使用完全一致

采用外部表的方式将数据存储在分布式数据库中

OLTP

OLAP

Spark

引擎

可扩展的数据分析组件,集成了原生的内存计算

适合报表分析、大表关联查询等

提供友好、高性能的关联查询

支持标准SQL、支持JDBC访问、支持Python等接口

通过使用 Spark连接组件,来访问分布式数据库存储引擎

OLAP

04 分布式数据库HTAP最佳实践

4.1 环境描述

本文的示例中,我们选择MySQL作为OLTP引擎,SparkSQL作为OLAP分析引擎。

  • 计算引擎可实现集群部署。MySQL和SparkSQL实例均可部署在多台服务器,对连接请求实现均衡的同时,避免了单点故障隐患;

  • 分布式存储引擎。SequoiaDB数据库分布式存储引擎中,数据节点分布在多台服务器上,这样能够充分利用服务器的数据存储和计算能力;

  • 网络隔离。在Spark计算引擎读写繁忙的情况下,会产生较大的网络传输从而侵占MySQL实例在线事务处理的带宽资源,因此,生产环境下建议为Spark和MySQL实例配置独立的网卡。

本次最佳实践案例的实验环境规划如下:

服务器规划:

IP地址

主机名

192.168.100.201

sdb01

192.168.100.202

sdb02

192.168.100.203

sdb03

组件部署:

节点

sdb01

sdb02

sdb03

SQL引擎

MySQL实例

PostgreSQL实例

SparkSQL实例

协调节点

协调节点

协调节点

协调节点

编目节点

编目节点(主)

编目节点

编目节点

数据节点

(副本)

数据组1-主副本

数据组1-备副本

数据组1-备副本

数据组2-主副本

数据组2-备副本

数据组2-备副本

数据组3-主副本

数据组3-备副本

数据组3-备副本

注:为了第4章节演示方便,本次将数据的主副本均设置到sdb01服务器。

节点

sdb01

sdb02

sdb03

SQL引擎

MySQL实例

PG实例

Spark实例

数据节点

首选连接

首选主副本

首选主副本

首选备副本

服务器配置:

规格

服务器数量

3台

CPU

8

内存

16GB

磁盘

100GB * 3

操作系统

Centos 7.4

软件版本:

软件

版本

SequoiaDB

3.4

MySQL

5.7.25

Spark

2.3.3

4.2 过程演示

演示场景:

1、 MySQL、PostgreSQL、SparkSQL跨引擎数据操作及查询

  • 在MySQL中,创建bills.orders表并插入数据,进行数据的增删改查操作;

  • 在PostgreSQL、SparkSQL中查询,并验证数据正确性;

2、 跨引擎Join查询

  • 在MySQL中再创建一张表bills.customers;

  • 在SparkSQL中进行bills.orders、bills.customers的表关联查询;

  • 查看各个数据副本的访问统计,来验证HTAP负载隔离。

4.2.1 创建测试orders表、进行HTAP配置

1、在MySQL实例中创建表的步骤如下:

登陆MySQL实例
    mysql -h 127.0.0.1 -P 3306 -uroot -proot
    创建bills数据库
      create database bills;
      use bills;
      创建 bills.orders表
        create table bills.orders (
        order_id int,
        customer_id int,
        p_date date,
        location varchar(100) ,
        primary key (order_id) );
        注:在SequoiaDB数据库中, 使用MySQL引擎建表,默认即使用SequoiaDB分布式存储引擎。

        2、在PostgreSQL实例中创建表

        在PostgreSQL客户端创建外部表bills.orders,并映射到数据库引擎中的orders表。

          //登陆PostgreSQL客户端
          /opt/sequoiasql/postgresql/bin/psql -p 5432 bills

          //加载SequoiaDB连接驱动
          create extension sdb_fdw;

          //配置与SequoiaDB连接参数
          create server sdb_server foreign data wrapper sdb_fdw options(address '192.168.100.202', service '11810', user 'sdbUserName', password 'sdbPassword', preferedinstance '1,M', transaction 'off');

          //创建orders表
          create foreign table orders (
          order_id int,
          customer_id int,
          p_date date,
          location varchar(100)
          ) server sdb_server options ( collectionspace 'bills', collection 'orders', decimal 'on' );

          3.SparkSQL实例中创建表

          在SparkSQL客户端创建外部表bills.orders,并映射到数据库引擎中的orders表。

            $ 登陆spark beeline客户端
            /opt/spark-2.3.3-bin-hadoop2.7/bin/beeline -u 'jdbc:hive2://192.168.100.203:10000'

            //创建orders表
            create table bills.orders (
            order_id int,
            customer_id int,
            p_date date,
            location varchar(100) )
            USING com.sequoiadb.spark OPTIONS ( host '192.168.100.203:11810', collectionspace 'bills', collection 'orders',preferredinstance '2,3,S') ;

            select * from bills.orders;

            说明Spark中orders表创建成功。

            Note:
            1、Preferedinstance选项:会话读操作优先选择的策略,取值列表:"M"、"S"、"A"、1-255。可以使用数组指定多个取值。"M":可读写实例(主实例) "S":只读实例(备实例) "A":任意实例 1-255:通过 instanceid 指定实例 ID 的实例。 
            2、Instanceid,是一个数据组内,各个副本的编号,默认是0。设置该参数后,可以SQL实例中建表时,指定其访问的首选副本。

            在本文中,将SQL实例的访问策略设置为:MySQL、PostgreSQL优先连接主副本,SparkSQL优先连接备副本,从而实现HTAP负载隔离。因此,还需要对所有数据组的各个副本设置其instanceid。

              //本例中将主副本的instanceid设置为1,两个备副本设置为2、3.
              //登陆SequoiaDB存储引擎
              $ sdb
              db = new Sdb( "192.168.100.201", 11810 )
              db.updateConf( { instanceid:1 }, { GroupName:"group1", NodeName:"sdb01:11830" } );
              db.updateConf( { instanceid:2 }, { GroupName:"group1", NodeName:"sdb02:11830" } );
              db.updateConf( { instanceid:3 }, { GroupName:"group1", NodeName:"sdb03:11830" } );
              //以group1为例,其他数据组操作类似。

              4.3.2 在MySQL中插入测试数据

              登陆MySQL,向bills.orders表中插入4条测试数据:

                insert into bills.orders values(10001,1,"2017-06-01","Beijing");
                insert into bills.orders values(10002,2,"2018-06-01","Shanghai");
                insert into bills.orders values(10003,3,"2019-06-01","Guangzhou");
                insert into bills.orders values(10004,4,"2020-06-01","Shenzhen");

                 查看数据:

                  select * from bills.orders;

                  4.3.3 在MySQL中操作数据

                  在MySQL中,更新bills.orders中一条记录,并查询:

                    update  bills.orders  set  location="Nanjing"  where  order_id=10001;                    
                    select * from bills.orders;

                    删除bills.orders表中一条记录(order_id=100002),并查询:
                      delete  from  bills.orders where  order_id=10002;
                      select * from bills.orders;

                      4.3.4 在PostgreSQL中查询数据

                      登陆PostgreSQL客户端,并查询orders表数据:

                        /opt/sequoiasql/postgresql/bin/psql -p 5432 bills

                        //查询orders表数据:
                        select * from orders;

                        这说明在MySQL中的数据,在PostgreSQL中是共享的。

                        4.3.5 在SparkSQL中查询数据

                        登陆SparkSQL客户端,并查询orders表数据:

                          /opt/spark-2.3.3-bin-hadoop2.7/bin/beeline -u 'jdbc:hive2://192.168.100.203:10000'

                          //查询orders表数据:
                          select * from bills.orders;

                          这说明,MySQL中所操作的数据,在Spark SQL中是共享的。

                          从数据的增、删、改、查操作可以看出,数据在MySQL和PostgreSQL、SparkSQL中是完全共享的。

                           

                          4.3.6 跨引擎JOIN查询

                          1. 创建第二张表bills.customers

                          MySQL中创建customers表结构:

                            create table bills.customers (
                            customer_id int,
                            customer_name varchar(100) ,
                            gender char(1),
                            birth_date date,
                            primary key (customer_id) );

                            Spark中创建customers表结构

                              create table bills.customers (
                              customer_id int,
                              customer_name varchar(100) ,
                              gender char(1),
                              birth_date date )
                              USING com.sequoiadb.spark OPTIONS ( host '192.168.100.203:11810', collectionspace 'bills', collection 'customers',preferredinstance '2,3,S') ;

                              2. 向2个表分别插入测试数据

                              登陆MySQL实例,向orders、customers表各插入50000条数据

                                //为便于插入,创建存储过程proc_insert
                                drop procedure if exists proc_insert;
                                delimiter ;;
                                create procedure proc_insert()
                                begin
                                declare i bigint default 1;
                                while i<50001
                                do
                                insert into bills.orders values (i*177,i,"2018-05-09",'Beijing');
                                insert into bills.customers values (i,'Tom','F',"2018-05-09");
                                set i=i+1;
                                end while ;
                                commit;
                                select i as "Inserted Rows of orders: ", i as " Inserted Rows customers: ";
                                end;;

                                //清空现有数据,调用存储过程,插入数据
                                delete from bills.orders;
                                call proc_insert();;
                                  //数据查询
                                  select count(*) from bills.orders;
                                  select count(*) from bills.customers;

                                  至此,数据库中已存在2张表,orders表、customer表,分别有50000条数据。

                                  3. 在Spark中进行JOIN查询

                                    select count(*)
                                    from bills.orders o inner join bills.customers c
                                    on o.customer_id=c.customer_id ;

                                    4.3.7 HTAP负载隔离验证

                                    将上章节的JOIN查询连续运行10次,使用SequoiaDB的节点监控工具sdbtop,来观察各个副本的读写次数统计。

                                    (备注:1、以数据组group1:11830为例,其他数据组效果相同;2、为了便于展示,此时重启了数据节点,将统计清零。)

                                    sdb01上的主副本:无任何数据读取。

                                    sdb02上的备副本:产生150472次数据读取。

                                    sdb03上的备副本:产生150569次数据读取。

                                    从结果可以看出:SequoiaDB的HTAP混合负载,已经通过多副本策略,实现了负载隔离效果:

                                    • MySQL对主副本进行写入;

                                    • SparkSQL实例对备副本进行只读查询;

                                    • OLTP、OLAP的负载运行在不同服务器上,互相不产生干扰。

                                    05 总结

                                    在本文中,我们介绍了巨杉数据库SequoiaDB的HTAP最佳实践,包括HTAP混合事务/分析处理的技术原理、负载隔离策略、操作步骤等。

                                    HTAP混合负载,意味着数据库可以同时承载在线交易业务和统计分析业务。分布式数据库,利用计算-存储分离的架构特点和访问隔离功能,结合了MySQL、PostgreSQL引擎和Spark计算引擎,使复杂的联机分析处理(OLAP)与联机交易(OLTP)处理在一个数据库中得以实现。

                                    分布式数据库提供了多种级别的隔离策略,来实现读写分离,使不同的业务场景访问不同类型的数据副本,使得业务访问性能得到了提升。

                                    往期技术干货
                                    最佳实践5|SequoiaDB巨杉数据库在线扩容(下)

                                    最佳实践5|SequoiaDB巨杉数据库在线扩容(上)

                                    最佳实践4|SequoiaDB巨杉数据库两地三中心部署
                                    最佳实践3|SequoiaDB同城双中心灾难恢复工具
                                    最佳实践2 | SequoiaDB同城双中心部署规划
                                    最佳实践 | SequoiaDB单中心三副本部署规划

                                    点击阅读原文,了解巨杉数据库最新资讯
                                    文章转载自巨杉数据库,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                    评论