成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何從0-1使用 Apache Arrow 構(gòu)建新數(shù)據(jù)系統(tǒng)

大數(shù)據(jù)
我們正處于一個(gè)數(shù)據(jù)系統(tǒng)的黃金時(shí)代。有許多新的數(shù)據(jù)庫正在不斷出現(xiàn)。根據(jù) DBDB(Database of Databases)的統(tǒng)計(jì),自 2020 年以來已經(jīng)出現(xiàn)了 124 個(gè)新的數(shù)據(jù)庫。這意味著幾乎每周都會(huì)有一個(gè)新的數(shù)據(jù)系統(tǒng)問世。

為了應(yīng)對(duì)大規(guī)模數(shù)據(jù)處理中的性能和互操作性挑戰(zhàn)。Arrow 致力于提供一種高效的跨平臺(tái)數(shù)據(jù)交換機(jī)制,使數(shù)據(jù)能夠在不同操作系統(tǒng)和編程語言之間迅速、一致地流動(dòng)。其設(shè)計(jì)注重性能優(yōu)化,并得到開源社區(qū)廣泛的支持,成為許多數(shù)據(jù)處理項(xiàng)目的核心組件,推動(dòng)了數(shù)據(jù)科學(xué)和分析領(lǐng)域的創(chuàng)新。本文將分享如何使用 Apache Arrow 來構(gòu)建一個(gè)完整的數(shù)據(jù)系統(tǒng)。

一、為什么要構(gòu)建新的數(shù)據(jù)系統(tǒng)

首先需要回答的問題就是為什么要構(gòu)建一個(gè)新的數(shù)據(jù)系統(tǒng)。

1. One Size Fits All or Not?

圖片

據(jù)圖靈獎(jiǎng)得主 Stonebraker 在 2005 年的一篇論文中指出,"One Size Fits All" 的概念已經(jīng)過時(shí)。這意味著使用一個(gè)通用的數(shù)據(jù)系統(tǒng)(如 Oracle 或 MySQL)無法完全滿足所有問題的需求。因此,許多領(lǐng)域都需要特定的專用系統(tǒng)。一個(gè)明顯的例子是交易場(chǎng)景中的 OLTP(聯(lián)機(jī)事務(wù)處理)和分析場(chǎng)景中的 OLAP(聯(lián)機(jī)分析處理)的分離。此外,還有眾多由于數(shù)據(jù)處理模型的不同而產(chǎn)生的新系統(tǒng),如適合實(shí)時(shí)計(jì)算的流處理和更適應(yīng)云計(jì)算的 NoSQL 等等。然而有些人持不同意見,他們嘗試在一個(gè)系統(tǒng)中解決所有問題。例如,試圖同時(shí)處理 OLTP 和 OLAP 的 HTAP,還有流批一體、NewSQL 等新概念。無論是否支持"One Size Fits All"的觀點(diǎn),新的想法和概念總是不斷涌現(xiàn), 所以也需要不斷構(gòu)建新的數(shù)據(jù)系統(tǒng)。

2. 數(shù)據(jù)庫的黃金時(shí)代

圖片

當(dāng)前,我們正處于一個(gè)數(shù)據(jù)系統(tǒng)的黃金時(shí)代。有許多新的數(shù)據(jù)庫正在不斷出現(xiàn)。根據(jù) DBDB(Database of Databases)的統(tǒng)計(jì),自 2020 年以來已經(jīng)出現(xiàn)了 124 個(gè)新的數(shù)據(jù)庫。這意味著幾乎每周都會(huì)有一個(gè)新的數(shù)據(jù)系統(tǒng)問世。

圖片

有了這么多數(shù)據(jù)系統(tǒng),我們?yōu)槭裁催€需要構(gòu)造一個(gè)新的數(shù)據(jù)系統(tǒng),這是否是重復(fù)造輪子呢?

3. 讀時(shí)建模

圖片

我們面對(duì)的場(chǎng)景是通用的日志處理,這是一項(xiàng)頗具挑戰(zhàn)的任務(wù),因?yàn)椴煌瑥S商,甚至同一廠商不同應(yīng)用的日志格式各不相同,而且一個(gè)尚處于開發(fā)中的系統(tǒng)的日志格式也會(huì)經(jīng)常變動(dòng)。常見的方法之一是寫時(shí)建模,即通過在數(shù)據(jù)庫中預(yù)先定義表結(jié)構(gòu)或者模式來存儲(chǔ)日志數(shù)據(jù)。然后,通過一些 ETL 工具,將數(shù)據(jù)轉(zhuǎn)化為所需的表格類型。然而,當(dāng)面對(duì)不同類型的數(shù)據(jù)時(shí),例如日志來自 Nginx、Apache 和 Windows IIS 等不同系統(tǒng),就需要維護(hù)多個(gè) ETL 流程來處理它們。另一種解決方案是讀時(shí)建模,即先將原始數(shù)據(jù)存儲(chǔ)起來,不進(jìn)行 ETL 處理,在實(shí)際使用時(shí)對(duì)字段進(jìn)行抽取。例如圖中查詢 1,就是從這三類日志數(shù)據(jù)中抽取出各自的 method、time 和 client 字段,并實(shí)時(shí)構(gòu)建一個(gè)新的結(jié)果表格。這種方法更適合處理多樣化的、不固定的數(shù)據(jù)模式。有興趣可以掃描上圖中的二維碼,它提供了一個(gè)有關(guān)讀時(shí)建模更加詳細(xì)的分享。

