跳到主要内容
版本:0.17

快速开始

在继续阅读之前,请确保你已经安装了 GreptimeDB

本指南通过引导你创建一个 metric 表和一个 log 表来介绍 GreptimeDB 的核心功能。

你将学习(10-15 分钟)

  • 在本地启动并连接到 GreptimeDB
  • 创建 metrics 和 logs 表并插入示例数据
  • 查询和聚合数据
  • 计算 5 秒窗口内的 p95 和 ERROR 计数并对齐它们
  • 关联 metrics 和 logs 来发现异常主机和时间点
  • 结合 SQL 和 PromQL 查询数据

连接到 GreptimeDB

GreptimeDB 支持多种协议与数据库进行交互。 在本快速入门文档中,我们使用 SQL 作为实例。

如果你的 GreptimeDB 实例运行在 127.0.0.1 中, 并且使用 MySQL 客户端默认端口 4002 或 PostgreSQL 客户端默认端口 4003, 你可以使用以下命令连接到数据库。

GreptimeDB 默认不开启鉴权认证。 在本章节中你可以在连接数据库时不提供用户名密码。

mysql -h 127.0.0.1 -P 4002

或者

psql -h 127.0.0.1 -p 4003 -d public

你也可以通过浏览器访问 DB 内置的 Dashboard 地址 http://127.0.0.1:4000/dashbaord 运行本文档中的 SQL。

创建表

假设你有一个名为 grpc_latencies 的事件(Events)表,用于存储的 gRPC 调用接口以及它的处理时间。表 schema 如下:

-- Metrics: gRPC 调用延迟(毫秒)
CREATE TABLE grpc_latencies (
ts TIMESTAMP TIME INDEX,
host STRING INVERTED INDEX,
method_name STRING,
latency DOUBLE,
PRIMARY KEY (host, method_name)
);
  • ts:收集指标时的时间戳,时间索引列。
  • host:主机名,设置了倒排索引
  • method_name:RPC 请求方法的名称,tag 列。
  • latency:RPC 请求的响应时间。

此外,还有一个名为 app_logs 的表用于存储日志:

-- Logs: 应用程序日志
CREATE TABLE app_logs (
ts TIMESTAMP TIME INDEX,
host STRING INVERTED INDEX,
api_path STRING,
log_level STRING,
log_msg STRING FULLTEXT INDEX WITH('case_sensitive' = 'false'),
PRIMARY KEY (host, log_level)
) with('append_mode'='true');
  • ts:日志条目的时间戳,时间索引列。
  • host:主机名,设置了倒排索引。
  • api_path:API 路径。
  • log_level:日志级别,tag 列。
  • log_msg:日志消息内容,设置了全文索引

通过将 append_mode 设置为 true 来启用 Append Only模式,这通常对性能有帮助。同时也支持其他表选项,如数据保留期等。

提示

我们在下面使用 SQL 来导入数据,因此需要手动创建表。但 GreptimeDB 本身是 schemaless 的,在使用其他写入方法时可以自动生成 schema。

写入数据

让我们插入一些模拟数据来模拟收集的指标和错误日志。

假设有两个服务器 host1host2 记录着 gRPC 延迟。 从 2024-07-11 20:00:10 开始,host1 的延迟显著增加。

下图显示了 host1 的不稳定延迟。

unstable latencies

使用以下 SQL 语句插入模拟数据。

2024-07-11 20:00:10 之前,主机正常运行:

INSERT INTO grpc_latencies (ts, host, method_name, latency) VALUES
('2024-07-11 20:00:06', 'host1', 'GetUser', 103.0),
('2024-07-11 20:00:06', 'host2', 'GetUser', 113.0),
('2024-07-11 20:00:07', 'host1', 'GetUser', 103.5),
('2024-07-11 20:00:07', 'host2', 'GetUser', 107.0),
('2024-07-11 20:00:08', 'host1', 'GetUser', 104.0),
('2024-07-11 20:00:08', 'host2', 'GetUser', 96.0),
('2024-07-11 20:00:09', 'host1', 'GetUser', 104.5),
('2024-07-11 20:00:09', 'host2', 'GetUser', 114.0);

2024-07-11 20:00:10 之后,host1 的响应时间变得不稳定,处理时间大幅波动,偶尔会出现数千毫秒的峰值:


