InfluxDB 和 Kafka:InfluxData 如何在生产环境中使用 Kafka
作者:Anais Dotis-Georgiou / 产品, 用例, 开发者
2019 年 8 月 14 日
导航至
继 CTO Paul Dix 最初发布 InfluxDB 2.0 版本公告以及面向公开 Beta 版发布 InfluxDB Cloud 2.0 新版本之后,我认为社区会对了解 InfluxData 如何提供多租户、水平可扩展的时间序列存储感兴趣。
本系列的第一部分向我们介绍了 Kafka 以及 Kafka 的一些基本概念。我们还了解了 Wayfair 和 Hulu 如何使用 InfluxDB 和 Kafka 创建容错、可扩展、快速的数据管道。事实证明,Hulu 和 Wayfair 并非唯一利用 Kafka 解决方案的公司。InfluxData 在生产环境中使用 Kafka 作为 InfluxDB Cloud 2.0 的高级预写日志,与多家其他公司一样
本博客系列的第二部分包括
- Kafka 解决的问题概述
- Kafka 如何以及为何是好的解决方案
- 内部使用 Kafka 于 InfluxDB Cloud 2.0 的优势总结
什么是 WAL?
预写日志 (WAL) 是几乎所有高性能数据库(包括时间序列数据库)中的常见做法。它是一个日志,一个仅追加的文件,记录了将要对数据库执行的操作。WAL 有几个优点,但它们主要用于在数据库系统中保持写入持久性和原子性。
持久性 – 首先在 WAL 中持久化操作可确保即使数据库崩溃,这些操作也将被执行。通过在 WAL 中记录操作,然后再对内存中的表示形式进行更改,可以在需要时恢复并重新应用这些操作,从而确保写入持久性。
原子性 – 原子性是指数据库系统属性,保证完全发生。如果服务器在执行各种操作时中途崩溃,数据库可以查看 WAL 以查找其停止的位置并完成作业,从而保证作业将完全执行。
此外,采用 WAL 批处理也比每次 WAL 同步执行一次突变快得多,这节省了客户端的长时间等待。包括 Prometheus、Cassandra、Timescale 和 InfluxDB 在内的多家时间序列数据库公司都使用 WAL。但是,WAL 也有一些缺点
- 它们不可扩展,因为它们的大小只能与 RAM 一样大;对于多租户云解决方案的请求量而言,这不够大。
- 虽然 WAL 很快,但还不够快 – Kafka 快得多。
- WAL 的持久性仅与它使用的文件系统一样。没有复制;因此,如果磁盘损坏,您将丢失所有数据。
InfluxDB Cloud 2.0 使用 Kafka 作为 WAL 来克服这些缺点。
InfluxDB Cloud 2.0 和 Kafka 解决的问题 – 从 1.x 到 2.0 的变化
WAL 在 Cloud 1.x 中运行良好,因为它只需要为单个租户扩展。Cloud 2.0 不仅是多租户的,而且 Cloud 2.0 中的存储节点也像 OSS 存储节点一样 – 它们是独立的、独立的存储引擎,彼此之间不通信。尽管如此,Cloud 2.0 更具弹性和稳健性(它为 99% 的级别提供 SLA)。那么,如何实现多租户和高效的水平扩展呢?通过复杂的数据分区。此数据分区由 Kafka 处理。Kafka 分区用作 WAL,Kafka 代理节点提供 InfluxDB Cloud 2.0 所需的持久性、可扩展性和效率。Kafka 充当一个非常大的分布式 WAL。
是什么使 Kafka 成为 InfluxDB Cloud 2.0 的良好解决方案?
InfluxDB Cloud 2.0 满足 InfluxDB Cloud 1.x 未满足的多个要求。InfluxDB Cloud 2.0 包括以下要求里程碑
- 多租户 – 良好地处理集群中的多个租户。处理围绕授权的性能问题。
- 弹性 – 存储层是水平可扩展的。
- 高效 – 存储层应尽可能多地利用跨租户的硬件资源。租户应共享资源。
- 稳健 – 数据完整性应能抵抗故障。
- 容错 – 在必要时(故障、部署等),应易于更换存储层中的节点。
- 隔离 – 租户应无法访问另一个租户的数据或对另一个租户产生不利影响。
Kafka 是一个好的解决方案,因为它通过以下方式帮助 InfluxDB Cloud 2.0 满足这些要求
- 多租户 – 单个数据批次分布在 Topic 内的 Kafka 分区中。每个存储引擎运行一个 Kafka 消费者,其任务是从分区日志中读取消息。由于在 Kafka 的生产者端使用了批处理,因此从分区日志读取的消息通常包含指向多个租户的点。
- 弹性 – 在 InfluxDB Cloud 2.0 平台中,写入路径包含两个主要组件:预写日志和存储引擎。Cloud 2.0 中的 WAL 由 Kafka 分区表示,这些分区是可扩展且经过实战考验的。分区和存储引擎是分布式且可独立扩展的。与 InfluxDB 1.x 中 WAL 和存储引擎在同一进程中不同,在 InfluxDB Cloud 2.0 中,它们是单独的分布式进程。当 WAL 未与存储层分离时,存储层无法独立扩展。如果存储层仅需要支持更重的读取负载,则在写入负载保持不变的情况下同时扩展存储层和 WAL 效率不高。将 WAL 与存储层分离使 InfluxDB Cloud 2.0 能够在需要时有效地仅扩展存储层。
- 高效 – 当客户端将一批点写入 Kafka 层时,数据会分发到拥有分区的 Kafka 生产者,数据会在此处短暂保存,而不会立即写入 Kafka 分区。Kafka 生产者会保留数据,直到生产者有足够大的批次写入。Kafka 生产者在保留增长的批次的同时,还将其他数据批次写入 Kafka 分区 – 使存储引擎能够有效地处理大量数据批次,而不是处理来自单个客户端的小批次数据。此外,当客户端写入 WAL 时,它们不会被阻止等待写入在存储层中变得持久。
- 稳健 – 捕获通过 Kafka 生产者提交的每个写入和删除操作,并将它们以仅追加的方式存档在外部系统上,可以减轻几种可能的缺陷。如果发生缺陷或用户错误,则可以通过将存档的命令重新播放回 WAL 来恢复存储桶。这种架构可防止因不正确的数据序列化、丢弃的写入、拒绝的写入、不正确的压缩、静默删除和意外数据删除(来自用户错误)而引起的任何缺陷。
- 容错 – 存储层旨在容忍 Kafka 层的完全丢失。在这种情况下,存储层仍然可用于读取。每个分区都在多个存储节点上复制,因此该层可以容忍一部分存储节点不可用,而不会影响读取。
- 隔离 – 存储引擎和存储节点在 2.x 中彼此不知道。
InfluxDB Cloud 2.0 存储层架构
让我们看一下 InfluxDB Cloud 2.0 存储层架构,以更好地了解 Kafka 如何帮助 InfluxDB 实现这些要求。
- 点数据通过序列键在分区之间均匀分布。
- 每个分区复制 3 次。因此,丢失一个 Kafka 代理节点不会导致其分区数据丢失。
- 生产者写入单个领导者以负载均衡生产,以便每个写入都可以由单独的代理和机器提供服务。
- Kafka 管理跨节点的复制。客户端只需写入一个节点。此节点是领导者,领导者是按分区划分的。如果节点不可用,则具有副本的节点将成为必要分区的新领导者。
- 存储层的 Write API(未显示)将一批点写入 Kafka 层,数据会在此处保存,直到批次包含最佳数量的点,以确保对分区进行高效写入。
- 多个存储引擎消费同一分区。
- 存储节点有多个存储引擎,每个存储引擎消费一个 Kafka 分区。
- 由于有多个副本数据源可供读取,因此分区的消费可能以不同的速率发生。一个数据源可能领先于另一个数据源。查询层使用存储层的 Kafka 消费进度来确定哪个副本是最新的。具有最高偏移量或日志中最远的分区用于确定查询层应从何处读取,因为它最新。
- 一些存储引擎负责将数据同步到对象存储。
使用 Kafka 作为高级 WAL 的优势总结
使用 Kafka 作为高级 WAL 将 InfluxDB Cloud 转换为水平可扩展且多租户的时间序列数据库。Kafka 既持久又快速。Kafka 的持久性使用户确信用户的写入是安全可靠的。Kafka 的速度消除了瓶颈,并节省了客户端的长时间等待。我希望这篇文章能让您对 InfluxDB Cloud 2.0 或至少对 Kafka 感到兴奋。如果您有任何疑问,请在我们的社区站点或 Slack 频道上发布。