PostgreSQL - 利用citus處理地理大數(shù)據(jù)

GitHub地址: https://github.com/QingyaFan/effective-backend

實(shí)際問題

實(shí)際業(yè)務(wù)中镀虐,會(huì)有非常大的地理數(shù)據(jù)集的存儲(chǔ)需求你弦,比如全世界的點(diǎn)狀POI蹬挺,數(shù)據(jù)量級(jí)已達(dá)億級(jí)別,存儲(chǔ)在單一的PostgreSQL數(shù)據(jù)表中,查詢性能會(huì)差很多鹅颊,如果對(duì)這些數(shù)據(jù)進(jìn)行空間分析丁存,復(fù)雜的計(jì)算肩杈,動(dòng)不動(dòng)就耗時(shí)十幾二十分鐘,不能滿足實(shí)時(shí)的要求解寝,因此扩然,我們開始尋找一個(gè)可以解決這個(gè)問題的方案。

要找方案聋伦,我們首先要弄清楚原來的瓶頸在哪里夫偶。為什么存儲(chǔ)在單表中性能差?

  • 記錄多觉增,掃描時(shí)間過長兵拢;
  • 寫入和更新時(shí)會(huì)產(chǎn)生表級(jí)的鎖,其他的寫入和更新操作只能等待逾礁;
  • 單磁盤I/O性能有限说铃。

單表存儲(chǔ)可能存在的問題?

  • 單表數(shù)據(jù)是單文件存在的嘹履,數(shù)據(jù)量過大可能會(huì)達(dá)到磁盤存儲(chǔ)單文件的大小瓶頸腻扇。

Citus是什么

首先,Citus是一個(gè)PostgreSQL的擴(kuò)展砾嫉,類似于PostGIS幼苛、pgRouting,它主要的作用是將一張大表分布到多臺(tái)機(jī)器的數(shù)據(jù)庫中焕刮,并且可已經(jīng)將查詢分布到不同節(jié)點(diǎn)并行執(zhí)行蚓峦,最后匯總結(jié)果。Citus是單coordinator济锄,多worker結(jié)構(gòu)暑椰,coordinator統(tǒng)籌協(xié)調(diào),worker是真正干活的壯丁荐绝。

Citus數(shù)據(jù)分布及查詢執(zhí)行示意圖

從Citus官網(wǎng)盜了一張圖來一汽,這張圖說的很清楚,當(dāng)存儲(chǔ)數(shù)據(jù)時(shí),Coordinator節(jié)點(diǎn)會(huì)把當(dāng)前表分為多個(gè)分片(shard)召夹,并將分片安裝某種算法分布到各個(gè)worker節(jié)點(diǎn)岩喷,并記錄一份元數(shù)據(jù),如果開啟了“分片復(fù)制”(Shard Replication)监憎,兩個(gè)不同的節(jié)點(diǎn)中可能會(huì)存在同一分片的不同副本纱意,為了防止單點(diǎn)故障造成的數(shù)據(jù)丟失。當(dāng)一個(gè)針對(duì)分布式表的查詢進(jìn)來鲸阔,Coordinator會(huì)根據(jù)數(shù)據(jù)的分布偷霉,將查詢分別分配到各個(gè)worker節(jié)點(diǎn),最后匯總結(jié)果褐筛。安排的明明白白类少。

什么時(shí)候用Citus!

  • 數(shù)據(jù)分布式存儲(chǔ)的應(yīng)用(Multi-tenant Application)渔扎,實(shí)測單節(jié)點(diǎn)vs四臺(tái)citus集群入庫20G數(shù)據(jù)有7倍的差距硫狞;
  • 實(shí)時(shí)分析與統(tǒng)計(jì)(Real-Time Dashboards),只適合節(jié)點(diǎn)之間IO非常小的場景晃痴;
  • 時(shí)間序列數(shù)據(jù)的查詢分析(Timeseries Data)残吩,不甚了解。

Citus不是萬金油倘核,啥時(shí)候不要用世剖?

  • 各個(gè)worker節(jié)點(diǎn)間有大量的數(shù)據(jù)流動(dòng),I/O過大笤虫,會(huì)將并行執(zhí)行節(jié)省的優(yōu)勢抵消掉旁瘫,反倒不如單節(jié)點(diǎn)高配機(jī)器