INSERT INTO grpc_latencies (ts, host, method_name, latency) VALUES
('2024-07-11 20:00:10', 'host1', 'GetUser', 150.0),
('2024-07-11 20:00:10', 'host2', 'GetUser', 110.0),
('2024-07-11 20:00:11', 'host1', 'GetUser', 200.0),
('2024-07-11 20:00:11', 'host2', 'GetUser', 102.0),
('2024-07-11 20:00:12', 'host1', 'GetUser', 1000.0),
('2024-07-11 20:00:12', 'host2', 'GetUser', 108.0),
('2024-07-11 20:00:13', 'host1', 'GetUser', 80.0),
('2024-07-11 20:00:13', 'host2', 'GetUser', 111.0),
('2024-07-11 20:00:14', 'host1', 'GetUser', 4200.0),
('2024-07-11 20:00:14', 'host2', 'GetUser', 95.0),
('2024-07-11 20:00:15', 'host1', 'GetUser', 90.0),
('2024-07-11 20:00:15', 'host2', 'GetUser', 115.0),
('2024-07-11 20:00:16', 'host1', 'GetUser', 3000.0),
('2024-07-11 20:00:16', 'host2', 'GetUser', 95.0),
('2024-07-11 20:00:17', 'host1', 'GetUser', 320.0),
('2024-07-11 20:00:17', 'host2', 'GetUser', 115.0),
('2024-07-11 20:00:18', 'host1', 'GetUser', 3500.0),
('2024-07-11 20:00:18', 'host2', 'GetUser', 95.0),
('2024-07-11 20:00:19', 'host1', 'GetUser', 100.0),
('2024-07-11 20:00:19', 'host2', 'GetUser', 115.0),
('2024-07-11 20:00:20', 'host1', 'GetUser', 2500.0),
('2024-07-11 20:00:20', 'host2', 'GetUser', 95.0);

host1 的 gRPC 请求的响应时间遇到问题时,收集了一些错误日志:

INSERT INTO app_logs (ts, host, api_path, log_level, log_msg) VALUES
('2024-07-11 20:00:10', 'host1', '/api/v1/resource', 'ERROR', 'Connection timeout'),
('2024-07-11 20:00:10', 'host1', '/api/v1/billings', 'ERROR', 'Connection timeout'),
('2024-07-11 20:00:11', 'host1', '/api/v1/resource', 'ERROR', 'Database unavailable'),
('2024-07-11 20:00:11', 'host1', '/api/v1/billings', 'ERROR', 'Database unavailable'),
('2024-07-11 20:00:12', 'host1', '/api/v1/resource', 'ERROR', 'Service overload'),
('2024-07-11 20:00:12', 'host1', '/api/v1/billings', 'ERROR', 'Service overload'),
('2024-07-11 20:00:13', 'host1', '/api/v1/resource', 'ERROR', 'Connection reset'),
('2024-07-11 20:00:13', 'host1', '/api/v1/billings', 'ERROR', 'Connection reset'),
('2024-07-11 20:00:14', 'host1', '/api/v1/resource', 'ERROR', 'Timeout'),
('2024-07-11 20:00:14', 'host1', '/api/v1/billings', 'ERROR', 'Timeout'),
('2024-07-11 20:00:15', 'host1', '/api/v1/resource', 'ERROR', 'Disk full'),
('2024-07-11 20:00:15', 'host1', '/api/v1/billings', 'ERROR', 'Disk full'),
('2024-07-11 20:00:16', 'host1', '/api/v1/resource', 'ERROR', 'Network issue'),
('2024-07-11 20:00:16', 'host1', '/api/v1/billings', 'ERROR', 'Network issue');

查询数据

根据 tag 和时间索引进行过滤

你可以使用 WHERE 子句来过滤数据。例如,要查询 2024-07-11 20:00:15 之后 host1 的延迟:

SELECT *
FROM grpc_latencies
WHERE host = 'host1' AND ts > '2024-07-11 20:00:15';
+---------------------+-------+-------------+---------+
| ts | host | method_name | latency |
+---------------------+-------+-------------+---------+
| 2024-07-11 20:00:16 | host1 | GetUser | 3000 |
| 2024-07-11 20:00:17 | host1 | GetUser | 320 |
| 2024-07-11 20:00:18 | host1 | GetUser | 3500 |
| 2024-07-11 20:00:19 | host1 | GetUser | 100 |
| 2024-07-11 20:00:20 | host1 | GetUser | 2500 |
+---------------------+-------+-------------+---------+
5 rows in set (0.14 sec)

你还可以在过滤数据时使用函数。例如,你可以使用 approx_percentile_cont 函数按主机分组计算响应时间的 95 百分位数:

SELECT 
approx_percentile_cont(0.95) WITHIN GROUP (ORDER BY latency) AS p95_latency,
host
FROM grpc_latencies
WHERE ts >= '2024-07-11 20:00:10'
GROUP BY host;
+-------------------+-------+
| p95_latency | host |
+-------------------+-------+
| 4164.999999999999 | host1 |
| 115 | host2 |
+-------------------+-------+
2 rows in set (0.11 sec)

