VictorialMetrics 集羣模式的使用

前面我們介紹了單節點版本的 VictorialMetrics 的使用,對於低於每秒一百萬個數據點的攝取率,建議使用單節點版本而不是集羣版本。單節點版本可根據 CPU 內核、RAM 和可用存儲空間的數量進行擴展。單節點版本比集羣版本更容易配置和操作,所以在使用集羣版本之前要三思而後行。上面我們介紹了 VM 的單節點版本的基本使用,接下來我們來介紹下如何使用集羣版。

集羣版主要特點:

組件

前面我們瞭解了 VM 的基本架構,對於集羣模式下主要包含以下幾個服務:

每個服務都可以進行獨立擴展,vmstorage 節點之間互不瞭解、互不通信,並且不共享任何數據。這樣可以增加集羣的可用性,並且簡化了集羣的維護和擴展。最小的集羣必須包含以下節點:

但是我們建議爲每個服務組件運行至少兩個節點以實現高可用性,這樣當單個節點暫時不可用時,集羣會繼續工作,而且其餘節點還可以處理增加的工作負載。如果你的集羣規模較大,那麼可以運行多個小型的 vmstorage 節點,因爲這樣可以在某些 vmstorage 節點暫時不可用時減少剩餘 vmstorage 節點上的工作負載增加。

各個服務除了可以通過參數標誌進行配置之外,也可以通過環境變量的方式進行配置:

多租戶

VM 集羣也支持多個獨立的租戶(也叫命名空間),租戶由 accountIDaccountID:projectID 來標識,它們被放在請求的 urls 中。

集羣擴展

VM 集羣的性能和容量可以通過兩種方式進行擴展:

對於集羣擴展有一些通用的建議:

集羣可用性

去重

如果 -dedup.minScrapeInterval 命令行標誌設置爲大於 0 的時間,VictoriaMetrics 會去除重複數據點。例如,-dedup.minScrapeInterval=60s 將對同一時間序列上的數據點進行重複數據刪除,如果它們位於同一離散的 60 秒存儲桶內,最早的數據點將被保留。在時間戳相等的情況下,將保留任意數據點。

-dedup.minScrapeInterval推薦值是等於 Prometheus 配置中的 scrape_interval 的值,建議在所有抓取目標中使用一個 scrape_interval 配置。

如果 HA 中多個相同配置的 vmagent 或 Prometheus 實例將數據寫入同一個 VictoriaMetrics 實例,則重複數據刪除會減少磁盤空間使用。這些 vmagent 或 Prometheus 實例在其配置中必須具有相同的 external_labels 部分,因此它們將數據寫入相同的時間序列。

容量規劃

集羣容量隨着可用資源的增加而線性擴展,每個節點類型所需的 CPU 和內存數量很大程度上取決於工作負載 - 活躍時間序列的數量、序列流失率、查詢類型、查詢 QPS 等。建議爲你的生產工作負載部署一個測試的 VictoriaMetrics 集羣,並反覆調整每個節點的資源和每個節點類型的節點數量,直到集羣變得穩定。同樣也建議爲集羣設置監控,有助於確定集羣設置中的瓶頸問題。

指定保留所需的存儲空間(可以通過 vmstorage 中的 -retentionPeriod 命令行標誌設置)可以從測試運行中的磁盤空間使用情況推斷出來。例如,如果在生產工作負載上運行一天後的存儲空間使用量爲 10GB,那麼對於 -retentionPeriod=100d(100 天保留期)來說,它至少需要 10GB*100=1TB 的磁盤空間。可以使用 VictoriaMetrics 集羣的官方 Grafana 儀表板 (https://grafana.com/grafana/dashboards/11176) 監控存儲空間使用情況。

建議留出以下數量的備用資源。

VictoriaMetrics 集羣的一些容量規劃技巧:

副本和數據安全

默認情況下,VictoriaMetrics 的數據複製依賴 -storageDataPath 指向的底層存儲來完成。

但是我們也可以手動通過將 -replicationFactor=N 命令參數傳遞給 vminsert 來啓用複製,這保證瞭如果多達 N-1vmstorage 節點不可用,所有數據仍可用於查詢。集羣必須至少包含 2*N-1vmstorage 節點,其中 N 是複製因子,以便在 N-1 個存儲節點丟失時爲新攝取的數據維持指定的複製因子。

例如,當 -replicationFactor=3 傳遞給 vminsert 時,它將所有攝取的數據複製到 3 個不同的 vmstorage 節點,因此最多可以丟失 2 個 vmstorage 節點而不會丟失數據。vmstorage 節點的最小數量應該等於 2*3-1 = 5,因此當 2 個 vmstorage 節點丟失時,剩餘的 3 個 vmstorage 節點可以爲新攝取的數據提供服務。

啓用複製後,必須將 -dedup.minScrapeInterval=1ms 命令行標誌傳遞給 vmselect 節點,當多達 N-1vmstorage 節點響應緩慢和 / 或暫時不可用時,可以將可選的 -replicationFactor=N 參數傳遞給 vmselect 以提高查詢性能,因爲 vmselect 不等待來自多達 N-1vmstorage 節點的響應。有時,vmselect 節點上的 -replicationFactor 可能會導致部分響應。-dedup.minScrapeInterval=1ms 在查詢期間對複製的數據進行重複數據刪除,如果重複數據從配置相同的 vmagent 實例或 Prometheus 實例推送到 VictoriaMetrics,則必須根據重複數據刪除文檔將 -dedup.minScrapeInterval 設置爲更大的值。

請注意,複製不會從災難中保存,因此建議執行定期備份。另外 複製會增加資源使用率 - CPU、內存、磁盤空間、網絡帶寬 - 最多 -replicationFactor 倍。所以可以將複製轉移 -storageDataPath 指向的底層存儲來做保證,例如 Google Compute Engine 永久磁盤,該磁盤可以防止數據丟失和數據損壞,它還提供始終如一的高性能,並且可以在不停機的情況下調整大小。對於大多數用例來說,基於 HDD 的永久性磁盤應該足夠了。

備份

建議從即時快照執行定期備份,以防止意外數據刪除等錯誤。必須爲每個 vmstorage 節點執行以下步驟來創建備份:

從備份恢復:

在瞭解了 VM 集羣的一些配置細節後,接下來我們就來開始部署 VM 集羣。

部署

如果你已經對 VM 組件非常瞭解了,那麼推薦使用 Helm Chart 的方式進行一鍵安裝。

☸ ➜ helm repo add vm https://victoriametrics.github.io/helm-charts/
☸ ➜ helm repo update
# 導出默認的 values 值到 values.yaml 文件中
☸ ➜ helm show values vm/victoria-metrics-cluster > values.yaml
# 根據自己的需求修改 values.yaml 文件配置
# 執行下面的命令進行一鍵安裝
☸ ➜ helm install victoria-metrics vm/victoria-metrics-cluster -f values.yaml -n NAMESPACE
# 獲取 vm 運行的 pods 列表
☸ ➜ kubectl get pods -A | grep 'victoria-metrics'

我們這裏選擇手動方式進行部署,之所以選擇手動部署的方式是爲了能夠了解各個組件的更多細節。

由於 vmstorage 組件是無狀態的,這裏我們先使用 StatefulSet 進行部署,由於該組件也是可以進行擴展的,這裏我們首先部署兩個副本,對應的資源清單如下所示:

# cluster-vmstorage.yaml
apiVersion: v1
kind: Service
metadata:
  name: cluster-vmstorage
  namespace: kube-vm
  labels:
    app: vmstorage
spec:
  clusterIP: None
  ports:
    - port: 8482
      targetPort: http
      name: http
    - port: 8401
      targetPort: vmselect
      name: vmselect
    - port: 8400
      targetPort: vminsert
      name: vminsert
  selector:
    app: vmstorage
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: vmstorage
  namespace: kube-vm
  labels:
    app: vmstorage
spec:
  serviceName: cluster-vmstorage
  selector:
    matchLabels:
      app: vmstorage
  replicas: 2
  podManagementPolicy: OrderedReady
  template:
    metadata:
      labels:
        app: vmstorage
    spec:
      containers:
        - name: vmstorage
          image: "victoriametrics/vmstorage:v1.77.0-cluster"
          imagePullPolicy: "IfNotPresent"
          args:
            - "--retentionPeriod=1"
            - "--storageDataPath=/storage"
            - --envflag.enable=true
            - --envflag.prefix=VM_
            - --loggerFormat=json
          ports:
            - name: http
              containerPort: 8482
            - name: vminsert
              containerPort: 8400
            - name: vmselect
              containerPort: 8401
          livenessProbe:
            failureThreshold: 10
            initialDelaySeconds: 30
            periodSeconds: 30
            tcpSocket:
              port: http
            timeoutSeconds: 5
          readinessProbe:
            failureThreshold: 3
            initialDelaySeconds: 5
            periodSeconds: 15
            timeoutSeconds: 5
            httpGet:
              path: /health
              port: http
          volumeMounts:
            - name: storage
              mountPath: /storage
  volumeClaimTemplates:
    - metadata:
        name: storage
      spec:
        storageClassName: longhorn
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: "2Gi"

首先需要創建一個 Headless 的 Service,因爲後面的組件需要訪問到每一個具體的 Pod,在 vmstorage 啓動參數中通過 --retentionPeriod 參數指定指標數據保留時長,1 表示一個月,這也是默認的時長,然後通過 --storageDataPath 參數指定了數據存儲路徑,記得要將該目錄進行持久化。

同樣直接應用該資源即可:

☸ ➜ kubectl apply -f https://p8s.io/docs/victoriametrics/manifests/cluster-vmstorage.yaml
☸ ➜ kubectl get pods -n kube-vm -l app=vmstorage
NAME          READY   STATUS    RESTARTS   AGE
vmstorage-0   1/1     Running   0          5m40s
vmstorage-1   1/1     Running   0          3m31s
☸ ➜ kubectl get svc -n kube-vm -l app=vmstorage
NAME                TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                      AGE
cluster-vmstorage   ClusterIP   None         <none>        8482/TCP,8401/TCP,8400/TCP   5m46s

接着可以部署 vmselect 組件,由於該組件是無狀態的,我們可以直接使用 Deployment 來進行管理,對應的資源清單文件如下所示:

# cluster-vmselect.yaml
apiVersion: v1
kind: Service
metadata:
  name: vmselect
  namespace: kube-vm
  labels:
    app: vmselect
spec:
  ports:
    - name: http
      port: 8481
      targetPort: http
  selector:
    app: vmselect
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vmselect
  namespace: kube-vm
  labels:
    app: vmselect
spec:
  selector:
    matchLabels:
      app: vmselect
  template:
    metadata:
      labels:
        app: vmselect
    spec:
      containers:
        - name: vmselect
          image: "victoriametrics/vmselect:v1.77.0-cluster"
          imagePullPolicy: "IfNotPresent"
          args:
            - "--cacheDataPath=/cache"
            - --storageNode=vmstorage-0.cluster-vmstorage.kube-vm.svc.cluster.local:8401
            - --storageNode=vmstorage-1.cluster-vmstorage.kube-vm.svc.cluster.local:8401
            - --envflag.enable=true
            - --envflag.prefix=VM_
            - --loggerFormat=json
          ports:
            - name: http
              containerPort: 8481
          readinessProbe:
            httpGet:
              path: /health
              port: http
            initialDelaySeconds: 5
            periodSeconds: 15
            timeoutSeconds: 5
            failureThreshold: 3
          livenessProbe:
            tcpSocket:
              port: http
            initialDelaySeconds: 5
            periodSeconds: 15
            timeoutSeconds: 5
            failureThreshold: 3
          volumeMounts:
            - mountPath: /cache
              name: cache-volume
      volumes:
        - name: cache-volume
          emptyDir: {}

其中最重要的部分是通過 --storageNode 參數指定所有的 vmstorage 節點地址,上面我們使用的 StatefulSet 部署的,所以可以直接使用 FQDN 的形式進行訪問。直接應用上面的對象:

☸ ➜ kubectl apply -f https://p8s.io/docs/victoriametrics/manifests/cluster-vmselect.yaml
☸ ➜ kubectl get pods -n kube-vm -l app=vmselect
NAME                       READY   STATUS    RESTARTS   AGE
vmselect-bcb54965f-5rkml   1/1     Running   0          2m4s
☸ ➜ kubectl get svc -n kube-vm -l app=vmselect
NAME       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
vmselect   ClusterIP   10.107.227.214   <none>        8481/TCP   2m17s

如果要進行查詢,那麼我們可以直接對外暴露 vmselect 這個 Service 服務即可,修改 Grafana 數據源地址爲 http://<select-service>/select/0/prometheus/

接着就需要部署用來接收指標數據插入的 vminsert 組件,同樣該組件是無狀態的,其中最重要的也是需要通過 --storageNode 參數指定所有的 vmstorage 節點:

# cluster-vminsert.yaml
apiVersion: v1
kind: Service
metadata:
  name: vminsert
  namespace: kube-vm
  labels:
    app: vminsert
spec:
  ports:
    - name: http
      port: 8480
      targetPort: http
  selector:
    app: vminsert
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vminsert
  namespace: kube-vm
  labels:
    app: vminsert
spec:
  selector:
    matchLabels:
      app: vminsert
  template:
    metadata:
      labels:
        app: vminsert
    spec:
      containers:
        - name: vminsert
          image: "victoriametrics/vminsert:v1.77.0-cluster"
          imagePullPolicy: "IfNotPresent"
          args:
            # - -replicationFactor=2 # 可以開啓數據副本
            - --storageNode=vmstorage-0.cluster-vmstorage.kube-vm.svc.cluster.local:8400
            - --storageNode=vmstorage-1.cluster-vmstorage.kube-vm.svc.cluster.local:8400
            - --envflag.enable=true
            - --envflag.prefix=VM_
            - --loggerFormat=json
          ports:
            - name: http
              containerPort: 8480
          readinessProbe:
            httpGet:
              path: /health
              port: http
            initialDelaySeconds: 5
            periodSeconds: 15
            timeoutSeconds: 5
            failureThreshold: 3
          livenessProbe:
            tcpSocket:
              port: http
            initialDelaySeconds: 5
            periodSeconds: 15
            timeoutSeconds: 5
            failureThreshold: 3

由於本身是無狀態的,所以可以根據需要增加副本數量,也可以配置 HPA 進行自動擴縮容。直接應用上面的資源清單:

☸ ➜ kubectl apply -f https://p8s.io/docs/victoriametrics/manifests/cluster-vminsert.yaml
☸ ➜ kubectl get pods -n kube-vm -l app=vminsert
NAME                        READY   STATUS    RESTARTS   AGE
vminsert-66c88cd497-l64ps   1/1     Running   0          2m27s
☸ ➜ kubectl get svc -n kube-vm -l app=vminsert
NAME       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
vminsert   ClusterIP   10.96.125.134   <none>        8480/TCP   70s

集羣模式的相關組件部署完成後,同樣我們可以先去配置前面的 Prometheus,將其數據遠程寫入到 VM 中來,修改 remote_write 的地址爲 http://vminsert:8480/insert/0/prometheus/,注意和單節點模式的 API 路徑不一樣,如下所示:

# vm-prom-config3.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: kube-vm
data:
  prometheus.yaml: |
    global:
      scrape_interval: 15s
      scrape_timeout: 15s
    remote_write:    # 寫入到遠程 VM 存儲,url 是遠程寫入接口地址
    - url: http://vminsert:8480/insert/0/prometheus/
      # queue_config:    # 如果 Prometheus 抓取指標很大,可以加調整 queue,但是會提高內存佔用
      #   max_samples_per_send: 10000  # 每次發送的最大樣本數
      #   capacity: 20000  
      #   max_shards: 30   # 最大分片數,即併發量。
    scrape_configs:
    - job_name: "nodes"
      static_configs:
      - targets: ['192.168.0.109:9111''192.168.0.110:9111''192.168.0.111:9111']
      relabel_configs: # 通過 relabeling 從 __address__ 中提取 IP 信息,爲了後面驗證 VM 是否兼容 relabeling
      - source_labels: [__address__]
        regex: "(.*):(.*)"
        replacement: "${1}"
        target_label: 'ip'
        action: replace

更新 Prometheus 配置,然後啓動 Prometheus,前面的單機模式的 VM 可以先停掉:

☸ ➜ kubectl apply -f https://p8s.io/docs/victoriametrics/manifests/vm-prom-config3.yaml
☸ ➜ kubectl scale deploy victoria-metrics --replicas=0 -n kube-vm
☸ ➜ kubectl scale deploy prometheus --replicas=1 -n kube-vm

配置成功後正常數據就可以開始寫入到 vmstorage 了,查看 vmstorage 日誌可以看到成功創建了 partition,證明現在已經在開始接收數據了:

☸ ➜ kubectl logs -f vmstorage-0 -n kube-vm
......
{"ts":"2022-05-06T08:35:15.786Z","level":"info","caller":"VictoriaMetrics/lib/storage/partition.go:206","msg":"creating a partition \"2022_05\" with smallPartsPath=\"/storage/data/small/2022_05\", bigPartsPath=\"/storage/data/big/2022_05\""}
{"ts":"2022-05-06T08:35:15.802Z","level":"info","caller":"VictoriaMetrics/lib/storage/partition.go:222","msg":"partition \"2022_05\" has been created"}

然後可以去 Grafana 重新查看 Dashboard 是否正常:

如果現在需要新增 vmstorage 節點,那麼需要按照下面的步驟進行操作:

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/NDPgeCxNnz84etMHNt0wJg