天天看点

TimescaleDB时间序列数据库

TimescaleDB:

这是一款支持完整sql开源的时间序列数据库。

用处

1、数据量庞大

2、只做时间索引类的插入

3、很少更新数据

TimescaleDB的好处:

  1. 基于时序优化
  2. 自动分片(自动按时间、空间分片(chunk))
  3. 全 SQL 接口
  4. 支持垂直于横向扩展
  5. 支持时间维度、空间维度自动分区。空间维度指属性字段(例如传感器 ID,用户 ID 等)
  6. 支持多个 SERVER,多个 CHUNK 的并行查询。分区在 TimescaleDB 中被称为 chunk。
  7. 自动调整 CHUNK 的大小
  8. 内部写优化(批量提交、内存索引、事务支持、数据倒灌)。

    内存索引,因为 chunk size 比较适中,所以索引基本上都不会被交换出去,写性能比较好。

    数据倒灌,因为有些传感器的数据可能写入延迟,导致需要写以前的 chunk,timescaleDB 允许这样的事情发生(可配置)。

  9. 复杂查询优化(根据查询条件自动选择 chunk,最近值获取优化(最小化的扫描,类似递归收敛),limit 子句 pushdown 到不同的 server,chunks,并行的聚合操作)
  10. 利用已有的 PostgreSQL 特性(支持 GIS,JOIN 等),方便的管理(流复制、PITR)
  11. 支持自动的按时间保留策略(自动删除过旧数据)

超表的创建

--将普通的表转换为超标 将时间字段作为分片字段
SELECT create_hypertable('表名', '字段');
           

超表的操作跟普通表的操作一样,只不过是插件自动帮我们分片

参数详解:

chunk_time_interval:显式配置时间间隔,就是根据时间来自行分区,默认是7天,选择时间间隔的关键属性是属于最近间隔的块(包括索引)(或块,如果使用空间分区)适合内存。因此,我们通常建议设置间隔,使这些块不超过主内存的 25%。

--创建超表的时候设置时间间隔 例:设置一天
SELECT create_hypertable('conditions', 'time', chunk_time_interval => 86400000000);
SELECT create_hypertable('conditions', 'time', chunk_time_interval => INTERVAL '1 day');
           

针对已创建的超标设置

SELECT set_chunk_time_interval('表名', interval '24 hours');
SELECT set_chunk_time_interval('表名', 86400000000);
按空间分区,创建4个分区
SELECT create_hypertable('表名', 'time', 'location', 4);
           

获取超表空间大小

SELECT hypertable_size('devices') ;
           

数据保留策略:

相当于任务,定时清除历史数据

--清除6个月以前的历史数据
SELECT add_retention_policy('表名', INTERVAL '6 months');
           
--删除现有表的策略
SELECT remove_retention_policy('表名');
           

手动删除旧的数据块

--要删除超过三周的所有数
SELECT drop_chunks('stocks_real_time', INTERVAL '3 weeks');
           
--删除超过两周但新于三周的所有数据:
SELECT drop_chunks(
  'stocks_real_time',
  older_than => INTERVAL '2 weeks',
  newer_than => INTERVAL '3 weeks'
)
           

创建连续聚合:

聚合查询:

--当前语句查询当前数据集 每天的 最高值,最低值,第一个值和最后的一个值
SELECT
  time_bucket('1 day', "time") AS day,
  symbol,
  max(price) AS high,
  first(price, time) AS open,
  last(price, time) AS close,
  min(price) AS low
FROM stocks_real_time srt
GROUP BY day, symbol
ORDER BY day DESC, symbol;
           

从聚合查询变为连续聚合:

可以通过CREATE MATERIALIZED VIEW命令触发数据库创建具有给定名称的物化视图,(相当于里面是有数据存储的)WITH (timescaledb.continuous)指示 TimescaleDB 创建一个连续的聚合,而不仅仅是一个通用的物化视图。最后,在AS关键字之后添加之前的查询。

CREATE MATERIALIZED VIEW stock_candlestick_daily
WITH (timescaledb.continuous) AS
SELECT
  time_bucket('1 day', "time") AS day,
  symbol,
  max(price) AS high,
  first(price, time) AS open,
  last(price, time) AS close,
  min(price) AS low