通过关键词搜索日志

通过关键词 timeout 过滤日志消息:

SELECT
*
FROM
app_logs
WHERE
lower(log_msg) @@ 'timeout'
AND ts > '2024-07-11 20:00:00'
ORDER BY
ts;
+---------------------+-------+------------------+-----------+--------------------+
| ts | host | api_path | log_level | log_msg |
+---------------------+-------+------------------+-----------+--------------------+
| 2024-07-11 20:00:10 | host1 | /api/v1/billings | ERROR | Connection timeout |
| 2024-07-11 20:00:10 | host1 | /api/v1/resource | ERROR | Connection timeout |
| 2024-07-11 20:00:14 | host1 | /api/v1/billings | ERROR | Timeout |
| 2024-07-11 20:00:14 | host1 | /api/v1/resource | ERROR | Timeout |
+---------------------+-------+------------------+-----------+--------------------+

@@ 操作符用于短语搜索

Range query

你可以使用 range query来实时监控延迟。例如,按 5 秒窗口计算请求的 p95 延迟:

SELECT
ts,
host,
approx_percentile_cont(0.95) WITHIN GROUP (ORDER BY latency)
RANGE '5s' AS p95_latency
FROM
grpc_latencies
ALIGN '5s' FILL PREV
ORDER BY
host,ts;
+---------------------+-------+-------------+
| ts | host | p95_latency |
+---------------------+-------+-------------+
| 2024-07-11 20:00:05 | host1 | 104.5 |
| 2024-07-11 20:00:10 | host1 | 4200 |
| 2024-07-11 20:00:15 | host1 | 3500 |
| 2024-07-11 20:00:20 | host1 | 2500 |
| 2024-07-11 20:00:05 | host2 | 114 |
| 2024-07-11 20:00:10 | host2 | 111 |
| 2024-07-11 20:00:15 | host2 | 115 |
| 2024-07-11 20:00:20 | host2 | 95 |
+---------------------+-------+-------------+
8 rows in set (0.06 sec)

Range query 是一个非常强大的功能,用于基于时间窗口查询和聚合数据,请阅读手册以了解更多。

指标和日志的关联查询

通过组合两个表的数据,你可以快速地确定故障时间和相应的日志。以下 SQL 查询使用 JOIN 操作关联指标和日志:

-- 将指标和日志对齐到 5 秒时间桶,然后关联
WITH
-- 指标: 每个主机在 5 秒时间桶内的 p95 延迟
metrics AS (
SELECT
ts,
host,
approx_percentile_cont(0.95) WITHIN GROUP (ORDER BY latency) RANGE '5s' AS p95_latency
FROM grpc_latencies
ALIGN '5s' FILL PREV
),
-- 日志: 相同 5 秒时间桶内每个主机的 ERROR 计数
logs AS (
SELECT
ts,
host,
count(log_msg) RANGE '5s' AS num_errors
FROM app_logs
WHERE log_level = 'ERROR'
ALIGN '5s'
)
SELECT
m.ts,
m.p95_latency,
COALESCE(l.num_errors, 0) AS num_errors,
m.host
FROM metrics m
LEFT JOIN logs l
ON m.host = l.host AND m.ts = l.ts
ORDER BY m.ts, m.host;
+---------------------+-------------+------------+-------+
| ts | p95_latency | num_errors | host |
+---------------------+-------------+------------+-------+
| 2024-07-11 20:00:05 | 104.5 | 0 | host1 |
| 2024-07-11 20:00:05 | 114 | 0 | host2 |
| 2024-07-11 20:00:10 | 4200 | 10 | host1 |
| 2024-07-11 20:00:10 | 111 | 0 | host2 |
| 2024-07-11 20:00:15 | 3500 | 4 | host1 |
| 2024-07-11 20:00:15 | 115 | 0 | host2 |
| 2024-07-11 20:00:20 | 2500 | 0 | host1 |
| 2024-07-11 20:00:20 | 95 | 0 | host2 |
+---------------------+-------------+------------+-------+
8 rows in set (0.02 sec)

我们可以看到当 gRPC 响应时间增大的时间窗口内,错误日志也显著增多,并且确定问题在 host1

通过 PromQL 查询数据

GreptimeDB 支持 Prometheus 查询语言及其 API,允许你使用 PromQL 查询指标。例如,你可以使用以下查询获取每个主机在过去 1 分钟内的 p95 响应时间:

quantile_over_time(0.95, grpc_latencies{host!=""}[1m])

要测试这个查询,使用以下 curl 命令:

curl -X POST \
-H 'Authorization: Basic {{authorization if exists}}' \
--data-urlencode 'query=quantile_over_time(0.95, grpc_latencies{host!=""}[1m])' \
--data-urlencode 'start=2024-07-11 20:00:00Z' \
--data-urlencode 'end=2024-07-11 20:00:20Z' \
--data-urlencode 'step=1m' \
'http://localhost:4000/v1/prometheus/api/v1/query_range'

这里我们设置 step 为 1 分钟。

输出:

{
"status": "success",
"data": {
"resultType": "matrix",
"result": [
{
"metric": {
"__name__": "grpc_latencies",
"host": "host1",
"method_name": "GetUser"
},
"values": [
[
1720728000.0,
"103"
]
]
},
{
"metric": {
"__name__": "grpc_latencies",
"host": "host2",
"method_name": "GetUser"
},
"values": [
[
1720728000.0,
"113"
]
]
}
]
}
}

更强大的是,你可以使用 SQL 来执行 PromQL 并混合使用两者,例如:

TQL EVAL ('2024-07-11 20:00:00Z', '2024-07-11 20:00:20Z','1m')
quantile_over_time(0.95, grpc_latencies{host!=""}[1m]);

这个 SQL 查询将输出:

+---------------------+---------------------------------------------------------+-------+-------------+
| ts | prom_quantile_over_time(ts_range,latency,Float64(0.95)) | host | method_name |
+---------------------+---------------------------------------------------------+-------+-------------+
| 2024-07-11 20:00:00 | 113 | host2 | GetUser |
| 2024-07-11 20:00:00 | 103 | host1 | GetUser |
+---------------------+---------------------------------------------------------+-------+-------------+

重写上面的关联示例:

WITH
metrics AS (
TQL EVAL ('2024-07-11 20:00:00Z', '2024-07-11 20:00:20Z', '5s')
quantile_over_time(0.95, grpc_latencies{host!=""}[5s])
),
logs AS (
SELECT
ts,
host,
COUNT(log_msg) RANGE '5s' AS num_errors
FROM app_logs
WHERE log_level = 'ERROR'
ALIGN '5s'
)
SELECT
m.*,
COALESCE(l.num_errors, 0) AS num_errors
FROM metrics AS m
LEFT JOIN logs AS l
ON m.host = l.host
AND m.ts = l.ts
ORDER BY
m.ts,
m.host;
+---------------------+---------------------------------------------------------+-------+-------------+------------+
| ts | prom_quantile_over_time(ts_range,latency,Float64(0.95)) | host | method_name | num_errors |
+---------------------+---------------------------------------------------------+-------+-------------+------------+
| 2024-07-11 20:00:05 | 103 | host1 | GetUser | 0 |
| 2024-07-11 20:00:05 | 113 | host2 | GetUser | 0 |
| 2024-07-11 20:00:10 | 140.89999999999998 | host1 | GetUser | 10 |
| 2024-07-11 20:00:10 | 113.8 | host2 | GetUser | 0 |
| 2024-07-11 20:00:15 | 3400 | host1 | GetUser | 4 |
| 2024-07-11 20:00:15 | 114 | host2 | GetUser | 0 |
| 2024-07-11 20:00:20 | 3375 | host1 | GetUser | 0 |
| 2024-07-11 20:00:20 | 115 | host2 | GetUser | 0 |
+---------------------+---------------------------------------------------------+-------+-------------+------------+

通过使用 TQL 命令,你可以结合 SQL 和 PromQL 的强大功能,使关联分析和复杂查询不再困难。

GreptimeDB 控制台

GreptimeDB 提供了一个仪表板用于数据探索和管理。

数据探索

按照安装部分中的说明启动 GreptimeDB 后,你可以通过 HTTP 地址 http://localhost:4000/dashboard 访问控制台。

点击 + 按钮添加一个新的查询,在命令文本中编写你的 SQL 命令,然后点击 Run All。 下方的 SQL 会查询 grpc_latencies 表中的所有数据。

SELECT * FROM grpc_latencies;

然后点击结果面板中的 Chart 按钮来可视化数据。

select gRPC latencies

使用 InfluxDB Line Protocol 导入数据

除了 SQL,GreptimeDB 还支持多种协议,其中最常用之一是 InfluxDB Line Protocol。 在仪表板中点击 Ingest 图标,你可以以 InfluxDB Line Protocol 格式上传数据。

例如,将以下数据粘贴到输入框中:

grpc_metrics,host=host1,method_name=GetUser latency=100,code=0 1720728021000000000
grpc_metrics,host=host2,method_name=GetUser latency=110,code=1 1720728021000000000

然后点击 Write 按钮来导入数据到 grpc_metrics 表。如果该表不存在,将会自动创建该表。

下一步

你现在已经体验了 GreptimeDB 的核心功能。 要进一步探索和利用 GreptimeDB: