分享嘉宾:高大月@美团点评,Apache Kylin PMC成员,Druid Commiter

编辑整理:Druid中国用户组 6th MeetUp

出品平台:DataFunTalk

--

导读: 长久以来,对SQL和权限的支持一直是Druid的软肋。虽然社区早在0.9和0.12版本就分别添加了对SQL和Security的支持,但根据我们了解,考虑到功能的成熟度和稳定性,真正把SQL和Security用起来的用户是比较少的。本次分享将介绍社区SQL和Security方案的原理,以及美团点评在落地这两个功能的过程中所遇到的问题、做出的改进、和最终取得的效果。下面开始今天的分享:

我今天的分享内容包括四部分。首先,和大家介绍一下美团对Druid的使用现状,以及我们在构建Druid平台的过程中遇到的挑战。第二部分,介绍Druid SQL的基本原理和使用方式,以及我们在使用Druid SQL的过程中遇到的问题和做的一些改进。第三部分,介绍Druid在数据安全上提供的支持,以及我们结合自身业务需求在Druid Security上的实践经验。最后,对今天的分享内容做一个总结。

--

01 Druid在美团的现状和挑战

1.Druid应用现状

美团从16年开始使用Druid,集群版本从0.8发展到现在的0.12版本。线上有两个Druid集群, 总共大概有70多个数据节点。

数据规模上,目前有500多张表,100TB的存储,最大的表每天从Kafka摄入的消息量在百亿级别。查询方面,每天的查询量有1700多万次,这里包括了一些程序定时发起的查询,比如风控场景中定时触发的多维查询。性能方面,不同的应用场景会有不同的要求,但整体上TP99响应时间在一秒内的表占了80%,这和我们对Druid的定位——秒级实时OLAP引擎是一致的。

2.Druid平台化挑战

把Druid作为一个服务提供给业务使用的过程中,我们主要遇到了易用性、安全性、稳定性三方面的挑战。

易用性:业务会关心Druid的学习和使用成本有多高,是否能很快接入。大家知道,Druid本身对数据写入和查询只提供了基于JSON的API接口,你需要去学习接口的使用方法,了解各种字段的含义,使用成本是很高的。这是我们希望通过平台化去解决的问题。

安全性:数据是很多业务的核心资产之一,业务非常关心Druid服务能否保障他们的数据安全。Druid较早的版本对安全的支持较弱,因此这一块也是我们去年重点建设的部分。

稳定性:一方面需要解决开源系统落地过程中出现的各种稳定性问题,另一方面,如何在查询逻辑不可控的情况下,在一个多租户的环境中定位和解决问题,也是很大的挑战。

--

02 Druid SQL的应用和改进

在Druid SQL出现之前,Druid查询通过基于JSON的DSL来表达(下图)。这种查询语言首先学习成本很高,用户需要知道Druid提供了哪些queryType,每种queryType需要传哪些参数,如何选择合适的queryType等。其次是使用成本高,应用需要实现JSON请求的生成逻辑和响应JSON的解析逻辑。

通过Druid SQL,你可以将上面的复杂JSON写成下面的标准SQL。SQL带来的便利是显而易见的,一方面对于程序员和数据分析师没有额外的学习成本,另一方面可以使用类似JDBC的标准接口,大大降低了门槛。

1.Druid SQL简介

下面我简单地介绍一下Druid SQL。

首先,Druid SQL是0.10版本新增的一个核心模块,由Druid社区提供持续的支持和优化,因此不管是稳定性还是完善性,都会比其他给Druid添加SQL方言的项目更好。

从原理上看,Druid SQL主要实现了从SQL到原生JSON查询语言的翻译层。由于只是做了一层语言的翻译,好处是Druid SQL对集群的稳定性和性能不会有很大影响,缺点是受限于原生JSON查询的能力,Druid SQL只实现了SQL功能的一个子集。

调用方式上,Druid SQL提供了HTTP和JDBC两种方式来满足不同应用的需求。最后表达力上,Druid SQL几乎能表达所有JSON查询能实现的逻辑,并且它能自动帮你选择最合适的queryType。

下面是三个Druid SQL的例子。

第一个例子是近似TopN查询。对于根据某个指标分析单个维度TopN值的需求,原生的JSON查询提供了一种近似TopN算法的实现。Druid SQL能够识别出这种模式,生成对应的近似TopN查询。

第二个例子是半连接。我们知道Druid是不支持灵活JOIN的,但业务经常会有这样的需求,就是以第一个查询的结果作为第二个查询的过滤条件,用SQL表达的话就是in subquery,或者半连接。Druid SQL对这种场景做了特殊支持,用户不需要在应用层发起多个查询,而是写成in subquery的形式就行了。Druid SQL会先执行子查询,将结果物化成外层查询过滤条件,然后再执行外层的查询。

