写点什么

Apache Kudu 在网易的实践

  • 2021-08-08
  • 本文字数:3179 字

    阅读完需:约 10 分钟

Apache Kudu在网易的实践

本文主要介绍 Apache Kudu 及在网易实时数据采集、维表数据关联、实时数仓 ETL、ABtest 等场景的实践应用。主要内容包括:

  • 系统概述:认识 kudu,理解 Kudu 的系统设计与定位

  • 生产实践:分享网易内部的典型使用场景

  • 遇到的问题:实际使用过程中遇到的问题和问题的排障过程

  • 功能展望:对 Kudu 功能特性的展望

Kudu 定位与架构

Kudu 是一个存储引擎,可以接入 Impala、Presto、Spark 等 Olap 计算引擎进行数据分析,容易融入 Hadoop 社区。Kudu 整合了随机读写和大数据分析能力,具有低延迟的随机读写能力和高吞吐量的批量查询能力。


与 HBase、Casandra 不同,Kudu 要求声明 Schema。Schema 可以为上层计算引擎提供更多元数据,进行计算优化。Kudu 的每个字段有主键、列名和列类型。拿到列类型信息后能够对不同列进行编码和压缩,优化存储空间,减少磁盘开销。Kudu 支持 bitshuffle、运行长度编码、字典编码等列编码方式,这些编码会根据列的类型不同做不同设计。比如对于重复值多、重复值变化不大的数据的压缩率很好。


Kudu 使用列式存储给 Kudu 带来了如下特性:

1. 存储上可以节约空间

2. 可以对查询做更多优化,如将过滤条件下推到 kudu 执行,节约计算资源

3. 支持向量化操作

Kudu 的 Schema 和列存


Kudu 数据存储在 Table 中,Tablet 是 Kudu 的读写单元,Table 内的数据会划分到各个 Tablet 进行管理。


创建 Table 时,需要指定 Table 的分区方式。Kudu 提供了两种类型的分区方式 range partitioning ( 范围分区 ) 、 hash partitioning ( 哈希分区 ),这两种分区方式可以组合使用。分区的目的是把 Table 内的数据预先定义好分散到指定的片数量内,方便 Kudu 集群均匀写入数据和查询数据。范围分区支持查询时快速定位数据,哈希分区可以在写入时避免数据热点,可以适应各个场景下的数据。



Kudu 有管理节点(Master)和数据节点(Tablet Server)。管理节点管理元数据,管理表到分片映射关系、分片在数据节点内的位置的映射关系,Kudu 客户端最终会直接链接数据节点。

 


Kudu 作为分布式系统,为了保障数据可用性和高可用,支持多副本。Kudu 使用 Raft 协议来实现分布式环境下副本之间的数据一致性。Raft 算法数据不依赖其他存储和文件系统,优势在于可以保证服务高可用、服务可用性、一致性的均衡。

Kudu 的 update 设计

Olap 中对 update 的设计会影响到 Olap 性能。update 操作可能引发数据多版本问题和 update 引发的数据 merge 问题。

 



Tablet 是 Kudu 数据读写单元,Tablet 下更细分的数据存储单元是 RowSet。RowSet 有两种, 分别是 MemRowSet 和 DiskRowSet,不同 RowSet 维护了不同组件范围内的数据。内存中的 MemRowSet 在到达一定大小后会刷盘成为 DiskRowSet。




 Kudu 把更新操作当作一条新操作,而不是写一条新日志。更新操作是 Undo/Redo 记录,这些内存中的更新操作会被整合为 DeltaMemstore 持久化。Base 数据、Undo 数据、Redu 数据写在同一个 RowSet 中。这样的存储设计优点是可以在更新时候快速找到数据,缺点是查询时需要确认查询的主键在哪个 RowSet 位置中。

 

Kudu 也使用了 LSM 的结构。Kudu 的 comopaction 有多种:MinorDeltaCompaction、MajorDeltaCompaction、MergingCompaction。



 Kudu 的 update 是一个多版本操作,目的是写入和读取时互相不干扰、不需要读时额外加锁。

小结

Kudu Update 设计特点:

 

• 更新已经 flush 的数据和写入新数据走不通的处理逻辑,原始数据和更新位于同一个 Rowset,不用跨 Rowset 进行 merge

• 通过 base 数据的 RowID 和更新时间戳作为 REDO/UNDO 数据的 key,读取更新高效

• Key 大小固定,存储和比较效率高