圖片

讀時(shí)建模的關(guān)鍵是有一個(gè)支持動(dòng)態(tài)數(shù)據(jù)表模式的數(shù)據(jù)查詢引擎,才能夠在沒有預(yù)先定義數(shù)據(jù)模式的情況下查詢各種類型的數(shù)據(jù)。

下面介紹一下動(dòng)態(tài)數(shù)據(jù)表模式可能是什么樣子的。在我們收集的數(shù)據(jù)中,可能有不同格式的日志。例如,有以鍵值對(duì)表示的日志,如綠色框所示;也可能有以 JSON 格式表示的日志,如紅色框所示。在支持動(dòng)態(tài)數(shù)據(jù)表模式的系統(tǒng)中,可以在同一數(shù)據(jù)集中同時(shí)查詢到這兩種類型的日志。

圖片

接下來,我們可以通過字段提取的方式對(duì)這兩類數(shù)據(jù)進(jìn)行格式化處理,從而得到一個(gè)合并在一起的二維表結(jié)構(gòu)。

圖片

最后,可以使用一些函數(shù)對(duì)數(shù)據(jù)進(jìn)行歸一化和合并。這樣做可以得到一個(gè)直觀明確的數(shù)據(jù)表,便于后續(xù)機(jī)器學(xué)習(xí)系統(tǒng)和報(bào)表系統(tǒng)進(jìn)行處理。在這個(gè)過程中,我們可能會(huì)遇到同一個(gè)字段有不同類型的情況。例如,某個(gè)同名字段在某類日志中可能以整數(shù)形式存儲(chǔ),而在另一個(gè)日志中可能以浮點(diǎn)數(shù)形式存儲(chǔ);或者在導(dǎo)入數(shù)據(jù)時(shí)沒有進(jìn)行適當(dāng)處理,導(dǎo)致某些字段被導(dǎo)入為字符串類型。因此,同一個(gè)字段中可能同時(shí)包含多種不同類型的數(shù)據(jù)。

圖片

構(gòu)建數(shù)據(jù)庫是一項(xiàng)復(fù)雜的工程,其中包含許多子任務(wù)??梢赃x擇改造一個(gè)開源項(xiàng)目,也可以從頭開始構(gòu)建?,F(xiàn)有項(xiàng)目要么無法滿足讀時(shí)建模的需求,要么架構(gòu)相對(duì)陳舊,不適合現(xiàn)代云計(jì)算服務(wù)的架構(gòu)。而且改造現(xiàn)有系統(tǒng),難度也比較大,因?yàn)榫哂泄潭ǖ哪J绞呛芏嘞到y(tǒng)的前置條件。因此,我們決定從頭開始構(gòu)建這個(gè)系統(tǒng),第一步就是定義內(nèi)存中的數(shù)據(jù)格式。

二、什么是 Apache Arrow,為什么是 Apache Arrow

下面介紹一下什么是 Apache Arrow,我們?yōu)槭裁催x擇了 Apache Arrow,以及我們要用它來做一些什么事情。

1. 內(nèi)存數(shù)據(jù)格式

圖片

內(nèi)存中的數(shù)據(jù)可以根據(jù)分布的不同,分為行式存儲(chǔ)和列式存儲(chǔ)。在行式存儲(chǔ)中,數(shù)據(jù)按照行的方式排列,類似于 C 或 C++ 中的二維數(shù)組,每一行連續(xù)存儲(chǔ),將相關(guān)的信息放在一起。而在列式存儲(chǔ)中,同一列的數(shù)據(jù)放在一起,構(gòu)成一個(gè)長(zhǎng)數(shù)組。圖中是包含三個(gè)屬性(session_id,timestamp 和 ip)的二維表,左邊是它在行式存儲(chǔ)中的內(nèi)存表示,右邊是它在列式存儲(chǔ)中的內(nèi)存表示。

圖片

在事務(wù)處理的場(chǎng)景中,行式存儲(chǔ)是非常自然的選擇。因?yàn)榇蟛糠植僮鞫际且砸恍袨閱挝贿M(jìn)行的,可以使用 session_id 構(gòu)建 B 樹或 B+ 樹等索引,通過這個(gè)索引很快定位到 session_id 對(duì)應(yīng)的具體的某一行,然后進(jìn)行刪除或修改操作。

