k8s與監控--改造telegraf的buffer實現

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

改造telegraf的buffer實現

前言

最近在使用telegraf的情境中,要求資料在程式意外終止的時候不丟失。按照telegraf最初的原始實現,在running_output內部維護了兩個buffer,分別是metrics和failMetrics。這兩個buffer是基於go中channel實現的。由於沒有持久化機制,在意外退出的時候,存在遺失資料的風險。所以這篇文章主要講述之前telegraf保證資料安全的一些措施和我們對代碼的一些最佳化。

telegraf關於資料安全的處理辦法

關於兩個buffer,定義在running_output.go的struct中。

// RunningOutput contains the output configurationtype RunningOutput struct {    Name              string    Output            telegraf.Output    Config            *OutputConfig    MetricBufferLimit int    MetricBatchSize   int    MetricsFiltered selfstat.Stat    MetricsWritten  selfstat.Stat    BufferSize      selfstat.Stat    BufferLimit     selfstat.Stat    WriteTime       selfstat.Stat    metrics     *buffer.Buffer    failMetrics *buffer.Buffer    // Guards against concurrent calls to the Output as described in #3009    sync.Mutex}

這個兩個buffer的大小提供了配置參數可以設定。

metrics:           buffer.NewBuffer(batchSize),failMetrics:       buffer.NewBuffer(bufferLimit),

顧名思義。metrics存放要發送到指定output的metric,而failMetrics存放發送失敗的metric。當然失敗的metrics會在telegraf重發機制下再次發送。

    if ro.metrics.Len() == ro.MetricBatchSize {        batch := ro.metrics.Batch(ro.MetricBatchSize)        err := ro.write(batch)        if err != nil {            ro.failMetrics.Add(batch...)        }    }

在向metrics增加metrics的時候,做是否達到批量發送的數量,如果達到就調用發送方法。當然還有定時的解決方案,如果一直沒有達到MetricBatchSize,也會在一定時間後發送資料。具體實現代碼在agent.go中

    ticker := time.NewTicker(a.Config.Agent.FlushInterval.Duration)    semaphore := make(chan struct{}, 1)    for {        select {        case <-shutdown:            log.Println("I! Hang on, flushing any cached metrics before shutdown")            // wait for outMetricC to get flushed before flushing outputs            wg.Wait()            a.flush()            return nil        case <-ticker.C:            go func() {                select {                case semaphore <- struct{}{}:                    internal.RandomSleep(a.Config.Agent.FlushJitter.Duration, shutdown)                    a.flush()                    <-semaphore                default:                    // skipping this flush because one is already happening                    log.Println("W! Skipping a scheduled flush because there is" +                        " already a flush ongoing.")                }            }()

在程式接受到停止訊號後,程式會首先flush剩下的資料到output中,然後退出進程。這樣可以保證一定的資料安全。

基於redis實現buffer的持久化

在持久化機制的選型中,優先實現redis。本身redis效能高,而且具備完善的持久化。
具體的實現架構如下:

將原buffer中功能抽象出buffer.go介面。
具體代碼:

package bufferimport (    "github.com/influxdata/telegraf"    "github.com/influxdata/telegraf/internal/buffer/memory"    "github.com/influxdata/telegraf/internal/buffer/redis")const (    BufferTypeForMemory = "memory"    BufferTypeForRedis  = "redis")type Buffer interface {    IsEmpty() bool    Len() int    Add(metrics ...telegraf.Metric)    Batch(batchSize int) []telegraf.Metric}func NewBuffer(mod string, size int, key, addr string) Buffer {    switch mod {    case BufferTypeForRedis:        return redis.NewBuffer(size, key, addr)    default:        return memory.NewBuffer(size)    }}

然後分別記憶體和redis實現了Buffer介面。
其中NewBuffer相當於一個Factory 方法。
當然在後期可以實現基於file和db等buffer實現,來滿足不同的情境和要求。

redis實現buffer的要點

由於要滿足先進先出的要求,選擇了redis的list資料結構。redis中的list是一個字串list,所以telegraf中metric資料介面要符合序列化的要求。比如屬性需要可匯出,即public。所以這點需要改動telegraf對於metric struct的定義。另外可以選擇json或是msgpack等序列化方式。我們這邊是採用的json序列化的方式。

結語

改造以後,可以根據自己的需求通過設定檔來決定使用channel或是redis來實現buffer。各有優劣,記憶體實現的話,效能高,受到的依賴少。而redis這種分布式儲存,決定了資料安全,但是效能會有一定的損耗,畢竟有大量的序列化和還原序列化以及網路傳輸,當然依賴也增加了,取決於redis的可靠性,建議redis叢集部署。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.