小米有品 x StarRocks:极致性能打造小米式性价比数据平台

本文发表于: &{ new Date(1637251200000).toLocaleDateString() }

作者:汪细勖,小米高级研发工程师;陈亦奇,小米有品研发工程师

小米有品是小米旗下精品生活电商平台,也是小米“新零售”战略的重要一环。依托小米生态链体系,延续小米的“爆品”模式,致力于将“小米式的性价比”延伸到更广泛的家居生活领域。有品数据中心主要负责有品电商的数据资产,提供数据分析服务。数据分析帮助做出有效决策,有效决策促进业务增长,业务增长需要更多的数据分析,形成闭环。

历史架构及业务痛点

受限于以往业务规模以及技术条件,曾经的小米数据中心的架构如下图:

业务数据和流量数据通过数据采集服务传送到 Talos,实时数据通过 Spark Streaming 进行 ETL 处理,商品数据聚合之后写入 MySQL 中,其他数据写入 Druid 中做预聚合;离线数据直接写入 Hive 中,通过 Spark SQL 提供查询服务。这套架构随着业务的快速发展,已经越来越不满足用户需求,主要表现为以下几点:

  • 数据快速膨胀,查询性能成为瓶颈
  • 维护多套系统,运维成本,机器成本高
  • Druid 去重效果差,不支持明细数据

StarRocks 在小米有品的应用实践

OLAP 引擎调研

为了解决这些问题, 我们调研了多款 OLAP 引擎,没有一款引擎能从数据规模,查询性能,灵活性三个方面满足我们的需求。结合实际,综合考虑,我们选择了 StarRocks 作为小米有品数据中心的新一代 OLAP 引擎。主要考虑到 StarRocks 有以下几点优势: 

  • 极致查询性能:单表查询性能已经超过 ClickHouse,多表 Join 经过 CBO 优化,性能远超 ClickHouse
  • 同时支持明细和聚合模型:支持 Duplicate/Aggregate/Unique 三种数据模型,同时支持物化视图
  • 高效数据导入:高效支持流式导入和批量导入
  • 运维简单,高可用:多副本,一致性协议支持高可用,自动化运维,操作简单

当前架构

采用 StarRocks 作为小米有品数据中心的 OLAP 引擎之后,我们当前的架构是这样的:

业务数据和流量数据通过数据采集服务,写入 Talos 中,实时数据通过 Flink 进行 ETL,实时写入 StarRocks 中;离线数据通过 Spark 进行 ETL,写入 Hive 中,然后导入到 StarRocks 中。由 StarRocks 作为统一的查询引擎,架构简单明了。

数据写入

数据首先写入 STG 层,STG 层是数据缓冲层,包含了订单 Binlog 数据,优惠数据 Binlog,退款数据 Binlog,流量日志等;ODS 层进行数据的解析,DWD 层对数据清洗、过滤及相关业务逻辑处理;DWS 层按照主题或者维度进行轻度聚合,最后数据写入 StarRocks 中。

目前在 StarRocks 之中主要包含了 SKU 聚合模型、页面聚合模型、优惠聚合模型、明细模型以及维度模型,那么聚合数据采用Aggregate模型;明细数据采用 Duplicate 模型,然后在此基础上再采用物化视图来加速;离线数据通过 Broker Load 方式导入;实时数据通过 Stream Load 方式导入。

经过半年的努力,我们目前已经实现了小米内部的各大平台与 StarRocks 的互联互通,一键操作, 从 Flink、Hive、Hadoop、Kafka、Spark、MySQL 等平台上,将数据一键操作写入 StarRocks 中,也可以一键操作将 StarRocks 数据迁移到 Flink、Hive、Hadoop、Spark、Presto 中,实现了StarRocks 与各大平台的互联互通,一键操作,让数据在各大平台自由流动,方便用户操作和使用。

数据建模