但在分析型場(chǎng)景中,用戶通常不會(huì)使用所有屬性,而是只會(huì)對(duì)某些屬性進(jìn)行運(yùn)算。例如,如果想知道表中有多少個(gè)不同的 IP 地址時(shí),只需要關(guān)心 ip 這一列,而不關(guān)心 session_id 或 timestamp。在這種情況下,列式存儲(chǔ)就更為適合,因?yàn)橹恍枳x取 ip 這一列數(shù)據(jù),從而避免讀取其他不必要數(shù)據(jù)的開銷,減少了 IO 和內(nèi)存的消耗。而且,列式存儲(chǔ)的數(shù)據(jù)在磁盤或內(nèi)存中都是連續(xù)存儲(chǔ)的,可以更好保證數(shù)據(jù)的局部性,從而充分利用現(xiàn)代 CPU 的緩存和 SIMD(單指令多數(shù)據(jù))向量化等運(yùn)算機(jī)制。另外,相同屬性的數(shù)據(jù)放在一起可以更好地進(jìn)行壓縮。例如,可以使用字典或其他高效的壓縮算法將這些具有相同屬性的數(shù)據(jù)放在一起進(jìn)行壓縮。對(duì)于日志處理這種分析型的應(yīng)用來說,列存儲(chǔ)是更合適的選擇。

2. Apache Arrow 的優(yōu)勢(shì)

圖片

那么我們還要不要繼續(xù)造輪子?還是定義一套自己的列式存儲(chǔ)內(nèi)存格式?

圖片

現(xiàn)在許多系統(tǒng)都定義了自己的內(nèi)存數(shù)據(jù)格式,這帶來了數(shù)據(jù)轉(zhuǎn)換的問題。試想,如果我們想在 pandas 中調(diào)用 Spark 進(jìn)行數(shù)據(jù)處理,那么要從 pandas 基于的 Python 環(huán)境轉(zhuǎn)換到 Spark 基于的 Java 環(huán)境,其中需要經(jīng)過 Py4J、JVM 和 Spark 三層數(shù)據(jù)轉(zhuǎn)換。同樣地,如果我們定義了自己的內(nèi)存格式,也會(huì)面臨類似的數(shù)據(jù)轉(zhuǎn)換問題,特別是在需要與其他系統(tǒng)進(jìn)行互操作時(shí)。幸運(yùn)的是,借助 Apache Arrow,可以在 PySpark 啟用 Arrow 格式,就可以與 pandas 直接共享內(nèi)存,實(shí)現(xiàn)內(nèi)存交換。

Arrow 到底是什么呢?Arrow 本身并不是一個(gè)數(shù)據(jù)存儲(chǔ)或執(zhí)行引擎,而是一種高性能、內(nèi)存中的列式存儲(chǔ)標(biāo)準(zhǔn)。它與具體的語言或應(yīng)用程序無關(guān),無論是用 C++、Python 還是 Rust 等語言,都可以進(jìn)行跨語言跨系統(tǒng)的互操作。因?yàn)樵谌魏苇h(huán)境中,Arrow 數(shù)據(jù)的內(nèi)存表示是完全一致的,所以在進(jìn)行跨系統(tǒng)傳輸時(shí),不需要進(jìn)行內(nèi)存拷貝、序列化或反序列化等工作,實(shí)現(xiàn)了零拷貝。Arrow 沒有發(fā)明新的數(shù)據(jù)存儲(chǔ)方式,比如浮點(diǎn)數(shù)仍然按 IEEE 754 標(biāo)準(zhǔn)進(jìn)行表示,但 Arrow 在標(biāo)準(zhǔn)化方面做了很多工作,例如如何表示空值 NULL、如何處理時(shí)間戳以及時(shí)區(qū)的表示等等。這些細(xì)節(jié)看起來很微小,但它們的重要性是在任何平臺(tái)和任何語言下的標(biāo)準(zhǔn)化。因此,一個(gè)全新的數(shù)據(jù)引擎也無需重新發(fā)明這些內(nèi)存格式。

圖片

使用 Arrow 后,可以實(shí)現(xiàn)在不同系統(tǒng)之間共享內(nèi)存,從而實(shí)現(xiàn)零拷貝。這意味著我們不是避免了繁重的數(shù)據(jù)復(fù)制和轉(zhuǎn)換,而是直接共享內(nèi)存中的數(shù)據(jù),使得數(shù)據(jù)處理過程更加高效。

圖片

Arrow 還有以下幾個(gè)好處。

