Loading

TimescaleDB 实现 Prometheus 远程存储

Prometheus是一个开源且社区驱动的监视系统,一开始非常简单。Prometheus之所以令人赞叹,是其以简单直接的方式解决监控问题。他们的原则是做一件事,并且做好。这反映在例如PromQL语言的设计中。

但是,这种原则也存在限制性。值得赞扬的是,Prometheus的开发人员预见到他们的产品是opinionated,他们内置可扩展性以允许其他系统对其进行改进。反过来,Prometheus用户经常将其他系统视为增加其监视设置的一种方式。

这就是TimescaleDB和PostgreSQL出现的地方。特别是,Prometheus用户经常出于以下原因而转向TimescaleDB和PostgreSQL:

  • 可扩展,持久的长期数据存储
  • 广泛的工具生态系统使操作更轻松
  • 使用SQL查询功能和灵活性

通过将Prometheus和TimescaleDB一起使用,可以将Prometheus的简单性与TimescaleDB的可靠性,功能和灵活性相结合,并选择最适合手头任务的方法。例如,您可以使用PromQL或完整SQL进行查询,或同时使用两者。

本教程的目的是如何将TimescaleDBPrometheus集成在一起

1. 为什么要将TimescaleDBPrometheus结合使用

Long term data storage

为了保持Prometheus的简单易用,其创建者有意省略了一些通常会期望的缩放功能。Prometheus中的数据存储在实例内部,并且不被复制。将计算和数据存储都存储在一个节点上可能使其更易于操作,但也使其难以扩展并确保高可用性。

因此,Prometheus并非旨在作为长期存储。从文档中:

Prometheus is not arbitrarily scalable or durable in the face of disk or node outages and should thus be treated as more of an ephemeral sliding window of recent data.

另一方面,TimescaleDB可以轻松处理TB级的数据,并支持高可用性和复制,使其非常适合长期数据存储。此外,它提供了高级功能,例如完整的SQL,联接和复制,而这在Prometheus中是不可用的。

工作原理:记录到Prometheus中的所有metrics都首先写入本地节点,然后再写入TimescaleDB。这意味着所有metrics 都将立即备份,因此Prometheus节点上的任何磁盘故障都会减轻后果。

TimescaleDB还可以存储其他类型的数据(metrics, time-series, relational),使您可以集中来自不同来源的监视数据,并简化堆栈。您甚至可以合并这些不同类型的数据,并将上下文添加到监视数据中以进行更丰富的分析。

Operational ease
Prometheus有几种长期存储方式,但是,所有这些技术所面临的挑战是它们可能会需要您的团队来操作和管理另一个系统。

TimescaleDB是一个例外。TimescaleDB的外观和操作类似于PostgreSQL,这意味着如果您已经在运行PostgreSQL实例,则可以在操作TimescaleDB节点或集群时重用该知识。这也意味着您还可以使用广泛的PostgreSQL生态系统中的任何现有工具。

扩展Prometheus的唯一方法是federation。但是,在某些情况下,federation并不适合:例如,从多个Prometheus实例复制大量数据以由一台计算机处理时。这可能会导致性能下降,可靠性降低(附加故障点)以及某些数据丢失。这些问题都可以由TimescaleDB解决。

SQL查询能力
PromQLPrometheus本地查询语言。这是一种非常强大且具有表现力的查询语言,可让您轻松地对指标数据进行切片和切块,并应用各种特定于监视的功能。

但是,有时您可能需要比PromQL提供的查询更大的查询灵活性和功能。例如,尝试使指标与发生的事件和事件相互关联,运行更细粒度的查询以进行主动故障排除,或者对指标应用机器学习或其他形式的更深入的分析。

在这里,TimescaleDB的完整 SQL 支持可以提供很大的帮助。使用TimescaleDB,您可以将SQL的全部宽度应用于Prometheus数据,将指标数据与您可能拥有的任何其他数据结合起来,并运行更强大的查询。

2. 如何在Prometheus中使用TimescaleDB

要将TimescaleDBPostgreSQL连接到Prometheus,有两个组件:

  1. Prometheus PostgreSQL Adapter
  2. 具有pg_prometheustimescaledb扩展名的PostgreSQL数据库

At a high-level, here's how it works:

首先将所有数据收集到Prometheus中。然后,Prometheus将其转发到已配置的Prometheus PostgreSQL Adapter,后者再将数据转发给具有pg_prometheus扩展的TimescaleDB数据库。

Timescale 官网的 tutorials 中教程使用的 docker 映像,不适用于我们的环境,下面教程展示的我们从源代码安装的过程。

3. 搭建环境

开始之前,我们的虚机中已经安装了Prometheus,并且以源码方式安装了TimescaleDB

3.1 安装 pg_prometheus

pg_prometheus项目地址:https://github.com/timescale/pg_prometheus

百度网盘链接:https://pan.baidu.com/s/1FHSqtiFIU_afhcIGIpjozw
提取码:hwva,可将文件解压至安装目录,取代 git clone

git clone https://github.com/timescale/pg_prometheus
cd pg_prometheus
# git checkout 0.2.2
make
sudo make install

若 sudo pg_config 提示找不到命令。这是因为 sudo 在切换成 root 用户的时候,env 并不会去保留这些环境变量,需要特别的指明才可以。向 /etc/sudoers 文件中 env_reset 下增加一行。

Defaults        env_keep+="PATH PYTHONPATH LD_LIBRARY_PATH MANPATH JAVA_HOME"

另外,secure_path 变量里面也要加上 /usr/local/pgsql/bin 路径。

Defaults        secure_path="/usr/local/pgsql/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

验证一下pg_prometheus扩展有没有装好。我们连接 TimescaleDB 命令:

$ psql -U postgres
psql (11.8)
Type "help" for help.

postgres=# SELECT name, default_version,installed_version FROM pg_available_extensions WHERE name LIKE '%prometheus%';

应该看到类似于以下输出的内容:

     name      | default_version | installed_version 
---------------+-----------------+-------------------
 pg_prometheus | 0.2.2           | 
(1 row)

3.2 创建Prometheus数据库

$ psql -U postgres
    
-- CREATE USER prometheus WITH LOGIN PASSWORD 'secret';    
-- Create the role
CREATE ROLE prometheus WITH LOGIN PASSWORD 'secret';  
CREATE DATABASE prometheus OWNER prometheus;

-- Optionally grant permissions to the database user (`prometheus`) that will own the Prometheus data
GRANT ALL PRIVILEGES ON DATABASE prometheus TO prometheus;

\connect prometheus;

CREATE EXTENSION timescaledb; 
CREATE EXTENSION pg_prometheus;

创建表格。

-- 创建表,只使用pg_prometheus
-- SELECT create_prometheus_table('metrics');

-- 让pg_prometheus 使用 TimescaleDB 扩展。
SELECT create_prometheus_table('metrics',use_timescaledb=>true);

-- 配置数据保留,默认情况下,数据存储90天,然后删除
-- SELECT set_default_retention_period(180 * INTERVAL '1 day');

查看一下创建的表格。

# \dt
             List of relations
 Schema |      Name      | Type  |  Owner   
--------+----------------+-------+----------
 public | metrics_copy   | table | postgres
 public | metrics_labels | table | postgres
 public | metrics_values | table | postgres
(3 rows)

# \d metrics_values
                     Table "public.metrics_values"
  Column   |           Type           | Collation | Nullable | Default 
-----------+--------------------------+-----------+----------+---------
 time      | timestamp with time zone |           | not null | 
 value     | double precision         |           |          | 
 labels_id | integer                  |           |          | 

Indexes:
    "metrics_values_labels_id_idx" btree (labels_id, "time" DESC)
    "metrics_values_time_idx" btree ("time" DESC)
Triggers:
    ts_insert_blocker BEFORE INSERT ON metrics_values FOR EACH ROW EXECUTE PROCEDURE _timescaledb_internal.insert_blocker()
    
# \d metrics_labels
                               Table "public.metrics_labels"
   Column    |  Type   | Collation | Nullable |                  Default        
-------------+---------+-----------+----------+--------------------------------------------
 id          | integer |           | not null | nextval('metrics_labels_id_seq'::regclass)
 metric_name | text    |           | not null | 
 labels      | jsonb   |           |          | 
Indexes:
    "metrics_labels_pkey" PRIMARY KEY, btree (id)
    "metrics_labels_metric_name_labels_key" UNIQUE CONSTRAINT, btree (metric_nam
e, labels)
    "metrics_labels_labels_idx" gin (labels)
    "metrics_labels_metric_name_idx" btree (metric_name)

