767
技術社區[雲棲]
無人駕駛背後的技術 - PostGIS點雲(pointcloud)應用 - 2
標簽
PostgreSQL , PostGIS , box , grid , pointcloud , pgpointcloud , point聚合 , KNN , 自動駕駛 , 自動配送 , 無人駕駛 , 機器人配送 , 物流 , 無用功
背景
無人駕駛、配送機器人的業務背景,方案設計請參考:
《無人駕駛背後的技術 - PostGIS點雲(pointcloud)應用》
本文針對以上文章,補充一些新鮮內容。
一、transfer table消除索引build、格式檢查等無用功
在服務端存儲了所有的pointcloud數據,而終端(如無人車)僅僅需要車輛需要行經的位置(既定線路、活動範圍、行政區)的points數據。
終端的數據是從服務端下發而來。
假設服務端的數據已經按行政區或GEOHASH CODE range劃分,建立了對應的分區表,並且已經構建了GiST索引。
這些表的數據從服務端LOAD(通過insert\copy的方式)到終端(無人車)時,正常情況下無人車還需要再構建一次GiST索引。重複構建索引屬於無用功,是浪費資源的做法。
而如果使用transfer table的方法,直接LOAD貝數據文件,索引文件,構建數據庫catalog元數據,可消除終端數據insert、COPY方式引入的重複勞動(BUILD索引、檢查數據格式等)。實現快速導入,還能節能減排。
使用table transfer節能減排。關鍵的因素,數據的分區需要足夠細致,這樣的話導出到終端不會造成數據冗餘。(例如終端要的是杭州市西湖區的點雲數據,而服務端是按市級行政區分區的,那麼使用table transfer需要拷貝整個杭州市的數據文件到終端(無人車),那就很不好。)
pgtransfer是一個插件,用法如下
https://postgrespro.com/docs/postgresproee/9.6/pgtransfer.html
二、大量數據優化之 - 線性存儲與BRIN索引
GiST是空間聚集索引,支持的數據類型包括地理位置類型等。支持按距離排序,按距離搜索數據等,GiST精確度非常高。
geohash是一種編碼,將地球上的經緯度從坐標轉換為一串字符串, 對於相鄰的位置,geohash的字符串也是相似的,相鄰的位置geohash值擁有相同的prefix。
詳見:
PostGIS提供的st_geohash函數可以將geometry類型轉換為一串geohash字符串。
https://postgis.net/docs/ST_GeoHash.html
GiST索引的優劣
1. 當需要按某個點,搜索附近的點,並按順序輸出記錄時,GiST索引的效率非常的高。(當需要按空間順序返回大量記錄時,GiST索引不占優勢。)
2. 當位置數據量非常大時,由於GiST索引需要計算空間聚集,建立索引的速度會比較慢。(如果數據是並發插入的,可以調動所有的CPU資源構建索引,性能不錯,例如32核可以達到17萬/s的寫入速度(含GiST索引)。)
3. GiST索引包含了空間數據的VALUE,占用的空間比較大(相比接下來的BRIN索引)。
4. 如果數據在空間維度上亂序存儲,使用GiST索引返回大量相鄰數據時,會導致heap IO放大。原理如下
geohash的優劣
geohash是一串字符串,相鄰的位置,字符串也有順序相似性。
如果將數據按geohash排序存儲(堆存儲本身是無序的,但是可以使用cluster語法,按某個索引排序存儲),那麼數據將變成空間有序存儲的模式,有序存儲有一個好處,不同的數據塊存儲的數據的BOUND非常清晰。
當數據有序存儲時,可以使用塊級索引(BRIN),按geohash搜索一個範圍的數據時,從brin返回包含這個範圍的數據塊,然後從這些數據塊中獲取數據,效率非常高。(獲取少量數據的效率不如GiST,但是獲取大量數據的效率與GiST相當)
《PostgreSQL 物聯網黑科技 - 瘦身幾百倍的索引(BRIN index)》
BRIN索引存儲的是每個數據塊(或者連續的數據塊)的元信息(min,max,avg,count,nulls count等)。適合有序存儲(VALUE與行號線性相關性好)的數據。
作為點雲數據索引的案例如下:
https://2016.foss4g-na.org/sites/default/files/slides/gbroccolo_FOSS4GNA2016_pointcloud_0.pdf
《Manage LiDAR data with PostgreSQL》
GiST和BRIN選哪個?
1. 如果大量的需求是返回少量數據,並且有KNN搜索,距離排序輸出的需求。建議使用GiST,效率極其高。比如軌跡係統,比拚REDIS性能還要高400%:
《PostgreSQL 物流軌跡係統數據庫需求分析與設計 - 包裹俠實時跟蹤與召回》
2. 如果大量的需求是返回大量點數據(例如100萬以上),那麼建議將數據按geohash堆順序存儲,減少IO放大,並使用BRIN索引減少索引的BUILD時間和索引的空間占用。
https://postgis.net/docs/using_postgis_dbmanagement.html
geohash的分區作用
通常用戶存儲地理信息,會使用geometry字段,然而geometry類型分區表不好實現。
一個比較理想的方法是使用geohash來進行範圍分區(因為相鄰位置的geohash也相似)。
在PostgreSQL中,有兩種方法實現分區:一種是實體字段,一種是表達式分區。如果你使用的是Greenplum,隻支持實體字段分區。
create table test(id int, loc geometry, loc_geohash text); -- loc_geohash=st_geohash(loc),按loc_geohash進行範圍分區
或
create table test(id int, loc geometry); -- 按表達式st_geohash(loc)進行範圍分區。
三、大量數據優化之 - 聚合與prefix搜索
數據聚合對大批量數據的查詢有非常好的性能提升效果。
在第一篇文章中已經介紹了,數據聚合後,查詢500萬個點,響應時間從43秒降到了312毫秒。
《無人駕駛背後的技術 - PostGIS點雲(pointcloud)應用》
聚合的方法也很多:
1. 使用網格聚合,前一篇文章已有介紹。
2. 另一種方法是使用geohash prefix聚合,也較為通用。
https://postgis.net/docs/ST_GeoHash.html
四、獲取道路覆蓋點雲 - 道路與格子
終端(無人車)在規劃好路線後,需要下載道路覆蓋到的點雲數據,在PostGIS中屬於兩個集合類型,求overlap。
比如
1. 點雲表:點雲的數據是按geohash或網格聚合的數據,比如每個格子代表一平米的區域。
2. 道路:道路覆蓋的區域,是一個多邊形。
在點雲表中取出與多邊形overlap的數據即可,這個操作可以使用GiST索引,效率非常高。
https://postgis.net/docs/ST_Geometry_Overabove.html
https://postgis.net/docs/reference.html
五、量產無人車 - 點雲數據流式克隆
終端需要存儲運行區域的片區點雲數據,通常在一個片區運行的無人車會有很多輛,每輛無人車的數據是一樣的。
那麼如何給無人車灌點雲數據呢?如何更新增量點雲數據呢?
一個比較好的辦法,每個片區有片區的本地數據庫,本地數據庫的內容來自雲端(全量庫)。
當點雲數據有更新時,首先更新雲端的數據,雲端的數據在下推到每個片區的片區數據庫。
無人車的數據則來自片區數據庫,為了保證數據可以增量流式更新,可以使用PostgreSQL的流式複製,無人車作為備庫,流式追蹤片區數據庫的REDO增量,保證數據是最新的。
隻要無人車能連通片區網絡,那麼就可以流式增量的同步片區數據。
如果無人車的數據隻有隻讀需求,那麼建議使用物理流複製(效率最高),如果無人車的數據除了隻讀,還有寫的需求,可以使用PG 10的邏輯訂閱(同步效率低於物理流複製,但是更新量不大的話,可以接受)。
《PostgreSQL 邏輯訂閱 - 給業務架構帶來了什麼希望?》
《PostgreSQL 10.0 preview 功能增強 - 備庫支持邏輯訂閱,訂閱支持主備漂移了》
《PostgreSQL 10.0 preview 功能增強 - 邏輯複製支持並行COPY初始化數據》
《PostgreSQL 10.0 preview 邏輯複製 - 原理與最佳實踐》
參考
《無人駕駛背後的技術 - PostGIS點雲(pointcloud)應用》
最後更新:2017-05-24 14:31:33