2G記憶體搞定一億資料的分析引擎

菜鳥嗯菜鳥發表於2023-11-20

執行大資料服務對伺服器的配置要求是比較高的,相應的經濟成本也不會低。 本人做資料分析相關工作,一直在尋找高效能低成本的開源OLAP引擎,但是並沒有找到 ,既然這樣,那就自己搞一個。

EuclidOLAP

Eu clid OLA P 是我 一個 開源OLAP多 維資料庫,它目前具有以下的幾個特點:

  • 針對百億級別資料量查詢時可以達到毫秒級響 應;

  • 能夠支 持非常複雜的查詢,包括跨模型的關聯查詢;

  • 支援實時的增刪改查;

  • 可以部署為叢集模式,也能以單機模式執行在低配置伺服器上。


在將來EuclidOLAP將會演化成基於雲原生、容器、彈性資源的存算分離的架構模式。

EuclidOLAP的Github地址:

剩下的內容分為兩部分,首先簡要介紹一下EuclidOLAP的資料模型與儲存結構,然後在一臺3G記憶體的低配伺服器上執行一個EuclidOLAP示例並對一個一億資料量的模型進行分析。

資料模型與儲存結構

EuclidOLAP採用了立方體(Cube)和維度(Dimension)作為資料模型,如下所示:

維度就相當於座標軸,你可以將一個關聯N個維度的Cube想象成一個N維立方體,同時把所有度量值想象成是儲存於一個多維陣列中。 多維陣列結構會帶來一個嚴重的問題——記憶體容量爆炸,為了解決這個問題,像Cogons、Essbase這些傳統多維資料庫的解決辦法是採用稀疏維和密集維結構: 稀疏的幾個維度被構建為索引,密集的維度則被構建為資料塊——相對密集的更小的多維陣列。

由於根據密集構成的資料塊也會存在資料空洞,所以上述的這種資料結構也會浪費掉一些記憶體。

EuclidOLAP的解決辦法是在多維陣列元素前面新增座標偏移量,然後進行完全壓縮,這樣雖然也需要額外的記憶體來儲存偏移量資料,但其消耗的記憶體相對於前面那兩種結構來說是可以忽略不計的。

EuclidOLAP會同時構建 一個索引結構,它會根據資料偏移量進行快速定位,以確定度量資料的座標和聚合查詢時的資料範圍。

在邏輯層面,EuclidOLAP的這個索引結構很像圖-2中稀疏維索引,但不同之處在於EuclidOLAP的這個索引結構可以表示從全部稀疏維到全部密集維的各種情況,我給它起了個名字——彈性索引結構。

在一個關聯個N個維度的Cube中,彈性索引可以表示N+1種索引結構:

在邏輯模型層 面,你還是可以將EuclidOLAP Cube中的度量資料想象成是儲存於一個有著大量資料空洞的巨大的多維陣列之中。

這種彈性索引結構同樣存在問題,在新增資料時會導致整個資料結構的變化,我會在以後的文章中專門來介紹針對這個問題的解決辦法。

接下來進入實踐環節。

執行EuclidOLAP服務例項

EuclidOLAP中自帶了一個一億資料量的Cube,它需要佔用不到2G記憶體,我在一臺2400M記憶體的機器上執行過,你需要準備一臺CentOS、Redhat、Ubuntu或Debian伺服器,記憶體最好不低於3G。

EuclidOLAP自帶了一個名為Nile Online Store的Cube,它關聯了六個維度:日期(Date )、地區(Region )、商品(Goods )、支付方式(Payment Methods )、客戶型別(Customer Types )、銷售渠道(Sales Channels )。

這個Cube有一個度量值:Sales,為了演示方便,所有的明細度量值都是1。

EuclidOLAP支援多維資料庫的標準語言——MDX(Multi-Dimensional  Expressions ),它在語法結構上類似於SQL,不同之處在於MDX在語義層面直接描述多維結構,它對於複雜分析的支援能力要強於SQL。

按下面的步驟下載並執行EuclidOLAP服務:

    wget

      tar zxvf EuclidOLAP-v0.1.6.1.tar.gz

        cd EuclidOLAP

          ./bin/start.sh &

          檢視日誌:

            tail -n 5 log/euclid.log

            當日志中顯示了Net service startup on port 8760內容時表示EuclidOLAP已經成功執行。


            第一個MDX 是一個執行全彙總的查詢。

            select
                [Measures].Sales on 0,
                Date.[ALL] on 1
            from [Nile Online Store];

            在EuclidO LAP目錄中執行olap客戶端工具:

              ./bin/olap-cli

              執行MDX查詢:

              這個查詢將全 部明細資料彙總查出,結果是100000000。

              第二個MDX 對明細資料進行查詢,它在商品維度(Goods )、支付方式維度(Payment Methods )、客戶型別維度(Customer Types )和銷售渠道維度(Sales Channels )上進行了限定,然後按日期維度(Date )和地區維度(Region )檢視Sales度量值:

              select
                  {Date.[2022].Q1, Date.[2022].Q2, Date.[2022].Q3, Date.[2022].Q4} on 0,
                  {Region.Europe.France, Region.Europe.Germany, Region.Europe.[United Kingdom]} on 1
              from [Nile Online Store]
              where
              ([Goods].[Foodstuff].[Drink].[Tea], [Payment Methods].[PayPal], [Customer Types].[New customers], [Sales Channels].[Direct sales]);

              執行這個MDX將立即返 回結果。

              第三個MDX 與第二個類似,它沒有在日期和地區之外的其他維度進行限定,該查詢將在其他四個維度上進行彙總。日期和地區維度分別指定了年份和洲級別的維度成員,這要比第二個MDX具有更高的彙總粒度。

              select
                  {Date.[2020], Date.[2021], Date.[2022]} on 0,
                  {Region.Asia, Region.Europe, Region.[North America]} on 1
              from [Nile Online Store];

              第四個MDX 是一個複雜邏輯的查詢,它將按地區查詢2022年總體銷售額最高的那個季度的前三種暢銷商品的銷售資料:

              select
                  CrossJoin(
                      TopCount(Date.[2022].Children, 1, [Measures].Sales),
                      TopCount(LateralMembers([Goods].[Foodstuff].[Drink].[Tea]), 3, [Measures].Sales)) on 1,
              Region.ROOT.Children() on 0
              from [Nile Online Store];


              最後說一下MDX這個東西。 MDX 與SQL 語法相似,如同SQL 查詢一樣,每個MDX 查詢都要求有SELECT、FROM 和可選的WHERE部分。 SQL的語義模型描述Table結構,MDX的語義模型描述Cube結構,相同的一套業務模型可以放在SQL星型表結構中,也可以放在MDX Cube模型中,但是基於Cube使用MDX能更好的支援複雜且比SQL更加直觀。 關於MDX的詳細介紹我也會發布在以後的文章中。


              來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559044/viewspace-2996244/,如需轉載,請註明出處,否則將追究法律責任。

              相關文章