首先,Arrow 原生實(shí)現(xiàn)了七種程序語言,并在此基礎(chǔ)上實(shí)現(xiàn)了更多語言的綁定,包括 Rust、C++、C、Python 等,基本覆蓋了主流的程序語言。并且得到大量數(shù)據(jù)系統(tǒng)的支持,如 PyTorch、Spark、ClickHouse 和 DuckDB 等,在這些系統(tǒng)中,數(shù)據(jù)可以采用 Arrow 格式進(jìn)行輸出。

其次,Arrow 的性能表現(xiàn)不錯(cuò)。有一個(gè) Benchmark 對(duì)比了基于 Arrow 的數(shù)據(jù)引擎 DataFusion、Polars 與 DuckDB 的性能,雖然前兩者稍慢于 DuckDB,但仍然是可接受的成績(jī)。盡管看起來 Arrow 在每個(gè)小功能點(diǎn)上沒有什么創(chuàng)新,但綜合起來,它提供了一個(gè)相對(duì)完整的解決方案,并且模塊化做得非常好,API 對(duì)于系統(tǒng)的侵入性也較小。

此外,Arrow 的擴(kuò)展性較強(qiáng),比如可以擴(kuò)展 Arrow 的類型,將機(jī)器學(xué)習(xí)中的一些類型如 tensor 在 Arrow 中實(shí)現(xiàn);也可以使用 API 擴(kuò)展自定義的計(jì)算函數(shù)。

總而言之,Arrow 的主要貢獻(xiàn)在于為列式存儲(chǔ)提供了一個(gè)標(biāo)準(zhǔn)和生態(tài)系統(tǒng),因此對(duì)開發(fā)者和用戶來說,它可以作為一個(gè)現(xiàn)代數(shù)據(jù)技術(shù)棧的標(biāo)準(zhǔn)和基礎(chǔ)。

圖片

Arrow 擁有非?;钴S的開源社區(qū)。除了 Arrow Rust 等相關(guān)項(xiàng)目外,截至 2023 年 10 月,Arrow 本身已經(jīng)得到了超過一萬兩千個(gè) GitHub 的 star。上圖展示了 Arrow 在最近一個(gè)月的活躍程度,包括 PR、issue 以及貢獻(xiàn)者等方面的數(shù)據(jù),足以看到 Arrow 是一個(gè)非?;钴S的項(xiàng)目,并不需要擔(dān)心它的持續(xù)性和穩(wěn)定性,可以預(yù)期 Arrow 能夠長(zhǎng)期存在并會(huì)持續(xù)完善。

圖片

Arrow 通過幫助標(biāo)準(zhǔn)化內(nèi)存格式,為構(gòu)建數(shù)據(jù)系統(tǒng)提供了一個(gè)起點(diǎn)。然而,這只是開始,還有許多其他任務(wù)有待完成。例如,需要聚合、排序等更多的算子;需要開發(fā)客戶端 API 和數(shù)據(jù)交換功能;需要支持新的硬件,尤其是在信創(chuàng)領(lǐng)域,需要考慮對(duì) ARM 指令集和國產(chǎn)硬件的兼容。

如此一來,構(gòu)建一個(gè)數(shù)據(jù)系統(tǒng)變得非常復(fù)雜。上述工作也只能初步構(gòu)建一個(gè)勉強(qiáng)滿足小規(guī)模使用的數(shù)據(jù)系統(tǒng),而完成這個(gè)階段可能需要 10 年甚至更長(zhǎng)時(shí)間。如果我們想要構(gòu)建一個(gè)更大規(guī)模、分布式和高可用的數(shù)據(jù)系統(tǒng),所需要的時(shí)間可能是前一階段的幾倍甚至更長(zhǎng)。

按照人月神話的理論,投入更多的人力并不能線性地減少完成時(shí)間。因此,構(gòu)建新的數(shù)據(jù)庫是一個(gè)非常昂貴的事情,需要巨大的時(shí)間、人力和經(jīng)濟(jì)成本,這也是為什么新的數(shù)據(jù)庫創(chuàng)業(yè)公司需要籌集大量資金和足夠的時(shí)間。

雖然現(xiàn)在是數(shù)據(jù)庫的黃金時(shí)代,但也是最具挑戰(zhàn)性的時(shí)期。如果新的想法不能迅速實(shí)現(xiàn),很難在市場(chǎng)上生存。好在有 Arrow。Arrow 不僅提供了基本的內(nèi)存數(shù)據(jù)格式和模型,還提供了一些算子和計(jì)算功能,以及持久化、數(shù)據(jù)交換和跨平臺(tái)執(zhí)行等模塊。通過使用 Arrow,能夠大大節(jié)省構(gòu)建數(shù)據(jù)系統(tǒng)的時(shí)間和開發(fā)成本。

三、使用 Apache Arrow 構(gòu)建數(shù)據(jù)系統(tǒng)

