關於 relabel_configs 中 hashmod 的用法

今天有朋友在羣裏問了一段關於 Prometheus hashmod 配置的問題,如圖:

關於 relabel_configs 中 hashmod 的用法

此配置出自 Brian 的博客 scaling-and-federating-prometheus。

那這段配置到底是什麼意思?因爲以前沒用過這個配置,所以只好去翻看源碼。

核心源碼解讀

閱讀的過程中,發現 relabel.go#L41 的代碼與配置非常相關:

func relabel(lset labels.Labels, cfg *config.RelabelConfig) labels.Labels {
    values := make([]string, 0, len(cfg.SourceLabels))
    for _, ln := range cfg.SourceLabels {
        values = append(values, lset.Get(string(ln)))
    }
    val := strings.Join(values, cfg.Separator)

    lb := labels.NewBuilder(lset)

    switch cfg.Action {
    // 此處省略代碼
    // 判斷值是否匹配,如果不匹配那麼將放棄此 target
    case config.RelabelKeep:
        if !cfg.Regex.MatchString(val) {
            return nil
        }
    // 對字段 source_labels 的值進行 md5 和取餘,並將結果存到自定義目標字段中
    case config.RelabelHashMod:
        mod := sum64(md5.Sum([]byte(val))) % cfg.Modulus
        lb.Set(cfg.TargetLabel, fmt.Sprintf("%d", mod))
    // 此處省略代碼
    default:
        panic(fmt.Errorf("relabel: unknown relabel action type %q", cfg.Action))
    }

    return lb.Labels()
}

有了代碼參考,一開始的配置就容易理解了,它的邏輯爲:

配置的第一個 souce_labels 是對同一個任務抓取目標的 LabelSet 進行預處理,具體而言就是將抓取目標地址進行 hashmod, 並將 hashmod 的值存到一個自定義字段 tmp_hash 中。
配置的第二個 souce_labels 對預處理後的抓取目標進行篩選,只選取
tmp_hash 值滿足正則匹配的,例子中 hashmod != 1 將全部被忽略。
通過以上兩步,就非常容易對相同 job 的抓取目標進行散列,從而抓取命中的部分。

散列均衡性測試

抓取目標的散列是否足夠均衡呢?

下面是根據 Prometheus 的 mod 計算方法編寫的一段測試代碼:

package main

import (
    "crypto/md5"
    "fmt"
)

func main() {
    nodes := []string{
        "192.168.1.1:9090", "192.168.1.2:9090", "192.168.1.3:9090", "192.168.1.4:9090", "192.168.1.5:9090",
        "192.168.1.6:9090", "192.168.1.7:9090", "192.168.1.8:9090", "192.168.1.9:9090", "192.168.1.10:9090",        
    }

    for _, ip := range nodes {
       mod := sum64(md5.Sum([]byte(ip))) % 3
       fmt.Printf("%s mode is %d \n", ip, mod)
    }

}

func sum64(hash [md5.Size]byte) uint64 {
    var s uint64

    for i, b := range hash {
        shift := uint64((md5.Size - i - 1) * 8)

        s |= uint64(b) << shift
    }
    return s
}

輸出結果爲:

192.168.1.1:9090 mode is 3
192.168.1.2:9090 mode is 1
192.168.1.3:9090 mode is 0
192.168.1.4:9090 mode is 0
192.168.1.5:9090 mode is 1
192.168.1.6:9090 mode is 2
192.168.1.7:9090 mode is 3
192.168.1.8:9090 mode is 1
192.168.1.9:9090 mode is 1
192.168.1.10:9090 mode is 1

可以看到,當目標地址足夠多的時候,還是能夠滿足均勻散列。

配置的意義

以前在文章 Prometheus 集羣方案之 remote read 實戰 中已經介紹過按照業務將 Prometheus server 拆分成的思路,即便如此,有些數據(比如一個機房的所有機器信息)還是特別大,超過了單機承載能力。

此時我們可以採用 hashmod 配置,使用同樣的配置列表,將抓取目標散列到不同的 Prometheus server 中去, 從而很好實現 Prometheus 數據收集的橫向擴展。

Mysql 備份恢復分享

時間:7月11日21:00-22:00

大綱

備份基本概念
備份工具
備份恢復的常見方案
嘉賓: Carlos
多年 MYSQL 運維工程師,愛庫存 DBA,擅長常用 MySQL 環境部署與調優,熟悉雲廠商數據庫服務功能實現原理,喜歡研究阿里數據庫月報。
獲取鏈接找它WeChat:17812796384

Python 免費視頻(100+課時)
鏈接: https://pan.baidu.com/s/1ACq_TJ0yT94nEGmqzXWtLA 提取碼: ex2j
(下載播放器和視頻,用播放器打開視頻輸入下面的註冊碼和id就可以觀看了)
註冊碼: kUxVvtuuA6 學校ID:V00419
如有任何操作問題聯繫WeChat amy:17812796384

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章