写点什么

京东 OLAP 实践之路

  • 2021-05-18
  • 本文字数:4477 字

    阅读完需:约 15 分钟

京东OLAP实践之路

本文主要介绍京东在构建 OLAP 从无到有各环节考虑的重点,由需求场景出发,剖析当前存在的问题,并提供解决方案,最后介绍 OLAP 的发展过程。

需求场景

1. 京东数据入口


① 业务数据:订单

京东作为一家电商企业,拥有自营商品销售平台和全链路物流通道。首先第一数据入口就是订单,针对不同订单进行多维度分析,比如:对订单分析、对店铺分析、对商品品类分析等等。

展开对订单维度来说,因为我们作为电商,订单是非常重要的一个维度分析和数据支撑,所以常结合订单 SKU,计算品类下单转化率。


② 行为数据:点击和搜索

用户在京东商城的操作,比如点击和搜索,我们会将用户的这些行为结合订单信息,来做一些分析,比如分析商品的热销和滞销程度,以及转化情况,最常见的就是漏斗分析,来计算转化率。


③ 广告和推荐

基于用户下单情况,我们会推送广告和推荐给到用户,然后进行计算,分析广告触达相关情况。


④ 监控指标

对于监控指标,是我们一个巨大的场景,因为在我们这里,除了用户行为数据,还有很多运维的数据也需要管理起来。

2. 京东数据出口



京东的数据出口,主要分类两大类:离线和实时

① 离线

  • 月报和周报

典型离线场景:财务报表经常需要月报周报。

  • 机器学习

会用到大量的一些训练数据,这些数据的生成也会用到 OLAP 的一些特性来把数据进行分析,产生一些训练的数据。


② 实时

  • 交互式查询

非研发同事,比如营运分析人员,经常需要临时查询业务数据,比如查询最近一周订单的汇总以及明细数据,对这些数据进行分析,辅助决策。

  • 实时大屏展示

平台做大促或者实时监控运营情况,会依照大屏的指标,实时动态调整资源。比如营销策略、广告费投入、供应链库存。尤其重要的是,在大促销的时候,可以进行动态资源的调整,比如车辆资源调度、根据促销效果决策活动是否需要进行调整等。

问题与解决方案

以上是京东的部分业务场景,和大多数阐述数据架构不同,我们本次将数据搭建的过程分为 4 个方面:数据怎么写进来;写进来以后怎么进行存储;存储以后又怎么进行取用;最后是如何管理前 3 个环节。

1. 写



① 数据源及数据结构多样性

现状:

数据源来源多样化:文件系统(本地文件 &分布式系统文件)& MQ

  • 本地文件,比如说服务器本地的数据,直接导入进来

  • 数据量比较大时,在用户本地存不了这么大的数据量,会将数据存储在 HDFS 上

  • Kafka 或者 MQ 数据,上游将产生的数据直接存储到消息队列中,在京东内部,这种 MQ 的系统有多个,但是我们需要统一进行接入

  • 数据结构的多样化,最常见:CSV、TSV、JSON、AVRO、PARQUET、BINLOG 等

问题:

多种数据源及数据类型,对于开发人员来说,进行数据分析的成本相对比较高,我们希望分析人员,只需要专注于业务逻辑本身,直接进行 SQL 查询,而无需关心数据来源。

解决方案:

建立统一导入数据服务,将多样化的数据源和数据类型进行封装,通过给用户配置权限,用户只需要在可视化界面直接进行操作,即可完成数据的导入操作,具体的操作也是比较简单,以 MQ 数据源举例:

  • 选择数据源的 topic

  • 指定导入的目标源

  • 选择数据格式

  • 选择对应的数据字段类型等等


② 数据的时效性

现状:

实时的数据需要实时进行计算和展示;离线的数据,可以定时的推送并计算一次,对时效的要求比较低。

问题:

如何保证实时和离线数据的时效性,且不会相互影响?

解决方案:

对实时集群和离线集群进行物理隔离,防止互相干扰,这样做的好处有:

实时和离线对于资源的需求不同,实时数据写入非常频繁,而离线的数据只是在指定运行的时间点比较多,区分开便于管理。


