开源时间序列数据库的分析 – 第1部分

在这篇文章中,我们对流行的开源时序数据库引擎进行了时序数据的存储和计算能力的分析。

周肇峰写的

一个受欢迎的开源时间序列数据库。

image.png

以下是DB-Engines网站在2019年4月时刻的时序数据库排名。为了进行详细分析,我们选择了开源的和分布式的时序数据库。排名前十位中,被公认为独立的存储引擎的RRD入榜。Graphite底层采用的是Whisper,可以认为是经过优化的更强大的RRD数据库。由于Kdb+和eXtremeDB不是开源的,所以它们不在分析范围之内。开源的InfluxDB和Prometheus底层都是基于levelDB开发的独立存储引擎。商业版本的InfluxDB支持分布式存储引擎,并且Prometheus的路线图也计划支持分布式存储引擎。

最终,我们选择了OpenTSDB、KairosDB和InfluxDB进行详细分析。由于我对OpenTSDB非常熟悉,并且一直在研究其源代码,所以我对OpenTSDB的描述更加详细。然而,对于其他时序数据库我知之甚少,如果在分析过程中有误,欢迎进行更正。

开放时间序列数据库(OpenTSDB)

OpenTSDB是一种分布式、可扩展的时序数据库,它支持每秒写入速度达到数百万条数据,并支持以毫秒级精度保存数据,而无需牺牲精度来持久保存数据。其出色的写入性能和存储功能依赖于底层的HBase。HBase通过LSM树存储引擎和分布式架构实现了出色的写入性能,而出色的存储性能则依赖于完全分布式可扩展的HDFS底层。OpenTSDB深度依赖于HBase,并根据HBase底层存储结构的属性进行了许多微妙的优化。在最新版本中,还支持了BigTable和Cassandra的扩展。

建筑师

image.png

下图展示了OpenTSDB的架构,其核心组件是TSD和HBase。TSD是无状态的节点集群,可以任意扩展,并且不依赖于HBase以外的组件。TSD提供HTTP和Telnet接口,支持数据写入和查询。与HBase的O&M相比,TSD的部署和运维非常简单,这也是支持BigTable和Cassandra扩展的原因之一。

数据模型

OpenTSDB在指标建模中,数据点包含以下组件。

    • Metric: sys.cpu.user や stock.quote のような時系列データのインジケータの名前。

 

    • Timestamp: その時点での特定の時間を表す秒またはミリ秒単位のUnixタイムスタンプ。

 

    • タグ: 1つまたは複数のタグ。タグは、対象の異なる次元を記述するために使用されます。タグは、タグ・キーとタグ値で構成されます。タグ・キーはディメンションであり、タグ値はディメンションの値である。

 

    値:指標の値。現在のところ、数値型の値のみがサポートされています。

存储模型

总结最优化的要点如下:

    • データを最適化:メトリック、タグキー、タグ値にUniqueIDを割り当て、元の値とUniqueIDのインデックスを確立します。データテーブルには、元の値ではなく、メトリック、タグキー、タグ値に対応するuniqueIDが格納されます。

 

    • キー値の数を最適化:HBaseのボトム層ストレージモデルをよく理解していれば、行の各カラムが格納時にキー値に対応していることがわかると思いますが、そのため、行やカラムの数を減らすことでストレージスペースを大幅に節約でき、クエリの効率を向上させることができます。

 

    クエリを最適化: HBaseのサーバーサイドフィルタを利用して多次元クエリを最適化し、グループバイや精度削減クエリは事前集約やロールアップを利用して最適化しています。

UIDTable是OpenTSDB在HBase上的一些关键表的结构设计。首先是tsdb-uid表,其结构如下所示。

image.png

度量衡、标签键和标签值都被分配了相同固定长度的唯一ID,其默认长度为3字节。TSDB-UID表使用两个列族存储度量衡、标签键、标签值和唯一ID之间的映射与反向映射,并总共包含6个映射数据。

以下是这个例子的一个解释。

    • タグキーは’host’であり、対応するuniqueIDは’001’です。

 

    • タグ値は ‘static’ で、対応する uniqueID は ‘001’ です。

 

    メトリックは’proc.loadavg.1m’で、対応するユニークIDは’052’です。

给每个指标、标签键和标签值分配唯一的ID的好处如下。首先,可以大大减少存储空间和数据传输量。由于一个值可以用3个字节表示,所以可以获得相当高的压缩率。其次,通过使用固定长度的字节,能够轻松地从rowkey中解析出所需的值,并且可以大幅减少Java堆内存的占用(与字符串相比,字节可以节省大量内存),从而减轻了GC的负担。

然而,在固定字节的UID编码中,UID的数量有上限。在3字节中,最大允许拥有16777216个不同的值,这在大多数情况下足够了。长度是可以调整的,但不能动态地改变。

数据表

第二个关键表是以下数据表的结构:

image.png

在这个表中,相同时间的数据存储在同一行中,行中的每一列表示一个数据点。如果一行以第二级精度,那么该行可以最多包含3600个数据点,如果以毫秒级精度,该行可以最多包含3600000个数据点。

这个表的微妙之处在于rowkey和修饰符(列名)的设计,以及数据行的整体紧凑策略。涉及rowkey的格式。

<metric><timestamp><tagk1><tagv1><tagk2>tagv2>...<tagkn><tagvn>

