大数据实时多维OLAP分析数据库Apache Druid入门分享-上

@

概述

定义

Apache Druid 官网地址 https://druid.apache.org/

Apache Druid 官网最新文档地址 https://druid.apache.org/docs/latest/design/

Apache Druid源码地址 https://github.com/apache/druid

Apache Druid是一个集时间序列数据库(timeseries databases)、数据仓库(data warehouses)和全文检索日志分析系统系统(logsearch systems)特点于一体的分析性数据平台,由MetaMarket公司研发的⼀款针对海量数据进⾏⾼性能实时分析的OLAP引擎的实时分析型数据库(包含存储引擎和分析引擎),捐献给Apache基⾦会。最新版本为25.0.0

注意:此Apache Druid非阿里巴巴开源项目数据库连接池Druid,不要混为一谈。

Apache Druid是一个分布式的、支持实时多维 OLAP 分析、列式存储的数据处理系统,支持高速的实时数据读取处理、支持实时灵活的多维数据分析查询;最常被当作数据库用以支持摄取、高性能查询、高聚和高并发API 、高稳定运行的应用场景。Druid支持根据时间戳对数据进行预聚合摄入和聚合分析,在时序数据处理分析场景中也可以使用Druid。Druid有对应的GUI页面,适用于面向事件类型的数据、实时数据提取、高性能查询场景。

其中OLAP分析分为关系型联机分析处理(ROLAP)和多维联机分析处理(MOLAP),MOLAP需要数据预计算好为一个多维数组,典型方式就是Cube,而ROLAP就是数据本身什么样就是什么样,查询时通过MPP提高分布式计算能力。Druid是ROLAP路线,实时摄取数据,实时出结果,不像Kylin一样,有一个显式的预计算过程。

MPP和Lambda补充说明

  • MPP:俗称大规模并行处理,数据库集群中,每个节点都有独立的磁盘存储系统跟内存系统,业务数据根据数据库模型跟应用特点被划分到各个节点,MPP就是将任务并行分散到多个节点,每个节点计算完毕后将结果汇总下来得到最终结果。
  • Lambda架构:该架构的设计是为了在处理大规模数据时,同时发挥流处理和批处理的优势。通过批处理提供全面、准确的数据,通过流处理提供低延迟的数据,从而达到平衡延迟、吞吐量和容错性的目的。为了满足下游的即席查询,批处理和流处理的结果会进行合并。一般有三层。
    • Batch Layer:批处理层,对离线的历史数据进行预计算。
    • Speed Layer:加速处理层,处理实时的增量数据。
    • Serving Layer:合并层,计算历史数据和实时数据都有了。