• 不需要查询出主键数据也能获取更新数据

• 在大多数使用场景下能够实现更高效的读取

• 如果返回的结果不要求顺序,直接从 RowSet 中读出数据,不用 merge

• 如果更新较少,REDO 会快速 merge 到 base 数据,这时在读取最新数据时,可以不进行 apply REDO 的操作

生产实践

实时数据采集场景

实时数据分析中,一些用户行为数据有更新的需求。没有引入 Kudu 前,用户行为数据会首先通过流式计算引擎写入 HBase,但 HBase 不能支撑聚合分析。为了支撑分析和查询需求,还需要把 HBase 上的数据通过 Spark 读取后写入其他 OLAP 引擎。使用 Kudu 后,用户行为数据会通过流式计算引擎写入 Kudu,由 Kudu 完成数据更新操作。Kudu 可以支持单点查询,也可以配合计算引擎做数据分析。


维表数据关联应用

有些场景中,日志的事件表还需要和 MySQL 内维度表做关联后进行查询。使用 Kudu,可以利用 NDC 同步工具,将 MySQL 中数据实时同步导入 Kudu,使 Kudu 内数据表和 MySQL 中的表保持数据一致。这时 Kudu 配合计算引擎就可以直接对外提供结果数据,如产生报表和做在线分析等。省去了 MySQL 中维度表和数据合并的一步,大大提升了效率。

 

实时数仓 ETL

Kudu 作为分布式数据存储引擎,可以和 Hadoop 生态更好结合,因此在生产中我们采用了使用 Kudu 替换 Oracle 的做法,提升了扩展性。

 

ABTEST

在我们的 ABTest 业务中有两种日志,行为日志和用户分流日志。



架构升级前,我们采用了比较传统的模式,将用户行为日志和用户分流日志分别写入 HDFS 作为存储的 ODS 层,通过 Spark 做清洗、转换后导入 HDFS 作为存储的 DWD 层,再通过 Spark 进行一步清洗、按照时间或其他纬度做简单聚合后写入 DWS 层。

 

这个架构的问题是数据产出时间比较长,数据延迟在天级别。业务方需要更及时地拿到 ABTest 结果。

 


 架构升级后,使用 Kafka 作为 ODS、DWD 层存储。Flink 在 ODS 层数据的基础上继续做一层整理和过滤,写入 DWD 形成明细表数据;DWD 层在 Flink 中做简单聚合后写入 DWS 层,Kudu 在 DWS 层作为数据存储。

 

Flink 开窗口实时修正实验数据,这一操作在 Kudu 完成;超出了 Flink 时间窗口的数据更新则由离线补数据的操作在 Kudu 中完成修正。

 

架构升级后,数据延迟大大降低,能够让 ABTest 业务方更实时地拿到结果。

我们遇到的问题 

问题 1: 节点负载不均衡

一些大表场景下会有负载不均衡问题。Kudu 不会把 range 下的哈希分片当作一张表,而是把整个表的分片当成了平等的表进行处理。而在真实使用场景中,range 基本是时间字段;需要让 range 的 hash 分片更均匀地分布在各节点上,防止数据倾斜。下图是数据倾斜的情况展示:

 


我们的解决方案是实现了一套优化版本的负载均衡算法,这个算法能够把 range 表当作单独的表做负载均衡,解决了数据倾斜。下图是优化后效果:


问题 2: 表结构设计复杂

问题 3: 没有二级索引,只能通过控制主键顺序和分区键来优化某几种查询模式

问题 4: 创建表时需要根据业务场景专门设计表结构

问题 2-4,对业务方要求比较高,经常需要专人介入引导业务方导入数据。为了解决问题,我们内部设计了二级索引来解决上述问题。二级索引可以满足查询性能的要求,同时减少用户设计表时候的复杂度:

 

  • 通过支持二级索引来优化包含非主键列过滤的查询

  • 支持二级索引能够降低业务设计表结构的复杂度

  

社区对二级索引的支持进度 KUDU-2038:Add b-tree or inverted index on value field

Kudu 功能展望

BloomFilter

BloomFilter 成本较低、效率较高。Join 场景下,小表动态生成 BloomFilter 下推到存储层,防止大表在 Join 层做数据过滤。最近的 Kudu 中已经支持了 BloomFilter 作为过滤条件。

灵活分区哈希

