AI实践哪家强?来 AICon, 解锁技术前沿,探寻产业新机! 了解详情
写点什么

eBay 是如何进行大数据集元数据发现的

作者:Satbeer Lamba, Sudeep Kumar

  • 2019-02-03
  • 本文字数:3360 字

    阅读完需:约 11 分钟

eBay是如何进行大数据集元数据发现的

很多大数据系统每天都会收集数 PB 的数据。这类系统通常主要用于查询给定时间范围内的原始数据记录,并使用了多个数据过滤器。但是,要发现或识别存在于这些大型数据集中的唯一属性可能很困难。


在大型数据集上执行运行时聚合(例如应用程序在特定时间范围内记录的唯一主机名),需要非常巨大的计算能力,并且可能非常慢。对原始数据进行采样是一种发现属性的办法,但是,这种方法会导致我们错过数据集中的某些稀疏或稀有的属性。

介绍

我们在内部实现了一个元数据存储,可以保证实时发现大量来自不同监控信号源的所有唯一属性(或元数据)。它主要依赖于后端的 Elasticsearch 和 RocksDB。Elasticsearch 让聚合可以查找在一个时间范围内的唯一属性,而 RocksDB 让我们能够对一个时间窗口内具有相同哈希的数据进行去重,避免了冗余写入。


我们提供了三种监控信号源的元数据发现:指标、日志和事件。

指标

指标是周期性的时间序列数据,包含了指标名称、源时间戳、map 形式的维度和长整型数值,例如 http.hits 123456789034877 host=A。


在上面的示例中,http.hits 是指标名称,1234567890 是 EPOC UTC 时间戳,34877 是长整型数值,host=A 是维度{K,V}键值对。我们支持发现指标名称和带有维度 map 的名称空间。

日志

日志是来自各种应用程序或软件/硬件基础设施的日志行。


我们用以下格式表示日志:



日志对用例(也称为名称空间)来说总是可发现的。每个日志行都可以是某种特定类型,例如 stdout 或 stderr。


日志信号的类型(也称为名称)也是可发现的,如上例所示,键值 map 也是可发现的。

事件

事件类似于日志和指标。它们可以被视为一种稀疏指标,表示为系统内的事件。它们是非周期性的。例如,路由器交换机变为不可用时会被记录为事件。此外,它们可能会有点冗长,可能会包含大量的文本信息用以说明事件期间发生了什么。


事件的一个简单示例:



与日志和指标类似,事件也有名称空间和名称,两者都是可发现的。可发现的字段键让我们能够在已知字段上执行聚合操作,例如 MIN、MAX 和 COUNT。


下面的截图突出显示了我们的产品控制台中的发现属性:


方法和设计

所有监控信号最初都由我们的 ingress 服务实例负责接收。这些服务节点使用自定义分区逻辑将不同的输入监控信号(日志、指标和事件)推送到 Kafka 数据总线主题上。元数据存储 ingress 守护程序负责消费这些监控信号,然后将它们写入到后端 Elasticsearch。



我们收集的监控信号被推送到 Kafka 总线上,它们是我们的源数据流。Kafka 的一个优点是它提供了持久存储,即使下游管道处于维护或不可用状态。我们还在入口服务上使用自定义 Kafka 分区器,以确保具有相同哈希值的键始终位于相同的 Kafka 分区上。不同的监控信号内部使用不同的哈希值。例如,我们使用基于名称空间+名称的哈希值来表示指标信号,而日志信号则使用了基于“名称空间+维度{K,V}”的哈希值。这种分组有助于降低下游 Kafka 消费者需要处理的数据量基数,从而有效地减少内存占用总量。


与我们的元数据存储入口守护进程类似,还有其他一些消费者将原始监控信号写入到后端存储,如 Hadoop、HBase、Druid 等。单独的发现管道可以在随后将这些原始监控信号输出,而无需执行昂贵的运行时聚合。


我们使用 RocksDB 作为元数据存储的嵌入式数据缓存,避免了对后端 Elasticsearch 数据接收器的重复写入。我们之所以选择 RocksDB,是因为它的基准测试结果非常令人满意,并且具有很高的配置灵活性。


元数据存储入口守护程序在处理记录时,会将记录的键哈希与高速缓存中已存在的哈希进行对比。如果该记录尚未加载到缓存中,就将它写入 Elasticsearch,并将其哈希键添加到缓存中。如果记录已存在于缓存中,则不执行任何操作。


