打造更可持续的随叫随到体验(赞助内容)
确保系统可靠性不应以牺牲团队利益为代价。Datadog 的这份实用指南展示了如何设计可持续的轮班值守流程,从而减少员工倦怠并提高响应速度。
获取循序渐进的最佳实践,以便您可以:
-
利用基于信号的监测降低警报噪音
-
通过明确角色和更智能的升级机制简化响应流程
-
设计轮岗制度以支持恢复和长期可持续性
免责声明:本文内容来源于Datadog工程团队和P99大会组织者在网上分享的信息。所有技术细节均归Datadog工程团队所有。原文链接和参考文献位于文末的参考文献部分。我们已尽力分析这些信息并提供我们的观点。如果您发现任何不准确或遗漏之处,请留言,我们将尽力修正。
在云监控领域,Datadog 的运营规模极其庞大。该公司的平台必须每秒从全球数百万台主机上采集数十亿个数据点。
这种持续不断的信息流带来了巨大的工程挑战:如何以既快速又经济高效的方式存储、管理和查询这些数据?
对于 Datadog 工程团队来说,答案是从零开始构建自己的解决方案。
本文将深入探讨 Datadog 工程团队如何构建 Monocle——他们自主研发的时间序列存储引擎,用于驱动其实时指标平台。本文将分析数据库背后的技术决策和巧妙的优化措施。
借助人工智能加速发展:编写值得信赖的代码(赞助内容)
人工智能正在加速开发,但所有这些新代码都造成了瓶颈——谁来验证代码的质量和安全性?不要让新的技术债务和安全风险悄然出现。Sonar 的自动化代码审查功能,无论代码是人工编写还是人工智能生成,都能让您对每一行代码都充满信心。
借助 SonarQube,您的团队可以:
-
安心使用人工智能:持续进行质量和安全分析。
-
及早解决问题:在合并之前检测并应用自动修复程序。
-
保持标准:确保所有代码每次都符合团队的质量标准,以保证代码的长期健康。
立即开始使用 SonarQube,推动 AI 赋能开发,并在所有代码中建立信任。
高级指标平台架构
在深入了解自定义数据库引擎之前,重要的是要了解它在系统中扮演什么角色。
他们定制的引擎名为 Monocle,只是一个更大的“指标平台”中的一个专用组件。该平台是一个完整的系统,负责收集、处理、存储和提供所有客户指标。
单个数据点的旅程始于“指标边缘”。该组件充当入口,接收来自数百万客户系统的海量数据。之后,数据被传递给“存储路由器”。顾名思义,该路由器的主要任务是处理传入数据,并智能地决定其存储位置。
由此,Datadog 的第一个重大设计决策就显而易见了。
Datadog 工程团队意识到并非所有数据查询都相同。例如,工程师查询去年的性能报告与自动警报系统检查过去 30 秒内发生的故障,两者的需求截然不同。为了满足这两种需求,他们将存储拆分为两个规模庞大的专用系统。
-
第一个系统是长期指标存储系统。该系统就像一个庞大的历史档案库,专为高强度分析查询而构建,工程师可能需要分析长达数月甚至数年的性能趋势。
-
第二个系统是实时指标存储系统,也是本文的重点。该系统是一个高速、高性能的引擎,仅存储最新数据,大约是最近 24 小时的数据。虽然这听起来似乎不多,但该系统处理了平台绝大部分的工作负载:99% 的查询。正是这些查询驱动着 Datadog 的实时仪表盘和关键的自动化监控。换句话说,当用户看到屏幕上的图表实时更新时,正是这个系统在发挥作用。
时间序列数据点由两部分组成:
-
数据:这是实际时间戳和正在测量的值。例如 [下午 12:00:01,85.5]。
-
元数据:这些是描述数据是什么的标签,例如 service:api、host:server-10 或 region:us-east-1。
Datadog 工程团队做出了一个关键决定,将这两个部分存储在单独的专用数据库中:
-
索引数据库仅存储标签(元数据)。它的唯一任务就是以极快的速度查找数据。当用户请求“显示美国东部所有服务的 CPU 使用率”时,该索引数据库会立即找到所有与这些标签匹配的唯一数据流。
-
实时时间序列数据库 (RTDB) 仅存储时间戳和值。它是一种高度优化的存储方式,从索引数据库获取流列表后,仅检索原始数值。
使用 Kafka
Datadog 工程团队最独特的架构决策或许在于其数据库集群的组织方式。在许多传统的分布式数据库中,服务器节点(集群中的各个计算机)会不断相互通信。它们通过“聊天”来协调各自的任务,在彼此之间复制数据(这一过程称为数据复制),以及确定在其中一个节点发生故障时该如何应对。
Datadog 的 RTDB 节点不会这样做。
相反,整个系统都是围绕 Apache Kafka 设计的。Kafka 充当中心位置,所有新数据都会先写入 Kafka,然后再写入数据库。这种以 Kafka 为中心的设计是集群稳定性和速度的关键。
请参见下图,图中展示了 RTDB 集群以及 Kafka 的作用:
Datadog 工程团队使用 Kafka 来执行三个关键功能,否则数据库节点必须自己执行这些功能。
-
首先是数据分发。Kafka 中的数据被组织成“主题”(类似于指标),每个主题又被分割成更小的日志,称为“分区”。团队设计的系统使得每个 RTDB 数据库节点都被分配了一组特定的分区进行读取。这样就巧妙地划分了数十亿个传入数据点,而无需节点之间进行任何协调。
-
其次,Kafka 充当预写式日志 (WAL)。这是确保数据安全的一种标准数据库概念。通过使用 Kafka 作为 WAL,Datadog 创建了一个“单一数据源”。如果 RTDB 节点因硬件故障而崩溃,数据不会丢失。当节点重启时,它只需重新连接到 Kafka,找到其上次读取的位置,并补齐所有错过的数据。
-
第三,Kafka 负责数据复制。为了防止数据丢失,您必须在不同的物理位置保留数据副本。团队利用 Kafka 的内置复制功能,自动将数据分区复制到不同的数据中心(称为可用区)。这提供了开箱即用的强大灾难恢复能力。
Monocle:锈蚀中的定制引擎
每个 RTDB 节点的核心是 Monocle,这是 Datadog 自主研发的存储引擎。请参见下图:
团队对性能的追求在此展现得淋漓尽致,令人印象深刻。虽然早期版本的平台使用了功能强大的开源数据库引擎 RocksDB,但团队最终决定自行构建。通过从零开始创建 Monocle,他们可以根据自身特定需求定制每一个决策,从而将效率提升到了一个全新的高度。
Monocle 使用 Rust 编写,Rust 是一种现代编程语言,以其安全性保证和“媲美 C 语言”的性能而闻名。它基于 Tokio 构建,Tokio 是 Rust 生态系统中一个流行的框架,用于编写高速异步应用程序,这些应用程序可以同时处理多个任务而不会出现性能瓶颈。
核心数据模型:哈希标签
Monocle 的关键创新在于其简洁的数据模型。如前所述,时间序列由其标签定义,例如“system.cpu.user”、“host:web-01”和“env:prod”。正是这组标签使得每个序列都独一无二。然而,这些标签集可能很长,搜索起来也很复杂。
Datadog 工程团队极大地简化了这一过程。Monocle 不再处理这些复杂的字符串,而是对系列的所有标签进行哈希处理,将其转换为一个唯一的数字。然后,数据库只需将数据存储在一个简单的映射中:
(Organization, Metric Name, Tag Hash) -> (A list of [Timestamp, Value] pairs)
这种设计速度极快,因为对于任何给定的时间序列,查找所有数据都变成了使用单个哈希值进行直接高效的查找。独立的索引数据库负责人性化的部分:它告诉系统,对 env: prod 的查询对应于特定的“标签哈希值”列表。
《Monocle》杂志内幕
Monocle 的速度主要来自两个方面:它的并发模型和它的存储结构。
Monocle 采用所谓的“单核线程”或“无共享”架构。您可以想象服务器中的每个 CPU 核心都有其专属的工作线程,这些线程完全独立运行。每个工作线程拥有自己的数据、缓存和内存。它们之间没有任何共享。
当 Kafka 接收到新数据时,系统会对其进行哈希处理。然后,系统会将哈希数据发送到拥有该哈希值的特定工作线程的队列中。由于每个工作线程只能访问自己的数据,因此无需使用锁、无需协调、也无需等待。这消除了传统数据库中常见的性能瓶颈,即不同线程通常需要等待彼此才能访问同一条数据。
请看下图:
Monocle 的存储布局采用日志结构合并树(LSM 树)。这种设计对于像 Datadog 这样写入密集型的工作负载来说效率极高。
以下是与 LSM 树相关的主要概念:
-
内存表:所有新数据都以批处理的形式存储在内存中,结构称为内存表。
-
刷新:当内存表已满时,它会被“刷新”到磁盘,成为一个完整的只读文件。系统永远不会修改旧文件。
-
压缩:随着时间的推移,一个名为压缩的后台进程会将这些小文件合并成更大、更有序的文件,从而进行清理。
Datadog 工程团队在此设计中增加了两项关键优化:
-
竞技场分配器:通常情况下,当刷新 Memtable 时,数据库需要从内存中释放数百万个小对象,这是一个缓慢的过程。Monocle 使用自定义的竞技场分配器。这意味着 Memtable 会获得一大块内存(一个竞技场)。操作完成后,整块内存会被一次性释放,效率大大提高。
-
基于时间的文件剪枝:由于 99% 的查询都针对近期数据,Monocle 利用了这一特性。磁盘上的每个文件都有一个已知的时间范围(例如,上午 10:00 至 10:10)。当收到针对最近一小时的查询时,Monocle 可以立即剪枝(忽略)所有不在该时间窗口内的文件。这减少了它需要读取的文件数量,从而找到了答案。
压力下保持速度
采用“每个核心一个线程”的设计来处理如此多的查询,带来了独特的挑战。
由于查询会被分发到所有工作进程,因此它的速度取决于其中速度最慢的工作进程。如果某个工作进程正忙于执行后台任务(例如繁重的数据压缩),则可能会导致其他所有工作进程的查询都无法执行。这是一个经典的计算机科学问题,称为队头阻塞。
为了解决这个问题,团队构建了一个两层系统来管理查询负载并保持响应速度。
-
第一层是准入控制。它就像一道简单的“大门”。如果系统检测到负载过高(例如,从 Kafka 读取数据滞后或内存不足),这道“大门”就会停止接受新的查询。这可以防止数据库过载。
-
第二层是更智能的基于成本的调度系统。该层使用一种名为 CoDel(受控延迟)的知名算法来主动管理延迟。它可以根据查询的成本(即查询需要完成的工作量)来确定查询的优先级,并确保即使在大量且不可预测的查询突发情况下,数据库也能保持响应,不会崩溃。
结论
Datadog 工程团队对 Monocle 的工作远未结束。他们已经在规划平台的下一步发展,其中涉及两项重大变革。
-
更智能的路由:目前的系统虽然有效,但相对静态。团队正在开发一个动态的负载均衡系统,使集群能够实时调配数据。例如,当许多工程师在突发事件期间同时查询同一组指标时,数据库就能自动适应查询“热点”区域。
-
合并点和标签:这是一项根本性的变革。团队计划将两个独立的数据库(索引数据库和实时数据数据库)合并成一个统一的系统。新数据库将不再仅仅存储标签哈希值,而是会将完整的标签字符串与其对应的时间戳和值一起存储。
为了实现这一目标,团队将采用列式数据库格式。
在列式数据库中,数据按列而不是按行存储。这意味着查询只需读取所需的特定标签和值,从而极大地提高了分析速度。
这是一项复杂的工程,可能需要对其“每个核心的线程数”模型进行彻底的重新设计,但这凸显了 Datadog 不断突破性能极限的决心。
参考:
赞助我们
让您的产品触达超过 100 万名科技专业人士。
我们的新闻简报会将您的产品和服务直接推送给重要的受众——数十万名工程领导者和高级工程师——他们对重大的技术决策和大宗采购具有影响力。
名额有限,立即预订!
广告位通常提前约 4 周售罄。为确保您的广告触达这一极具影响力的受众群体,请立即发送电子邮件至[email protected] 预订您的广告位。
原文: https://blog.bytebytego.com/p/how-datadog-built-a-custom-database





