【实操系列】基于AnalyticDB PostgreSQL数据共享实现企业级跨多业务的敏捷分析

简介: 云数据仓库AnalyticDB PostgreSQL 版发布了最新自研的云原生架构实例,实现了跨实例间的数据共享能力。允许进行跨实例间的实时数据共享且无需进行数据迁移,可支持构建安全、高效、灵活的数据分析场景。本文介绍了依托数据共享实现云数仓跨多业务实例的敏捷数据分析方案;

业务介绍

背景

企业数据分析中存在着不同类型的使用场景,如

‒ 数据工程师: 维护ETL(ELT)数据链路,包含实时的数据链路,定时的批处理任务等;

‒ 业务分析师: 对数据进行交互式分析,对成熟的分析模型产品化(BI)并定时刷新等任务;

‒ 业务人员: 通过BI工具对成熟的分析模型下的业务运营数据进行业务分析;

‒数据科学家: 在特征仓库中寻找需要的特征,并按目标进行模型搭建和训练;


这些使用场景对于底层数据仓库的要求均不一样, 存在着存储和计算的不均衡, 峰谷时段的不一致和功能需求的不统一;如果期望使用一个数据仓库实例来满足所有的需求,会存在以下问题

‒ IT人员不足导致业务响应迟缓

‒ 高峰期的资源争夺导致业务不满足预期,即使通过资源队列也无法保证弹性的或不可预测业务要求

‒ 多业务下的数据的权限管理复杂多,大量Data Mart下的冗余数据导致数据探索效率下降;


那么怎么能够让底层的架构更加贴近业务,灵活的包裹业务所需要的分析资源并持续灵活演进,我们发现Redshift & Snowflake的数据共享在很大的程度上解决了这个问题,通过星型模型的实例部署方式灵活的构建大数据中台和小业务前台的架构,通过无数据copy的模式构建无数数据的“毛细血管”,让数据也在业务间顺畅的流动起来!



AnalyticDB PostgreSQL在国内OLAP厂商中率先推出了数据共享能力,本文介绍了一个标准的数据共享解决方案。我们选取了最为常用的数仓架构下,数据工程师将业务数据库上的数据通过ETL整合入仓,开放给企业内的客户进行使用。 为方便理解,本文选取了TPC-DS的销售数据作为样本进行场景描述。

目前该企业内的组织架构存在着多个独立的业务部门,他们由于业务的独立性故配置了不同的资源实例。本文描述对于业务(市场部)和数据科学两个独立的业务两个部门的进行描述。

业务场景

1.业务部门主要的使用场景为运营大屏及业务分析师,需要使用市场投放数据和销售结果进行实时效果追踪,同时支持分析师基于业务需求进行Ad-hoc(一次性)业务分析;

2.数据科学部门主要使用场景为销售预测模型搭建及模型效果评估BI。


而基于企业内部的组织架构和实例使用特征,不同的业务部门保有独立的实例来实现业务,现在需要对销售数据分析时,各个业务团队需维护数据同步链路,将ETL实例上准备好的数据同步至业务实例才可进使用。


当前解决方案

目前两个业务部门将数据导出至OSS, 在导出后copy各自的业务实例中,整个链路的同步速度较慢,同时该链路无工具帮助用户观察实时进度,维护工作非常繁琐。


当前方案的痛点

  1. 数据的导入导出同步速度较慢,数据的实时性交较难保证。
  2. 该同步方式无工具支持,过程涉及人工干预,显著的增加了运维工作。
  3. 对于一次性分析的业务,数据的搬迁人工介入,工作量较大,分析效率大幅受影响。
  4. 数据的多次copy造成了企业的存储空间浪费, 成本较高。

方案架构图:

21.png

数据共享方案详解

AnalyticDB PostgreSQL为此场景提供了数据共享的解决方案。在对于ETL上的数据源,向下游各个业务实例需要使用的数据库进行数据共享链路的搭建,使其可以实时的访问ETL实例的数据源并与本地的业务进行Join分析;

数据共享架构

22.png

实施步骤