FROM stocks_real_time srt
GROUP BY day, symbol;
           

查询数据的话只需要查询当前视图数据即可

SELECT * FROM stock_candlestick_daily
  ORDER BY day DESC, symbol;
           

实时连续聚合

默认情况下,所有连续聚合都创建为实时聚合。这意味着 TimescaleDB 会将UNION尚未通过刷新策略具体化的最新数据附加(或)到连续聚合的输出中

使用和设置连续聚合策略:

1、自动连续聚合刷新策略

--此策略每天运行一次,由 设置schedule_interval。当它运行时,
--它会具体化 3 天前到 1 小时前的数据,由 start_offset和设置end_offset。
--偏移时间是相对于查询执行时间计算的。
--执行的查询是在连续聚合中定义的查询stock_candlestick_daily。
SELECT add_continuous_aggregate_policy('stock_candlestick_daily',
  start_offset => INTERVAL '3 days',
  end_offset => INTERVAL '1 hour',
  schedule_interval => INTERVAL '1 days');
           

2、手动刷新

这在插入或修改超出刷新策略start_offset和end_offset间隔的数据时最有用。这在边缘物联网系统中很常见,其中设备长时间失去互联网连接,并在重新连接后最终发送历史读数。

--此手动刷新仅更新您的连续聚合一次。它不会自动使聚合保持最新。
--要设置自动刷新策略,请参阅前面关于连续聚合刷新策略的部分。
--当前语句是刷新1周前到当前的数据到连续聚合中
CALL refresh_continuous_aggregate(
  'stock_candlestick_daily',
  now() - INTERVAL '1 week',
  now()
);
           

数据压缩

要启用压缩,您需要ALTER超stocks_real_time表。启用压缩时可以指定三个参数:

timescaledb.compress(必需):在超表上启用 TimescaleDB 压缩

timescaledb.compress_orderby(可选):用于对压缩数据进行排序的列

timescaledb.compress_segmentby(可选):用于对压缩数据进行分组的列

如果不指定compress_orderby或compress_segmentby列,则压缩数据按超表时间列自动排序

在超表上启用压缩

ALTER TABLE stocks_real_time SET (
  timescaledb.compress,
  timescaledb.compress_orderby = 'time DESC',
  timescaledb.compress_segmentby = 'symbol'
);
           

自动压缩:

压缩策略:

add_compression_policy:许您设置一个策略,系统会根据该策略在块达到给定年龄后在后台自动压缩块。

添加策略以压缩“cpu”超表上超过 60 天的块。

SELECT add_compression_policy('cpu', INTERVAL '60d');
           

压缩超表上超过两周的数据

SELECT add_compression_policy('stocks_real_time', INTERVAL '2 weeks');
           

与连续聚合策略和保留策略类似,当您运行此 SQL 时,包含至少两周前的数据的所有块都将被压缩stocks_real_time,并创建循环压缩策略。

不要试图压缩所有数据,这一点很重要。尽管您可以将新数据插入到压缩块中,但无法更新或删除压缩行。因此,最好只在数据老化后才压缩数据,一旦数据不太可能需要更新。

手动压缩:

compress_chunk 函数用于压缩特定的块。当用户想要更多地控制压缩的调度时,这最常用来代替 add_compression_policy函数。

使用此查询手动压缩包含超过 2 周的数据的块。如果您手动压缩超表块,请考虑添加 if_not_compressed=>true(设置为true跳过已压缩的块)到compress_chunk()函数中。否则,TimescaleDB 在尝试压缩已压缩的块时会显示错误

SELECT compress_chunk(i, if_not_compressed=>true)
  FROM show_chunks('stocks_real_time', older_than => INTERVAL ' 2 weeks') i;
           

验证压缩:

可以使用此查询检查超表的整体压缩率,以查看应用压缩前后压缩块的大小

SELECT pg_size_pretty(before_compression_total_bytes) as "before compression",
  pg_size_pretty(after_compression_total_bytes) as "after compression"
  FROM hypertable_compression_stats('stocks_real_time');
           
上一篇: worker