发布于: Jun 29, 2022

物联网 开发平台千千万我们该如何选择呢?以车联网平台为例,我们来介绍 Amazon Timestream 全托管时间序列数据库服务的优越性。

在建模之前,我们先了解一下 Amazon Timestream 中的一些基本概念。

  • Time series 时间序列:在一段时间范围内,记录的一个或者多个数据点(也就是 records)序列。比如一个短时间的股价,一个短时间的 CPU或内存利用率,以及一段时间 Iot 传感器的温度压力值等。
  • Record 记录: 在时间序列当中的一个数据点
  • Dimension: 时间序列当中的一个 mete-data 属性值。包含 dimension 的 key 值以及实际值。比如对于 Iot 传感器,常见的 dimension name 为设备 ID,dimension value 为 12345.
  • Measure:record 当中实际被测量的值。比如一个设备的实际温度或者湿度。Measure 包含 measure names(相当于为 key 值)以及 measure values。
  • Timestamp 时间戳: 表明测量值是在哪个时间点被测量的。
  • Table: 存储时间序列的表
  • Database:数据库

根据定义,我们对上述 schema 当中的 key 做一个分类,将反应设备基本情况类的信息归类到 DIMENSION 里,将实际需要上报的值归类为 MEASURE 类,建模如下: 

 

Column

Type

Timestream attribute type

1

trip_id

varchar

DIMENSION

2

vin

varchar

DIMENSION

3

measure_value::double

double

MEASURE_VALUE

4

measure_name

varchar

MEASURE_NAME

5

time

timestamp

TIMESTAMP

测试目的

为了验证 Amazon Timestream 数据库可以支持车联网实时数据监控和查询,我们设计了针对 Amazon Timestream 的测试场景,其中涉及端到端集成和性能测试。测试期望验证下列场景

  1. 数据可以通过流式注入的方式写入 Amazon Timestream 数据库
  2. 数据注入速率不小于每秒 1000 条数据,每条数据 Playload 大致在 8KB 左右。
  3. 数据按照百万级、千万级和亿级分阶段测试,数据保留时间为 1 周。超过此时间段的数据将移至数据湖中保存,数据湖数据处理不在本文讨论访问。
  4. 为了良好的成本效率,测试不同存储分层下的 Amazon Timestream 的性能表现,保证数据可以平滑的在不同层级的存储中转换
  5. 测试在不同存储分层下时间窗口内查询,聚合,跨表查询等性能

架构说明

在此次压测中,我们用 python 程序模拟物联网设备产生数据的过程,数据将实时写入到流式存储介质 Kinesis Data Stream 当中,通过由 Flink 构建的 timestream data connector ,实时读取 kinesis 里的数据,并写入到 Amazon Timestream 中。

压测步骤

  1. 在此处下载此次压缩所需要的代码,并按照 README 的步骤进行必要软件的下载、安装以及运行。
  2. 启动 timestream flink connector (在 README 当中也包含此步骤)
cd /home/ec2-user/timestream/amazon-timestream-tools/integrations/flink_connector
mvn clean compile
mvn exec:java -Dexec.mainClass="com.amazonaws.services.kinesisanalytics.StreamingJob" -Dexec.args="--InputStreamName TimestreamTestStream --Region us-east-1 --TimestreamDbName kdaflink --TimestreamTableName kinesis-6yi"
mvn exec:java -Dexec.mainClass="com.amazonaws.services.kinesisanalytics.StreamingJob" -Dexec.args="--InputStreamName TimestreamTestStream --Region us-east-1 --TimestreamDbName kdaflink --TimestreamTableName kinesis-6yi --TimestreamIngestBatchSize 75"
  1. 在另一个 terminal 或者另一台服务器启动执行生产数据的 python 程序(在 README 当中也包含此步骤)。
# cd /home/ec2-user/timestream/amazon-timestream-tools/tools/kinesis_ingestor
python3 timestream_kinesis_data_gen_blog.py --stream TimestreamTestStream --region us-east-1
  1. 此时,如无错误,Amazon Timestream 将持续被写入数据。可以在 kinesis 的监控,Amazon Timestream 监控中,观察写入延迟等指标。也可以在 Amazon Timestream 中,通过 count 的方式查询写入条数。当观测达到目标数量级时,停止写入。
  2. 如果希望提高并行写入速度,可以通过增大 producer 脚本(timestream_kinesis_data_gen_blog.py)的并行来解决,但此时应注意 kinesis 的写入速度是否达到瓶颈。kinesis 单个 shard 有1MB/s 或者 1000 条/s 的写入限制,如到达瓶颈,请增大 kinesis 的 shard 数量。
  3. 在写入完成后,在确保测试服务器已经配置了 Amazon Web Services CLI 后,运行 query_test.py 脚本,根据自己的需要,更改替换 profile_name (默认为 default), DATABASE_NAME ,TABLE_NAME ,RIGHT_TABLE_NAME (做 join 操作) ,QUERY_REPEAT (运行 query 的次数) 等参数。此脚本将记录在不同的 SQL 查询下,每次以及平均的延迟数据。