Citus的特點(diǎn)

  1. 從單節(jié)點(diǎn)數(shù)據(jù)庫到Citus集群無需更改應(yīng)用邏輯,無縫集成琼蚯。

當(dāng)你從單節(jié)點(diǎn)切換到Citus集群時(shí)酬凳,你會(huì)發(fā)現(xiàn)這是一件多么容易的事情,不需要更改任何應(yīng)用邏輯遭庶,之前你面對(duì)的是一個(gè)PostgreSQL宁仔,之后你還是面對(duì)的一個(gè)PostgreSQL,不同的是峦睡,之后你有了強(qiáng)大的存儲(chǔ)和算力翎苫,而且這都是由citus的coordinate節(jié)點(diǎn)管理的,不需要我們維護(hù)榨了。

  1. 并行執(zhí)行查詢提高效率煎谍,且性能隨著節(jié)點(diǎn)數(shù)量增加線性增加。但不適用于需要各節(jié)點(diǎn)匯總數(shù)據(jù)龙屉,涉及大量IO的情景呐粘,這樣反而會(huì)抵消并行執(zhí)行省下的時(shí)間满俗。

Citus通過使用鉤子和擴(kuò)展API來實(shí)現(xiàn)PostgreSQL的分布式存儲(chǔ)和并行計(jì)算,因此很多PostgreSQL擴(kuò)展也能使用citus提供的能力作岖,包括PostGIS唆垃,這就為我們使用Citus集群來管理和分析地理大數(shù)據(jù)提供了可能。但是需要注意痘儡,要配合Citus使用其它擴(kuò)展辕万,Citus必須是第一個(gè)啟用的擴(kuò)展,其次沉删,必須在coordinator和worker節(jié)點(diǎn)都安裝相應(yīng)擴(kuò)展渐尿。所以我們需要在所有機(jī)器節(jié)點(diǎn)上安裝Citus和PostGIS。

嘗試

本示例使用了6臺(tái)機(jī)器做集群丑念,1臺(tái)coordinator涡戳,5臺(tái)worker

  1. 首先在各個(gè)節(jié)點(diǎn)上安裝PostgreSQL结蟋,安裝Citus擴(kuò)展脯倚,安裝PostGIS擴(kuò)展;
  2. 修改PostgreSQL的配置嵌屎,啟動(dòng)時(shí)預(yù)加載citus推正,并配置各個(gè)節(jié)點(diǎn)的PostgreSQL互相聯(lián)通,可互相訪問宝惰;
  3. 啟動(dòng)數(shù)據(jù)庫植榕,啟用擴(kuò)展。
systemctl start postgresql-10.service
systemctl enable postgresql-10.service
psql -U postgers -c "create extension citus;"
psql -U postgers -c "create extension postgis;"

添加worker

在coordinator節(jié)點(diǎn)添加所有worker節(jié)點(diǎn)尼夺,

psql -U postgres -c "select * from master_add_node('ip-or-name', port);"

最后列出所有節(jié)點(diǎn)檢查是否添加成功尊残,

psql -U postgres -c "SELECT * FROM master_get_active_worker_nodes();"

遷移數(shù)據(jù)

遷移現(xiàn)有的數(shù)據(jù)到citus集群

允許服務(wù)間斷的場景:

首先將原來的數(shù)據(jù)備份,將一張表由單表調(diào)整為distributed淤堵,需要在灌數(shù)據(jù)之前聲明寝衫,所以我們需要三個(gè)步驟:首先備份并恢復(fù)表結(jié)構(gòu),然后聲明表為distributed拐邪,最后備份并恢復(fù)數(shù)據(jù)慰毅,此時(shí)數(shù)據(jù)會(huì)分布到各個(gè)worker。

  • 備份表結(jié)構(gòu)

pg_dump -Fc --no-owner --schema-only --dbname db_name > db_name_schema.back

pg_restore --dbname db_name db_name_schema.back

  • 聲明distributed

select * from create_distributed_table('table_name', 'id')

  • 灌數(shù)據(jù)

pg_dump -Fc --no-owner --data-only --dbname db_name > db_name_data.back

pg_restore --dbname db_name db_name_data.back

不允許服務(wù)間斷

可以使用PostgreSQL的logical replication扎阶,將在用的老數(shù)據(jù)庫指向Citus主節(jié)點(diǎn)汹胃,這樣新老數(shù)據(jù)庫處于同步狀態(tài),然后統(tǒng)一將服務(wù)的數(shù)據(jù)庫連接地址切換到Citus东臀。

