京东OLAP实践之路-程序员宅基地

技术标签: 运维  编程语言  hadoop  分布式  大数据  

导读本文主要介绍京东在构建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服务,用户可以上面操作。就如前面所说,用户选择数据源,再选一个目标源,点击它执行导入,就可以完成。

今天的分享就到这里,谢谢大家。 


在文末分享、点赞、在看,给个3连击呗~


分享嘉宾:

李阳

京东 | 资深研发工程师

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/w397090770/article/details/116617464

智能推荐

Java必须掌握的全局变量和局部变量(含面试大厂题和源码)-程序员宅基地

文章浏览阅读884次,点赞25次,收藏20次。在Java中,全局变量和局部变量的概念通常与类变量(有时被认为是全局变量)和方法内的变量(局部变量)相关联。虽然Java本身没有全局变量的概念,但类的静态变量经常被用作全局变量。

Android系统新产品定制_export build_target 還原-程序员宅基地

文章浏览阅读1.1k次。配置过程分析:1: . ./build/envsetup.shincluding device/samsung/smdkv210/vendorsetup.sh------------------------------------------------------------------build/envsetup.sh末尾有:# Execute the contents o_export build_target 還原

SQLCookBook第四章学习日记11_insert into default-程序员宅基地

文章浏览阅读450次。第四章 插入、更新与删除 4.1插入新纪录4.2插入默认值_insert into default

ESD保护二极管ESD9B3.3ST5G 以更小的空间实现强大的保护 车规级TVS二极管更给力-程序员宅基地

文章浏览阅读594次。ESD9B3.3ST5G是一款 双向ESD保护 TVS二极管,设计用于保护电压敏感型来自ESD的组件。良好的夹紧能力,低泄漏,而且,快速响应时间可为设计提供一流的保护:暴露在静电放电下。反应速度快,电容值低,体积小,集成度高,封装多样化,漏电流低,电压值低有助于保护敏感的电子电路。ESD9B3.3ST5G ESD静电保护二极管应用于手机和配件、便携式电子产品、工业控制设备、机顶盒、电子仪器仪表、服务器,笔记本电脑和台式机、显示端口等。

宁波中软国际实习日记(一):SSM框架开发环境搭建-程序员宅基地

文章浏览阅读807次,点赞2次,收藏2次。宁波中软国际实习日记第一天:搭建开发环境1.0 JDK安装2.0 IDEA安装3.0 Tomcat安装、部署4.0 Maven安装、部署5.0 MySQL安装6.0 Notepad++安装1.0 JDK安装实习所用JDK版本是JDK8,在官网的下载页面找到Java SE 8u151/ 8u152的JDK download 按钮。点进去。双击安装程序后,一直点next就行。接下来是环境变..._中软国际实习日记

django数据存入mysql数据库_Django学习系列15:把POST请求中的数据存入数据库-程序员宅基地

文章浏览阅读231次。要修改针对首页中的POST请求的测试。希望视图把新添加的待办事项存入数据库,而不是直接传给响应。为了测试这个操作,要在现有的测试方法test_can_save_a_post_request中添加3行新代码# lists/tests.pydeftest_can_save_a_post_request(self):response= self.client.post(‘/‘, data={‘item_..._django http post mysql

随便推点

CSS三角、界面样式(cursor、input输入边框不改变颜色、textarea拖拽不改变大小)、vertical-align、溢出文字省略号显示、CSS初始化_html css input::cue-程序员宅基地

文章浏览阅读1.5k次,点赞2次,收藏7次。vertical-align的可选值为:1. bottom: 图片的底线和文字的底线对齐,2. baseline:默认,图片的底线和文字的基线对齐,3. middle: 图片的中线和文字的中线对齐,4. top:图片的顶线和文字的顶线对齐。不同浏览器对有些标签的默认值是不同的,为了消除不同浏览器对HTML文本呈现的差异,所以需要进行CSS初始化。当我们选择input输入框,进行文字输入的时候,边框会改变颜色。textarea默认可以在右下角进行拖拽,改变输入框的大小。CSS初始化参考如下。_html css input::cue

【CS231N】5、神经网络静态部分:数据预处理等-程序员宅基地

文章浏览阅读84次。一、疑问二、知识点1. 白化​ 白化操作的输入是特征基准上的数据,然后对每个维度除以其特征值来对数值范围进行归一化。该变换的几何解释是:如果数据服从多变量的高斯分布,那么经过白化后,数据的分布将会是一个均值为零,且协方差相等的矩阵。该操作的代码如下:# 对数据进行白化操作:# 除以特征值 Xwhite = Xrot / np.sqrt(S + 1e-5)​ 警告:夸大的噪声。注意分母..._人工神经网络系统中的静态数据

MyEclipse开发教程:使用REST Web Services管理JPA实体(四)-程序员宅基地

文章浏览阅读81次。MyEclipse 在线订购年终抄底促销!火爆开抢>>MyEclipse最新版下载使用REST Web Services来管理JPA实体。在逆向工程数据库表后生成REST Web服务,下面的示例创建用于管理博客条目的简单Web服务。你将学会:利用数据库逆向工程开发REST Web服务部署到Tomcat服务器使用REST Web服务资源管理器进行测试没有MyEcli..._myeclipse项目中不能选add rest web service compatibility

后端面试每日一题 垃圾回收算法,面试资料分享-程序员宅基地

文章浏览阅读854次,点赞10次,收藏17次。校验的内容就是此对象是否重写了 finalize() 方法,如果该对象重写了 finalize() 方法,那么这个对象将会被存入到 F-Queue 队列中,等待 JVM 的 Finalizer 线程去执行重写的 finalize() 方法,在这个方法中如果此对象将自己赋值给某个类变量时,则表示此对象已经被引用了。它是指将内存分为大小相同的两块区域,每次只使用其中的一块区域,这样在进行垃圾回收时就可以直接将存活的东西复制到新的内存上,然后再把另一块内存全部清理掉。// 等待 finalize() 执行。

LeetCode 1427. 字符串的左右移_leetcode 1427 python-程序员宅基地

文章浏览阅读246次。LeetCode 1427. 字符串的左右移文章目录LeetCode 1427. 字符串的左右移题目描述一、解题关键词二、解题报告1.思路分析2.时间复杂度3.代码示例2.知识点总结相同题目题目描述给定一个包含小写英文字母的字符串 s 以及一个矩阵 shift,其中 shift[i] = [direction, amount]: direction 可以为 0 (表示左移)或 1 (表示右移)。 amount 表示 s 左右移的位数。 左移 1 位表示移除 s 的第一个字符,并_leetcode 1427 python

好用的不行不行!超级炫酷的键盘最应该留给最般配的猿们!-程序员宅基地

文章浏览阅读2k次。在北半球,3月是春季的第一个月,春天象征着希望和美好。关注我的读者大多数都是(程序)猿,所以好用的键盘必不可少!今天为了感谢大家对本公众号的大力支持我联合了10个号主送11个炫酷键盘,不..._cole mak键盘