此次实施为一个典型的中心辐射型业务模型,在ETL集群中进行ETL,这个集群可以为BI工程师,业务分析师以及数据科学家提供分析所需的数据,为了业务独立性和资源隔离的需要,在不同的集群中运行业务分析和数据科学分析。由ETL集群作为数据生产者,业务分析集群和数据科学分析集群作为数据消费者。

在本案例中,使用TPC-DS中的6个表作为基础表进行演示:

  • CUSTOMER_ADDRESS
  • CUSTOMER_DEMOGRAPHICS
  • DATE_DIM
  • ITEM
  • CUSTOMER
  • STORE_SALES

步骤1:模拟ETL集群中建表

在ETL集群中创建创建6个基础表。这些表数据为业务数据,一般情况为通过DTS等工具导入到ADB PG中,这里模拟业务数据建表。

create schema sales;
set search_path = sales;
create table customer_address
(
    ca_address_sk             integer               not null,
    ca_address_id             char(16)              not null,
    ca_street_number          char(10)                      ,
    ca_street_name            varchar(60)                   ,
    ca_street_type            char(15)                      ,
    ca_suite_number           char(10)                      ,
    ca_city                   varchar(60)                   ,
    ca_county                 varchar(30)                   ,
    ca_state                  char(2)                       ,
    ca_zip                    char(10)                      ,
    ca_country                varchar(20)                   ,
    ca_gmt_offset             decimal(5,2)                  ,
    ca_location_type          char(20)                      
)
distributed by (ca_address_sk);
create table customer_demographics
(
    cd_demo_sk                integer               not null,
    cd_gender                 char(1)                       ,
    cd_marital_status         char(1)                       ,
    cd_education_status       char(20)                      ,
    cd_purchase_estimate      integer                       ,
    cd_credit_rating          char(10)                      ,
    cd_dep_count              integer                       ,
    cd_dep_employed_count     integer                       ,
    cd_dep_college_count      integer                       
)
distributed by (cd_demo_sk);
create table date_dim
(
    d_date_sk                 integer               not null,
    d_date_id                 char(16)              not null,
    d_date                    date                          ,
    d_month_seq               integer                       ,
    d_week_seq                integer                       ,
    d_quarter_seq             integer                       ,
    d_year                    integer                       ,
    d_dow                     integer                       ,
    d_moy                     integer                       ,
    d_dom                     integer                       ,
    d_qoy                     integer                       ,
    d_fy_year                 integer                       ,
    d_fy_quarter_seq          integer                       ,
    d_fy_week_seq             integer                       ,
    d_day_name                char(9)                       ,
    d_quarter_name            char(6)                       ,
    d_holiday                 char(1)                       ,
    d_weekend                 char(1)                       ,
    d_following_holiday       char(1)                       ,
    d_first_dom               integer                       ,
    d_last_dom                integer                       ,
    d_same_day_ly             integer                       ,
    d_same_day_lq             integer                       ,
    d_current_day             char(1)                       ,
    d_current_week            char(1)                       ,
    d_current_month           char(1)                       ,
    d_current_quarter         char(1)                       ,
    d_current_year            char(1)                       
)
distributed by (d_date_sk);
create table item
(
    i_item_sk                 integer               not null,
    i_item_id                 char(16)              not null,
    i_rec_start_date          date                          ,
    i_rec_end_date            date                          ,
    i_item_desc               varchar(200)                  ,
    i_current_price           decimal(7,2)                  ,
    i_wholesale_cost          decimal(7,2)                  ,
    i_brand_id                integer                       ,
    i_brand                   char(50)                      ,
    i_class_id                integer                       ,
    i_class                   char(50)                      ,
    i_category_id             integer                       ,
    i_category                char(50)                      ,
    i_manufact_id             integer                       ,
    i_manufact                char(50)                      ,
    i_size                    char(20)                      ,
    i_formulation             char(20)                      ,
    i_color                   char(20)                      ,
    i_units                   char(10)                      ,
    i_container               char(10)                      ,
    i_manager_id              integer                       ,
    i_product_name            char(50)                      
)
distributed by (i_item_sk);
create table customer
(
    c_customer_sk             integer               not null,
    c_customer_id             char(16)              not null,
    c_current_cdemo_sk        integer                       ,
    c_current_hdemo_sk        integer                       ,
    c_current_addr_sk         integer                       ,
    c_first_shipto_date_sk    integer                       ,
    c_first_sales_date_sk     integer                       ,
    c_salutation              char(10)                      ,
    c_first_name              char(20)                      ,
    c_last_name               char(30)                      ,
    c_preferred_cust_flag     char(1)                       ,
    c_birth_day               integer                       ,
    c_birth_month             integer                       ,
    c_birth_year              integer                       ,
    c_birth_country           varchar(20)                   ,
    c_login                   char(13)                      ,
    c_email_address           char(50)                      ,
    c_last_review_date        char(10)                      
)
distributed by (c_customer_sk);
create table store_sales
(
    ss_sold_date_sk           integer                       ,
    ss_sold_time_sk           integer                       ,
    ss_item_sk                integer               not null,
    ss_customer_sk            integer                       ,
    ss_cdemo_sk               integer                       ,
    ss_hdemo_sk               integer                       ,
    ss_addr_sk                integer                       ,
    ss_store_sk               integer                       ,
    ss_promo_sk               integer                       ,
    ss_ticket_number          integer               not null,
    ss_quantity               integer                       ,
    ss_wholesale_cost         decimal(7,2)                  ,
    ss_list_price             decimal(7,2)                  ,
    ss_sales_price            decimal(7,2)                  ,
    ss_ext_discount_amt       decimal(7,2)                  ,
    ss_ext_sales_price        decimal(7,2)                  ,
    ss_ext_wholesale_cost     decimal(7,2)                  ,
    ss_ext_list_price         decimal(7,2)                  ,
    ss_ext_tax                decimal(7,2)                  ,
    ss_coupon_amt             decimal(7,2)                  ,
    ss_net_paid               decimal(7,2)                  ,
    ss_net_paid_inc_tax       decimal(7,2)                  ,
    ss_net_profit             decimal(7,2)                  
)
distributed by (ss_item_sk, ss_ticket_number);