概述

  • 构建快速和现代化云原生、流原生的实时分析型数据库:Druid 是为快速查询和快速摄入数据的工作流而设计的;Druid 有强大的 UI,运行时可操作查询,支持高并发性,通常用于需要交互式、一致的用户体验。
  • 与现有数据管道轻松集成:Druid从Kafka和Amazon Kinesis等消息队列传输数据,从数据湖(HDFS、Amazon S3等)批量加载文件。Druid支持最流行的结构化和半结构化数据文件格式。
  • 在高并发性下进行快速、一致的查询:Druid 对数据摄入和数据查询的基准性能测试大大超过了传统解决方案,结合了新颖的存储思想、索引结构以及精确和近似查询,实现亚秒级查询。
  • 广泛的适用性:Druid是专为实时和历史数据的快速临时查询而构建;Druid为点击流、APM(应用性能管理系统)、供应链、网络遥测、数字营销、风险/欺诈和许多其他类型的数据等场景解锁了新的查询类型和工作流;场景详细说明如下:
    • 用户活动和行为:Druid 经常用在点击流,访问流和活动流数据上。具体场景包括:衡量用户参与度,为产品发布追踪 A/B 测试数据,并了解用户使用方式。Druid 可以做到精确和近似计算用户指标,例如不重复计数指标、日活用户指标(平均精度 98%)。Druid 可以用来做“漏斗分析”,测量有多少用户做了某种操作,没做某些操作。这对产品追踪用户注册十分有用。
    • 网络流:Druid 常常用来收集和分析网络流数据。Druid 被用于管理以任意属性切分组合的流数据。Druid 能够提取大量网络流记录,并且能够在查询时快速对数十个属性组合和排序,这有助于网络流分析。这些属性包括一些核心属性,如 IP 和端口号,也包括一些额外添加的强化属性,如地理位置、服务、应用、设备和 ASN。
    • 数字营销:Druid 常常用来存储和查询在线广告数据。这些数据通常来自广告服务商,它对衡量和理解广告活动效果,点击穿透率,转换率(消耗率)等指标至关重要。Druid 最初就是被设计成一个面向广告数据的强大的面向用户的分析型应用程序。在存储广告数据方面,Druid 已经有大量生产实践,全世界有大量用户在上千台服务器上存储了 PB 级数据。
    • 应用性能管理:Druid 常常用于追踪应用程序生成的可运营数据;和用户活动使用场景类似,这些数据可以是关于用户怎样和应用程序交互的,它可以是应用程序自身上报的指标数据。Druid 可用于下钻发现应用程序不同组件的性能如何,定位瓶颈和发现问题。不像许多传统解决方案,Druid 具有更小存储容量、更小复杂度、更大数据吞吐的特点。它可以快速分析数以千计属性的应用事件,并计算复杂的加载、性能、利用率指标。比如基于95 %查询延迟的 API 终端。可以以任何临时属性组织和切分数据,如以天为时间切分数据、以用户画像统计、按数据中心位置统计。
    • 物联网和设备指标:Driud 可以作为时间序列数据库解决方案,来存储处理服务器和设备的指标数据。收集机器生成的实时数据,执行快速临时的分析,去估量性能、优化硬件资源和定位问题。和许多传统时间序列数据库不同,Druid 本质上是一个分析引擎。Druid 融合了时间序列数据库、列式分析数据库和检索系统的理念。它在单个系统中支持了基于时间分区、列式存储和搜索索引。基于时间的查询、聚合和检索过滤查询都会特别快。可以在指标中包括百万唯一维度值,并随意按任何维度组合 group 和 filter(Druid 中的 dimension 维度类似于时间序列数据库中的 tag)。可以基于 tag group 和 rank,并计算大量复杂的指标。而且在 tag 上检索和过滤会比传统时间序列数据库更快。
    • OLAP 和商业智能:Druid 经常用于商业智能场景。加速查询和增强应用。和基于 Hadoop 的 SQL 引擎(如 Presto 或 Hive)不同,Druid 为高并发和亚秒级查询而设计,通过 UI 强化交互式数据查询。这使得 Druid 更适合做真实的可视化交互分析。
  • 部署在公共、私有和混合云中:Druid可以部署在任何*NIX环境的商用硬件上,无论是在云中还是在内部;部署Druid都是很容易,通过添加和删除Druid服务实现扩缩容。

特征

Druid主要的优点在于支持流式和批量数据的导入、高并发亚秒级查询、存储索引优化。

  • 低延迟交互式查询:Druid提供低延迟实时数据摄取(⼊库),并采⽤预聚合、列式存储、位图索引等⼿段使得海量数据分析能够亚秒级响应。

  • ⾼可⽤性( High Available ):Druid 使⽤ HDFS/S3 作为 Deep Storage,Segment 会在多个Historical 节点上进⾏加载;摄取数据时也可以多副本摄取,保证数据可⽤性和容错性。

  • 可伸缩( Horizontal Scalable ):Druid 部署架构都可以⽔平扩展,增加⼤量服务器来加快数据摄取,在生产环境中可以部署到数十台多数百台服务器组成的集群中,可以提供每秒百万条数据的写入,针对万亿条记录保证亚秒级的查询。

  • 大规模并⾏处理( Parallel Processing ): Druid 可以在整个集群中并⾏处理查询。

  • 丰富的查询能⼒( Rich Query ):Druid⽀持时间序列、 TopN、GroupBy等查询,同时提供了2种查询⽅式:API 和 SQL。除了原生的基于 JSON 的查询外,Druid 还支持基于 HTTP 和 JDBC 的 SQL。

  • 列式存储:Druid使用面相列的存储,对于OLAP分析需要读取列分析的场景加快了速度,同时一列数据中有很多共性的数据,数据的压缩效果好,占用空间小,支持快速扫描及聚合查询。

  • 支持实时或者批量读取数据:Druid支持实时获取数据,实时获取的数据可以实时查询,也支持批量读取数据。

  • 集群自动平衡,方便运维:Druid集群扩大或者缩小时,只需要增加或者减少对应的机器数,Druid集群自动会平衡各个节点,不需要停机。

  • 对数据进行预聚合或预计算:Druid可以人为指定按照某些时间粒度对相同维度的数据进行在数据摄取阶段预聚合计算,既加快了查询速度,也减少了数据存储空间。

  • 近似算法:Druid 应用了近似 count-distinct、近似排序以及近似直方图和分位数计算的算法,这些算法占用有限的内存使用量,通常比精确计算要快得多;对于精度要求比速度更重要的场景,Druid还提供了精确 count-distint 和精确排序。

  • bitmap索引快速过滤:Druid中可以通过bitmap构建索引,对数据进行压缩,加快查询过滤速度。

  • 基于时间的分区:Druid 首先按时间对数据进行分区,另外同时可以根据其他字段进行分区,这意味着基于时间的查询将仅访问与查询时间范围匹配的分区,这将大大提高基于时间的数据的性能。

  • 不会丢失数据的云原生容错架构:一旦 Druid 摄取了数据,副本就安全地存储在深度存储介质 (通常是云存储、HDFS 或共享文件系统)中。即使某个 Druid 服务发生故障,也可以以从深度存储中恢复效据,对于仅影响的少数 Druid 服务的有限故障,副本可确保在系统恢复时仍然可以进行查询。

  • 灵活的数据模式:Druid 优雅地适应不断变化的数据模式和嵌套数据类型。