过去我们在进行建模的时候,广泛的采用的是大宽表,也就是将指标列和维度列都放在同一张表上。这会带来一个很严重的问题,就是当维度修改的时候,我们需要对数据进行重新的回溯,然后重新聚合计算,这样的话非常消耗时间。由于 StarRocks 良好的多表 Join 性能,我们改变了过去大宽表的形式,采用星型关联表来建模,可以支持维度动态修改,降低回溯成本。

数据查询

对于去重,过去主要是采用 Druid 来进行数据的去重,计算 PV/UV 等,由于 Druid 采用 HLL 近似算法,精度只能达到 97%到99%,对于 AB 实验以及搜索推荐算法进行优化效果的评估已经不能满足用户的需求了。StarRocks 支持 Bitmap 精确去重算法,精度提升到了100%。

除此之外,相比于传统的 Broadcast/Partition Shuffle Join 算法,StarRocks 提供了 Colocate Join 和  Bucket Shuffle Join 算法。Colocate Join 在数据写入时,保证多个表的数据按照分桶键分布,保持一致,这样多张表 Join 时可以在本地进行,减少网络传输,提升查询性能。在生产实践中我们发现能够带来3-4倍以上的产品性能的提升,非常强悍。

另外我们也广泛的使用了 Bucket Shuffle Join,相比于过去的 Broadcast/Partition Shuffle Join 需要传输多份数据,Bucket Shuffle Join 只用传输一份右表的数据。当 Join Key 包含左表分桶键,可以实现 Join 时,只用传输一份右表数据,减少数据网络传输,提高查询性能。通过测试发现 Bucket Shuffle Join 能带来提升2-3倍以上的查询性能。

综合比较,相比于之前的架构,现在的架构查询性能方面提升明显。聚合上卷查询,关联查询相较于此前基于 MySQL 的架构,基于 StarRocks 的架构性能可以提升20-30倍以上。StarRocks在明细聚合查询方面,相比于 Spark SQL,提升4倍以上。存储成本相比于 MySQL+Druid,降低2倍以上

平台展示

下图是我们基于 StarRocks 实现的小米有品数据中心的一个平台,主要是提供业务分析以及看板、报表等等这些服务。

未来规划

一、我们打算在小米集团内部广泛的推广 StarRocks,与商业平台,小米账号、MIUI、小爱等等这些业务部门进行一个深度的合作,发掘 StarRocks 潜力,探索 StarRocks 能力边界,满足业务部门丰富的需求。

二、我们准备携手 StarRocks 开发 Z-Order Indexing 来提升多维分析的查询性能。目前 StarRocks 在数据写入的时候,会在内存中将多个列按照字典的方式来进行排序,然后写入到磁盘中。这种字典排序的方式在实际的查询过程中,只有利于第一列的过滤,但是其他列的过滤效果都比较差。为了支持多维分析的场景,未来我们打算开发 Z-Order Indexing 来提升多维分析的查询性能。

三、我们准备携手 StarRocks 开发单副本 Compaction,减少对查询的影响。目前 StarRocks 在数据写入的时候会同时写多个副本,多副本 Compaction 占用资源多,影响查询性能,开发单副本 Compaction,分发 Compaction 结果,减轻对查询性能的影响。

总结

总的来说,首先我们觉得 StarRocks 运维简单,成本低。由于StarRocks同时支持明细和聚合模型,可以满足大多数场景,之前采用的多种引擎构建数据中心的架构,现在可以采用 StarRocks 作为唯一引擎,架构简单明了,运维高效便捷。StarRocks 相比于 Spark 引擎,机器成本降低50%以上。第二 StarRocks 查询性能优越,StarRocks 近乎实时的查询性能,针对很多典型场景进行优化的各种特性(Colocate Shuffle Join,Bucket Shuffle Join,CBO等),给用户带来了良好的使用体验。第三 StarRocks 既可存算一体,也可存算分离。目前 StarRocks 是存算一体的系统,但它同时支持 ES/MySQL/Hive 等外表功能,可以实现对 Hadoop 生态的查询,可以做到存算分离,对于节省成本,打通 Hadoop 生态很有意义。