度量衡、标签键和标签值都用UID表示。由于UID的字节长度是固定的属性,因此在解析rowkey时,可以通过使用字节偏移量来轻松提取相应的值。Qualifier的值表示数据点的时间戳的时间偏差,以小时为单位。例如,对于精度为秒的数据,对应于第30秒的数据的时间偏差为30,因此列名的值为30。使用时间偏差值作为列名的好处是可以大大节省存储容量。对于第二级数据,只需要2个字节,对于毫秒级数据,只需要4个字节,对于存储完整时间戳,只需要6个字节。在完整的数据行写入后,OpenTSDB还采用合并所有列到一个列中的压缩策略,主要是为了减少键值的数量。

查询优化

HBase 提供了简单的查询操作,如单行查询和范围查询。对于单行查询,需要提供完整的 rowkey。在范围查询中,需要提供行键范围,并且可以通过扫描范围内的所有数据来获取结果。一般来说,单行查询速度非常快,但范围查询的速度取决于扫描范围的大小。通常情况下,扫描几万行没有问题,但扫描数亿行可能会导致读取延迟加大。

OpenTSDB 提供了强大的查询功能。它支持对任意标签键进行过滤、按分组进行统计以及精度降低。标签键的过滤是查询的一部分,而按分组和精度降低是计算查询结果的一部分。查询条件中的主要参数包括指定的指标名称、标签键的过滤条件和时间范围。正如前一节所指出的,数据表的行键格式如下:<指标名称><时间戳><标签键1><标签值1><标签键2><标签值2>…<标签键n><标签值n>。根据查询参数,如果确定了指标名称和时间范围,就可以得出至少有一个行键范围进行扫描的结论。然而,这个扫描范围将查询具有相同指标名称和时间范围的所有标签键组合。如果标签键组合很多,那么扫描范围就无法控制,可能会非常大,因此查询效率基本上是不可接受的。

以下是针对OpenTSDB查询的具体优化策略:

    サーバ側のフィルタ

HBase具有丰富且具有可扩展性的过滤器。过滤器的工作原理是在服务器端扫描和过滤数据,然后将结果返回给客户端。服务器端过滤器的优化策略不能减少被扫描的数据量,但可以大幅减少发送的数据量。在OpenTSDB中,特定条件的标签键过滤器被转换为底层HBase服务器端过滤器。然而,这种优化效果有限,对查询的最重要影响因素不是发送效率,而是底层的范围扫描效率。

    • レンジクエリでスキャンされるデータ量を減らす

 

    • クエリの効率を上げるためには、やはりその範囲内でスキャンするデータ量を根本的に減らす必要があります。これは、クエリの範囲を減らすのではなく、その範囲内でスキャンするデータ量を減らすことに注意してください。ここでは、HBaseの重要なフィルタであるFuzzyRowFilterを使用します。FuzzyRowFilterは、指定された条件に従って範囲スキャンを行うと、動的に一定量のデータをスキップすることができます。ただし、この最適化はOpenTSDBが提供するすべてのクエリ条件に適用できるわけではなく、特定の条件を満たす必要がありますので、ここでは詳しくは説明しません。興味のある方はFuzzyRowFilterの原理を知ることができます。

 

    • 範囲クエリを1行クエリに最適化する

 

    今回の最適化は、先ほどの最適化よりも極端になっています。最適化の考え方は非常にわかりやすいです。クエリーするすべてのデータに対応する行キーがわかっていれば、範囲をスキャンする必要はなく、1つの行だけをクエリーすればよいのです。同様に、OpenTSDBが提供しているクエリの基準をすべて満たしていれば最適化を適用できるわけではなく、一定の基準を満たす必要があります。単一行のクエリの場合、特定の行キーが必要であり、データテーブル内の行キーの構成要素には、メトリック名、タイムスタンプ、タグが含まれます。メトリック名とタイムスタンプは決定することができます。タグも決定できれば、完全な行キーを構成することができます。したがって、この最適化を適用するには、すべてのタグキーに対応するタグ値を提供する必要があります。

以上是针对OpenTSDB的HBase查询的一些优化策略,但除了查询外,还需要对查询到的数据进行分组和精度削减等处理。此外,根据查询结果的数量而定,分组和精度削减的计算开销也很大。关于分组和精度削减计算的优化,几乎所有时间序列数据库都采用相同的优化方法,即预先聚合和自动滚动。这是在查询之前计算而不是之后的理念。然而,OpenTSDB在最新版本中暂不支持预先聚合和滚动。在正在开发的2.4版本中,提供了一种有些hack的解决方案。它只是提供了一个新的接口来支持预先聚合和滚动的结果写入。但是,数据的预先聚合和滚动计算仍需要用户自己在外部层实现。

总结

OpenTSDB的优点在于其能够进行数据写入和存储,这主要是因为底层依赖于HBase。缺点是无法进行数据查询和分析。尽管对查询进行了许多优化,但这些优化并不能适用于所有查询场景。在与其他一些时间序列数据库进行比较时,有人可能认为OpenTSDB在标签值过滤查询优化方面是最差的。预聚合和自动卷积支持在分组和下采样查询中不可用。然而,从功能角度来看,OpenTSDB API是最完善的,也是基准。

这个博客是从英文版翻译而来。您可以在这里查看原始版本。我们部分使用了机器翻译。如果有翻译错误,请您指出,我们将不胜感激。

阿里巴巴云拥有在日本的两个数据中心,并拥有60多个可用性区域,是亚太地区第一的云基础设施服务提供商(2019年加特纳)。更多关于阿里巴巴云的详细信息,请访问此处。阿里巴巴云日本官方网页。

bannerAds