淺談PipelineDB系列一: Stream資料是如何寫到Continuous View中的

來源:互聯網
上載者:User

標籤:creat   關注   syn   min   streams   啟動   recv   資料   .com   

PipelineDB Version:0.9.7

PostgreSQL Version:9.5.3

 

PipelineDB的資料處理組件:

從來看主要就是pipeline_streams,stream_fdw,Continuous View,Transform。

其實就是運用了Postgres的FDW功能來實現的stream功能。

從資料庫也能看到這個FDW

pipeline=# \des                  List of foreign servers       Name       |      Owner      | Foreign-data wrapper------------------+-----------------+---------------------- pipeline_streams | unknown (OID=0) | stream_fdw(1 row)

 

資料流轉入

可以看到資料流轉都是通過ZeroMQ來實現的(前面的版本0.8.2之前是通過TupleBuff來實現)

資料插入到Stream後然後調用ForiegnInsert,插入到初始化的IPC裡面去,在資料庫目錄下面有個pipeline/zmq

TransForm其實就是把資料的dest指向了Stream,資料庫預設有個pipeline_stream_insert其實這個是個Trigger,把tuple再扔到目標stream裡面。

或者你可以自己寫UDF,就是寫個trigger,資料可以寫到表或者別的FDW裡面,或者是自己封裝的訊息佇列IPC都沒問題,這塊自由發揮的空間就比較大。

 

首先我們來建立個STREAM跟CV

pipeline=# create stream my_stream(x bigint,y bigint,z bigint);CREATE STREAMpipeline=# create continuous view v_1 as select x,y,z from my_stream;CREATE CONTINUOUS VIEWpipeline=#

 插入一條資料:

pipeline=# insert into my_stream(x,y,z) values(1,2,3);INSERT 0 1pipeline=# select * from v_1; x | y | z---+---+--- 1 | 2 | 3(1 row)pipeline=#

資料插入到CV中了,我們現在來看看PipelineDB是如何插入的。

上面有介紹了Stream就是個FDW。我們來看看他的handler(source:src/backend/pipeline/stream_fdw.c)

/* * stream_fdw_handler */Datumstream_fdw_handler(PG_FUNCTION_ARGS){FdwRoutine *routine = makeNode(FdwRoutine);/* Stream SELECTS (only used by continuous query procs) */routine->GetForeignRelSize = GetStreamSize;routine->GetForeignPaths = GetStreamPaths;routine->GetForeignPlan = GetStreamScanPlan;routine->BeginForeignScan = BeginStreamScan;routine->IterateForeignScan = IterateStreamScan;routine->ReScanForeignScan = ReScanStreamScan;routine->EndForeignScan = EndStreamScan;/* Streams INSERTs */routine->PlanForeignModify = PlanStreamModify;routine->BeginForeignModify = BeginStreamModify;routine->ExecForeignInsert = ExecStreamInsert;routine->EndForeignModify = EndStreamModify;routine->ExplainForeignScan = NULL;routine->ExplainForeignModify = NULL;PG_RETURN_POINTER(routine);}

 主要是關注Streams Inserts這幾個函數.

每個worker process啟動的時候都會初始化一個recv_id,其實這個就是ZeroMQ的ID

資料會發送到對應的隊列裡面去,worker process就去這個IPC裡面去擷取資料

source:src/backend/pipeline/ipc/microbath.c

voidmicrobatch_send_to_worker(microbatch_t *mb, int worker_id){    ......worker_id = rand() % continuous_query_num_workers;}}recv_id = db_meta->db_procs[worker_id].pzmq_id;microbatch_send(mb, recv_id, async, db_meta);microbatch_reset(mb);} 

 首先是擷取worker_id 這個是隨機擷取的一個worker進程。stream資料隨機發到一worker process裡面去了

recv_id這個就是從初始化的IPC隊列擷取ID,資料就發送到該隊列裡面

最後就調用

pzmq_send(recv_id, buf, len, true)

 資料就推送到了IPC中了。

(gdb) precv_id$12 = 1404688165(gdb)

這部分就是資料生產者部分。

下面就是資料消費者CV

資料接受還是通過ZMQ的API來接受的

這個主要是worker process來幹活的

srouce:src/backend/pipeline/ipc/pzmq.c&reader.c

(gdb) p *zmq_state->me$8 = {id = 1404688165, type = 7 ‘\a‘, sock = 0x1139ba0, addr = "ipc:///home/pipeline/db_0.9.7/pipeline/zmq/1404688165.sock", ‘\000‘ <repeats 965 times>}(gdb)

 可以看到這個資料是從1404688165裡面擷取的 ,並且把IPC的addr也給出來了,這個就是我資料庫目錄

擷取到是個buf,然後unpack,從訊息裡面擷取到對應的Tuple.

擷取到了tuple後,然後就找所有的CV跟這個stream相關的target。遍曆他們,然後執行CV中對應的SQL。

執行流程跟標準SQL差不多也是初始化執行計畫然後ExecutePlan然後endplan 。

資料會到Combiner裡面,如果是AGG還會有一系列操作的。

如果資料符合CV的SQL邏輯,那麼資料就插入到對應的物理表。

這就是Stream的一個簡單的工作原理。

 

謝謝

 

淺談PipelineDB系列一: Stream資料是如何寫到Continuous View中的

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.