③ 数据的更新和删除

问题:

对于 OLAP 的架构来说,如何做到既要查询搜索又要更新呢?

解决方案:

  • 数据更新,采用覆盖写的方案。以订单为例,用户下了一个订单 1,此时下单状态为 1,后面用户进行了支付操作,订单状态为 2,那么我们会重新推送一条全量的数据,只是状态的字段值发生看变化。

  • 数据删除,采用删除分区然后重新导入这个分区数据,或者采用版本管理方式,因为通过新版本的数据会覆盖原来的版本,起到删除的作用。


③ 高吞吐

问题:

以京东现在的体量,每天的数据是很大的,如何解决高吞吐问题呢?

解决方案:

机房配置万兆网络,另外对于实时场景,配备 SSD;离线场景,配备 HDD。

2. 存



① 海量数据

问题:

京东的数据,TB 数据量是非常常见的,有些时候会达到 PB 级别,那么采用单机的方式肯定是行不通的,那么如何解决数据存储的问题呢?

解决方案:

  • 采用分布式解决大规模数据的问题。

  • 为了提高效率,采用了列式存储,对后续指标的计算效率也有提升,其实在 OLAP 的架构中,大多数都是列式存储。

  • 采用不同类别的压缩方式,比如 snappy 等。


② 容错性

问题:

数据现在是科技类企业非常重要的资产,那么如何保障数据的安全性性呢?

解决方案:

其一:多副本的容错方式,我们的 OLAP 采用三副本的方式,所以其中 1 个或 2 个副本损坏或迁移时做扩容都比较容易处理。

其二:RAID 独立磁盘冗余阵列(RAID,redundant array of independent disks),因为磁盘金属机器经常会坏,加上有一些机器过保存在损坏的风险,所以我们也通过 raid 解决一部分数据容错性的问题,防止磁盘坏掉之后整个机器不能提供服务的情况。


③ 一致性

解决方案:

解决数据的一致性的问题,需要使用到分布式协调和本地事务机制。

  • 分布式协调,比如 zookeeper

  • 本地事务机制:对于本地的提交,是否通过事务来保证数据的一致性

通过两者的结合,来实现数据的一致性。

3. 读



① 查询速度

问题:

数据存储到系统中以后,如何高效的进行取用呢?

解决方案:

  • 通用方式,数据进行分区分片,在很多场景,对数据的分析都是按照时间进行分区,分区以后,再进行分片或者分桶。

    比如:订单信息,我们可能按天查询,那么就可以按照实际日期进行分区;比如,存储 10 年的数据,不可能全部查询,我们按照统计则按月进行分区。

  • 预聚合,提前进行预计算,减少一次性计算的数据量,提高性能。

  • 索引,大部分场景下会使用索引,比如做明细查询,可能会到 hash 索引、betree、范围查询或者倒排。

  • 物化视图,其实和预聚合的功能类似,数据进入到物化视图中时,提前进行一些预计算。


② 易用性

问题:

如何实现系统的易用性?

解决方案:

  • 需要 OLAP 系统兼容 JDBC 和 ODBC,同时支持标准的 SQL。

  • 提供界面化的操作,这种方式可以避免所有的运营分析人员都具备 Mysql 等数据库的环境,可以直接登入图形化界面进行查询的操作。


③ QPS

问题:

如何提高 QPS?

解决方案:

  • 缓存,使用 doris 时,增加比如 partitioncache,或者结果级缓存,或者分区缓存机制来提升查询效率。

  • 多副本,设置多副本的方式,通过牺牲部分存储空间,来提升 QPS,但是这个效果有限。

  • 提升机器的规模。

4. 管理



现状:

早期我们碰到磁盘坏了,搞得手忙脚乱,替换磁盘或者是下机器操作时间很长,而且这个操作完成之后还涉及重新平衡数据或者数据迁移,这个过程非常麻烦。

问题:

如何降低运维成本?

解决方案:

  • 建设监控和报警机制,进行提前预防。

  • 优化节点的下线,在京东系统中,有两种方式:

    方式 1:通过黑名单的方式,如果监控到某个节点经常不健康,我们会把它纳入黑名单,并将他踢下线了。

    方式 2:通过脚本操作,但是从最开始我们需要替换一个节点,估计从发现到替换完成得三小时,现在通过一些比较自动化的东西,现在大概十分钟左右能做到一个节点的替换。