最后是一个嵌套GroupBy的例子。Druid SQL能够识别出这种多层的GroupBy结构,生成对应的原生嵌套GroupBy JSON 。

2.Druid SQL架构

下面介绍Druid SQL的整体架构。

Druid SQL是在查询代理节点Broker中实现的功能,主要包含Server和SQL Layer两个模块。

Server模块负责接收和解析请求,包括HTTP和JDBC两类 。对于普通的HTTP请求,新增相应的REST Endpoint即可。对于JDBC,Druid复用了Avatica项目的JDBC Driver和RPC定义,因此只需要实现Avatica的SPI就行了。由于Avatica的RPC也是基于HTTP的,因此两者可以使用同一个Jetty Server。

SQL Layer负责将SQL翻译成原生的JSON查询,是基于Calcite项目实现的。Calcite是一个通用的SQL优化器框架,能够将标准SQL解析、分析、优化成具体的执行计划,在大数据领域得到了广泛的使用。图中浅绿色的组件是Calcite提供的,浅蓝色的组件是Druid实现的,主要包括三个。

首先,DruidSchema组件为Calcite提供查询解析和验证需要的元数据,例如集群中包含哪些表,每张表各个字段的名称和类型等信息。RulesSet组件定义了优化器使用的转换规则。由于Druid SQL只做语言翻译,因此这里都是一些逻辑优化规则(例如投影消除、常量折叠等),不包含物理优化。通过RulesSet,Calcite会将逻辑计划转成DruidRel节点,DruidRel包含了查询的所有信息。最后,QueryMaker组件会尝试将DruidRel转成一个或多个原生JSON查询,这些JSON查询最终提交到Druid的QueryExecution模块执行。

3.API选择: HTTP or JDBC

Druid SQL提供了HTTP和JDBC两种接口,我应该用哪个?我们的经验是,HTTP适用于所有编程语言,Broker无状态,运维较简单;缺点是客户端处理逻辑相对较多。JDBC对于Java应用更友好,但是会导致Broker变成有状态节点,这点在做复杂均衡时需要格外注意。另外JDBC还有一些没有解决的BUG,如果你使用JDBC接口,需要额外关注。

4.改进

下面介绍我们对Druid SQL做的一些改进。

第一个改进是关于Schema推导的性能优化。我们知道Druid是一个schema-less系统,它不要求所有的数据的schema相同,那如何定义Druid表的schema呢?社区的实现方式是:先通过SegmentMetadataQuery计算每个segment的schema,然后合并segment schema得到表的segment,最后在segment发生变化时重新计算整个表的schema。

社区的实现在我们的场景下遇到了三个问题。第一是Broker启动时间过长。我们一个集群有60万个segment,测试发现光计算这些segment的schema就需要半小时。这会导致Broker启动后,需要等半个小时才能提供服务。第二个问题是Broker需要在内存中缓存所有Segment的元数据,导致常驻内存增加,另外schema刷新会带来很大的GC压力。第三个问题是,社区方案提交的元数据查询量级与Broker和Segment个数的乘积成正比的,因此扩展性不好。

针对这个问题,我们分析业务需求和用法后发现:首先schema变更是一个相对低频的操作,也就是说大部分segment的schema是相同的,不需要去重复计算。另外,绝大数情况业务都只需要用最新的schema来查询。因此,我们的解决方案是,只使用最近一段时间,而不是所有的segment来推导schema。改造后,broker计算schema的时间从半小时降低到了20秒,GC压力也显著降低了。

第二个优化是关于日志和监控。请求日志和监控指标是我们在运维过程中重度依赖的两个工具,比如慢查询的定位、SLA指标的计算、流量回放测试等都依赖日志和监控。但是0.12版本的SQL既没有请求日志,也没有监控指标,这是在上线前必须要解决的问题。我们的目标有两个:首先能记录所有SQL请求的基本信息,例如请求时间、用户、SQL内容,耗时等;其次能将SQL请求和原生的JSON查询关联起来。因为执行层面的指标都是JSON查询粒度的,我们需要找到JSON查询对应的原始SQL查询。

我们的解决方案已经合并到0.14版本。首先,我们会给每个SQL请求分配唯一的sqlQueryId。然后我们扩展了RequestLogger接口,添加了输出SQL日志的方法。下图是一个例子,对于每个SQL请求,除了输出SQL内容外,也会输出它的sqlQueryId,可以用来与客户端的日志做关联。还会输出SQL对应的每个JSON查询的queryId,可以用来和JSON查询做关联分析。

