Influxdb的Meta data分析
Meta分析
一圖抵千言
metadata.png
按上圖,我們從右到從逐一簡單介紹一下
ShardInfo
定義了一個Shard的id和它位於哪個data node上;
ShardGroupInfo
封裝了ShardGroup的相關資訊
Influxdb是按時間寫入資料的,每個DB都有自己的
Retention Policy
(這個我們後面會介紹),這個Retention Policy
規定了每兩個ShardGroup之間的時間跨度ShardGroup Duration
, 即每過一個ShardGrup Duration
就會生產切換到下一個新的ShardGroup;這個ShardGroupInfo就記錄了當前這個ShardGroup的相關資訊,比較主要的資訊有:
3.1 StartTime: 這個Group裡最早的時間
3.2 EndTime: 這個Group裡最晚的時間
3.3 根據上面的兩個時間,我們就可以按時間和時間範圍來查詢到相應的ShardGroup;
3.4 Shards []ShardInfo: 這個ShardGroup包含的所有Shard,對於同一個ShardGroup,按Series key(Point key)不同雜湊寫到不同的Shard中;
RetentionPolicyInfo
封裝了Retention Policy: 包括了複本個數,資料保留時長,ShardGroup切分時長和當前節點的所有
ShardGroup
資訊定義了按時間和時間範圍查詢相應SahrdGroup的方法
DatabaseInfo
管理
RetentionPolicies
和ContinuousQueries
UserInfo
封裝了使用者資訊:使用者名稱,密碼,對db的操作許可權
總結
上面介紹的每個物件基礎都提供了對其管理的下層metadata資訊的增,刪,查的方法;
Meta Client
定義
定義在
services/meta/client.go
中,負責所有和meta data有關的操作和請求處理
type Client struct { logger *zap.Logger mu sync.RWMutex closing chan struct{} changed chan struct{} cacheData *Data // Authentication cache. authCache map[string]authUser path string retentionAutoCreate bool}
主要就是操作上面介紹過的cacheData *Data
;
提供了大量的方法,基出上都是對上述
Data
型別包含的meta資訊的增,刪,查,改操作
主要方法介紹
snapshot
方法:將meta資料寫入磁碟,所有的meta資訊都有對應的protocol buffer結構,依賴protocol buffer作序列化和反序列化:
func snapshot(path string, data *Data) error { filename := filepath.Join(path, metaFile) tmpFile := filename + "tmp" f, err := os.Create(tmpFile) defer f.Close() var d []byte //利用protocol buffer作二進位制的序列化 if b, err := data.MarshalBinary(); err != nil { return err } else { d = b } //寫入檔案 if _, err := f.Write(d); err != nil { return err } if err = f.Sync(); err != nil { return err } //close file handle before renaming to support Windows if err = f.Close(); err != nil { return err } return file.RenameFile(tmpFile, filename) }
Load
方法:meta資料是會儲存到磁碟的,influxdb啟動時也會從磁碟上讀取:
func (c *Client) Load() error { file := filepath.Join(c.path, metaFile) f, err := os.Open(file) defer f.Close() data, err := ioutil.ReadAll(f) //利用protocol buffer作反序列化 if err := c.cacheData.UnmarshalBinary(data); err != nil { return err } return nil}
commit
方法:influxdb執行時,所有的meta資訊在記憶體裡都快取一分,當meta資訊有改動時,透過此方法立即寫入磁碟,同時更新記憶體裡的快取
func (c *Client) commit(data *Data) error { data.Index++ // try to write to disk before updating in memory if err := snapshot(c.path, data); err != nil { return err } // update in memory c.cacheData = data // close channels to signal changes close(c.changed) c.changed = make(chan struct{}) return nil}
ShardGroupsByTimeRange
和ShardsByTimeRange
:按給定的時間查詢已有的ShardGroup和Shard
func (c *Client) ShardGroupsByTimeRange(database, policy string, min, max time.Time) (a []ShardGroupInfo, err error) { ... // 先找到RetentionPolicyInfo rpi, err := c.cacheData.RetentionPolicy(database, policy) if err != nil { return nil, err } else if rpi == nil { return nil, influxdb.ErrRetentionPolicyNotFound(policy) } groups := make([]ShardGroupInfo, 0, len(rpi.ShardGroups)) //遍歷RPI中的所有ShardGroup for _, g := range rpi.ShardGroups { if g.Deleted() || !g.Overlaps(min, max) { continue } groups = append(groups, g) } return groups, nil}
PrecreateShardGroups
: 預先建立ShardGroup, 避免在相應時間段資料到達時才建立ShardGroup
func (c *Client) PrecreateShardGroups(from, to time.Time) error { c.mu.Lock() defer c.mu.Unlock() data := c.cacheData.Clone() var changed bool // 遍歷所有的DatabaseInfo資訊 for _, di := range data.Databases { for _, rp := range di.RetentionPolicies { if len(rp.ShardGroups) == 0 { // No data was ever written to this group, or all groups have been deleted. continue } // ShardGroups中的所有ShardGroup已經是按時間排序好的,最後一個也就是最新的一個ShardGroup g := rp.ShardGroups[len(rp.ShardGroups)-1] // Get the last group in time. // if !g.Deleted() && g.EndTime.Before(to) && g.EndTime.After(from) { // Group is not deleted, will end before the future time, but is still yet to expire. // This last check is important, so the system doesn't create shards groups wholly // in the past. // Create successive shard group. // 計算出需要建立的ShardGroup的開始時間 nextShardGroupTime := g.EndTime.Add(1 * time.Nanosecond) // if it already exists, continue if sg, _ := data.ShardGroupByTimestamp(di.Name, rp.Name, nextShardGroupTime); sg != nil { continue } newGroup, err := createShardGroup(data, di.Name, rp.Name, nextShardGroupTime) if err != nil { continue } changed = true } } } if changed { if err := c.commit(data); err != nil { return err } } return nil}
Influxdb定義了一個Service:Precreator Serivec(services/precreator/service.go),實現比較簡單,週期性的呼叫PrecreateShardGroups
,看是否需要建立ShardGroup
func (s *Service) runPrecreation() { defer s.wg.Done() for { select { case <-time.After(s.checkInterval): if err := s.precreate(time.Now().UTC()); err != nil { s.Logger.Info("Failed to precreate shards", zap.Error(err)) } case <-s.done: s.Logger.Info("Terminating precreation service") return } } }
作者:掃帚的影子
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3034/viewspace-2817413/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- R資料分析:網狀meta分析的理解與實操
- influxdb知識總結(2)--- influxdb 中的重要概念UX
- influxdbUX
- Data Lake Analytics的Geospatial分析函式函式
- Meta分析如何聯絡原作者?
- Flutter框架分析- Parent DataFlutter框架
- influxdb的基本概念UX
- InfluxDB入門UX
- meta元素的用法
- meta
- SpringBoot2.0原始碼分析(四):spring-data-jpa分析Spring Boot原始碼
- influxdb使用入門UX
- JMeter+InfluxDB+GrafanaJMeterUXGrafana
- [異常等待事件latch undo global data]分析事件
- TLS1.3抓包分析----解密Application DataTLS解密APP
- Meta Learning
- Kubernetes監控之InfluxDBUX
- Influxdb 介紹與使用UX
- influxdb 原理與應用UX
- Jmeter+Influxdb+Grafana搭建JMeterUXGrafana
- InfluxDB 管理工具UX
- InfluxDB Linux 下安裝Linux
- Go 實現 nginx log 讀取 分析 寫入InfluxDB 並用Grafana 顯示GoNginxUXGrafana
- InfluxDB從原理到實戰 - 一篇文章搞懂InfluxDB時區UX
- 為什麼是InfluxDB | 寫在《InfluxDB原理和實戰》出版之際UX
- 故障分析 | 從 data_free 異常說起
- [效能測試+資料採集展示分析+告警策略]Jmeter+Collectd+Influxdb+GrafanaJMeterUXGrafana
- Web 頁面 Meta 的 Referrer PolicyWeb
- meta標籤的作用及整理
- influxdb官網文件翻譯UX
- InfluxDB簡介與php用法UXPHP
- Influxdb 資料寫入流程UX
- 時序資料庫influxdb資料庫UX
- influxDB叢集模式實踐UX模式
- influxdb與傳統資料庫的比較UX資料庫
- Node.js連線influxdb的使用封裝Node.jsUX封裝
- 時序資料庫之InfluxDB的基本操作資料庫UX
- 時序資料庫InfluxDB的基本語法資料庫UX