測試性能

All things done着饥!接下來進(jìn)行一些簡單的測試。

導(dǎo)入數(shù)據(jù)與數(shù)據(jù)分布

數(shù)據(jù)量: 122608100 個(gè)多邊形惰赋,恢復(fù)數(shù)據(jù)耗時(shí)7分鐘贱勃,每個(gè)節(jié)點(diǎn) 9.1 G 數(shù)據(jù);這些數(shù)據(jù)恢復(fù)到一臺(tái)相同配置單主機(jī)的 PostgreSQL 數(shù)據(jù)庫數(shù)據(jù)量是,耗時(shí) 55分鐘贵扰,28 G 數(shù)據(jù)仇穗。將近8倍的差距,但是我們注意到數(shù)據(jù)是有一定程度的冗余的戚绕,因此citus可以承受單節(jié)點(diǎn)的數(shù)據(jù)丟失纹坐。

緩沖區(qū)操作處理時(shí)間

對(duì)1.2億的數(shù)據(jù)進(jìn)行6米半徑的緩沖區(qū)分析,并將結(jié)果存入數(shù)據(jù)庫

insert into buffer_result (id, the_geom) select id, st_buffer(the_geom, 6) as the_geom from table_name;

citus集群舞丛,56分鐘耘子;單機(jī),120分鐘球切,差距并不明顯谷誓,原因其實(shí)我們上面提到過,計(jì)算結(jié)果需要匯總吨凑,且涉及到了大量的IO捍歪,觀察處理過程注意到,15分鐘計(jì)算完成鸵钝,25分鐘匯總數(shù)據(jù)糙臼,16分鐘寫入結(jié)果,而單機(jī)不需要匯總數(shù)據(jù)恩商。

不涉及匯總的操作

對(duì)1.2億多邊形統(tǒng)計(jì)總節(jié)點(diǎn)數(shù):

select sum(st_npoints(the_geom)) from table_name;

citus集群耗時(shí)1.7秒变逃,而單節(jié)點(diǎn)耗時(shí)50秒,差距很明顯怠堪。

總結(jié)

以上的測試中揽乱,數(shù)據(jù)庫并沒有進(jìn)行很好的調(diào)優(yōu),是比較粗糙的結(jié)果粟矿,但也足以說明問題凰棉。

  • 數(shù)據(jù)分布式存儲(chǔ)的應(yīng)用(Multi-tenant Application),實(shí)測單節(jié)點(diǎn)vs四臺(tái)citus集群入庫20G數(shù)據(jù)有7倍的差距嚷炉;
  • 實(shí)時(shí)分析(Real-Time Dashboards)渊啰,只適合節(jié)點(diǎn)之間IO非常小的場景。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末申屹,一起剝皮案震驚了整個(gè)濱河市绘证,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌哗讥,老刑警劉巖嚷那,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異杆煞,居然都是意外死亡魏宽,警方通過查閱死者的電腦和手機(jī)腐泻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來队询,“玉大人派桩,你說我怎么就攤上這事“稣叮” “怎么了铆惑?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長送膳。 經(jīng)常有香客問我员魏,道長,這世上最難降的妖魔是什么叠聋? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任撕阎,我火速辦了婚禮,結(jié)果婚禮上碌补,老公的妹妹穿的比我還像新娘虏束。我一直安慰自己,他們只是感情好脑慧,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布魄眉。 她就那樣靜靜地躺著砰盐,像睡著了一般闷袒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上岩梳,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天囊骤,我揣著相機(jī)與錄音,去河邊找鬼冀值。 笑死也物,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的列疗。 我是一名探鬼主播滑蚯,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼抵栈!你這毒婦竟也來了告材?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤古劲,失蹤者是張志新(化名)和其女友劉穎斥赋,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體产艾,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疤剑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年滑绒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隘膘。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡疑故,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出弯菊,到底是詐尸還是另有隱情焰扳,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布误续,位于F島的核電站吨悍,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蹋嵌。R本人自食惡果不足惜育瓜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望栽烂。 院中可真熱鬧躏仇,春花似錦、人聲如沸腺办。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽怀喉。三九已至书妻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間躬拢,已是汗流浹背躲履。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留聊闯,地道東北人工猜。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像菱蔬,于是被迫代替她去往敵國和親篷帅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350