第三个改进虽然比较小,但是对服务的稳定性很重要。我们知道,JSON查询要求用户指定查询的时间范围,Druid会利用这个范围去做分区裁剪,这对提高性能非常重要。但是Druid SQL并没有这方面的限制。用户写SQL经常会忘记加时间范围的限定,从而导致全表扫描,占用大量的集群资源,是一个很大的风险。所以我们添加了对where条件的检查,如果用户没有指定时间戳字段的过滤条件,查询会直接报错。

--

03 Druid Security的实践经验

首先介绍我们在数据安全上面临的问题。当时使用的是0.10版本,这个版本在数据安全上没有任何的支持,所有的API都没有访问控制,任何人都能访问甚至删除所有的数据,这对业务的数据安全来说是一个非常大的隐患。

我们希望实现的目标有五点:所有API都经过认证、实现DB粒度的权限控制、所有数据访问都有审计日志、业务能平滑升级到安全集群、对代码的改动侵入性小。

为了实现这些目标,我们首先调研了Druid在后续版本中新增的安全功能。

1.Druid Security 功能和原理

0.11版本支持了端到端的传输层加密(TLS),能够实现客户端到集群,以及集群各个节点之间的传输层安全。0.12版本引入了可扩展的认证和鉴权框架,并且基于这个框架,提供了BA和Kerberos等认证方式,以及一个基于角色的鉴权模块。

下面这张图介绍认证鉴权框架的原理和配置。

2.Druid Security社区方案缺点

社区方案能满足我们大部分的需求,但还存在一些问题。

第一个问题是我们发现浏览器对BA认证的支持很差。因此对于Web控制台,我们希望走统一的SSO认证。

第二个问题是为了支持业务平滑过渡到安全集群,上线初期必须兼容非认证的请求,当时我们使用的0.12版本没有该功能。

第三个问题是社区基于角色的鉴权模块只提供了底层的管理API,用户直接使用这些API非常不方便。

最后一个问题是社区还不支持审计日志。

针对这些问题,我们做了三个主要的改进。

3.改进

改进一:基于DB的访问控制

首先,为了简化权限的管理,我们引入了DB的概念,并实现了DB粒度的访问控制。业务通过DB的读写账号访问DB中的表。

改进二:自动管理权限DB

通过任务接入平台维护DB和DataSource的映射关系,并在DB和DataSource发生变化时,调用鉴权模块接口更新权限DB。

改进三:支持SSO认证和非认证访问

自定义认证链条,通过SSO认证Filter实现Web控制台的SSO认证,通过非安全访问Filter兜底,兼容非认证的请求。

注意事项

(1)使用0.13以上版本 (或者cherrypick高版本的bugfix)

(2)上线流程

  • 启用basic-security功能,用allowAll兜底
  • 初始化权限DB,创建匿名用户并授权
  • 将allowAll替换为anonymous
  • 逐步回收匿名用户的权限

    (3)上线顺序:coordinator->overlord->broker->historical->middleManager

--

04 总结

1.关于SQL

(1)如果还在用原生的JSON查询语言,强烈建议试一试

(2)社区在不断改进SQL模块,建议使用最新版本

(3)Druid SQL本质上是一个语言翻译层

  • 对查询性能和稳定性没有太大影响
  • 受限于Druid本身的查询处理能力,支持的SQL功能有限