此外Druid也有不足之处,比如:

  • 有限的join能力,Druid适用于清洗好的数据实时写入,不需要更新数据,所以数据在写入Druid之前一般需要拉宽处理,在从Druid中查询数据时,直接查询这张宽表即可;在join右侧的表都会自动存放内存再做关联,这样会降低性能;
  • 不支持多时间维度,所有维度为String类型。
  • 不支持精准去重。

适用场景

如果使用场景符合下面的一些特性,那么Druid 将会是一个非常不错的选择:

  • 数据的插入频率非常高,但是更新频率非常低。
  • 大部分的查询为聚合查询(aggregation)和分组报表查询(reporting queries);例如我们常使用的 "group by" 查询,同时还有一些检索和扫描查询。
  • 查询的延迟被限制在 100ms 到 几秒钟之间。
  • 具有时间属性(Druid 针对时间做了特殊优化和设计)。
  • 在多表场景下,每次查询仅命中一个大的分布式表,查询又可能命中多个较小的 lookup 表。
  • 场景中包含高基维度数据列(例如 URL,用户 ID 等),并且需要对其进行快速计数和排序。
  • 需要从 Kafka、HDFS、文本文件或者对象存储(例如,AWS S3)中载入数据。

不适用场景

如果使用场景是下面的一些情况的话,Druid 不是一个较好的选择:

  • 根据主键对现有数据进行低延迟更新操作,Druid 支持流式插人,但不支持流式更新(更新操作通过后台批处理作业完成)。
  • 不太关注延迟的离线数据系统,查询的延迟不是系统设计的重要考虑。
  • 使用场景中包括大连接(将一个大事实表连接到另一个大事实表)且可以接受花费较长时间查询响应。

横向对比

image-20230131135956719

  • Druid:是一个实时处理时序数据的OLAP数据库,因为它的索引首先按照时间分片,查询的时候也是按照时间线去路由索引。适合预聚合模型,不适合即席查询分享,不支持多事实表JOIN,不适合明细查询。
  • Kylin:核心是Cube,Cube是一种预计算技术,基本思路是预先对数据作多维索引,查询时只扫描索引而不访问原始数据从而提速。不适合即席查询(提前定于模型预聚合,预技术量大),不支持明细查询,外部依赖较多,不支持多事实表Join。
  • Presto:它没有使用MapReduce,大部分场景下比Hive快一个数量级,其中的关键是所有的处理都在内存中完成。不支持预聚合,自己没存储。
  • Impala:基于内存运算,速度快,支持的数据源没有Presto多。不支持预聚合,自己没存储。
  • Spark SQL:基于Spark平台上的一个OLAP框架,基本思路是增加机器来并行计算,从而提高查询速度。
  • ElasticSearch:最大的特点是使用了倒排索引解决索引问题。根据研究,ES在数据获取和聚集用的资源比在Druid高。不支持预聚合,不适合超大规模数据处理,组合查询性能欠佳。
  • ClickHouse:C++编写的高性能OLAP工具,不支持高并发,数据量超大会出现瓶颈(尽量选择预聚合出结果表),非常吃CPU资源,支持MVCC。

框架选型:从超大数据的查询效率来看 Druid > Kylin > Presto > Spark SQL,从支持的数据源种类来讲 Presto > Spark SQL > Kylin > Druid。

部署

单机部署

# 下载apache-druid最新版本25.0.0
wget https://dlcdn.apache.org/druid/25.0.0/apache-druid-25.0.0-bin.tar.gz
# 下载兼容hadoop3的apache-druid最新版本25.0.0
wget https://dlcdn.apache.org/druid/25.0.0/apache-druid-25.0.0-hadoop3-bin.tar.gz
# 解压文件
tar -xvf apache-druid-25.0.0-bin.tar.gz
# 进入目录
cd apache-druid-25.0.0