步骤2:在ETL集群创建共享

在ETL集群中使用如下的语句创建共享”salesdatashare”。

create datashare salesdatashare;

创建完共享后,在ETL集群侧可以向共享中添加下游需要使用的数据表,这些个添加操作将数据表的元数据封装入数据共享并授权下游直接使用,数据无拷贝或挪动。

alter datashare salesdatashare add table customer_address;
alter datashare salesdatashare add table customer_demographics;
alter datashare salesdatashare add table date_dim;
alter datashare salesdatashare add table item;
alter datashare salesdatashare add table customer;
alter datashare salesdatashare add table store_sales;

步骤3:将共享赋权给市场业务实例和数据科学分析实例

在ADB PG产品内,会使用GUID对数据库进行唯一标识,GUID在不同的实例间也不重复。

数据共享需要对目标数据库的GUID进行白名单授权,故两个目标实例需要向ETL实例提供GUID。

GUID获取方法,可在数据库内使用以下语句获取该库的GUID。

select dbuuid as guid from pg_database d, rds_share_identifier si
where d.oid = si.dboid and d.datname = current_database();

本案例假定3个涉及的数据库GUID分别为:

名称

GUID

ETL集群

821a235c-85b2-4fed-aa35-bbe6123e8e56

BI分析集群

668862c4-e55a-4ab6-8d10-1c8ab5b8f48a

数据科学分析集群

e6fc2a5e-07bd-4ae4-af94-dd917a3e6a13

在ETL集群中,将共享赋权给业务分析实例和数据科学分析实例,授权语句如下:

-- BI分析集群
grant usage on datashare salesdatashare to database "668862c4-e55a-4ab6-8d10-1c8ab5b8f48a";
-- 数据科学分析集群
grant usage on datashare salesdatashare to database "e6fc2a5e-07bd-4ae4-af94-dd917a3e6a13";

步骤4:在业务分析集群中导入共享并使用共享数据

当授权完成后,需要在消费的实例内进行数据共享的导入后才可使用。