下面介紹 Arrow 如何助力數(shù)據(jù)系統(tǒng)的開發(fā)以及如何使用 Arrow 構(gòu)建一個(gè)數(shù)據(jù)系統(tǒng)。

1. 數(shù)據(jù)系統(tǒng)執(zhí)行流程

圖片

一個(gè)數(shù)據(jù)系統(tǒng)的執(zhí)行流程通常包括以下幾個(gè)步驟。

首先,當(dāng)系統(tǒng)接收到用戶的查詢請(qǐng)求時(shí),會(huì)利用存儲(chǔ)和索引來獲取相關(guān)資源。

接下來,系統(tǒng)會(huì)根據(jù)用戶查詢生成一個(gè)邏輯計(jì)劃,該計(jì)劃表示了執(zhí)行查詢所需的關(guān)系代數(shù)和操作的抽象。

然后,邏輯計(jì)劃會(huì)在經(jīng)過優(yōu)化之后轉(zhuǎn)為物理計(jì)劃,即如何真正執(zhí)行查詢的計(jì)劃。

之后,在執(zhí)行引擎中,系統(tǒng)會(huì)執(zhí)行具體的操作,如表達(dá)式執(zhí)行、聚合、排序和物化視圖等算子。

最后,系統(tǒng)將結(jié)果保存到用戶指定的路徑或傳輸?shù)接脩舻目蛻舳恕?/span>

2. 數(shù)據(jù)存儲(chǔ)

圖片

我們的數(shù)據(jù)存儲(chǔ)模型是基于事件的,即基本的存儲(chǔ)單元抽象成了事件,類似于日志中的每一條日志。每個(gè)事件都有時(shí)間戳、原始信息和其他基本屬性,比如主機(jī)名、數(shù)據(jù)類型等。這些都是事件的元信息定義,我們將其抽象出來,并進(jìn)行索引。

對(duì)于日志中的其他內(nèi)容,我們將其作為原始數(shù)據(jù)存儲(chǔ)。底層存儲(chǔ)使用了 Parquet 這一列式持久化存儲(chǔ)標(biāo)準(zhǔn),其對(duì) Arrow 有很好的支持。Parquet 還會(huì)存儲(chǔ)一些元數(shù)據(jù),比如每列的存儲(chǔ)位置和一些統(tǒng)計(jì)信息,如最大值和最小值等。這樣就可以支持一些查詢的下推操作。如果數(shù)據(jù)中存儲(chǔ)了多列,但只想訪問某一列,可以直接定位到該列的存儲(chǔ)位置,而不需要將整個(gè)文件都讀入內(nèi)存中。

然而,Parquet 需要預(yù)先給定數(shù)據(jù)的模式,即存儲(chǔ)數(shù)據(jù)時(shí)需要先定義一個(gè)模式,無法直接支持動(dòng)態(tài)模式或者無模式數(shù)據(jù)。為了支持動(dòng)態(tài)模式的數(shù)據(jù),在 Parquet 的基礎(chǔ)上我們進(jìn)行了一些擴(kuò)展,這樣就可以在 Arrow 和 Parquet 的基礎(chǔ)上進(jìn)行簡(jiǎn)單的修改,從而完成數(shù)據(jù)存儲(chǔ)。

圖片

數(shù)據(jù)存儲(chǔ)之后,需要讀入到內(nèi)存中。每個(gè)數(shù)據(jù)在內(nèi)存中會(huì)以 Arrow 定義的 Record Batch 形式存在。這種表示方法用于描述一組數(shù)據(jù),并由其 Schema 指定數(shù)據(jù)的模式。

例如,有一列包含 session_id 字段的 Int64 類型數(shù)據(jù),一列包含 datetime 字段的String 類型數(shù)據(jù),還有一列包含 source_ip 字段的 String 類型數(shù)據(jù),Schema 中定義并存儲(chǔ)了這些字段的類型,而具體的數(shù)據(jù)存儲(chǔ)在 Arrow Array 中,不同 Record Batch 的 Schema 是可以變動(dòng)的。例如,在下一個(gè) Record Batch 中,session_id 字段可能變成 String 類型,而 time 字段可能變成 Timestamp 類型。

通過不同模式 Record Batch 的組合,就可以獲得不同模式的數(shù)據(jù)。這樣,就實(shí)現(xiàn)了從數(shù)據(jù)存儲(chǔ)到內(nèi)存表示的映射關(guān)系。

3. 索引/代碼/硬件資源

圖片

Arrow 并不是一個(gè)完整的查詢引擎。它缺少索引和用戶自定義函數(shù)等功能的支持,在我們的系統(tǒng)中,我們使用了時(shí)間戳索引和倒排索引,這樣用戶可以通過關(guān)鍵字和時(shí)間來定位到日志的位置。至于用戶自定義函數(shù)方面,我們向 Arrow 提交了一系列 PR,使其能夠支持用戶自定義函數(shù)。Arrow 在硬件資源方面有一些簡(jiǎn)單的實(shí)現(xiàn),比如內(nèi)存管理和線程池。但是,如果想要進(jìn)行更細(xì)粒度的管理,例如限制每個(gè)查詢的內(nèi)存使用或設(shè)置不同查詢?nèi)蝿?wù)的優(yōu)先級(jí),仍然需要自己開發(fā)。所以,從這個(gè)角度來看,Arrow 在這方面還有繼續(xù)完善的空間。

4. SQL 解析/計(jì)劃生成/執(zhí)行與傳輸

圖片

Arrow 也沒有提供將用戶的 SQL 語句解析成抽象語法樹的功能,但是我們可以使用一些開源工具,比如 ANTLR 和 Calcite,將 SQL 語句轉(zhuǎn)換成抽象語法樹。我們選擇使用 ANTLR 而不是 Calcite,是因?yàn)?Calcite 過于復(fù)雜且基于固定數(shù)據(jù)模式的假設(shè),在處理動(dòng)態(tài)模式時(shí)不太適用。

圖片

之后可以將抽象語法樹進(jìn)一步轉(zhuǎn)換成邏輯計(jì)劃,邏輯計(jì)劃描述了數(shù)據(jù)執(zhí)行的具體操作。在進(jìn)行查詢優(yōu)化時(shí),我們可以調(diào)整邏輯計(jì)劃來提高性能。

例如想要找到特定 ip 的最新訪問時(shí)間,首先需要從數(shù)據(jù)集中讀取相關(guān)數(shù)據(jù)。然后,根據(jù)指定的條件(這里是 ip 等于某個(gè)特定字符串)進(jìn)行數(shù)據(jù)過濾,并將需要的數(shù)據(jù)篩選出來。接下來,對(duì)過濾后的數(shù)據(jù)進(jìn)行聚合運(yùn)算計(jì)算其時(shí)間的最大值。

在此過程中,可以進(jìn)行一些優(yōu)化,其中一個(gè)常見的優(yōu)化是下推操作。通過下推,可以將讀取 ip 和 _time 兩個(gè)字段的操作下推到表掃描階段,從而每次讀取數(shù)據(jù)時(shí)都跳過其他不必要的字段。此外,我們還可以將條件表達(dá)式(例如,ip 等于特定字符串)嵌入到操作中,這樣每次讀取時(shí)只會(huì)讀取與我們需要的 ip 相匹配的數(shù)據(jù)。

通過在表掃描階段進(jìn)行這些優(yōu)化,可以節(jié)省大量的 IO 開銷和內(nèi)存資源,提高查詢性能。

圖片

邏輯計(jì)劃是一個(gè)抽象層,不包含在 Arrow 中,因此需要自己編寫邏輯計(jì)劃的代碼。

相對(duì)而言,邏輯計(jì)劃相對(duì)簡(jiǎn)單,因?yàn)榇蠖鄶?shù) SQL 查詢語言及關(guān)系代數(shù)和邏輯計(jì)劃可以相互對(duì)應(yīng)。物理計(jì)劃則相對(duì)復(fù)雜,因?yàn)樗c底層機(jī)器有關(guān),需要處理線程、并發(fā)和各種硬件。

最近,Arrow 提供了一個(gè)查詢執(zhí)行引擎——Acero,可以提供很大幫助。Acero 是一個(gè)基于推送(Push)的引擎,其最小執(zhí)行單元是 execution node,它的代碼非常清晰,并且具有清晰的 API 接口,包括如何處理其上游輸入和下游輸出,如何處理接收到的數(shù)據(jù)和停止接收數(shù)據(jù),以及暫停和繼續(xù)運(yùn)行等功能。

如果需要擴(kuò)展,只需按照 API 定義自己的節(jié)點(diǎn),并在 Acero 中注冊(cè)即可,就可以借助 Acero 進(jìn)行計(jì)算的調(diào)度和執(zhí)行,而不需要修改 Arrow 代碼。

圖片

我們注意到 Arrow 在處理動(dòng)態(tài)數(shù)據(jù)模式方面存在一些限制,因此對(duì) Arrow 進(jìn)行了一些擴(kuò)展。例如,添加了支持動(dòng)態(tài)模式的匯聚節(jié)點(diǎn) Schemaless SinkNode,它可以消除數(shù)據(jù)模式方面的一些限制。通過使用這個(gè)節(jié)點(diǎn),可以處理沒有嚴(yán)格定義模式的數(shù)據(jù)。這允許我們更靈活地處理各種數(shù)據(jù)類型,而不僅僅限于特定的固定模式。

圖片

在這個(gè)過程中,我們得到了一個(gè)支持動(dòng)態(tài)模式物理計(jì)劃的執(zhí)行節(jié)點(diǎn)。此外,Arrow 的另一個(gè)限制在于執(zhí)行節(jié)點(diǎn)創(chuàng)建時(shí)就需要預(yù)先定義數(shù)據(jù)的輸出模式。為了克服這個(gè)限制,我們進(jìn)行了一些改造,將數(shù)據(jù)輸出模式延遲到實(shí)際輸出時(shí)動(dòng)態(tài)生成。這樣,就能更好地支持動(dòng)態(tài)模式的數(shù)據(jù)引擎。另外,我們也對(duì) Arrow 提供的一些聚合函數(shù)和標(biāo)量函數(shù)進(jìn)行了動(dòng)態(tài)模式的擴(kuò)展。

圖片

這樣就可以使用 Arrow 來處理動(dòng)態(tài)模式數(shù)據(jù),并使用它執(zhí)行并調(diào)度查詢的。目前,Acero 還不支持物化視圖,但對(duì)于大規(guī)模數(shù)據(jù)來說,物化視圖非常重要。物化視圖可以預(yù)先計(jì)算并且儲(chǔ)存一些耗時(shí)或復(fù)雜場(chǎng)景的結(jié)果,在查詢時(shí)可以快速訪問和利用這些預(yù)先計(jì)算的結(jié)果。同樣,我們對(duì) Acero 進(jìn)行了一些擴(kuò)展,添加了中間狀態(tài)的處理方式,以便在 Arrow 中實(shí)現(xiàn)物化視圖,我們也計(jì)劃將這些一系列擴(kuò)展提交給 Arrow。

圖片

最后,當(dāng)查詢結(jié)束時(shí),需要進(jìn)行數(shù)據(jù)傳輸,可以是傳輸給用戶的客戶端,也可以是傳輸?shù)接脩羟岸诉M(jìn)行顯示。如果直接使用 ODBC 或者 JDBC,因?yàn)?ODBC 和 JDBC 本質(zhì)上只能處理行式數(shù)據(jù),行列的轉(zhuǎn)換無法避免,我們可以使用 Arrow Flight 和 Arrow Flight SQL 來規(guī)避這個(gè)問題。

Arrow Flight 是 Arrow 提供的基于 gRPC 或者 REST  的列式數(shù)據(jù)交換框架,無需復(fù)雜的開發(fā),直接使用其 API 即可實(shí)現(xiàn)列式數(shù)據(jù)傳輸,而避免了數(shù)據(jù)轉(zhuǎn)換。在 Arrow Flight 之上得到了與 SQL 數(shù)據(jù)庫交互的協(xié)議 Arrow Flight SQL。這樣我們就可以利用與 SQL 兼容的現(xiàn)有客戶端直接進(jìn)行查詢。

將來,Arrow 還將推出一個(gè)類似于 Arrow 自己的 JDBC 或者 ODBC 的工具,稱為 Arrow ADBC。這樣,原本與 ODBC 和 JDBC 兼容的數(shù)據(jù)庫客戶端將無需或只需極少修改代碼,就可以直接與 Arrow 進(jìn)行通信。

Arrow 幫助我們實(shí)現(xiàn)了數(shù)據(jù)存儲(chǔ)、物理計(jì)劃和傳輸這三個(gè)方面的重要功能。如果在自己的數(shù)據(jù)系統(tǒng)實(shí)現(xiàn)中不是動(dòng)態(tài)模式的,而僅僅是針對(duì)特定領(lǐng)域開發(fā)固定模式的新系統(tǒng),那么只需構(gòu)建索引、解析用以查詢的 SQL 或 Dataframe API,并轉(zhuǎn)換成邏輯計(jì)劃,然后使用 Calcite 的優(yōu)化器將其轉(zhuǎn)換為 Arrow 的物理計(jì)劃,最后直接使用 Arrow 執(zhí)行即可,需要構(gòu)建的東西非常少。

四、一些 Tips

我們?cè)?Arrow 的使用中積累了一些經(jīng)驗(yàn)和教訓(xùn)。作為一個(gè)新的數(shù)據(jù)產(chǎn)品或數(shù)據(jù)產(chǎn)品的底座,Arrow 還存在不少問題。

1. 踩過的一些坑

圖片

首先更新頻繁是 Arrow 社區(qū)活躍的體現(xiàn),意味著會(huì)有新的功能和改進(jìn),但同時(shí)它的接口還是不夠完善,我們建議盡量少修改原始代碼,而是向 Arrow 社區(qū)貢獻(xiàn)改進(jìn)并多做擴(kuò)展。Arrow 代碼庫可以分為三個(gè)層次:

  • Core 層:提供數(shù)據(jù)類型表示,這一層非常穩(wěn)定,新版本可以完全保證和之前版本的兼容。
  • Compute 層:提供計(jì)算算子,相對(duì)穩(wěn)定但可能有一些 bug,當(dāng)使用一些比較高級(jí)的指令集如 AVX512 指令集可能會(huì)有一些內(nèi)存對(duì)齊的問題。
  • Acero 層:是最新的執(zhí)行引擎,不夠穩(wěn)定而更適合開發(fā)測(cè)試。

Arrow 對(duì)于復(fù)雜類型的處理還不夠完備,比如 Union、List、JSON 等,需要額外的代碼實(shí)現(xiàn)。另外,Arrow 始于 2016 年,仍需要時(shí)間和大規(guī)模數(shù)據(jù)的驗(yàn)證。各個(gè)相關(guān)項(xiàng)目(包括 DuckDB 等)主要使用的是 Core 部分,對(duì)于 Arrow 的 Compute 和 Acero 等部分,仍然需要在更大規(guī)模的數(shù)據(jù)上進(jìn)行進(jìn)一步的驗(yàn)證。我們?cè)陂_發(fā)過程中遇到了一些問題已經(jīng)修復(fù)并向 Arrow 社區(qū)提交了改進(jìn)。目前看來,Arrow 處于相對(duì)穩(wěn)定的狀態(tài)。

2. DATA FUSION

圖片

最后,對(duì)于追求安全和現(xiàn)代化的考慮,我們建議使用 Arrow Rust 的實(shí)現(xiàn)。而且 Arrow 在 Rust 實(shí)現(xiàn)的基礎(chǔ)上推出了一個(gè)完整的數(shù)據(jù)引擎 DataFusion,它提供了比 Arrow 更強(qiáng)大的功能。DataFusion 在 Arrow 內(nèi)存格式的基礎(chǔ)上提供了 SQL 解析和查詢計(jì)劃等功能,也支持子查詢和其他高級(jí)函數(shù)。此外,DataFusion 也繼承了 Arrow 出色的模塊化和可擴(kuò)展的代碼風(fēng)格,基于 DataFusion 構(gòu)建新的數(shù)據(jù)引擎可以減少開發(fā)所需的時(shí)間,同時(shí)也能在開源社區(qū)獲得更多支持。

責(zé)任編輯:姜華 來源: DataFunTalk
相關(guān)推薦

2022-12-23 08:03:45

西瓜業(yè)務(wù)SEO前端

2023-10-30 07:30:08

VeCDP火山引擎

2023-06-26 19:25:18

效率消息中心業(yè)務(wù)線

2017-10-23 12:55:46

項(xiàng)目設(shè)計(jì)師流程

2016-01-14 13:07:20

美團(tuán)壓測(cè)工具工具

2017-01-18 09:33:07

數(shù)據(jù)構(gòu)建價(jià)值

2022-07-13 11:17:00

大數(shù)據(jù)規(guī)劃

2021-04-13 07:58:38

背包代碼模式

2022-07-06 07:27:52

32Core樹莓派集群

2019-12-13 09:00:58

架構(gòu)運(yùn)維技術(shù)

2022-01-17 13:31:53

value背包解法

2021-03-16 21:39:47

區(qū)塊鏈DEMOGo

2021-03-12 19:17:38

區(qū)塊鏈GoPython

2021-03-17 20:29:36

區(qū)塊鏈DEMOPython

2017-01-20 08:44:53

Apache Flum抓取數(shù)據(jù)

2017-08-10 09:11:38

規(guī)則引擎構(gòu)建

2025-05-26 10:00:00

TkinterGUIPython

2022-09-02 09:09:25

項(xiàng)目ReactES6

2025-03-20 14:50:24

2023-05-10 10:45:06

開源工具庫項(xiàng)目
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 欧美1—12sexvideos | 中文成人在线 | 四虎影院在线播放 | 麻豆精品一区二区三区在线观看 | 97国产一区二区 | 国产精品成人一区二区三区夜夜夜 | 欧美大片久久久 | 人人爽日日躁夜夜躁尤物 | av天天干 | 完全免费在线视频 | 日本视频中文字幕 | 欧美成人一区二区三区 | 黄色片网此| 国产日韩欧美 | 欧美片网站免费 | 国产精品日女人 | 亚洲欧美中文日韩在线v日本 | 91一区二区三区在线观看 | 亚洲欧洲小视频 | 欧美国产视频 | 在线观看国产精品一区二区 | 中文无吗| 一区二区三区四区在线 | av网站免费在线观看 | 久久精品视频一区二区 | 91免费小视频 | 成人性生交大片免费看中文带字幕 | 欧美在线a | 亚洲欧美在线免费观看 | 91中文在线观看 | 欧美1级 | 久久国产精品一区二区三区 | 精品欧美一区免费观看α√ | 午夜影院黄 | 亚洲成av人片在线观看 | 在线日韩欧美 | 国产日韩精品久久 | 免费在线观看av网站 | 成人在线免费观看 | 婷婷成人在线 | 97色在线视频 |