Clickhouse作为时间序列存储

Fil*_*kov 4 database time-series clickhouse

我只是想知道ClickHouse是否可用于存储时间序列数据,例如:带有列的模式:"some_entity_id","timestamp","metric1","metric2","metric3",...,"metricN ".其中包含度量标准名称的每个新列可以动态添加到表中,同时添加具有此度量标准名称的条目.

在官方文档中没有找到有关动态表扩展的任何信息.

那么这个案例可以在Clickhouse中实现吗?

UPD: 在一些基准测试之后,我们发现ClickHouse比我们当前的时间序列存储更快地写入新数据,但读取数据的速度要慢得多.

Ram*_*lat 13

将CH用作时间序列数据库的方法不止一种.我个人的偏好是使用一个字符串数组作为度量标准名称,使用一个Float64数组作为指标值.

这是一个示例时间序列表:

CREATE TABLE ts1(
    entity String,
    ts UInt64, -- timestamp, milliseconds from January 1 1970
    m Array(String), -- names of the metrics
    v Array(Float32), -- values of the metrics
    d Date MATERIALIZED toDate(round(ts/1000)), -- auto generate date from ts column
    dt DateTime MATERIALIZED toDateTime(round(ts/1000)) -- auto generate date time from ts column
) ENGINE = MergeTree(d, entity, 8192)
Run Code Online (Sandbox Code Playgroud)

这里我们为实体(cpu)加载两个指标(负载,温度):

INSERT INTO ts1(entity, ts, m, v) 
VALUES ('cpu', 1509232010254, ['load','temp'], [0.85, 68])
Run Code Online (Sandbox Code Playgroud)

并查询CPU负载:

SELECT 
    entity, 
    dt, 
    ts, 
    v[indexOf(m, 'load')] AS load
FROM ts1 
WHERE entity = 'cpu'

??entity????????????????????dt??????????????ts???load??
? cpu    ? 2017-10-28 23:06:50 ? 1509232010254 ? 0.85 ?
???????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

以元组数组的形式获取数据:

SELECT 
    entity, 
    dt, 
    ts, 
    arrayMap((mm, vv) -> (mm, vv), m, v) AS metrics
FROM ts1 

??entity????????????????????dt??????????????ts???metrics??????????????????????
? cpu    ? 2017-10-28 23:06:50 ? 1509232010254 ? [('load',0.85),('temp',68)] ?
??????????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

获取数据作为元组行:

SELECT 
    entity, 
    dt, 
    ts, 
    arrayJoin(arrayMap((mm, vv) -> (mm, vv), m, v)) AS metric
FROM ts1 

??entity????????????????????dt??????????????ts???metric?????????
? cpu    ? 2017-10-28 23:06:50 ? 1509232010254 ? ('load',0.85) ?
? cpu    ? 2017-10-28 23:06:50 ? 1509232010254 ? ('temp',68)   ?
????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

获取包含所需指标的行:

SELECT 
    entity, 
    dt, 
    ts, 
    arrayJoin(arrayMap((mm, vv) -> (mm, vv), m, v)) AS metrics
FROM ts1 
WHERE metrics.1 = 'load'

??entity????????????????????dt??????????????ts???metrics????????
? cpu    ? 2017-10-28 23:06:50 ? 1509232010254 ? ('load',0.85) ?
????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

获取度量标准名称和值作为列:

SELECT 
    entity, 
    dt, 
    ts, 
    arrayJoin(arrayMap((mm, vv) -> (mm, vv), m, v)) AS metric, 
    metric.1 AS metric_name, 
    metric.2 AS metric_value
FROM ts1 

??entity????????????????????dt??????????????ts???metric??????????metric_name???metric_value??
? cpu    ? 2017-10-28 23:06:50 ? 1509232010254 ? ('load',0.85) ? load        ?         0.85 ?
? cpu    ? 2017-10-28 23:06:50 ? 1509232010254 ? ('temp',68)   ? temp        ?           68 ?
?????????????????????????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

由于CH有很多有用的日期和时间函数,以及更高阶函数元组,我认为它几乎是一个自然的时间序列数据库.


zoo*_*ash 6

将架构修改为具有 4 列可能会更好:

“some_entity_id”、“时间戳”、“metric_name”、“metric_value”

您可以在 MergeTree 索引中包含“metric_name”,以提高搜索实体的特定指标时的性能。使用和不使用它进行测试,看看它是否对您进行的查询类型有用。

  • 它可能会扩大数据量,例如,如果您存储 5 个不同的指标,您将复制实体 ID 和时间戳 5 次。但是 ClickHouse 会压缩列数据,因此差异可能可以忽略不计。 (2认同)