概述
若計劃使用 TDengine 搭建一個時序數據平臺,須提前對計算資源、存儲資源和網絡資源進行詳細規劃,以確保滿足業務場景的需求。通常 TDengine 會運行多個進程,包括 taosd、taosadapter、taoskeeper、taos-explorer 和 taosx。
在這些進程中,taoskeeper、taos-explorer、taosadapter 和 taosx 的資源占用相對較少,通常不需要特別關注。此外,這些進程對存儲空間的需求也較低,其占用的 CPU 和內存資源一般為 taosd 進程的十分之一到幾分之一(特殊場景除外,如數據同步和歷史數據遷移。在這些情況下,濤思數據的技術支持團隊將提供一對一的服務)。系統管理員應定期監控這些進程的資源消耗,并及時進行相應處理。
在本節中,我們將重點討論 TDengine 數據庫引擎的核心進程 taosd 的資源規劃。合理的資源規劃將確保 taosd 進程的高效運行,從而提高整個時序數據平臺的性能和穩定性。
服務器內存需求
每個數據庫能夠創建固定數量的 vgroup,默認情況下為兩個。在創建數據庫時,可以通過 vgroups<num>
參數指定 vgroup 的數量,而副本數則由 replica<num>
參數確定。由于每個 vgroup 中的副本會對應一個 vnode,因此數據庫所占用的內存由參數 vgroups、replica、buffer、pages、pagesize 和 cachesize 確定。
為了幫助用戶更好地理解和配置這些參數,TDengine 的官方文檔的數據庫管理部分提供了詳細說明。根據這些參數,可以估算出一個數據庫所需的內存大小,具體計算方式如下(具體數值須根據實際情況進行調整)。
占用內存大小 = vgroups × replica × (buffer + pages × pagesize + cachesize)
以上參數意義參考 TDengine 創建數據庫
需要明確的是,這些內存資源并非僅由單一服務器承擔,而是由整個集群中的所有 dnode 共同分攤,也就是說,這些資源的負擔實際上是由這些 dnode 所在的服務器集群共同承擔的。若集群內存在多個數據庫,那么所需的內存總量還須將這些數據庫的需求累加起來。更為復雜的情形在于,如果集群中的 dnode 并非一開始就全部部署完畢,而是在使用過程中隨著節點負載的上升逐步添加服務器和 dnode,那么新加入的數據庫可能會導致新舊 dnode 之間的負載分布不均。在這種情況下,簡單地進行理論計算是不夠準確的,必須考慮到各個 dnode 的實際負載狀況來進行綜合評估。
系統管理員可以通過如下 SQL 查看 information_schema 庫中的 ins_vnodes 表來獲得所有數據庫所有 vnodes 在各個 dnode 上的分布。
select * from information_schema.ins_vnodes;
dnode_id |vgroup_id | db_name | status | role_time | start_time | restored |
===============================================================================================1| 3 | log | leader | 2024-01-16 13:52:13.618 | 2024-01-16 13:52:01.628 | true |1| 4 | log | leader | 2024-01-16 13:52:13.630 | 2024-01-16 13:52:01.702 | true |
客戶端內存需求
- 原生連接方式
由于客戶端應用程序采用 taosc 與服務器進行通信,因此會產生一定的內存消耗。這些內存消耗主要源于:寫入操作中的 SQL、表元數據信息的緩存,以及固有的結構開銷。假設該數據庫服務能夠支持的最大表數量為 N(每個通過超級表創建的表的元數據開銷約為 256B),最大并發寫入線程數為 T,以及最大 SQL 語句長度為 S(通常情況下為 1MB)。基于這些參數,我們可以對客戶端的內存消耗進行估算(單位為 MB)。
M = (T × S × 3 + (N / 4096) + 100)
例如,用戶最大并發寫入線程數為 100,子表數為 10 000 000,那么客戶端的內存最低要求如下:
100 × 3 + (10000000 / 4096) + 100 ≈ 2841 (MB)
即配置 3GB 內存是最低要求。
- RESTful/WebSocket 連接方式
當將 WebSocket 連接方式用于數據寫入時,如果內存占用不大,通常可以不予關注。然而,在執行查詢操作時,WebSocket 連接方式會消耗一定量的內存。接下來,我們將詳細討論查詢場景下的內存使用情況。
當客戶端通過 WebSocket 連接方式發起查詢請求時,為了接收并處理查詢結果,必須預留足夠的內存空間。得益于 WebSocket 連接方式的特性,數據可以分批次接收和解碼,這樣就能夠在確保每個連接所需內存固定的同時處理大量數據。
計算客戶端內存占用的方法相對簡單:只須將每個連接所需的讀 / 寫緩沖區容量相加即可。通常每個連接會額外占用 8MB 的內存。因此,如果有 C 個并發連接,那么總的額
外內存需求就是 8×C(單位 MB)。
例如,如果用戶最大并發連接數為 10,則客戶端的額外內存最低要求是 80(8×10)MB。
與 WebSocket 連接方式相比,RESTful 連接方式在內存占用上更大,除了緩沖區所需的內存以外,還需要考慮每個連接響應結果的內存開銷。這種內存開銷與響應結果的 JSON 數據大小密切相關,特別是在查詢數據量很大時,會占用大量內存。
由于 RESTful 連接方式不支持分批獲取查詢數據,這就導致在查詢獲取超大結果集時,可能會占用特別大的內存,從而導致內存溢出,因此,在大型項目中,建議使用 WebSocket 連接方式,實現流式結果集返回,從而避免內存溢出的風險
注意
- 建議采用 RESTful/WebSocket 連接方式來訪問 TDengine 集群,而不采用 taosc 原生連接方式。
- 在絕大多數情形下,RESTful/WebSocket 連接方式均滿足業務寫入和查詢要求,并且該連接方式不依賴于 taosc,集群服務器升級與客戶端連接方式完全解耦,使得服務器維護、升級更容易。
CPU 需求
TDengine 用戶對 CPU 的需求主要受以下 3 個因素影響:
- 數據分片:在 TDengine 中,每個 CPU 核心可以服務 1 至 2 個 vnode。假設一個集群配置了 100 個 vgroup,并且采用三副本策略,那么建議該集群的 CPU 核心數量為 150~300 個,以實現最佳性能。
- 數據寫入:TDengine 的單核每秒至少能處理 10,000 個寫入請求。值得注意的是,每個寫入請求可以包含多條記錄,而且一次寫入一條記錄與同時寫入 10 條記錄相比,消耗的計算資源相差無幾。因此,每次寫入的記錄數越多,寫入效率越高。例如,如果一個寫入請求包含 200 條以上記錄,單核就能實現每秒寫入 100 萬條記錄的速度。然而,這要求前端數據采集系統具備更高的能力,因為它需要緩存記錄,然后批量寫入。
- 查詢需求:雖然 TDengine 提供了高效的查詢功能,但由于每個應用場景的查詢差異較大,且查詢頻次也會發生變化,因此很難給出一個具體的數字來衡量查詢所需的計算資源。用戶需要根據自己的實際場景編寫一些查詢語句,以便更準確地確定所需的計算資源。
綜上所述,對于數據分片和數據寫入,CPU 的需求是可以預估的。然而,查詢需求所消耗的計算資源則難以預測。在實際運行過程中,建議保持 CPU 使用率不超過 50%,以確保系統的穩定性和性能。一旦 CPU 使用率超過這一閾值,就需要考慮增加新的節點或增加 CPU 核心數量,以提供更多的計算資源。
存儲需求
相較于傳統通用數據庫,TDengine 在數據壓縮方面表現出色,擁有極高的壓縮率。在大多數應用場景中,TDengine 的壓縮率通常不低于 5 倍。在某些特定情況下,壓縮率
甚至可以達到 10 倍乃至上百倍,這主要取決于實際場景中的數據特征。
要計算壓縮前的原始數據大小,可以采用以下方式:
RawDataSize = numOfTables × rowSizePerTable × rowsPerTable
示例:1000 萬塊智能電表,電表每 15min 采集一次數據,每次采集的數據量為 20B,那么一年的原始數據量約 7TB。TDengine 大概需要消耗 1.4TB 存儲空間。
為了迎合不同用戶在數據存儲時長及成本方面的個性化需求,TDengine 賦予了用戶極大的靈活性,用戶可以通過一系列數據庫參數配置選項來定制存儲策略。其中,keep 參數尤其引人注目,它賦予用戶自主設定數據在存儲空間上的最長保存期限的能力。這一功能設計使得用戶能夠依據業務的重要性和數據的時效性,精準調控數據的存儲生命周期,進而實現存儲成本的精細化控制。
然而,單純依賴 keep 參數來優化存儲成本仍顯不足。為此,TDengine 進一步創新,推出了多級存儲策略。
此外,為了加速數據處理流程,TDengine 特別支持配置多塊硬盤,以實現數據的并發寫入與讀取。這種并行處理機制能夠最大化利用多核 CPU 的處理能力和硬盤 I/O 帶寬,大幅提高數據傳輸速度,完美應對高并發、大數據量的應用場景挑戰。
技巧 如何估算 TDengine 壓縮率
用戶可以利用性能測試工具 taosBenchmark 來評估 TDengine 的數據壓縮效果。通過使用 -f 選項指定寫入配置文件,taosBenchmark 可以將指定數量的 CSV 樣例數據寫入指定的庫參數和表結構中。
在完成數據寫入后,用戶可以在 TDengine CLI 中執行 flush database 命令,將所有數據強制寫入硬盤。接著,通過 Linux 操作系統的 du 命令獲取指定 vnode 的數據文件夾大小。最后,將原始數據大小除以實際存儲的數據大小,即可計算出真實的壓縮率。
通過如下命令可以獲得 TDengine 占用的存儲空間。
taos> flush database <dbname>;
$ du -hd1 <dataDir>/vnode --exclude=wal
多級存儲
除了存儲容量的需求以外,用戶可能還希望在特定容量下降低存儲成本。為了滿足這一需求,TDengine 推出了多級存儲功能。該功能允許將近期產生且訪問頻率較高的數據存儲在高成本存儲設備上,而將時間較長且訪問頻率較低的數據存儲在低成本存儲設備上。通過這種方式,TDengine 實現了以下目標。
- 降低存儲成本:通過將海量極冷數據存儲在廉價存儲設備上,可以顯著降低存儲成本。
- 提高寫入性能:每級存儲支持多個掛載點,WAL 文件也支持 0 級的多掛載點并行寫入,這些措施極大地提高了寫入性能(實際場景中的持續寫入速度可達 3 億測
點/秒),在機械硬盤上也能獲得極高的硬盤 I/O 吞吐(實測可達 2GB/s)。
用戶可以根據冷熱數據的比例來決定高速和低成本存儲設備之間的容量劃分。
TDengine 的多級存儲功能在使用上還具備以下優點。
- 方便維護:配置各級存儲掛載點后,數據遷移等工作無須人工干預,存儲擴容更加靈活、方便。
- 對 SQL 透明:無論查詢的數據是否跨級,一個 SQL 即可返回所有數據,簡潔高效
網絡帶寬需求
網絡帶寬需求可以分為兩個主要部分—寫入查詢和集群內部通信。
寫入查詢是指面向業務請求的帶寬需求,即客戶端向服務器發送數據以進行寫入操作的帶寬需求。
集群內部通信的帶寬需求進一步分為兩部分:
- 各節點間正常通信的帶寬需求,例如,leader 將數據分發給各 follower,taosAdapter 將寫入請求分發給各 vgroup leader 等。
- 集群為響應維護指令而額外需要的內部通信帶寬,如從單副本切換到三副本導致的數據復制、修復指定 dnode 引發的數據復制等情況。
為了估算入站帶寬需求,我們可以采用以下方式:
由 于 taosc 寫入在 RPC 通信過程中自帶壓縮功能,因此寫入帶寬需求相對于 RESTful/WebSocket 連接方式較低。在這里,我們將基于 RESTful/WebSocket 連接方式的
帶寬需求來估算寫入請求的帶寬。
示例:1000 萬塊智能電表,電表每 15min 采集一次數據,每次采集的數據量為 20B,可計算出平均帶寬需求為 0.22MB。
考慮到智能電表存在集中上報的情況,在計算帶寬需求時須結合實際項目情況增加帶寬需求。考慮到 RESTful 請求以明文傳輸,實際帶寬需求還應乘以倍數,只有這樣才能得到估算值。
特別提示
網絡帶寬和通信延遲對于分布式系統的性能與穩定性至關重要,特別是在服務器節點間的網絡連接方面。我們強烈建議為服務器節點間的網絡專門分配 VLAN,以避免外部通信干擾。在帶寬選擇上,建議使用萬兆網絡,至少也要千兆網絡,并確保丟包率低于萬分之一。如果采用分布式存儲方案,必須將存儲網絡和集群內部通信網絡分開規劃。一個常見的做法是采用雙萬兆網絡,即兩套獨立的萬兆網絡。這樣可以確保存儲數據和集群內部通信互不干擾,提高整體性能。對于入站網絡,除了要保證足夠的接入帶寬以外,還須確保丟包率同樣低于萬分之一。這將有助于減少數據傳輸過程中的錯誤和重傳,從而提高系統的可靠性和效率。
服務器數量
根據前面對內存、CPU、存儲和網絡帶寬的預估,我們可以得出整個 TDengine 集群所需的內存容量、CPU 核數、存儲空間以及網絡帶寬。若數據副本數不是 1,還需要將總需求量乘以副本數以得到實際所需資源。
得益于 TDengine 出色的水平擴展能力,我們可以輕松計算出資源需求的總量。接下來,只須將這個總量除以單臺物理機或虛擬機的資源量,便能大致確定需要購買多少臺物理機或虛擬機來部署 TDengine 集群。
網絡端口要求
下表列出了 TDengine 的一些接口或組件的常用端口,這些端口均可以通過配置文件中的參數進行修改。
接口或組件名稱 | 端口 | 協議 |
---|---|---|
原生接口(taosc) | 6030 | TCP |
RESTful 接口 | 6041 | TCP |
WebSocket 接口 | 6041 | TCP |
taosKeeper | 6043 | TCP |
statsd 格式寫入接口 | 6044 | TCP/UDP |
collectd 格式寫入接口 | 6045 | TCP/UDP |
openTSDB TELNET 格式寫入接口 | 6046 | TCP |
collectd 使用 openTSDB TELNET 格式寫入接口 | 6047 | TCP |
icinga2 使用 openTSDB TELNET 格式寫入接口 | 6048 | TCP |
tcollector 使用 openTSDB TELNET 格式寫入接口 | 6049 | TCP |
taosX | 6050, 6055 | TCP |
taosExplorer | 6060 | TCP |
訪問官網
更多內容歡迎訪問 TDengine 官網