PostgreSQL IoT,車聯網 - 實時軌跡、行程實踐 1

標籤

PostgreSQL , 實時軌跡 , IoT , 車聯網 , GIS


背景

車聯網,IoT場景中,終端爲傳感器,採集各個指標的數據(同時包括時間、GIS位置信息,速度,油耗,溫度,EDU採集指標),在運動過程中,通過GPS準實時上報到服務端。

服務端則通常根據設備(比如車輛)、時間範圍,查詢指定設備在某個時間區間的行程。

例如:

1、設備軌跡點表

create table tbl (  
  id int primary key,  -- 主鍵  
  sid int,  -- 傳感器(車輛)ID  
  xxx int,  -- 行程ID  
  geo geometry,  -- 位置  
  att jsonb,  -- 屬性  
  crt_time timestamp  -- 時間  
);  

2、查詢

select * from tbl where sid=? and crt_time between x and y;  

這種方法的問題(一個點一條記錄):

1、查詢性能問題,有IO放大(因爲傳感器都活躍),一個行程的每個點都落在不同的BLOCK裏面,查詢有IO放大。

2、空間佔用,一個點一條記錄,壓縮比低。

3、行程運算,行程的所有點沒有合併,運算效率差。

行程合併問題

爲了解決以上問題,可以新建行程表,並將點的數據合併到行程。

create table tbl_agg (  
  xxx int,  -- 行程ID  
  geo 軌跡類型, -- 軌跡  
  agg jsonb[]  -- 其他屬性聚合  
)  

例如,每隔N秒,將點表的數據,按行程ID爲主鍵更新到行程表。

insert into tbl_agg on conflict (geo) do ?   
select xxx,geo_agg(geo),jsonb_agg(jsonb) from tbl where crt_time between ? and ?;  

這種做法有性能問題:

1、鎖

如果併發聚合的話,很顯然可能多個會話中會出現同樣的xxx行程ID字段,所以會有鎖衝突。

2、IO放大

如果要解決鎖的問題,我們可以用HASH,每個會話算其中的一個HASH value,但是這樣就會導致掃描時IO放大,例如8個並行,則有效數據僅八分之一。相當於IO多掃描了7次。

3、CPU只能用一核

爲了解決第一個問題,也可以使用串行方法,串行就只能用一核。

4、GAP,由於時間差的問題(例如INSERT到達的數據有錯亂,那麼可能導致中間出現GAP,聚合的行程缺少一些點)

5、實時性,異步合併到行程表,顯然,查詢行程表時,可能還有一些POINT沒有合並進來,那麼就會導致即刻查詢行程缺少最近沒有合併的點(延遲)。

行程合併優化

爲了解決前面提到的5個問題。行程合併的流程可以優化。

1、點表分區,對點表進行分區。按行程ID HASH。

create table tbl (like old_tbl including defaults) partition by list (abs(mod(hashtext(行程字段),16)));   
  
do language plpgsql $$  
declare  
begin  
  for i in 0..15 loop  
    execute 'create table tbl_'||i||' partition of tbl for values in ('||i||')';  
    execute 'create index idx_tbl_'||i||'_1 on tbl_'||i||' (id)';  
    execute 'create index idx_tbl_'||i||'_2 on tbl_'||i||' (crt_time)';  
  end loop;  
end;  
$$;  

2、由於點表分區了,而且行程ID HASH分區,每個分區一個行程合併處理進程(沒有鎖的問題),總共就可以開多個並行來提高合併行程的處理並行度。提高整體合併行程的性能。

3、行程表,分區。解決行程表垃圾回收的問題。

行程是UPDATE(APPEND POINT到行程類型中)的形式,所以UPDATE會很多,會經常需要對行程表進行VACUUM。

如果行程表不分區,行程表就會很大,目前PG的VACUUM,對於單個表來說,同一時間只能一個核來進行垃圾回收,還沒有支持單表並行VACUUM。

所以行程表如果很大,並且需要頻繁垃圾回收時,爲了避免垃圾回收速度趕不上垃圾產生速度,同樣也可以使用分區。

與點表分區類似,最好使用一樣的分區鍵。  

參考

《PostgreSQL pipelinedb 流計算插件 - IoT應用 - 實時軌跡聚合》

《PostgreSQL 時序最佳實踐 - 證券交易系統數據庫設計 - 阿里雲RDS PostgreSQL最佳實踐》

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