時序數據庫Influx-IOx源碼學習一(項目背景)

爲什麼會發起IOx項目

原文請參見: https://www.influxdata.com/blog/announcing-influxdb-iox/

1. 下一步的目標

原文中介紹到,過去的7年時間的發展中,InfluxDB 在 metrics 數據的處理上已經成爲了非常出色的數據庫,並且在 analytics 方面也很不錯。但對於現有的架構來講有一個限制就是不能處理非常大的基數 (significant cardinality),也就是說tags裏不能設置太多的值。比如說:不能處理分佈式追蹤數據 (distributed tracing data) 的這種場景。

另外在開源方面,InfluxDB 僅僅支持單機版本的開源,對於分佈式版本只有企業版本或者雲上纔會提供,這個決定給分佈式時序數據庫留下了很大一塊空白的市場。

所以在大方向上,InfluxDB 定義了13個要求,大家可以在原文中找到,總結爲:

  • 從設計上減少對於用戶的限制:比如 tag 或者 field.

  • 交給用戶更多的控制權:比如內存分區副本讀寫索引

  • 支持container的運行環境

  • 大數據的倒入倒出

  • 細粒度的訂閱數據

  • 兼容更多的生態,包括數據標準及分析等

  • 可以運行在邊緣或者數據中心

  • 可以支持內嵌腳本(我理解爲UDF這類)

2. 更開放的許可

InfluxDB對於分佈式版本是閉源的,這使得它在市場上和其它產品相比存在很大的差距,使得過去的幾年中出現了很多時序數據庫。並且如果開源協議對商業是有限制的,那麼一些大的公司就會再開發自己的數據庫出來,或者是採用其它開源的數據庫,這樣就造成了大家相互之間的不兼容的。

如果開源的協議採用有限制的協議,那麼很多開發者除了內部使用外,即便是已經拿到開源的代碼都別無選擇的需要重新再開發。

開源創造了一個寒武紀大爆發,會創造出一個非常大的價值。開源不是零和博弈,一個非常大的社區和生態會爲所有人和供應商帶來更多的機會。

如果InfluxDB想成爲無數公司的傳感器、監測、數據分析的基礎方案,那麼唯一的方法就是可擴展、可採用、任何人可以商業化。綜上所述,InfluxDB選擇了 MIT & Apache 2雙重許可。

那麼InfluxDB如何盈利呢?在分佈式的版本中,可能需要一系列的運維、監控等外圍的工具,作爲盈利的點。這樣無論是雲產品還是開源版都是相同的代碼,不產生fork

3. 更新的設計

在現有的InfluxDB中,數據是這樣:

cpu,host=serverA,region=west user=23.2,system=53.2 1604944036000000000

意思是,存儲的cpu這個measurement;他有兩個tag,分別是hostregion;有兩個field,分別是usersystem;最後是一個納秒的時間戳。數據被存儲和索引爲:

measurement, tag key/value pairs, field name

基於時間排序的(time-value)的鍵值對被存儲爲了一個單獨的時間序列。measurementtag (key-value)field 被保存成了一個倒排索引。所以InfluxDB實際上是兩個數據庫,一個倒排索引和一個時間序列。這意味着,只要tag中存在裏新的值,就必須存儲在倒排索引中。比如在分佈式追蹤(distributed tracing ) 的場景裏,每行數據都有一個唯一的id,這意味着二級索引比時序數據還要大,服務器就需要浪費大量的cpu和內存來處理索引數據。

有一個解決的方案就是使用field來存儲,但是這樣限制來用戶的使用,必須考慮什麼時候爲標籤、什麼時候是字段,查詢的時候也需要考慮是否能使用到索引。

如果修改成爲無限的基數(cardinality),唯一的方式就是合併時序數據和倒排索引,這是數據庫設計的核心。

文章中還提到了嚴格的內存控制,如果想做內存控制,就不能使用MMAP,所有的數據(索引和時序數據)在InfluxDB中使用到的內存都需要被計算。

對象存儲作爲持久性層和批量數據導入導出的需求很難通過InfluxDB構建的底層存儲引擎來實現。現有的設計基本上假定是一個本地SSD,並且不允許將其中的數據導出到對象存儲並在查詢時導入。採用這種索引和時間序列數據分開的存儲結構也難以實現大量數據的導入和導出。

這些潛在的問題導致無法讓InfluxDB做的更好,所以需要從根本上重新思考數據庫的存儲結構及核心架構是該如何組織。

4. Rust, Arrow, 列式存儲

在決定重構核心的功能時,就必須要考慮使用什麼工具能夠讓這個重構的過程變得更快、更可靠、更面向社區。Rust作爲系統級編程語言及Apache Arrow作爲內存分析工具集,這兩款開源工具在過去的幾年中,取得了巨大的進步。

Rust可以爲我們提供了運行時行爲和內存管理的更細粒度控制。還有一個額外的好處就是併發編程更容易,消除了數據競爭。在Crates.io中又幾乎包含了所有你需要用到的東西。

Apache Arrow定義了一個內存的列式數據結構並且可以對接Parquet(列式持久化文件格式)、Flight(一個client/server的通信協議框架,傳輸大數據集的高性能網絡接口)。使用RustArrow還有一個額外的好處就是DataFusion(爲Apache Arrow提供Rust原生支持的SQL查詢引擎)。使用DataFusion作爲核心,意味着InfluxDB IOx將提供一個開箱即用的SQL子集。當然除了SQL之外,還會繼續支持InfluxQLFlux

基於列式存儲的數據模型:

  • Measurements會變爲Table(每一個measurement都是一張表)

  • Tags和Fields會成爲表中的列(這樣就需要通過measurement來鎖定一個範圍)

    • Tag和Field的Key在一個measurement中必須是唯一的

  • 時間也會作爲表中的列

除了scheme的組織,還選擇了Parquet作爲持久化文件格式。每個Parquet文件都包含了一張表中的部分數據,也就是每個Parquet文件只包含一個measurement的數據。實驗表明,ParquetInfluxDB自己的TSM引擎具有更好的壓縮比。

另外是用戶必須在創建數據庫的時候指定分區策略(比如基於時間的每2個小時)。對於每個分區,可以存儲一些摘要性的數據在內存中,包含分區都擁有哪些表,有什麼列,這些列的最大最小值等。這意味着查詢計劃可以在執行前通過這個元數據排除大量的分區數據。同時這種分區方案更容易使用對象存儲作爲長期存儲,並管理從內存到對象存儲再到索引的Parquet文件的數據生命週期。

現有的列式數據庫,並沒有單獨針對於時序數據做優化並且分離計算和存儲,尤其是具有非常優秀的字典和窗口聚合查詢。

最後文中提到了一點很有意思的研究方向,他說:我們需要一個能夠在內存中保存壓縮數據並對其執行查詢的系統。所以正在積極擴展DataFusion使其能夠處理更多的內存中的時序數據。

5.個人總結

整體看來,InfluxDB想把所有功能開源、分離計算和存儲,支持對象存儲的方式、精細的控制內存、並且可以在內存中處理壓縮的數據。不是什麼顛覆式創新,只是爲了更好的處理時序數據。


本文分享自微信公衆號 - 數據庫技術研究(atoildw)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

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