简化InfluxDB:数据分片和保留策略
作者:Margo Schaedel / 产品,用例,开发者
2018年6月5日
导航到
我最近做了一场关于InfluxDB和Telegraf的入门网络研讨会,在准备过程中,我痛苦地意识到,关于InfluxDB的许多概念对我来说仍然相当神秘。现在,如果你和我一样,数据库和数据存储可能不是你的强项。(如果它们是你的强项,偶尔回顾一下也无妨)。我以为我对InfluxDB作为一个时序数据存储器有相当深入的了解,但现在我发现,它比表面上的东西要多得多。巧合的是,InfluxDB的内部工作原理对我们社区的一些人来说也很神秘,因此有了这篇博客文章。在这篇指南(或类似的文章)中,我们将试图理解InfluxDB周围一些更加神秘的概念——特别是与保留策略、分片组以及分片有关的概念。我们将探讨它们是什么以及它们之间的关系。
在进入正题之前
如果你是时间序列数据库领域的初学者,或者这是你第一次阅读关于InfluxDB的内容,你可能需要做一些轻松的阅读,并获取一些背景知识。以下是一些有用的资源,可以帮助你了解情况:
保留策略
让我们首先解决保留策略。时序数据按其本质开始迅速堆积,当数据不再有用时删除旧数据可能很有帮助。保留策略提供了一种简单而有效的方式来实现这一点。它相当于数据的一个“过期”日期。一旦数据“过期”,它将自动从数据库中删除,这个动作通常被称为保留策略执行。但是,当需要删除数据时,InfluxDB并不只是逐个删除数据点;它将删除整个分片组。
分片组
碎片组是一个用于存储碎片的容器,而碎片中则包含实际的时间序列数据(关于这一点稍后再详细说明)。每个碎片组都对应一个保留策略,并且同一碎片组内的所有碎片都遵循相同的保留策略。此外,每个碎片组还有一个碎片组持续时间,它定义了每个碎片组覆盖的时间范围(时间间隔)。可以在配置保留策略时指定时间间隔。如果没有指定,碎片组持续时间默认为7天。
碎片
当我们考虑典型的时间序列数据库时,存储和查询的数据量很大,这要求我们采用一种不同的方法来对这些数据进行分类。这就是碎片发挥作用的地方。碎片是时间序列数据的理想容器。在InfluxDB中对数据进行碎片化可以提供一个高度可扩展的方法来提高吞吐量和整体性能,尤其是考虑到时间序列数据库中的数据很可能会随着时间的推移而增长。
碎片包含时间数据块,并映射到底层存储引擎数据库。InfluxDB的存储引擎称为TSM(时间结构合并树),它与LSM树非常相似。TSM文件是包含编码和压缩时间序列数据的文件,它们在碎片中组织。
所有碎片都属于单个碎片组,并且它们的时间间隔都在碎片组的时间间隔内。在InfluxDB的开源版本中,每个碎片组可以只有一个碎片,或者在多节点集群中经常出现的每个碎片组可以有多个碎片。
回到保留策略
暂时回到保留策略,让我们更详细地看看它们是如何结合在一起的。当你在InfluxDB中创建一个数据库时,你会自动为该数据库创建一个默认的保留策略,称为autogen。如果你选择不修改默认策略,则值设置为无限。在这种情况下,碎片组持续时间默认为7天。这意味着你的数据将存储在一周的时间窗口中。如果你的保留策略是autogen(或无限),则实际上数据并不会无限存储——这只意味着保留策略与碎片组持续时间相匹配,因此保留策略实际上是禁用的。另一方面,你可以设置保留策略的最小时间为一个小时。
另一种思考方式是,保留策略就像是一个用于碎片组生活的桶。一旦保留策略的到期日生效,你就会丢弃具有不符合保留策略到期日时间间隔的碎片组。所以即使时间流逝,你仍然可以访问相同数量的数据——它只是会在时间上移动。例如,如果我设置我的保留策略为一年,一旦我达到第一个年份,我就可以一直访问一年的数据。
正如你所看到的,碎片组(以及相关的碎片)与保留策略密切相关;如果保留策略有数据,它至少有一个碎片组。每个数据点,它是一个由任意数量的值和与特定时间点相关的标签组成的测量值,都必须与一个数据库和一个保留策略相关联。在这里,重要的是要记住,一个数据库可以有多个保留策略,并且每个数据库的保留策略都是唯一的。
开源与企业版
与开源版本的InfluxDB相比,当我们开始研究InfluxDB企业版的碎片、碎片组和保留策略时,事情会变得有些复杂。如果我们使用开源版本,我们只有一个InfluxDB节点实例,这意味着我们不需要担心数据的复制,因为该功能不可用。因此,碎片组中只包含一个碎片,实际上使它们成为同一件事(另一种思考方式是,碎片变得冗余)。这是因为你不需要在多个节点上均匀地分散数据——你只有一个节点!当保留策略启动时,你将丢弃整个碎片组。
另一方面,在InfluxDB企业版中,你可以有多个InfluxDB节点实例。如果你想了解更多关于这种集群功能的信息,我建议阅读这篇博客,它涵盖了基础知识。集群中有一个以上的节点是碎片组存在的原因。我们需要一种方法,在属于适当的数据库、保留策略和时间间隔的同时,均匀地将数据分散到多个节点。在企业版中,一个碎片组可以(并且通常确实可以)包含一组共享相同时间跨度的碎片。碎片组中的每个碎片将包含时间序列的不同子集。
我们还在InfluxDB企业版的复制因子中看到了作用。复制因子表示你想要制作的数据副本数量。你可以在数据库保留策略中指定复制因子。同一份数据的两个副本不能出现在同一个碎片组中。它们最好生活在不同的碎片组和不同的节点上。这样,如果某个节点宕机,你仍然可以在另一个节点上有备份。
实际操作中的展示
为了帮助大家更好地理解,让我们通过一些示例来考虑所有这些
对于开源版本,请记住我们只有一个节点实例,因此碎片组中只有一个碎片,如下所示
Data Points
---------------
series_a t0
series_a t4
series_b t2
series_b t6
series_c t3
series_c t8
series_d t7
series_d t9
Shard Group Z (t0 - t10)
-------------
Shard 1 (series_a, series_b, series_c, series_d)
从上面的简化示例中,你可以看到我们有一个从t0到t10的时间跨度碎片组(Z)和几个系列子集(a、b、c和d)。因为我们在这里不必担心分布(将数据均匀地分散到各个节点),所以所有系列都包含在一个碎片(碎片1)中。
对于企业版本,我们可以有多个节点,所以事情会变得稍微复杂一些。例如,如果我们有一个复制因子为1的两个节点集群
Data Points
---------------
series_a t0
series_a t4
series_b t2
series_b t6
series_c t3
series_c t8
series_d t7
series_d t9
Shard Group Z (t0 - t10)
-------------
Shard 1 (series_a, series_c) (Node A)
Shard 2 (series_b, series_d) (Node B)
你可以看到我们仍然有一个从t0到t10的时间跨度碎片组Z,但这个碎片组包含两个碎片。因为复制因子是1(即只有1份数据副本),所以分布优先级更高,因此一半数据存储在节点A上,另一半存储在节点B上。这样,数据在两个节点之间均匀分布,降低了性能问题的可能性。然而,如果我们把复制因子增加到2,复制优先级高于分布,结果看起来与开源示例非常相似。下面是示例
Data Points
---------------
series_a t0
series_a t4
series_b t2
series_b t6
series_c t3
series_c t8
series_d t7
series_d t9
Shard Group Z (t0 - t10)
-------------
Shard 1 (series_a, series_b, series_c, series_d) (Node A, Node B)
现在我们回到了一个碎片组(Z)中的一个碎片,但由于复制因子,它存在于两个节点上。现在让我们把保留策略加到这个混合中。
假设我们的数据库已经设置好,保留策略为1天(24小时),并且将分片组持续时间设置为推荐值1小时。如果是InfluxDB的OSS版本,分片组将包含一个分片。这个分片将包含1小时时间范围内的所有系列,类似于我们在第一个示例中看到的那样。
Shard Group Z (t0 - t60)
-------------
Shard 1 (series_a, series_b, series_c, series_d)
当然,对于每天的小时,都会创建一个新的分片组,持续60分钟,分片组的数量将继续增加,直到达到第25小时(一天后)。当执行保留策略时,我们会看到初始分片组已经超过了过期点,因此整个分片组将被删除。每小时都会这样重复。因此,在任何给定时间,我们都会有恰好一天的数据。
理解这一切
总结一下
- InfluxDB实例可以有一个或多个数据库。
- 这些数据库中的每一个都可以有一个或多个保留策略。
- 您可以在保留策略中指定保留间隔、分片组持续时间和复制因子。
- 每个保留策略可以有一个或多个分片组(只要存在数据)。
- 每个分片组可以有一个或多个分片(OSS版本总是1个分片)。
- 分片包含实际数据。
希望这篇帖子能帮助您稍微澄清一些事情,但如果您仍然感到困惑(相信我,我非常理解这种感觉),请通过Twitter @influxDB和@mschae16与我们联系,我们可以尝试回答您所有的问题。或者查看我们的优秀社区网站,在那里每个人都会聚集在一起,帮助彼此调试和理解神秘而神奇的InfluxData平台。