# \d metrics_copy
              Table "public.metrics_copy"
 Column |    Type     | Collation | Nullable | Default 
--------+-------------+-----------+----------+---------
 sample | prom_sample |           | not null | 
Triggers:
    insert_trigger BEFORE INSERT ON metrics_copy FOR EACH ROW EXECUTE PROCEDURE prometheus.insert_view_normal('metrics_values', 'metrics_labels')

3.3 安装 prometheus-postgresql-adapter

prometheus-postgresql-adapter项目地址:https://github.com/timescale/prometheus-postgresql-adapter

百度网盘链接:https://pan.baidu.com/s/1NXpA-cxx7VeFh6lfXW-F8A
提取码:50gd

# install dependency
sudo apt-get install golang-go

git clone https://github.com/timescale/prometheus-postgresql-adapter
cd prometheus-postgresql-adapter
# git checkout 0.6.0

make ## 用go编译遇到各种问题

# 尝试用prebuilt
wget https://github.com/timescale/prometheus-postgresql-adapter/releases/download/v0.6.0/prometheus-postgresql-adapter-0.6.0-linux-amd64.tar.gz
tar xf prometheus-postgresql-adapter-0.6.0-linux-amd64.tar.gz
mv prometheus-postgresql-adapter-0.6.0-linux-amd64/ prometheus-postgresql-adapter

本地启动

./prometheus-postgresql-adapter -pg-port 5432 --pg-user postgres

执行返回结果。

{"caller":"log.go:31","config":"\u0026{remoteTimeout:30000000000 listenAddr::9201 telemetryPath:/metrics pgPrometheusConfig:{host:localhost port:5432 user:postgres password: database:postgres schema: sslMode:disable table:metrics copyTable: maxOpenConns:50 maxIdleConns:10 pgPrometheusNormalize:true pgPrometheusLogSamples:false pgPrometheusChunkInterval:43200000000000 useTimescaleDb:true dbConnectRetries:0 readOnly:false} logLevel:debug haGroupLockID:0 restElection:false prometheusTimeout:-1 electionInterval:5000000000}","level":"info","ts":"2020-06-22T03:39:09.775Z"}
{"caller":"log.go:31","level":"info","msg":"host=localhost port=5432 user=postgres dbname=postgres password='' sslmode=disable connect_timeout=10","ts":"2020-06-22T03:39:09.775Z"}
{"caller":"log.go:31","level":"info","msg":"Initialized pg_prometheus extension","ts":"2020-06-22T03:39:10.023Z"}
{"caller":"log.go:35","level":"warn","msg":"No adapter leader election. Group lock id is not set. Possible duplicate write load if running adapter in high-availability mode","ts":"2020-06-22T03:39:10.025Z"}
{"caller":"log.go:31","level":"info","msg":"Starting up...","ts":"2020-06-22T03:39:10.025Z"}
{"addr":":9201","caller":"log.go:31","level":"info","msg":"Listening","ts":"2020-06-22T03:39:10.025Z"}

3.4 配置Prometheus,添加后端读写接口

若不需要安装 prometheus 获得监控数据,可不用执行此步骤
在 prometheus 目录下prometheus.yml中加入

remote_write:
  - url: "http://<adapter-address>:9201/write"
remote_read:
  - url: "http://<adapter-address>:9201/read"

3.5 导入数据

$ cd ~/P4/datasets/prom_data_csvs 
$ ls 
metrics_labels_202003201742.csv  metrics_values_202003201743.csv

$ psql -U postgres -d prometheus

\COPY metrics_labels FROM metrics_labels_202003201742.csv DELIMITER ',' CSV HEADER;
\COPY metrics_values FROM metrics_values_202003201743.csv DELIMITER ',' CSV HEADER;

遇到错误,因为开始的时候忘了加CSV文件的描述信息: DELIMITER ',' CSV HEADER

ERROR:  invalid input syntax for integer: ""id","metric_name","labels""
CONTEXT:  COPY metrics_labels, line 1, column id: ""id","metric_name","labels""
posted @ 2022-08-13 12:48  锦瑟,无端  阅读(514)  评论(0编辑  收藏  举报