性能表现

在此次测试中,我们分别通过上述方法向 Amazon Timestream 不同 table 里写入了百万,千万,和亿级别的数据,主要监控指标有 Amazon Timestream  的写入延迟, Query 查询速度。

写入延迟

在写入 TPS 在 6000 条/秒 下:

  • 7 千万条数据的写入时延在 40ms – 55ms
  • 6 亿条数据 Kinesis 写入的时延在 60ms – 75m

Query 查询速度

我们分别针对百万级,千万级,和亿级的数据量做了不同 SQL 语句下的测试;并且在每个数量级下,我们做了对比测试,以对比 Timestream 内存介质和磁性介质在不同查询语句下的表现。

对应 SQL 语句可在 query_test.py 中查看并做修改。

  • 百万级 records: 9547102 rows ( 950 万条)

Table

SQL count time window

SQL select limit 20

SQL between and great than

SQL group by

SQL case

SQL join

SQL max

数据在内存介质下

8.25s,
803.17MB

0.17s,
1.028MB

 0.33s,
0MB

7.4s,
24.08MB

0.27s,
0.49MB

6.76s,
95.94MB

9.53s,
15.81MB

数据在磁性数据介质下

0.93s,
803.17MB

0.48s,
0.004MB

0.72s,
1.68 MB

3.37s,
25.16MB

0.48s,
0.76 MB

1.68s,
96.37MB

2.34s,
70.81MB

  • 千万级 records:71602075 rows (7000 万条)

Table

Table size (rows)

SQL count time window

SQL select limit 20

SQL between and great than

SQL group by

SQL case

SQL join

SQL max

数据在内存介质下

71602075

9.13s,
7534MB

0.21s,
6.92MB

0.38s,
22KB

8.94s,
2540MB

0.21s,
4.51MB

1.33s,
368.0MB

5.69s,
494.9MB

数据在磁性数据介质下

 

0.77s,
7534MB

0.4s,
0.04MB

0.59 s,
5.15M

3.09 s,
2540MB

0.41 s,
0.902MB

1.26 s,
363.87MB

1.36 s,
29.1MB

  • 亿级 records:609769360 rows (约 6 亿条)

Table

SQL count time window

SQL select limit 20

SQL between and great than

SQL group by

SQL case

SQL join

SQL max

数据在内存介质下

14.94s,
62126MB

0.43s,
56MB

0.34s,
0.05MB

14.41s, 21024MB

0.43s
41.73MB

1.64s
367MB

19s,
928MB

数据在磁性存储介质下

1.7s,
62126 MB

0.62s,
0.113MB

0.648 s,
0.55MB

9.67s,
21024MB

0.64s,
1.28 MB

1.8s,
363.80 MB

6.56s,
5640.6 MB

结论

通过测试数据,我们可以得到以下结论:

  • Amazon Timestream 可以良好的支持大规模数据输入,提供了平滑的注入性能
  • Amazon Timestream 可以良好的支持大规模数据存储,并且通过不同分层,优化成本
  • Amazon Timestream 可以良好的支持典型时序查询,提供了丰富的时序查询方法,并且可以在海量数据情况下提供良好的查询性能。
  • 提升查询性能方面,我们有如下建议:
    • Amazon Timestream 所扫描的 data size 越大,返回速度越慢。这一点可以在每个表格中的 data size 与 response data 中得到证实。
    • 我们建议查询时仅包含对查询必不可少的度量和维名称。
    • 在可能的情况下,在查询的 WHERE 子句中包含一个时间范围。
    • 在可能的情况下,在查询的 WHERE 子句中比较维度和度量时,请使用相等运算符。
    • 使用 CASE 表达式执行复杂的聚合,而不是多次从同一张表中进行选择。
    • 仅在查询的 GROUP BY 子句中使用必要的列。
    • 如果使用 ORDER BY 子句查看前 N 个值或后N个值,请使用 LIMIT 子句以提升查询性能
  • 我们建议遵循其他最佳实践指南的建议,以优化工作负载的规模和性能。
  • 对于一些查询性的 SQL 语句,如 between and, 在内存当中的查询速度会更快;但对于一些分析类的服务,如 group by,在磁性存储介质下会有更好的效果。 这是因为:内存存储专为快速的时间点查询进行了优化,而磁性存储则为快速的分析查询进行了优化。此结论在 Amazon Timestream 官方文档当中可以得到理论支持。

相关文章