导入ETL集群中共享salesdatashare的语句如下:

import datashare salesdatashare from database "821a235c-85b2-4fed-aa35-bbe6123e8e56";

导入完成后,就可以在业务分析集群中查询到ETL端共享的数据并进行业务分析。


参考如下语句:

select
        c_customer_sk,
        c_customer_id,
        c_birth_year,
        c_birth_country,
        c_last_review_date_sk,
        ca_city,
        ca_state,
        ca_zip,
        ca_country,
        ca_gmt_offset,
        cd_gender,
        cd_marital_status,
        cd_education_status
from salesdatashare.sales.customer c, salesdatashare.sales.customer_address ca, salesdatashare.sales.customer_demographics cd
where
c.c_current_addr_sk=ca.ca_address_sk
and c.c_current_cdemo_sk=cd.cd_demo_sk;
select 
        i_item_id,
        i_product_name,
        i_current_price,
        i_wholesale_cost,
        i_brand_id,
        i_brand,
        i_category_id,
        i_category,
        i_manufact,
        d_date,
        d_moy,
        d_year,
        d_quarter_name,
        ss_customer_sk,
        ss_store_sk,
        ss_sales_price,
        ss_list_price,
        ss_net_profit,
        ss_quantity,
        ss_coupon_amt
from salesdatashare.sales.store_sales ss, salesdatashare.sales.item i, salesdatashare.sales.date_dim d
where ss.ss_item_sk=i.i_item_sk
and ss.ss_sold_date_sk=d.d_date_sk;

步骤5:在数据科学分析集群中导入共享并使用共享数据

同样的,在数据科学实例中也可同样导入ETL集群中共享的salesdatashare,

语句如下:

import datashare salesdatashare from database "821a235c-85b2-4fed-aa35-bbe6123e8e56";

这样在数据科学分析集群中也可以对ETL集群中的数据进行数据科学的分析,数据科学家可以随意地根据关注点编写SQL语句,对数据进行挖掘,分析其中的销售数据。

方案评估

实时性对比

这里对传统数据拷贝方式与数据共享方式进行实时性的对比,一下以32节点实例1TB数据量为例:

image.png

易用性对比

在易用性方面方面,数据拷贝与数据共享方式的有较大区别,数据共享整体仅需1~2分钟即可持续的稳定的提供一条数据跨实例使用的链路。数据拷贝链路需要大量的人工介入,并等待几个小时完成数据准备工作。

  • 中转存储介质:
  • 数据拷贝: 在数据实例间拷贝时,需要额外使用OSS作为数据中转存储,在数据导出和导入后还需清理冗余的中转存储。
  • 数据共享:无需任何中转存储介质
  • 目标库建表:
  • 数据拷贝: 传统方式需在目标端建表,OSS外表方式还需要在源端和目标端建外表。
  • 数据共享: 无需关心建表,导入即可用。

存储成本评估

image.png

方案总结

  1. 大幅减轻了业务团队的数据运维压力,无需维护ETL实例和业务实例间的数据同步链路,可更专注于管理域内数据面向BI的数据工程工作。
  2. 数据共享开通过程极简化化,可实现快速的数据共享支持Ad-hoc分析。
  3. 避免了数据拷贝导致的数据冗余。
  4. 实时数据同步,即数据源完成数据清洗工作后,所有的数据消费实例可实时进行分析,无需等待。

结束语

本文介绍了一个典型的多业务间数据分析的场景, 对于已构筑在ADBPG上的企业来说,随着业务的增长和业务件独特性的需要,需要进行底层基础架构的拆分以简化管理复杂度和低成本支持每个业务支持。由于ADBPG的的数据共享能力, 企业无需担心架构的独立性会导致数据孤岛,数据共享可持续保证技术架构的灵活性和跨业务的数据连通性。



