写点什么

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:005918
用户头像

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

关注

评论

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

如何用 Nacos 构建服务网格生态

阿里巴巴云原生

模块一作业

当归

WebRTC中的RefCountedObject解析

她的男人是程序员

关于飞书的告警通知,这里有个更好的办法

睿象云

运维 告警 运维平台 智能告警

使用mock模拟登录接口数据

与风逐梦

大前端 后端 Mock

Go- 切片的使用

HelloBug

Go 语言 切片 追加 拷贝 扩缩容

云原生多云容器编排平台karmada上手指南

谐云

云原生 开源技术

微信业务架构 | 架构实战营

樊江。

架构实战营

阿里巴巴首发:Java核心框架指导手册1小时点击量破千万!

Java 编程 面试 程序人生 Alibaba

通过明道云实现培训机构客户管理

明道云

cocoapods 的主模块如何判断子模块有没有被加载?

fuyoufang

ios swift 8月日更

阿里资深架构师终于把微服务架构与实践第2版PDF分享出来了

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

仿照Hystrix,手写一个限流组件

码农参上

限流 Hystrix 8月日更

如何对接口参数的描述进行集中管理

CodeNongXiaoW

大前端 测试 后端 接口工具

CERT和CWE之间有什么联系?

鉴释

安全编码规范 cwe cert

高可用 | Xenon 实现 MySQL 高可用架构 部署篇

RadonDB

MySQL 数据库 Xenon RadonDB

计算机网络常用知识总结

Java 架构 后端 网络 计算机

【“互联网+”大赛华为云赛道】GaussDB命题攻略:支持三种开发语言,轻松完成数据库缓冲池

华为云开发者联盟

数据库 华为云 GaussDB 互联网+ 缓冲池

关于告警管理的软件,您还只知道Pagerduty吗?

睿象云

运维 告警 运维平台 智能告警 告警管理

浅析智慧交通有哪些应用场景?

一只数据鲸鱼

数据可视化 智慧城市 智慧交通 城市交通

👊 【Spring技术原理】异步编程机制以及功能分析讲解

码界西柚

spring springboot 异步编程 8月日更

Spring 配置加载

樊江。

Spring Framework

Go- 数组

HelloBug

数组 Go 语言

Go- 切片的定义

HelloBug

slice Go 语言 切片

关于C++中“不能返回对象引用”的思考

她的男人是程序员

来!看排名一年上升16位的ClickHouse,如何在京东落地实践

京东科技开发者

数据库 Clickhouse

TCP协议认知篇

邱学喆

TCP协议 拥塞避免算法 慢启动算法 坚持定时器 TCP状图切换

干货!4大实验项目,深度解析Tag在可观测性领域的最佳实践!

观测云

可观测性 dataflux tag ngix

华为18级工程师三年心血终成趣谈网络协议文档(附大牛讲解)

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

打开vscode好像打开了原神?vscode原神背景推荐,比博燃

CodeNongXiaoW

vscode vscode背景 原神

如何从内部保障企业数据安全?用IT运维审计系统可以吗?

行云管家

网络安全 数据安全 堡垒机 IT运维 运维审计

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