(4) 要留意的坑

  • 大集群的schema推导效率
  • Broker需要等schema初始化后再提供服务(#6742)

2.关于Security

(1)Druid包含一下Security特性,建议升级到最新版本使用

  • 传输层加密
  • 认证鉴权框架
  • BA和Kerberos认证
  • RBAC鉴权

(2)认证鉴权框架足够灵活,可根据自身需求扩展

(3)经历生产环境考验,完成度和稳定性足够好

(4)上线前应充分考虑兼容性和节点更新顺序


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

本文首发于微信公众号“DataFunTalk”


嘉宾介绍:

高大月,Apache Kylin PMC成员,Druid Commiter,开源和数据库技术爱好者,有多年的SQL引擎和大数据系统开发经验。目前在美团点评负责OLAP引擎的内核开发、平台化建设、业务落地等工作。


注:欢迎转载,转载请留言或私信。

Druid SQL和Security在美团点评的实践的更多相关文章

  1. 美团点评SQL优化工具SQLAdvisor开源快捷部署

    美团点评SQL优化工具SQLAdvisor开源快捷部署 git clone https://github.com/Meituan-Dianping/SQLAdvisor.gityum install ...

  2. Apache Kylin在美团点评的应用

      本文原载自大数据杂谈微信公众号. 感谢美团点评工程师高大月撰文并授权转载. 高大月,美团点评工程师,Apache Kylin PMC成员,目前主要在美团点评数据平台负责OLAP查询引擎的建设. 背 ...

  3. 美团点评DBProxy读写分离使用说明

    目的 因为业务架构上需要实现读写分离,刚好前段时间美团点评开源了在360Atlas基础上开发的读写分离中间件DBProxy,关于其介绍在官方文档已经有很详细的说明了,其特性主要有:读写分离.负载均衡. ...

  4. 美团点评基于MGR的CMDB高可用架构搭建之路【转】

    王志朋 美团点评DBA 曾在京东金融担任DBA,目前就职于美团点评,主要负责金融业务线数据库及基础组件数据库的运维. MySQL Group Replication(以下简称MGR),于5.7.17版 ...

  5. 美团点评MySQL数据库高可用架构从MMM到MHA+Zebra以及MHA+Proxy的演进

    本文介绍最近几年美团点评MySQL数据库高可用架构的演进过程,以及我们在开源技术基础上做的一些创新.同时,也和业界其它方案进行综合对比,了解业界在高可用方面的进展,和未来我们的一些规划和展望. MMM ...

  6. 深入详解美团点评CAT跨语言服务监控(七)消息分析器与报表(二)

    CrossAnalyzer-调用链分析 在分布式环境中,应用是运行在独立的进程中的,有可能是不同的机器,或者不同的服务器进程.那么他们如果想要彼此联系在一起,形成一个调用链,在Cat中,CrossAn ...

  7. 深入详解美团点评CAT跨语言服务监控(一) CAT简介与部署

    前言: CAT是一个实时和接近全量的监控系统,它侧重于对Java应用的监控,除了与点评RPC组件融合的很好之外,他将会能与Spring.MyBatis.Dubbo 等框架以及Log4j 等结合,支持P ...

  8. Leaf——美团点评分布式ID生成系统

    背景 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识.如在美团点评的金融.支付.餐饮.酒店.猫眼电影等产品的系统中,数据日渐增长,对数据分库分表后需要有一个唯一ID来标识一条数据或消息,数 ...

  9. 美团点评CAT监控平台研究

    1. 美团点评CAT监控平台研究 1.1. 前言 此文根据我对官方文档阅读并记录整理所得,中间可能会穿插一些自己的思考和遇坑 1.2. 简介 CAT 是基于 Java 开发的实时应用监控平台,为美团点 ...

  10. 饿了么监控系统 EMonitor 与美团点评 CAT 的对比

    背景介绍 饿了么监控系统EMonitor:是一款服务于饿了么所有技术部门的一站式监控系统,覆盖了系统监控.容器监控.网络监控.中间件监控.业务监控.接入层监控以及前端监控的数据存储与查询.每日处理总数 ...

随机推荐

  1. PAT甲级 1001. A+B Format (20)

    题目原文: Calculate a + b and output the sum in standard format -- that is, the digits must be separated ...

  2. iOS 登陆的实现四种方式

    iOS 登陆的实现四种方式 一. 网页加载: http://www.cnblogs.com/tekkaman/archive/2013/02/21/2920218.ht ml [iOS登陆的实现] A ...

  3. Luogu2045 方格取数加强版

    题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变 ...

  4. 【git】idea /git bash命令 操作分支

    1.需求 因为目前要对项目做一些改动,而项目又即将上线,这些新的改动又不需要一起上线,所以这个时候需要在原有的master分支上重新拉出一个分支进行开发. 2.分支操作 打开git bash工具→切换 ...

  5. [C++]Linux之多进程运行代码框架

    声明:如需引用或者摘抄本博文源码或者其文章的,请在显著处注明,来源于本博文/作者,以示尊重劳动成果,助力开源精神.也欢迎大家一起探讨,交流,以共同进步- 0.0  多进程代码框架示例 /* @url: ...

  6. swiper添加了自动滚动效果,然后用手指划过页面,发现自动滚动效果不生效了

    我给swiper添加了自动滚动效果,然后用手指划过页面,发现自动滚动效果不生效了,哪里出了问题呢? 添加参数 autoplayDisableOnInteraction : false,

  7. python深拷贝浅拷贝

    python深拷贝和浅拷贝问题: 什么是深拷贝? (个人理解)深拷贝就是将原有的数据一模一样的拷贝一份,然后存到另一个地址中,而不是引用地址 什么是浅拷贝? (个人理解)就是引用地址 (1)用等于号的 ...

  8. 完成向后台添加用户的ssm项目,完整版

    1:ssm框架整合 1.1添加maven依赖pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns: ...

  9. 树莓派指定静态IP

    1.备份并清空 interfaces 文件 cp /etc/network/interfaces /etc/network/interfaces.bak vi /etc/network/interfa ...

  10. [置顶] Android中使用Movie显示gif动态图

    转载请注明:  http://blog.csdn.net/u012975705/article/details/48717391 在看这篇博文之前对attr自定义属性还是不是很熟的童鞋可以先看看:An ...