相关实践学习
使用CLup和iSCSI共享盘快速体验PolarDB for PostgtreSQL
在Clup云管控平台中快速体验创建与管理在iSCSI共享盘上的PolarDB for PostgtreSQL。
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
相关文章
|
28天前
|
Cloud Native OLAP OLTP
在业务处理分析一体化的背景下,开发者如何平衡OLTP和OLAP数据库的技术需求与选型?
在业务处理分析一体化的背景下,开发者如何平衡OLTP和OLAP数据库的技术需求与选型?
126 4
|
3月前
|
SQL 运维 关系型数据库
基于AnalyticDB PostgreSQL的实时物化视图研发实践
AnalyticDB PostgreSQL企业数据智能平台是构建数据智能的全流程平台,提供可视化实时任务开发 + 实时数据洞察,让您轻松平移离线任务,使用SQL和简单配置即可完成整个实时数仓的搭建。
367 1
|
3月前
|
Cloud Native 关系型数据库 分布式数据库
阿里云PolarDB云原生数据库:重塑企业级数据库的新标杆
阿里云PolarDB云原生数据库凭借其出色的性能、可扩展性、稳定性以及Serverless能力,成为企业级数据库的新标杆。它能够快速响应业务需求,灵活伸缩资源,确保系统稳定可靠。同时,PolarDB还提供全面的数据加密、访问控制和审计功能,确保用户数据的安全性。此外,它还支持与第三方工具和服务提供商的集成,提供更多定制化的解决方案。总之,阿里云PolarDB云原生数据库为企业提供了一种高效、可靠、经济的数据库解决方案,值得企业考虑选择。
|
4月前
|
存储 SQL Java
王日宇:基于 StarRocks 和 Paimon 打造湖仓分析新范式
本文根据 StarRocks Summit 2023 演讲实录整理而成,主要分享了基于 StarRocks 和 Paimon 打造湖仓分析方案及背后的技术原来和未来规划。
783 0
|
1月前
|
关系型数据库 MySQL OLAP
PolarDB +AnalyticDB Zero-ETL :免费同步数据到ADB,享受数据流通新体验
Zero-ETL是阿里云瑶池数据库提供的服务,旨在简化传统ETL流程的复杂性和成本,提高数据实时性。降低数据同步成本,允许用户快速在AnalyticDB中对PolarDB数据进行分析,降低了30%的数据接入成本,提升了60%的建仓效率。 Zero-ETL特性包括免费的PolarDB MySQL联邦分析和PolarDB-X元数据自动同步,提供一体化的事务处理和数据分析,并能整合多个数据源。用户只需简单配置即可实现数据同步和实时分析。
|
3月前
|
SQL Java HIVE
使用 Paimon + StarRocks 极速批流一体湖仓分析
本文整理自阿里云智能高级开发工程师王日宇,在 Flink Forward Asia 2023 流式湖仓(二)专场的分享。
79856 2
使用 Paimon + StarRocks 极速批流一体湖仓分析
|
3月前
|
SQL C++
数仓之归因分析
数仓之归因分析
|
3月前
|
存储 人工智能 运维
轻喜到家基于 EMR-StarRocks 构建实时湖仓分析平台实践
本文从轻喜到家的历史技术架构与痛点问题、架构升级需求与 OLAP 选型过程、最新技术架构及落地场景应用等方面,详细介绍了轻喜到家基于 EMR-StarRocks 构建实时湖仓分析平台实践经验。
904 0
轻喜到家基于 EMR-StarRocks 构建实时湖仓分析平台实践
|
3月前
|
SQL 存储 分布式计算
Hologres实时湖仓能力增强,挑战5分钟加速分析OSS数据
5分钟快速使用Hologres实时湖仓能力,无需移动数据,直接加速读取存储于数据湖OSS上的Hudi、Delta、Paimon等格式类型的数据
|
3月前
|
存储 对象存储 SQL
【获奖名单公示】Hologres实时湖仓分析挑战赛
5分钟快速使用Hologres实时湖仓能力,无需移动数据,直接加速读取存储于数据湖OSS上的Hudi、Delta、Paimon等格式类型的数据
【获奖名单公示】Hologres实时湖仓分析挑战赛

热门文章

最新文章

相关产品

  • 云原生数据仓库AnalyticDB MySQL版
  • 云原生数据仓库 AnalyticDB PostgreSQL版