发展历程

1.0 时代



1.0 时代的场景比较少,数据量也比较少,主要是订单相关的一些数据,分析通过关系型数据库就能搞定,比如说 oracle 或者 mysql。


可通过数据储备同步到备库做分析,或者 mysql 一个是 slave 库,主库做一些利用线上业务,然后备库对存货的一些分析和查询。

2.0 时代



到了 2.0 场景,不再是简单处理订单问题,还要处理物流、供应链、客服、支付等等场景。

场景大增,数据量也爆发式增长,从原来的 G 到现在的 TB 甚至 PB 级别。传统关系性数据库,已经不能满足需求了。


这个时候我们开始搭建了离线数仓,在数仓中进行分析,主要用 Hive 和 Spark 进行计算,数据都是 T-1,临时查询数据的体验非常差,需要耗时分钟级别且还是昨天的数据。

3.0 时代



为提升查询数据的速度和数据的时效性,开始做实时查询。我们现在使用统一 OLAP 服务,从最开始使用 Kylin 处理一些离线的业务,到现在我们用了 doris 和 clickhouse 结合起来,同时处理实时和离线,统一服务接口,对用户和开发人员开放。


同时针对不同的业务,提供不同的计算引擎,我们现在提供一个整体打包解决方案,业务只需要在 OLAP 的服务上,进行统一部署到数据技术平台即可,大大减少了开发成本。

未来规划



① 管理平台优化

  • ClickHouse 的动态伸缩。

  • 智能化运维。智能优化节点上下线或者数据均衡这些方面的工作。主要想要通过减少人工干预操作,降低时间的浪费。在京东的系统中,现在拥有上千台的服务器,如果一直由人工来处理的话,那么成本非常高。


② 优化查询速度

  • 优化实时计算缓存。在 doris 中,使用 partitioncacahe 或者 sqlcache 在离线场景中比较有效,后续将考虑在实时计算中引入缓存进行优化。

  • 索引智能化管理。索引的引擎有非常多种,如果需要开发人员了解所有的引擎,学习成本是比较高的,我们能不能做成智能化的索引引擎呢?这样的话用户不需要再去关心类似的一个索引怎么建的问题,而是我们在通过用户的一些查询行为分析,自动的来给他做索引的创建,这样简化工作成本,让开发人员有更多的心思去做好运营和分析。

问答环节

Q1:请问老师贵司有用过 druid 引擎吗?

A1:没有,我们调研发现,第一,druid 对 sql 的支持不是很友好;第二,druid 擅长于持续性的数据场景,但是京东订单是一个频繁发生状态变化的一个场景,它是不太好处理的,所以当时我们也没有选 druid。


Q2:clickhouse 和 doris 如何根据业务场景选型,有哪些坑?

A2:

第一,查询性能:在查询表不多即没有太多表关联情况下,clickhouse 查询速度比较快,但是在做大表关联查询时,doris 的性能会好于 clickhouse。

第二,QPS:clickhouse 是在极限使用 CPU 的性能,但是 doris 的 QPS 性能在某些场景下会比 clickhouse 好。

第三,运维成本:doris 的运维成本会小于 clickhouse,至少现在对我们来看,因为它会有节点自动上下线扩容收容会很方便,但是 clickhouse 做这个方面比较麻烦。

第四,数据更新:clickhouse 数据更新的引擎有三种,用户在使用的时候比较麻烦,但是 doris,它直接进行数据覆盖,就能做到一个更新,操作更方便。


Q3:doris 和 clickhouse 是自动选择,还是需要用户自己去选,如果是自动选的话,识别机制是什么样的?

A3:目前还没有做到自动选。当前先整体提供解决方案,我们为用户提供技术支撑,未来可能会想着如何去打通统一化,因为它的模型创建不太一样,它的 sql 是有差异的。


Q4:数据接入 CK 方面,京东目前是什么样的方案?

A4:目前有两条路线。

