数仓系统 4次升级,过程中的一些思考。

1,537 阅读4分钟

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!

1:项目背景

bi系统往往决定一家公司的日常决策,所以必须要够灵活、底层数据通用、指标体系归一、能快速接入相关指标体系至关重要。过程中不断的与产品、业务不断的沟通升级。从渠道分析、会员、核心数据、埋点体系验证、人群画像、自定义报表、漏斗、全平台数据打通、推荐系统ab/test,打磨出一套BI雏形。

2:数仓系统的衍变

我们的数仓系统经过了4次大版本衍变,详细如下:

数仓版本相关的技术方案
1.0azkaban定制执行离线脚本(hive -f 执行脚本),ads层建立es外表。bi系统仅支持离线数据。
2.0迁移离线脚本到db,建立ods,dwd,dim,mid,dws ads层,通过spark sql 执行job。ads层的数据同步到es。
3.0建立主题、指标,dws层的数据接入kylin 。通过指标完成底层的数据指标复用,降低指标入口来源维护,实时数据分析引入clickhouse。
4.0维护所有的主题,字典,指标,组件,可视化(多组件整合),cube 自动化构建。所有离线、实时任务都迁移到dolphinscheduler 。

看到上面的每一步,我很庆幸自己和团队的每一个人成员都敢于去挑战自己。当然我们在做的过程中也看过业内商业化产品(神策、友盟、字节),毕竟在跟着业内主流走,大方面不会偏。

3:数仓的治理

bi系统是负责展示大数据的门户,背后的底层逻辑搭建、模型的抽离至关重要。我重点说下每一个版本,我们做了一些什么样的治理。首先大致了解一下数据中台的系统架构,详细如下: 数据中台.jpg

1.石器时代(es  外表)

刚开始搭建bi体系的时候,我们的各种体系都比较欠缺。当初为了快速响应业务,所有的报表都通过外表处理。(快速的创建报表体系,让相关人员看到初步的成果)详细如下:

##hive对应的 es 外表

CREATE EXTERNAL TABLE `app.channel_hour_analyse_report`(
  `id` string COMMENT 'doc_id', 
  `channel_number` string COMMENT '渠道号', 
  `install_device_count` bigint COMMENT '安装量', 
  `staticdate` string COMMENT '时间', 
  `hour` bigint COMMENT '小时')
ROW FORMAT SERDE 
  'org.elasticsearch.hadoop.hive.EsSerDe' 
STORED BY 
  'org.elasticsearch.hadoop.hive.EsStorageHandler' 
WITH SERDEPROPERTIES ( 
  'serialization.format'='1')
LOCATION
  'hdfs://nameservice1/user/hive/warehouse/app.db/channel_hour_analyse_report'
TBLPROPERTIES (
  'es.mapping.id'='id', 
  'es.nodes'='prod-es1:9200,prod-es2:9200,prod-es3:9200', 
  'es.resource'='d_custom_channel_operation_day_hour_table/_doc', 
  'es.write.operation'='upsert', 
  'last_modified_by'='test', 
  'last_modified_time'='1603697145', 
  'transient_lastDdlTime'='1603697145')

##hive 对应的hbase 外表

create EXTERNAL table `dwd.dw_public_userid_deviceid_relation`(
`rowkey` string  COMMENT  'rowkey',
`userid`  string  COMMENT  'userid',
`deviceid`  string  COMMENT  'deviceid' ,
`last_login_time`  string  COMMENT  'last_login_time',
`use_count`  INT  COMMENT  'use_count',
`reserve1`  string  COMMENT  '预留字段1',
`reserve2`  string  COMMENT  '预留字段2' 
) STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' WITH 
SERDEPROPERTIES ("hbase.columns.mapping"= 
":key, 
cf:userid, 
cf:deviceid, 
cf:last_login_time, 
cf:use_count, 
cf:reserve1, 
cf:reserve2") TBLPROPERTIES ("hbase.table.name" = "userid_deviceid_relation");
2.青铜时代(脚本迁移到spark sql)

所有的脚本迁移到db,建议分为ods、dwd、dim、dws、ads 层,同一层的数据设置优先级,因为同一层的数据可能存在相互依赖的情况。一定要把数据来源, sink 目标表,ddl,exec_sqls(建议 JsonArray存储),app项目,分区,exec_level(建议越小约优先执行),状态,创建人,时间,修改人,时间(方便以后问题追踪),还可以扩展到kylin,clickhouse 等olap场景是否使用。  所有的数据取消外表,通过spark job 写入es 。

val frame: DataFrame = spark.sql(read).filter(_.getString(0) != null).coalesce(10)
frame.show()
EsSparkSQL.saveToEs(frame, index, esConfig)
3.铁器时代(引入kylin)

通过spark sql 执行整体的执行时间降低40%。但是业务需要添加纬度过滤,我们对应的sql 就需要成倍的增加。对于后期的脚本维护成本是比较大的,所以引入kylin。建立纬度、度量,迁移历史spark 脚本。注意 kylin 提交spark 任务,刚开始通过hive on spark 执行任务。后续优化通过livy 提交任务到spark ,整合的性能有较大的提升。在本次项目中引入字典库、模型为工业时代打下基础。 kylin.jpg

4.工业时代(数仓建模)

引入kylin以后所有的数据层还是通过dws load hive 数据到kylin ,但是底层的hive元数据管理,主题、指标管理、复合指标管理、组件管理、可视化管理都是人工维护。为了打通河西走廊,我们把底层所有的同一行为的数据收缩统一、所有的度量、纬度通过系统动态构建cube。并且适配其他的olap 组件接入。 指标说明.jpg

private RestClient getOrCreateRestClient(KylinRestClientType clientType) {
        RestClient restClient = restClientHashMap.get(clientType);
        if (restClient == null) {
            switch (clientType) {
                case CUBE:
                    restClient = new CubeClient();
                    break;
                case MODEL:
                    restClient = new ModelClient();
                    break;
                case METADATA:
                    restClient = new MetadataClient();
                    break;
                default:
                    LOG.error("Can't match Client:{}", clientType);
            }
            LOG.info("create Kylin restClient type:{}", clientType);
            restClientHashMap.put(clientType, restClient);
        }
        return restClient;
}

4:总结

每一次的新尝试,都会有一定的突破。过程中有一些地方不够完美或不是足够的合理,但思维的碰撞促使我们不断的进步。业界有很多开源的数据展示组件像superset,metabase等,但是这些都离不开底层的指标与建模。欢迎大家一起讨论数据建模管理,以上是个人的一些思考。个别出处有问题,欢迎大家指正。