image-20230131150345801

  • bin:工具脚本
  • conf:配置文件
  • extensions:druid的扩展包
  • hadoop-dependencies:druid的hadoop依赖包
  • lib:核心依赖包
  • licenses:licenses文件
  • quickstart:快速启动相关文件,包含示例数据
# 单机启动druid
./bin/start-druid -m 16g

image-20230131152024903

启动后在druid的根目录下产生两个目录,一个log和一个var。所有持久状态如集群元数据存储和服务段都保存在Druid根目录下的var目录中;每个服务写入var/sv下的日志文件,可以通过删除整个var目录将Druid恢复到安装后的原始状态。

image-20230131152931041

访问Druid的控制台页面:http://192.168.5.52:8888/

image-20230131153308964

入门示例

拿官方提供quickstart的示例数据文件来演示

image-20230131163104678

在“查询”视图中,单击“连接外部数据”。选择“本地磁盘”,输入值(分别输入基本目录和通配符文件过滤器(由UI提供),允许您一次指定要摄入的多个文件)后单击连接数据。

image-20230131172255098

在Parse页面上在将数据加载到Druid之前可以检查原始数据和执行操作

image-20230131163627727

单击Done返回到Query视图,该视图显示新生成的查询,查询将样例数据插入到名为wikipedia(原来为wikiticker-2015-09-12-sampled,修改表名)的表中。

生成SQL如下

REPLACE INTO "wikipedia" OVERWRITE ALL
WITH "ext" AS (SELECT *
FROM TABLE(
  EXTERN(
    '{"type":"local","baseDir":"quickstart/tutorial/","filter":"wikiticker-2015-09-12-sampled.json.gz"}',
    '{"type":"json"}',
    '[{"name":"time","type":"string"},{"name":"channel","type":"string"},{"name":"cityName","type":"string"},{"name":"comment","type":"string"},{"name":"countryIsoCode","type":"string"},{"name":"countryName","type":"string"},{"name":"isAnonymous","type":"string"},{"name":"isMinor","type":"string"},{"name":"isNew","type":"string"},{"name":"isRobot","type":"string"},{"name":"isUnpatrolled","type":"string"},{"name":"metroCode","type":"long"},{"name":"namespace","type":"string"},{"name":"page","type":"string"},{"name":"regionIsoCode","type":"string"},{"name":"regionName","type":"string"},{"name":"user","type":"string"},{"name":"delta","type":"long"},{"name":"added","type":"long"},{"name":"deleted","type":"long"}]'
  )
))
SELECT
  TIME_PARSE("time") AS "__time",
  "channel",
  "cityName",
  "comment",
  "countryIsoCode",
  "countryName",
  "isAnonymous",
  "isMinor",
  "isNew",
  "isRobot",
  "isUnpatrolled",
  "metroCode",
  "namespace",
  "page",
  "regionIsoCode",
  "regionName",
  "user",
  "delta",
  "added",
  "deleted"
FROM "ext"
PARTITIONED BY DAY

单击Run执行查询。这个任务可能需要一两分钟才能完成。完成后,任务将显示其持续时间和插入到表中的行数。视图被设置为自动刷新,因此不需要刷新浏览器就能看到状态变化。

image-20230131172001331

输入SQL,点击运行查询数据

SELECT
  channel,
  COUNT(*)
FROM "wikipedia"
GROUP BY channel
ORDER BY COUNT(*) DESC

image-20230131172545737

也可以使用Druid SQL API提交和取消Druid SQL查询。Druid SQL API可以在https://ROUTER:8888/druid/v2/sql上找到,其中ROUTER是Druid ROUTER的IP地址.

curl -XPOST -H'Content-Type: application/json' http://localhost:8888/druid/v2/sql/ -d @wikipedia-top-pages-sql.json

image-20230131180123024

Druid的原生查询语言是基于HTTP的JSON,可以查看wikipedia-top-pages.json的内容

image-20230131225149365

{
  "queryType" : "topN",
  "dataSource" : "wikipedia",
  "intervals" : ["2015-09-12/2015-09-13"],
  "granularity" : "all",
  "dimension" : "page",
  "metric" : "count",
  "threshold" : 10,
  "aggregations" : [
    {
      "type" : "count",
      "name" : "count"
    }
  ]
}

可以通过http请求也可以通过druid控制台查询

curl -X POST 'http://localhost:8888/druid/v2/?pretty' -H 'Content-Type:application/json' -H 'Accept:application/x-jackson-smile' -d @wikipedia-top-pages.json

image-20230131225047677

  • 本人博客网站IT小神 www.itxiaoshen.com
posted @ 2023-01-31 23:16  itxiaoshen  阅读(874)  评论(0编辑  收藏  举报