RocksDB 缓存偏重于读取,但在刚开始时(重置缓存)时出现了一连串写入。对于当前负载,读取超过了 50 亿,以及数千万的写入,大部分写入发生在前几分钟。因此,在刚开始时可能存在消费者滞后的情况。对于较低的读写延迟,我们努力将所有缓存数据保存在 RocksDB 的内存中,以避免二次磁盘存储查找。我们还禁用了预写日志(WAL)和压缩。在基准测试中,我们发现 16GB 的内存就足以存储哈希值。



上图表示写入后端 Elasticsearch 的文档数。峰值对应于重置高速缓存之后的那段时间。


出于监控的目的,我们将所有 rocksDB 统计数据作为指标发送到我们的监控平台中。


我们使用 Elasticsearch 6.x 为后端聚合提供支持,用以识别监控信号中的不同属性。我们构建了一个包含 30 个节点的 Elasticsearch 集群,这些节点运行在配备了 SSD 和 64 GB RAM 的主机上,并通过我们的内部云平台来管理它们。我们为 Elasticsearch JVM 进程分配了 30 GB 内存,其余的留给操作系统。在摄取数据期间,基于监控信号中的不同元数据对文档进行哈希,以便唯一地标识文档。例如,根据名称空间、名称和不同的维度{K,V}对日志进行哈希处理。文档模型采用了父文档与子文档的格式,并按照名称空间和月份创建 Elasticsearch 索引。


我们根据{K,V}维度对根文档或父文档的 document_id 进行哈希处理,而子文档则根据名称空间、名称和时间戳进行哈希处理。我们为每一个时间窗口创建一个子文档,这个时间窗口也称为去抖动时段。去抖动时间戳是去抖动时段的开始时间。如果在去抖动期间发现了一个子文档,这意味着子文档的名称空间和名称的唯一组合与其父文档拓扑会一起出现。去抖动时间越短,发现唯一属性的时间近似就越好。Elasticsearch 索引中的父文档和子文档之间存在 1:N 的关联关系。



Elasticsearch 中的父子文档动态模板是这样的:



子文档的模板是这样的:



我们为 Elasticsearch 集群维护了两个负载均衡器(LB)。READ LB IP(VIP)用于客户端节点,负责所有的读取操作,WRITE LB VIP 则用于数据节点。这样有助于我们在不同的客户端节点上执行基于聚合的计算,而不会给数据节点造成太大压力。


如果你要频繁更新同一个文档,那么 Elasticsearch 不是最好的选择,因为文档的片段合并操作非常昂贵。在出现高峰流量时,后台的文档片段合并会极大地影响索引和搜索性能。因此,我们在设计文档时将其视为不可变的。


我们使用以下的命名法为 Elasticsearch 集群创建索引:



例如,以下是后端 Elasticsearch 服务器的索引:



我们按照月份来维护索引,并保留三个月的索引。如果要清除索引,就直接删除它们。


我们的发现服务是一个作为 Docker 镜像进行部署的 Web 应用程序,它公开了 REST API,用于查询后端元数据存储。


发现服务提供的关键 REST API 包括:


  • 在不同的监控信号(日志/事件/指标)上查找名称空间(或用例);

  • 查找给定时间范围内名称空间的所有名称;

  • 根据输入的名称空间、名称列表或给定的时间范围查找所有监控信号的维度键值;

  • 根据输入的名称空间和给定时间范围查找值键;

  • 根据输入维度{K,V}过滤器查找所有名称空间或名称;

  • 对于给定的名称空间、名称和不同的维度过滤器,还可以根据该唯一输入组合找到其他关联维度。


我们的元数据存储入口守护程序部署和托管在内部 Kubernetes 平台(也称为Tess.io)上。元数据存储入口守护程序的应用程序生命周期在 Kubernetes 上作为无状态应用程序进行管理。我们的托管 Kubernetes 平台允许在部署期间自定义指标注解,我们可以在 Prometheus 格式的已知端口上发布健康指标。监控仪表盘和警报是基于这些运行状况指标进行设置的。我们还在发现服务上公开了类似的指标,以捕获错误/成功率和平均搜索延迟。

性能

  • 我们能够在 10 个元数据入口守护进程节点(下游 Kafka 消费者)上每分钟处理 160 万个指标信号而不会出现任何性能问题;

  • 可以在几秒钟之内发现任何唯一的元数据属性;

  • 在我们的生产环境中,我们的去抖动窗口间隔设置为 12 小时,在每个去抖动期间,我们拥有约 4,000 万的唯一基数(最多可达 6000 万)。



目前,我们发现生产环境中触发的大多数查询的平均延迟为 100 毫秒。而且我们发现,跨名称空间触发的查询比基于目标名称空间的查询要慢得多。


结论

将发现功能与实际数据管道分离让我们能够快速深入了解原始监控数据。元数据存储有助于限制需要查询的数据范围,从而显著提高整体搜索吞吐量。这种方法还可以保护原始数据存储免受发现服务的影响,从而为后端存储节省了大量的计算资源。


查看英文原文:https://www.ebayinc.com/stories/blogs/tech/an-approach-for-metadata-store-on-large-volume-data-sets/


2019-02-03 08:005950
用户头像

发布了 731 篇内容, 共 468.8 次阅读, 收获喜欢 2007 次。

关注

评论

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

星环科技大数据与人工智能应用研究与案例分享

星环科技

人工智能 大数据 数据分析 数据开发 技术专题合集

DevTools 实现原理与性能分析实战

vivo互联网技术

chrome 前端 Web

单体应用与微应用典型架构比对

编程江湖

架构

【CSS 学习总结】第七篇 - CSS 布局-居中布局-水平居中布局

Brave

CSS 12月日更

ONES CTO 冯斌:如何在终身学习中跳出「恐慌区」

万事ONES

ONES

Kubernetes容器平台架构之道

巨子嘉

云计算 Kubernetes 云原生

Angular 变化检测详解

PingCode研发中心

angular

🍃【Spring专题】「技术原理」Spring Security的核心功能和加载运行流程的原理分析

码界西柚

spring spring security 框架搭建 12月日更

撬动百亿VRAR产业,让VR们“造”起来

华为云开发者联盟

AR vr 数字人 元宇宙 VR开发应用

带你掌握二进制SCA检测工具的短板及应对措施

华为云开发者联盟

测试 二进制 漏洞 二进制SCA检测

ONES 事记|ONES 参与信通院牵头编写的《DevOps 通用效能度量模型》

万事ONES

SaaS SaaS平台

软件开发中的常见的15个定律和原则释义及应用

码语者

软件开发原则 软件开发定律

网易有道 | REDIS 云原生实战

有道技术团队

redis

年终招聘

张老蔫

28天写作

Nocalhost:云原生开发新体验

CODING DevOps

云原生 Nocalhost

恒源云(GPUSHARE)_语音识别与语义处理领域之[机器翻译] 21.7 mRASP2

恒源云

深度学习 机器翻译 语音识别

如何让 Spring Security 「少管闲事」

mzlogin

Java spring spring security

在线JSON转JAVA工具

入门小站

工具

大数据开发之Hive SQL内置函数

@零度

大数据 Hive SQL

Java的异常处理

海拥(haiyong.site)

28天写作 12月日更

【转】Node进阶篇之基于 gRPC 协议的 Node 服务

@零度

前端开发 Node

起点决定高度:ONES 如何践行软件标准化

万事ONES

ONES 软件工具 企业管理软件

如何快速搭建一个简单的固资管理系统

全象云低代码

开源 前端 低代码 资管系统 低代码平台

架构实战营 4 期 - 第 3 周作业

周念

「架构实战营」

CNCC 演讲实录| 焱融 YRCloudFile 在 AI 训练中的性能优化实践

焱融科技

云计算 AI 云原生 高性能 文件存储

梦想总是要有的 - 工作20年程序员的2021年度总结

万俊峰Kevin

程序员 微服务 年终总结 年度总结 Go 语言

今天谈谈用户故事地图,不是用户故事

华为云开发者联盟

DevOps 敏捷 开发 用户故事 用户故事地图

Linux之locate命令

入门小站

Linux

Shell脚本好学吗?看看这个带你了解shell中色彩处理和awk使用技巧

学神来啦

Linux Shell linux运维 awk linux云计算

EasyAds:曾经自研的广告聚合SDK,如今在开源平台中唾手可得

EasyAds

sdk 聚合sdk 广告sdk 聚合广告sdk

Kubernetes API server工作原理

汪子熙

Kubernetes k8s 28天写作 docker image 12月日更

eBay是如何进行大数据集元数据发现的_大数据_InfoQ精选文章