跳到主要内容

Query Frontend

前面我们了解到 querier 这个组件可以提供一个统一的查询入口,所以当查询的数据规模较大的时候,对 querier 组件也会有很大的压力,为此 Thanos 也提供了一个 Query Frontend 的组件来提升性能,当然该组件是可选的。

Thanos Query Frontend 是 Thanos Query 的前端,它的目标是将大型查询拆分为多个较小的查询,并缓存查询结果来提升性能。

概述

Thanos Query Frontend 组件通过 thanos query-frontend 命令实现了一个放在 querier 前面的服务,以改进读取路径。它基于 Cortex Query Frontend 组件,所以你可以找到一些 Cortex 常见的特性,如查询拆分和结果缓存。可以使用下列命令来启动 Thanos Query Frontend:

thanos query-frontend \
--http-address "0.0.0.0:9090" \
--query-frontend.downstream-url="<thanos-querier>:<querier-http-port>"

目前只有范围查询(/api/v1/query_range 接口调用)实际上是通过 Query Frontend 处理的。所有其他 API 调用只是直接转到下游查询器,这意味着只有范围查询被拆分和缓存,但我们也计划支持即时查询。

特性

查询拆分

query frontend 会将多天的的查询拆分为多个单天的查询,游下游的 querier 去并行处理这些已拆分的查询。返回的查询结果由 query frontend 进行汇聚。这样可以防止大时间跨度的查询导致 queier 发生 OOM,并且能够更快的执行查询以及更好的查询负载均衡。查询前端根据配置的 --query-range.split-interval 标志将长查询拆分为多个短查询,--query-range.split-interval 的默认值为 24 小时,启用缓存时,它应该大于 0。

重试机制

query frontend 支持在 HTTP 请求失败时重试查询的重试机制,有一个 --query-range.max-retries-per-request 标志来限制最大重试次数。

查询缓存

query frontend 支持将查询结果进行缓存用以加速后续的查询。当缓存的结果不够完整时,query frontend 会计算出所需要的子查询并分配给下游的 querier 并行执行,子查询的步长会对齐以提升查询结果的可缓存性。当前支持的缓存后端有:memcached,redis 和内存,下面是这些缓存后端的一些配置。

内存缓存

type: IN-MEMORY
config:
max_size: ''
max_size_items: 0
validity: 0s

max_size 表示在内存中缓存的最大尺寸,单位可以是 KB、MB、GB。如果 max_size 和 max_size_items 都没有设置,就不会创建缓存。如果只设置 max_size 或 max_size_items 中的任意一个,则对其他字段没有限制。

memcached

type: MEMCACHED
config:
addresses: [your-memcached-addresses]
timeout: 500ms
max_idle_connections: 100
max_item_size: 1MiB
max_async_concurrency: 10
max_async_buffer_size: 10000
max_get_multi_concurrency: 100
max_get_multi_batch_size: 0
dns_provider_update_interval: 10s
expiration: 24h

expiration 表示指定 memcached 缓存有效时间,如果设置为 0,则使用默认的 24 小时过期时间,上面的配置是默认的 memcached 配置。

Redis

默认的 Redis 配置如下:

type: REDIS
config:
addr: ''
username: ''
password: ''
db: 0
dial_timeout: 5s
read_timeout: 3s
write_timeout: 3s
pool_size: 100
min_idle_conns: 10
idle_timeout: 5m0s
max_conn_age: 0s
max_get_multi_concurrency: 100
get_multi_batch_size: 100
max_set_multi_concurrency: 100
set_multi_batch_size: 100
expiration: 24h0m0s

expiration 表示指定 Redis 缓存有效时间,如果设置为 0,则使用默认的 24 小时过期时间。

慢查询日志

query frontend 还支持通过配置 --query-frontend.log-queries-longer-than 标志来记录运行时间超过某个持续时间的查询。

安装

安装 query frontend 最重要的就是通过 -query-frontend.downstream-url 指定下游的 querier,如下所示:

# thanos-query-frontend.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: thanos-query-frontend
namespace: kube-mon
labels:
app: thanos-query-frontend
spec:
selector:
matchLabels:
app: thanos-query-frontend
template:
metadata:
labels:
app: thanos-query-frontend
spec:
containers:
- name: thanos
image: thanosio/thanos:v0.25.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9090
name: http
args:
- query-frontend
- --log.level=info
- --log.format=logfmt
- --query-frontend.compress-responses
- --http-address=0.0.0.0:9090
- --query-frontend.downstream-url=http://thanos-querier.kube-mon.svc.cluster.local:9090
- --query-range.split-interval=12h
- --query-range.max-retries-per-request=10
- --query-frontend.log-queries-longer-than=10s
- --labels.split-interval=12h
- --labels.max-retries-per-request=10
- |-
--query-range.response-cache-config="config":
max_size: "200MB"
max_size_items: 0
validity: 0s
type: IN-MEMORY
- |-
--labels.response-cache-config="config":
max_size: "200MB"
max_size_items: 0
validity: 0s
type: IN-MEMORY
env:
- name: HOST_IP_ADDRESS
valueFrom:
fieldRef:
fieldPath: status.hostIP
livenessProbe:
failureThreshold: 4
httpGet:
path: /-/healthy
port: 9090
scheme: HTTP
periodSeconds: 30
readinessProbe:
failureThreshold: 20
httpGet:
path: /-/ready
port: 9090
scheme: HTTP
periodSeconds: 5
resources:
requests:
memory: 512Mi
cpu: 500m
limits:
memory: 512Mi
cpu: 500m
---
apiVersion: v1
kind: Service
metadata:
name: thanos-query-frontend
namespace: kube-mon
labels:
app: thanos-query-frontend
spec:
ports:
- name: http
port: 9090
targetPort: 9090
selector:
app: thanos-query-frontend
type: NodePort

这里我们开启了缓存,使用内存缓存,直接通过 -query-range.response-cache-config 参数来配置缓存配置,也可以通过 -query-range.response-cache-config-file 指定缓存配置文件,两种方式均可,为了验证结果,这里创建了一个 NodePort 类型的 Service,直接创建上面的资源对象即可:

☸ ➜ kubectl apply -f https://p8s.io/docs/thanos/manifests/thanos-query-frontend.yaml
☸ ➜ kubectl get pods -n kube-mon -l app=thanos-query-frontend
NAME READY STATUS RESTARTS AGE
thanos-query-frontend-78954bc857-nkxkk 1/1 Running 0 151m
☸ ➜ kubectl get svc -n kube-mon -l app=thanos-query-frontend
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
thanos-query-frontend NodePort 10.97.182.150 <none> 9090:30514/TCP 152m

然后可以通过任意节点的 30514 端口访问到查询前端:

查询前端

该前端页面和 querier 组件是一致的,但是在 querier 前面缓存包装了一层。