数字化与数字生态建设,是当前所有企业成长发展的必经之路。随着“加强新型基础设施建设”第一次被写入政府工作报告,5G、人工智能、工业互联网、智慧城市等新型基建彻底激发了数字的价值。

不过与数字世界蓬勃发展伴生而来的,是以指数形态爆炸增长的数据体量。在新基建中扮演重要角色的 5G、物联网、区块链等技术也蕴藏着丰富的诸如人、设备、车辆等流动变化且相互关联的数据,使得数据的来源、种类、结构、关联等因素都变得更为复杂,这也为数据分析的工作增加了不少难度。

并且在数据体量增长和数据种类丰富的同时,互联网应用对于数据分析实时性的要求也变得越来越高,尤其是在 5G 的加持下,越来越深的链接以及越来越快的触达速度,无一例外都在考验着企业决策的正确与否。在这样一个追求快+效率的时代,留给企业试错的空间正在越来越小。

因此需要依照不断变化的数据来做出实时精准的商业决策,需要从这些串联的数据中挖掘出有价值的信息,需要提前设定好与自身业务关系紧密的各种指标,这也意味着需要底层架构具备强大的数据存储以及分析计算能力,需要这些能力来满足实时变化的数据分析需求以赋能企业业务的目标。这就对企业的大数据平台提出了更高的要求。

然而当下数据之间包含大量节点,海量数据的来源可能是经过数十亿次的模拟、实验设备、互联网、应用等。对企业来说,需要把多个源头的数据进行整合,这就需要企业建立新的计算平台架构、从0开始建立数据分析模型并引入新的处理算法和索引技术,这无疑对开发者的技术能力提出了相当大的挑战。此外不只是技术者,业务分析和运营人员在这样一个快速变化的时代,也需要得到来自于数据的实时反馈。

因此,使用更加灵活的数据分析技术来为业务赋能正是突破业务十字路口的关键之举。通常来说,一般的数据分析能力就已经能够有效解决当下行业对于复杂关系数据分析的需求,然而这种对于实时性、灵活性需求极高的数据分析能力,即席查询无疑是更合适的那一个。

然而即便使用即席查询也不代表着一劳永逸,在应用即席查询的业务场景中,往往会出现各种各样的问题导致性能缓慢。秉着「让数据能力平民化」的使命,关于即席查询能力的场景化难题,易观数科也有着自己的思考。

即席查询也就是自定义多维查询,但是在建立大数据自定义多维查询过程当中,往往会遇到各种各样的问题:

  • 只查询单个总 PV 和总 UV,但是却读取了上百 G 数据;

  • 虽然 CPU 还没跑满,但是内存一直不够,各种 OOM;

  • CPU、内存、磁盘 IO 都空闲,但是查询性能就是慢;

  • 晚上跑 ETL 集群资源足够,白天分析师互相杀 SQL。

上述的这四种问题虽然都是在即席查询场景中相对常见的问题,但解决起来却并不容易。

易观数科围绕上述的这些痛点,成功构建了商业级别 Ad-hoc 查询引擎。基于用户行为分析产品易观方舟的经验,通过"减 IO、控内存、降带宽、优调度"这四个手段切实解决「即席查询 Ad Hoc」的上述相关难题。

一、减 IO

减 IO 是一个统称,是指在查询的每个环节中,都需尽量去减少向上一步传输的数据量。

场景1

只读取相关数据

以下表为例,分别从表中读取 xwhat、xwho、xwhen 这几列数据。

在减少 IO 的过程中,可以看见由于使用了 orcfile 这种列式存储的方式,能够轻松的把 ProjectNode 下推到 TableScanNode 节点,不需要读取过多的无用数据,仅仅读取需要的几列数据,从而起到减少数据从磁盘到内存 IO 的量。

场景2

建立稀疏索引

以下图为例,依然是从表中分别读取 xwhat、xwho、xwhen 这几列数据,并将 xwho="用户1" 作为这一行为的事件数据。

在该场景下,通过继续上面的动作,由于这部分额外增加了 xwho 的属性过滤,所以可以在存储数据时对 xwho 进行排序,并建立稀疏索引,尽可能的在 TableScanNode 时就利用有序索引+稀疏索引把数据过滤掉,进一步减少数据向上一节点传输的体量。

场景3

易观方舟的减 IO 方式

在易观方舟实际的转换漏斗模型中,需要采用多种减 IO 的措施。

二、控内存

上面提到了需要尽可能减少数据进入计算引擎内存的量,但是往往随着业务的发展,依然会面临硬件资源不足的情况出现。例如易观方舟就是一款私有化部署的智能用户数据中台,就经常会需要在有限的资源下满足客户多种的数据分析需求的挑战。

场景1

分桶执行策略

这里以一个场景为例,假设需要处理超过1个月的行为数据,预计内存使用 30G。但是当前用户单台硬件分配给秒算引擎的可用内存只有 10G,很明显此时硬件资源是无法满足业务查询需求的。

面对上述场景,这时就需要一个更优的执行策略--Bucekt Execution,也被称作分桶执行策略:优化后的内存占用=原内存占用/数据分桶个数。

通过把 30G 分为5个桶来执行,套用公式以后:优化后的内存占用只需要 6G。

场景2

流量洪峰时的策略执行

分桶执行策略可以在数据稳定的情况下使用,但是面对诸如618,双11等特殊时间节点下的流量爆点,数据往往会出现 N 倍变化的情况,此时上个场景中所提到的『分桶执行策略』就不太合适了,因为此时研发人员不清楚具体流量峰值,因此无法进行合理的物理分桶。如果对物理分桶过多,往往会造成小文件太多导致 HDFS 的 IO 性能变慢。

面对这个场景,就需要一个更为灵活的执行策略--Dynamic Bucekt Execution,即动态分桶执行策略:优化后的内存占用=原内存占用/数据分桶个数/用户 ID 分片数。

在动态分桶的基础上,优先保证每个桶的主键全局有序,再按照主键进一步进行范围切割。在这个场景案例中,只需要把每个桶的用户再细分为3份,这样总内存使用就只需要 2G 内存。

三、降带宽

通过以上2步,就已经可以很好地实现『减 IO、控内存』的目标了。但是在大数据场景中,影响效率的并非只有上文所提到的这两个因素,集群之间的网络带宽情况经常也会成为导致查询性能降低的诱因之一。

因此这部分的重点是降低带宽。通过把用户数据进行 hash 并分成多片,使每台机器只处理特定数据,这样就不会涉及到计算中间结果的再次 shuffle。

可参照下图,在使用该特性之前,所有的数据计算中间结果集 shuffle 到每个节点再次计算,这样会造成巨大的传输数据量;在使用该特性之后,网络传输数据量从 2.41GB 降低 68.71MB,降低了35倍,同时 CPU 执行时间也随之降低。

四、优调度

即便通过上述『减 IO、控内存、降带宽』这3个环节的性能优化后,在实际数据处理的过程中往往还是会遇到集群压力负载大、多用户同时查询等场景下的不可用情况。

此时就需要进一步梳理客户场景对 ad-hoc 查询的需求是什么,一般来说,有以下三点:

  • 查询结果确定可以出结果,而不是直接报错和多次人工重试;

  • 在多人使用的场景下,分析师希望自己先提交的查询一定能先出结果,而不是被后面的查询抢占资源;

  • 日常数据分析过程中,有一些紧急查询需要提前,不能等待其它任务完成。

通过以上一些场景需求,从而可以针对性定义了3个优化目标,分别为:查询结果可保证、查询速度可预期以及查询队列可控制。

目标1

查询结果可保证

具体流程可参见下图:

目标2

查询速度可预期

用户查询进入队列并行计算以后,有2个痛点需要解决,分别为先提交的查询先出结果确保不被大查询占用所有资源。针对这两个痛点,执行策略可以基于使用场景来调整:

  • FCFS 调度算法(First-Come,First-Served Scheduling),通常 FCFS 调度算法适应性最好,客户查询都遵循谁先提交查询,谁先出结果;

  • RR 轮转算法法(Round Robin,RR),该算法绝对公平,所有并发查询都会得到公平的资源;

针对以上这2种调度策略,通常在白天客户使用情况下建议使用 FCFS 调度,这样能够保证及时性。在夜间跑离线任务时,RR 调度能够确保资源的平均分配。

目标3

查询队列可控制

在实际场景中,并不是所有机器给出的策略都是最好的,所以易观方舟提供了可以人工调整队列的工具--插队模式"BOSS 队列"。同时配合 FCFS 调度算法,可以确保即便在高并发场景下,高优先级查询也能够优先在第一时间出结果。

优化结果

通过以上4步的持续迭代,也推动了方舟5.1版本的发布,并在内部模拟的多种查询场景中,为多个模块带来了数倍的性能提升。

最后

开源一直是易观数科所努力和实践的方向,易观也积极拥抱 Apache 社区,所用的组件基于完全 Apache license,实现了源码的自我可控;

易观数科也一直坚持【从社区中来,到社区中去】的工作方法论,易观数科已经把 kudu connector 完整实现了 Bucket Execution 的特性并反馈到了 PrestoSQL (近期更名为 Trino)社区,期待能够与社区共同成长。

最后易观数科为让整个数据处理有更快的数据分析速度,已经连续办有四届 OLAP 算法大赛,每年的 5、6月份开始报名,欢迎感兴趣的小伙伴关注哈,

为促进大数据行业的发展,也已免费开放支持私有化部署的易观方舟单机版 - Argo,欢迎下载试用。

同时我们也组织有 Presto、Clickhouse 、Alluxio 等大数据开源技术交流群,感兴趣的伙伴,欢迎关注本公众号后,回复“加群”,友情帮拉

你“在看”我吗?

即席查询(Ad Hoc)如何做到又快又稳?的更多相关文章

  1. SqlServer性能优化 即席查询(十三)

    执行计划,查询类别: 1.即席查询     2.预定义查询 select c.EnglishProductCategoryName,p.EnglishProductName,p.Color,p.Siz ...

  2. Optimize For Ad Hoc Workloads

    --临时工作负载优化   即席查询:也就是查询完没放到Cache当中,每次查询都要重新经过编译,并发高的时候很耗性能: 参数化查询: 一方面解决了重编译问题,但随着数据库数据数据的变更,统计信息的更新 ...

  3. SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问

    delphi ado 跨数据库访问 语句如下 ' and db = '帐套1' 报错内容是:SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATE ...

  4. Ad hoc sql

    SQL Server如何启用Ad Hoc Distributed Queries? 2011-08-11 14:53 wangdingbang CSDN博客 字号:T | T   本文主要介绍了SQL ...

  5. XE7 & IOS开发之开发账号(3):证书、AppID、设备、授权profile的申请使用,附Debug真机调试、Ad hoc下iPA文件生成演示(XCode5或以上版本推荐,有图有真相)

    网上能找到的关于Delphi XE系列的移动开发的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 注意,以下讨论都是以&q ...

  6. Sql导出数据报错-->SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问

    SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问,因为此组件已作为此服 ...

  7. SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT 'OpenRowset/OpenDatasource' 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用 'Ad Hoc Distributed Queries'。

    今天单位一ASP.NET网站,里面有个功能是导出数据,发现一导出就报错,报错内容是:SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT ...

  8. 解决SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问的方法

    1.开启Ad Hoc Distributed Queries组件,在sql查询编辑器中执行如下语句: reconfigure reconfigure 2.关闭Ad Hoc Distributed Qu ...

  9. SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用 'Ad Hoc Distributed Queries'。有关启用 'Ad Hoc Distributed Que

    看错误提示就知道是因为SQL Server的Ad Hoc Distributed Queries组件被禁用了,这里我用的SQL Server版本是2005,只需要开启Ad Hoc Distribute ...

随机推荐

  1. Proxmox 7.2 部署 DoraCloud桌面云,支持vGPU

    介绍 本文介绍了使用Proxmox + DoraCloud,将一台图形工作站(配置有Tesla P4显卡)改造成一台桌面云主机.可以满足多个桌面用户同时使用3D应用的需求. 该方案适合于小型工作室.电 ...

  2. Git 不识别文件名字母大小写变化

    问题 今天为一个项目撰写持续构建计划,撰写 Jenkinsfile 之后进行构建时报错: [2022-05-23 16:54:21] unable to prepare context: unable ...

  3. [BJOI2014]想法

    参考 P4581传送门 题意:给DAG,问每个点可以由多少个叶子到达. 思路: 随机化!!(题面有提示) 这道题利用在一个范围内随机的数期望均分范围的性质. 直接每个叶子在\([0,Max\_Rand ...

  4. 关于git flow的一点思考

    本文首发自我的公众号:成都有娃儿,这里把三篇文章合一,方便阅读. 现在相当多的公司或者团队都在使用git来做版本控制,结合我这些年的工作经历,我总结了一些个人认为不错的使用规范和习惯. 脱离背景来讲规 ...

  5. Redis - 读写模式 - 缓存一致性

    Cache Aside Pattern(旁路缓存模式) 读:从cache中读取数据,若读取到则直接返回:cache中不存在则去database中读取,然后更新到cache. 写:先更新database ...

  6. JAVA - ArrayList是否会越界?

    JAVA - ArrayList是否会越界? ArrayList并发add()可能出现数组下标越界异常. ArrayList是实现了基于动态数组的数据结构. LinkedList是基于链表的数据结构 ...

  7. 轻松解决pycharm中游标变宽的问题

    所谓的知者易,惑者难,一招回到解放前,遇到下面这种问题的解决方法: 轻轻动动你那可爱的手指头点击一下 insert插入键便可以轻松切换到你想要的游标了,不要感谢哥,哥也只是个过客

  8. 这就是艺术「GitHub 热点速览 v.22.25」

    作者:HelloGitHub-小鱼干 不知道写了那么久代码的你,是否还记得"代码写诗"这个词,它是用来形容代码的优雅.但是本周的项目,虽然你看到的是代码的成品,也会惊讶于它的艺术感 ...

  9. django--ORM表的多对一关系

    多对一关系是什么 Django使用django.db.models.ForeignKey定义多对一关系. ForeignKey需要一个位置参数:与该模型关联的类  class Info(models. ...

  10. Java开发学习(六)----DI依赖注入之setter及构造器注入解析

    一.DI依赖注入 首先来介绍下Spring中有哪些注入方式? 我们先来思考 向一个类中传递数据的方式有几种? 普通方法(set方法) 构造方法 依赖注入描述了在容器中建立bean与bean之间的依赖关 ...