---
# System prepended metadata

title: Observability

---

Observability
====
上篇回顧
[分布式可觀測性  Logging 淺談](https://ithelp.ithome.com.tw/articles/10277525/)
[分布式可觀測性 Structured Log](https://ithelp.ithome.com.tw/articles/10277678)

繼續淺談Observability的另兩個基石
- Metrics
- Tracing

# Metrics
在單體式架構上,主要的監控對象是OS與機器這物理節點, 所以經常直接使用OS自帶的工具.
以Linux來說```top```來看每個Process的CPU使用率、記憶體用量, ```mpstat```, ```vmstat```, ```iostat```等等的.
![linuxperf](https://ithelp.ithome.com.tw/upload/images/20211004/201049301Byy7jttuK.png)
Windows則是Task manager.
透過這些OS提供的命令與工具來監控.

但在現在分布式架構下, 數十數百台機器或是在VM上的OS, 監控的可觀測性成了挑戰.
於是陸續誕生了Cacti、Zabbix、Prometheus等很多監控系統, 
它們的特色是metrics數據的收集、數據的存放、數據的查詢展示都分離開來. 彼此透過網路協議與介面來傳遞資料.

現在常見的架構有兩種,
一種是數據的收集以Library形式, 與業務系統整合在程式專案中, 
在程式碼埋點的方式, 以Client調用的角度, 把調用資源或服務的耗時、請求量、慢查詢量, 
甚至能收集GC的資訊等等的送給另一個獨立出來的數據處理服務去做處理與分析.

以Go來說, Prometheus就有提供這樣的[Library](https://prometheus.io/docs/guides/go-application/)
Go自帶的[pprof](https://golang.org/doc/diagnostics)其實也是一種


另一種則是以Agent(Sidecar)或Exporter形式, 由它來負責數據收集與數據做處理 . 
通常它會負責採集特定指標資訊例如, 主機資訊, 或是各Process的CPU用量, 記憶體用量.

Prometheus提供非常多[exporter](https://prometheus.io/docs/instrumenting/exporters/)來採集特定指標
之後要介紹的Fluent-bit或Promtail則是以Agent形式
![fluent-bit agent](https://fluentbit.io/assets/img/blog/2020-12-03-common/blog-forwarder-aggregator.png)
![promtail](https://miro.medium.com/max/1838/1*gTD64wp0vn2AZ5SazChi_w.png)

# Trace
單體架構下, 基本上調用關係僅在同一個process的記憶體內做調用, 通常都是透過stack trace做調用鍊路的trace.
將這些資訊給匯出後, 再通過類似[Flame Graph](https://github.com/search?q=Flame+Graph)的工具, 進行可觀測性的分析. 也可透過圖, 來得知調用關係.
![FlameGraph](https://camo.githubusercontent.com/eecfbf00e6cc5baf6ae2b66283573d765f8fe29f1d3df10f4ce3423d942c0af3/687474703a2f2f7777772e6272656e64616e67726567672e636f6d2f466c616d654772617068732f6370752d626173682d666c616d6567726170682e737667)

但是在Distributed System下常常, 服務之間相互調用, 其調用的機器與網路甚至不是同一個.
一樣也是要透過調用鍊路收集的工具, 把Distributed System的調用鍊路整成一個跟stack trace很像的結構與資訊. 其中也包含每個調用鍊路的耗時時長.
這就是Distributed Tracing, 能參考去年我的文章[Distributed Tracing & OpenTelemetry介紹](https://ithelp.ithome.com.tw/articles/10248469)


## Time Series Data
前面兩個維度講的資料, 都是以Time Series Data的方式呈現. 
Time Series Data反應的是Metric指標在某一個時間點上的狀態. 
這種資料與MySQL這類的OLTP資料有所不同.
- 資料不可變
- 只有一直生成新數據, 不會去修改舊數據, 時間過了, 改變過去沒意義
- 按照時間依序生成一系列的數據
- 必備的欄位有Timestamp, 還會加上少說一個主要欄位(服務名稱,設備名稱...)當作索引
- 通常數據量比OLTP的數據龐大非常多
- 這些指標數據, 通常會以1s的間隔做聚合, 換句話說 就是看同一秒內機器的整體效能, 或是服務的效能
- 通常只對近期數據做關注, 一陣子以前的通常非常非常少被存取
- Metric指標或Label標籤要能被Aggregation聚合, 計算平均值、Maximum、Minimum之類的

Time Series Data會有一些獨特的概念
- Metric 指標
    - 被監控的對象, 溫度、速率、反應時間...
    - 一個Metric可以有多個Tag
    - 有幾種[Type, 可參考Prometheus給的](https://prometheus.io/docs/concepts/metric_types/)
- Label/Tag 標籤
    - 對指標特徵維度的說明
    - Key Value形式呈現
    - path=/Order  -> 表示這metric是針對api/order的可能counter可能是respone time的取樣, 要看metric是什麼
    - 所以若是Log沒以Structured Log格式呈現, 不方便取Key來當這Label的Key

所以 Metric+Label決定了一個計量的單位.
如果以MySQL來存放, 那一個Metric就會是一張表了, Label則是裡面的欄位, 可能還會有其他欄位像是Timestamp.

再來MySQL這類的資料庫, 通常以B+Tree做資料存儲結構, 通常會以讀取的順序依序做排序, 
![](https://sqlhints.com/wp-content/uploads/2018/05/Structure-of-Clustered-Index.jpg)
因為B+Tree預設是為了對磁碟做存取操作的, 它所有資料都存在Leaf葉子節點中.
每次查詢時, 需要從Root節點查詢到Leaf節點, 在從Leaf節點對應的位子進行讀取, 其存放的順序剛好跟讀取所需要的順序是一致的. 然後Leaf節點的資料是放在磁碟內的Page, 讀取一整個page出來後放到Memory中.
但沒人說物理Page剛好位子都是相鄰的.
這樣的結構好處是插入刪除的時間複雜度是O(log2N), 查詢要看情況, 可以非常好也能很不好.
這種隨機讀寫的場景蠻常見的, 會導致時間大多花在磁盤尋址上.

大家應該組機很常去跑CrystalDisskMark這工具, 來看磁碟的隨機讀寫與順序讀寫的速度快慢.
可以發現順序讀寫的效率跟俗機讀寫的效率不是一個量級的
哪怕你是SSD
![](https://p6-tt.byteimg.com/origin/pgc-image/b465e4d2c4424c2aa9bd5ffe5c18671d?from=pc)

但Time Series Data的另一個特徵是```海量的資料量```, 這些資料量在寫入是挑戰,
如果幾十萬筆, Log2N才多少, 但若是1億筆就可怕了
所以有下面結構的資料庫

## LSM-Tree
所以有令一種資料庫很適合存放Time Series Data, 它叫LSM-Tree (Log Structured Merge Tree)
核心思想是 將離散的```隨機```寫入請求都轉成批量的```順序```寫入請求
透過在記憶體整理後, 只要確保在記憶體時, 資料是按照順序排列的, 

當記憶體的資料累積到一個量時, 會做一些歸併整理, 在直接寫到硬碟中.
這樣子就不用一直的寫入了, 畢竟寫到記憶體是非常高效率的.
為了避免資料在資料庫當機後遺失, 也是會採取WAL(Write Ahead Log)的機制.

雖然它沒解決掉查找還是隨機位置的問題, 
但記得  監控在意的是過去短時間內的聚合資料而已. 近期的資料會在記憶體中, 查詢依然非常高效率.
![](https://img-blog.csdnimg.cn/20190521200208933.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA0NTQwMzA=,size_16,color_FFFFFF,t_70)

這類的介紹, 明年看有否機會深入.