一个是用户自己业务侧接入,因为有些历史原因,用户他已经用了很久的 clickhouse,他自己有比较成熟的一套接入系统。

一个是使用 clickhouse 来接入,不管是从离线还是从 kafka 中,这种方式是我们在平台侧,在平台侧开发了统一的 OLAP 服务,用户可以上面操作。就如前面所说,用户选择数据源,再选一个目标源,点击它执行导入,就可以完成。

 

分享嘉宾:

李阳

京东 | 资深研发工程师

京东资深研发工程师,拥有超过 10 年研发经验,擅长 OLAP 相关服务研发及分布式系统设计。


本文转载自:DataFunTalk(ID:dataFunTalk)

原文链接:京东OLAP实践之路

2021-05-18 07:002373

评论 1 条评论

发布
用户头像
很棒
2021-05-18 14:11
回复
没有更多了
发现更多内容

【web 开发基础】PHP 快速入门(9)-PHP 运算符之位运算符详解

迷彩

位运算 10月月更 PHP基础 PHP位运算

DDD领域驱动设计的概念解析

乌龟哥哥

微服务 10月月更

当我遇到10亿参数组合

FunTester

大家都在“卷”的推荐系统还有进步空间吗?看技术大牛们怎么说

小红书技术REDtech

Java之抽象类

魏铁锤

10月月更

【LeetCode】分割数组Java题解

Albert

算法 LeetCode 10月月更

Java领域又一神作!《凤凰架构》仅开源3小时,竟遭受Github万人哄抢

程序员小毕

程序员 架构 分布式 程序人生 系统设计

2022-10-24:以下go语言代码输出什么?A:3 3;B:3 4;C:0 0;D:0 1。 package main func main() { m := make(map[int]int

福大大架构师每日一题

golang 福大大 选择题

leetcode 191. Number of 1 Bits 位1的个数(简单)

okokabcd

LeetCode 数据结构与算法

高效IO之零拷贝技术

乌龟哥哥

10月月更

1024里的小温暖,用技术让生活变得更美好!

阿里技术

1024程序员节

[极客大挑战 2019]Http 题解

w010w

Web HTTP CTF 10月月更

OpenCloudOS社区发起的程序员节专属系列活动

B Impact

“程”风破浪的开发者|那些优化奇葩代码的方法

慕枫技术笔记

学习方法 代码 “程”风破浪的开发者

Java实现随机人名抽取

魏铁锤

10月月更

算法题学习---链表内指定区间反转

桑榆

算法题 10月月更 C++

一个“简单”的面试题:什么是环回地址127.0.0.1?

wljslmz

10月月更 127.0.0.1 环回地址

“程”风破浪的开发者|APP自动化效果测试工具

梦笔生花

学习方法 “程”风破浪的开发者 手机APP测试

Spring Boot「13」使用 Actuator

Samson

Java spring 学习笔记 spring-boot 10月月更

【愚公系列】2022年10月 Go教学课程 038-异常处理

愚公搬代码

10月月更

有没有完全自主的国产化数据库技术

王磊

观察者模式的基础原理

阿泽🧸

观察者模式 10月月更

应用数据库常见的数据切分方式

乌龟哥哥

数据库 10月月更

MapReduce作业生命周期

穿过生命散发芬芳

mapreduce 10月月更

C# 线程的优先级

IC00

C# 学习 程序员 上位机 10月月更

C# 快捷菜单ConTextMenustrip控件学习

IC00

C# 学习 程序员 上位机 10月月更

【资损】分布式环境中的幂等性控制设计

小明Java问道之路

架构 微服务 安全 10月月更 资损

【移动应用安全】移动应用安全概述及超级用户权限获取

w010w

android 移动应用安全 root 10月月更

【web 开发基础】PHP 快速入门(10)-PHP 其他运算符详解

迷彩

web开发 10月月更 PHP基础 三元运算符

Java | if语句和循环结构

陌上

ide Java、 10月月更

鸿蒙开发工具 DevEco Studio 3.0 体验与项目介绍

宇宙之一粟

HarmonyOS 鸿蒙应用开发 10月月更

京东OLAP实践之路_大数据_DataFunTalk_InfoQ精选文章