Kudu 每个 range 的 hash bucket 数量是固定的。考虑到时间和业务增长,在项目实施前期阶段要给 Kudu 哈希桶数量设置略大,但是数据量较小的场景下过大的分片个数对资源是一种浪费,社区也不推荐 hash bucket 设置得比较大。期望后续 Kudu 可以更灵活地适配 hash bucket 数。

 > KUDU-2671:Change hash number for range partitioning

多行事务

Kudu 暂时不能支持多行事务。目前更新主键需要业务自己实现逻辑检测。

> KUDU-2612:Implement multi-row transactions

Flexible Schema

一些业务场景下业务没有唯一主键,但只希望利用 Kudu 的大批量写入、聚合分析查询的特性。接入业务时 Kudu 对 Schema 的要求比较高,一些业务场景无法支持。

> KUDU-1879:Support table without a primary key


本文转载自:Datafuntalk(ID:datafuntalk)

原文链接:Apache Kudu在网易的实践

2021-08-08 07:003920

评论

发布
暂无评论
发现更多内容

CNStack 2.0:云原生的技术中台

阿里巴巴云原生

阿里云 云原生 技术中台

关于Zebec生态的改进提案,以及即将上线的 Nautilus 链

BlockChain先知

可路由计算引擎实现前置数据库

石臻臻的杂货铺

数据库

Top 5 OSSInsight 年度最佳 MLOps 开源工具

Jina AI

深度学习 开源框架 Jina MLOps OSSInsight.io

NFT铸造系统模式开发定制

开发微hkkf5566

UE干货| UE虚幻引擎调试神器—控件反射器

3DCAT实时渲染

游戏开发 虚幻引擎 ue 游戏开发引擎

真正的低代码平台

陈飞

PaaS SaaS 低代码平台

启科量子解决方案实践:使用QuTrunk+AWS Deep Learning AMI(TensorFlow2)构建量子神经网络

启科量子开发者官方号

人工智能 量子计算

BIGO 如何做到夜间同时运行 2.4K 个工作流实例?

白鲸开源

spark 工作流调度 Apache DolphinScheduler 离线计算

上海前端培训学习的就业前景

小谷哥

前端报表如何实现无预览打印解决方案或静默打印

葡萄城技术团队

单体应用、SOA、微服务,优劣势都有哪些?

FinFish

微服务 微服务架构 前端开发 移动开发 小程序化

新书上市 | 以过去预测未来,有趣的时间序列

图灵教育

机器学习 统计学 时间序列 时间序列预测

新书上市 | 以过去预测未来,有趣的时间序列

图灵社区

机器学习 统计学 时间序列 时间序列预测

点对点传输现状,镭速高速点对点传输解决方案

镭速

前端线下面授培训机构的选择

小谷哥

化繁为简|中信建投基于StarRocks构建统一查询服务平台

StarRocks

数据库 大数据 开源

Apache RocketMQ 入选 SegmentFault 年度中国技术品牌影响力企业榜单!

阿里巴巴云原生

阿里云 Apache RocketMQ

设计模式-工厂方法模式和抽象工厂模式

C++后台开发

数据结构 设计模式 后端开发 Linux服务器开发 C++开发

谷歌用Bard打响了Chat GPT的第一枪,百度版Chat GPT 何时出炉?

GPU算力

大数据培训学习怎么入门

小谷哥

RocketMQ 监控告警:生产环境如何快速通过监控预警发现堆积、收发失败等问题?

阿里巴巴云原生

阿里云 RocketMQ 云原生

速剖架构(一)-- 流量的自然走向

Dinfan

架构设计

基于流量双发平台的高效回归方案

网易云信

反垃圾 业务集群

浅谈 2022 前端工作流中全流程多层次的四款测试工具

Liam

前端 测试 前端开发 测试工具 测试开发

Go1.20新版本正式发布,新特性值得一看

王中阳Go

Go golang 高效工作 学习方法

程序员必备的数据库知识 2:Join 算法

NineData

数据库 程序员 join SQL sever NineData

在这些工厂、农田、服务区,看到智能中国的草蛇灰线

脑极体

人工智能 华为 许昌

干货分享 | UE游戏鼠标双击判定

3DCAT实时渲染

游戏开发 虚幻引擎 ue 游戏开发引擎

干货分享 | 3个Zbrush实用减面工具分享

3DCAT实时渲染

3D渲染 3D模型

《流浪地球2》“数字生命”最后一秒拯救人类,现实中AI也正在“长出”灵魂

硬科技星球

Apache Kudu在网易的实践_语言 & 开发_DataFunTalk_InfoQ精选文章