閱讀358 返回首頁    go 阿裏雲 go 技術社區[雲棲]


海量實時計算+OLTP+OLAP DB設計 - 阿裏雲(RDS、HybridDB) for PostgreSQL最佳實踐 - 泛電網係統應用

標簽

PostgreSQL , 國家電網 , 電表 , 餘額 , 流式計算 , 狀態監測 , 上下文相關


背景

電網係統是一個關係民生,又非常典型的傳統係統,雖然傳統,量可不小。在互聯網化(物聯網化)的今天,有很多值得借鑒和思考的點供給其他相關係統參考。

每個省份大概有億級戶電表,最大的地市可能有千萬戶級別。

以往我們電費是怎麼交的呢?我們小區是兩個月交一次,也就是說先消費,再付款的方式。這麼說起來電網真的是很仁義啊,現在哪有這麼多先消費再付款的呀。移動話費、家庭寬帶、天然氣等等,都是充值後使用的,欠費就給你停機停網。

不過還好,社會主義國民素質都是很不錯的,沒有那麼多用霸王電的,不交的話國家電網指定拉閘。

但是電費如果改成充值形式的,你會不會不習慣呢?操表員的崗位會逐漸淡出(估計很多地方已經沒有抄表員了)。

即使不改充值形式,實際上電力係統也還有很多事情是可做的,例如已家庭、小區、片區、行政區為分組的用電量實時監測、加速度監測、數據大盤、數據預測、應急響應 等等。

係統又該如何來設計呢?

下麵以電表實時監測為例,講解這個係統的設計,以及壓測。

業務需求分析

每個電表,每隔5分鍾采集一次電表數據。

記錄用電明細(用於將來的大盤分析),同時更新用戶的最後用電數據(提供也應用判斷用戶是否超量用電、是否盜電等)。

可能涉及到幾張表:

1、用電明細(每次上傳的讀數、用於對賬、分析等)

電表ID,時間,讀數

2、用戶實時用電量(實時狀態、規則預警、響應)

電表ID,上次時間,當前時間,日初讀數,月初讀數,年初讀數,上次讀數,當前讀數

3、預警規則表

比如5分鍾增量大於多少

比如5分鍾內用電為負數

4、異常用電明細(異常預警明細)

5、用戶賬戶(餘額、套餐等)

電表ID,餘額,套餐ID,創建時間,更新時間

6、元數據(套餐信息)

套餐ID,是否峰穀電,計價等信息

7、用戶充值記錄

G點分析

1、分析需求

全國我們估計10億級電表數,每5分鍾一個點,一天2880億數據,一年105萬億記錄。量還是蠻大的。

當然,通常明細統計不會這麼大的範圍,通常是地級市級別(千萬級戶數),一天28.8億,一年1萬億左右。

阿裏雲HybridDB for PostgreSQL是一個分布式MPP數據庫,麵向PB級數據分析型業務。具備非常強大的計算能力、存儲能力、OLAP功能(GIS、JSON、分析函數、多維分析、窗口、列存儲、分區、橫向擴展等)。

2、實時預警需求

對單個地市,每5分鍾的數據流量約千萬級別。每天28.8億流量。

阿裏雲RDS PostgreSQL支持處理每天千億級別的數據流量。28.8億非常輕鬆。

PostgreSQL 在全球有非常多的應用,從軍工、科研、商業到民用,無所不在(天文、新零售、時序、菜鳥、高德、流計算、時空搜索、任意維度挖掘、JSON、圖式搜索、文本搜索、圖像相似搜索、金融風控等)。

《PostgreSQL 應用案例》

3、套餐管理

套餐管理屬於典型的OLTP係統,阿裏雲RDS PostgreSQL可以非常好的支持。

架構設計

pic

設計以及性能指標參考:

1、明細數據,實時寫入RDS PostgreSQL,單台RDS PG寫入量可以做到每秒約200萬行,每天寫入約1700億左右。

建立小時級分區表。

RDS PG支持讀寫OSS外部表,支持並行將數據寫出到OSS對象存儲。

2、分析需求,使用HybridDB for PostgreSQL。

HDB for PG支持PG級海量數據分析,同時支持並行讀寫OSS對象存儲。支持並行計算、列存、壓縮、分析特性等。

阿裏內部有大量的HDB for PG應用案例,百TB 以上級別比比皆是。

3、調度係統,將明細數據從RDS PG,經OSS,導入HDB for PostgreSQL。整個過程數據都是並行處理的,不存在瓶頸。

4、實時監測、預警,采用RDS PG。單台RDS PG支持每秒30萬左右的單步更新(批量性能可以更好),每天更新量260億左右。直轄市級地市完全不是問題。

5、其他套餐相關OLTP需求,采用RDS PG。

6、曆史明細,例如1年前的明細。使用OSS存儲。

使用OSS存儲後,RDS PG, HDB PG可以使用OSS外部表,透明訪問這些曆史。即便需要分析,或者查詢明細也沒有問題。

擴容設計

1、明細業務擴容

按地市分庫,對於超級龐大地市,可以按電表HASH再分。(RDS PG單機已經有非常龐大的計算能力,後麵會有性能指標數據。水平擴容的可能性極低)

2、分析業務擴容。

HybridDB for PG,本身就是一個MPP數據庫,支持PB級體量的運算,通過OSS對象存儲與計算分離,支持幾乎無限容量的存儲。

3、實時監測業務擴容。

按地市分庫,對於超級龐大地市,可以按電表HASH再分。(RDS PG單機已經有非常龐大的計算能力,後麵會有性能指標數據。水平擴容的可能性極低)

4、其他套餐相關OLTP業務擴容。

業務量很小,不需要考慮擴容。

明細業務 DEMO

明細業務很簡單,就是單純的寫入。我有寫過很多類似的案例,可以參考如下案例中的數據。

1、運營商網關數據,金融行業數據,產生量大,並且要求快速插入大數據庫中持久化保存。

506萬行/s,1.78 GB/s,全天插入4372億,154TB數據。

《PostgreSQL 如何瀟灑的處理每天上百TB的數據增量》

2、《PostgreSQL on ECS + 雲盤》

173萬行/s,全天插入1500億。

分析 + 調度業務 DEMO

數據從OLTP係統,通過調度係統寫入OLAP係統,OLAP實現數據分析。整個流程如何實現的?請參考如下文章:

《打造雲端流計算、在線業務、數據分析的業務數據閉環 - 阿裏雲RDS、HybridDB for PostgreSQL最佳實踐》

實時監測 DEMO

即將發布的PG 10將包含流計算插件,實時監測除了使用傳統的手段,也可以使用PostgreSQL流計算插件來實現,流計算性能指標參考如下:

《"物聯網"流式處理應用 - 用PostgreSQL實時處理(萬億每天)》

《流計算風雲再起 - PostgreSQL攜PipelineDB力挺IoT》

另外,本文將介紹實時監測的傳統詳細用法如下,畢竟大多數用戶還是很傳統的。

表結構設計

demo涉及到三張表:

1、用戶實時用電量(實時狀態、規則預警、響應)

電表ID,上次時間,當前時間,日初讀數,月初讀數,年初讀數,上次讀數,當前讀數

insert returning

2、預警規則表

比如5分鍾增量大於多少

比如5分鍾內用電為負數

select ,CACHE

3、異常用電明細(異常預警明細)

insert

流程如下:

pic

建表和QUERY

我們這裏隻需要測試壓力最大的,實時電表數據更新和返回。

create table tbl_real_data (  
  uid int primary key,   -- 電表ID  
  last_time timestamp,   -- 上次更新時間  
  curr_time timestamp,   -- 當前時間  
  d1 float4,   -- 日初讀數,業務提供  
  d2 float4,   -- 月初讀數,業務提供  
  d3 float4,   -- 年初讀數,業務提供  
  d4 float4,   -- 上次讀數  
  d5 float4    -- 當前讀數,業務提供  
);  

QUERY設計,更新,並返回更新後的數據

insert into tbl_real_data values ($1,$2,$3,$4,$5,$6,$7,$8)   
  on conflict (uid) do   
  update set   
    last_time=tbl_real_data.curr_time,  
    curr_time=excluded.curr_time,  
    d1=coalesce(excluded.d1,tbl_real_data.d1),  
    d2=coalesce(excluded.d2,tbl_real_data.d2),  
    d3=coalesce(excluded.d3,tbl_real_data.d3),  
    d4=tbl_real_data.d5,  
    d5=excluded.d5  
  returning *;  

例子,插入實時電表數據,並返回更新前、更新後的狀態。業務根據返回的數據、規則實時預警、響應。

insert into tbl_real_data values (  
  1,      -- 電表ID  
  null,   -- 上次的更新時間  
  now(),  -- 當前時間  
  2,      -- 日初讀數,業務提供,翻轉時提供  
  3,      -- 月初讀數,業務提供,翻轉時提供  
  4,      -- 年初讀數,業務提供,翻轉時提供  
  null,   -- 上次讀數  
  6       -- 當前讀數  
)   
  on conflict (uid) do   
  update set   
    last_time=tbl_real_data.curr_time,  
    curr_time=excluded.curr_time,  
    d1=coalesce(excluded.d1,tbl_real_data.d1),  
    d2=coalesce(excluded.d2,tbl_real_data.d2),  
    d3=coalesce(excluded.d3,tbl_real_data.d3),  
    d4=tbl_real_data.d5,  
    d5=excluded.d5  
  returning *;  
  
 uid | last_time |         curr_time          | d1 | d2 | d3 | d4 | d5   
-----+-----------+----------------------------+----+----+----+----+----  
   1 |           | 2017-08-26 12:19:54.486801 |  2 |  3 |  4 |    |  6  
(1 row)  
  
insert into tbl_real_data values (  
  1,      -- 電表ID  
  null,   -- 上次的更新時間  
  now(),  -- 當前時間  
  null,   -- 日初讀數,業務提供,翻轉時提供  
  null,   -- 月初讀數,業務提供,翻轉時提供  
  null,   -- 年初讀數,業務提供,翻轉時提供  
  null,   -- 上次讀數  
  8       -- 當前讀數  
)   
  on conflict (uid) do   
  update set   
    last_time=tbl_real_data.curr_time,  
    curr_time=excluded.curr_time,  
    d1=coalesce(excluded.d1,tbl_real_data.d1),  
    d2=coalesce(excluded.d2,tbl_real_data.d2),  
    d3=coalesce(excluded.d3,tbl_real_data.d3),  
    d4=tbl_real_data.d5,  
    d5=excluded.d5  
  returning *;  
  
 uid |         last_time          |         curr_time          | d1 | d2 | d3 | d4 | d5   
-----+----------------------------+----------------------------+----+----+----+----+----  
   1 | 2017-08-26 12:19:54.486801 | 2017-08-26 12:20:01.452364 |  2 |  3 |  4 |  6 |  8  
(1 row)  
  
返回了上一個狀態,業務根據這些信息、以及配置的規則,進行實時預警。  

壓測

壓測腳本如下,1000戶,隨機upsert,返回最終狀態和上一個狀態。

vi test.sql  
  
\set uid random(1,10000000)  
\set d5 random(1,100000)  
insert into tbl_real_data (uid,curr_time,d5) values (:uid, now(), :d5)   on conflict (uid) do   update set     last_time=tbl_real_data.curr_time,    curr_time=excluded.curr_time,    d1=coalesce(excluded.d1,tbl_real_data.d1),    d2=coalesce(excluded.d2,tbl_real_data.d2),    d3=coalesce(excluded.d3,tbl_real_data.d3),    d4=tbl_real_data.d5,    d5=excluded.d5  returning *;  

結果

pgbench -M prepared -n -r -P 1 -f ./test.sql -c 64 -j 64 -T 120  
  
tps = 291094.784574 (including connections establishing)  
tps = 291123.921221 (excluding connections establishing)  

性能指標

1、明細業務(單庫性能指標)

173萬行/s,全天插入1500億明細。可以滿足4.7億戶的大地市需求。

(5分鍾上傳一次電表讀數,需要防止風暴,例如采用隨機開始時間。)

2、分析業務

PB級。

3、實時監測業務(單庫性能指標)

29萬行/s,全天監測次數250億次。可以滿足8000萬戶的大地市需求。

(5分鍾上傳一次電表讀數,需要防止風暴,例如采用隨機開始時間。)

城市人口規模統計數據(截取自互聯網):

重慶3000萬規模,北京2300萬規模,東京3700萬規模。電表戶數按3:1算,也在1000萬出頭。PostgreSQL單機能力遠超全球最大人口城市的需求。

雲端產品

阿裏雲 RDS PostgreSQL

阿裏雲 HybridDB for PostgreSQL

阿裏雲 海量對象存儲OSS

阿裏雲 RDS redis

小結

電網係統是關係到民生的係統,以往我們電費基本上都是按月結算,將來水電都有可能會像手機話費、天然氣一樣套餐的形式。

計費實際上也不是特別簡單,涉及到峰穀電、階梯價、商業、工業電等,將來如果有套餐出現,會更加複雜。

不過不用擔心,阿裏雲RDS PG, HDB PG, OSS, redis等雲端產品,從“用電明細、實時監測、全網海量OLAP分析、套餐類OLTP管理”等方麵著手,可以很好的解決電網係統的需求。

參考

《PostgreSQL物理"備庫"的哪些操作或配置,可能影響"主庫"的性能、垃圾回收、IO波動》

《PostgreSQL 老濕機圖解平安科技遇到的垃圾回收"坑"》

《PostgreSQL 9.6 快照過舊 - 源碼淺析》

《PostgreSQL on Linux 最佳部署手冊》

《PostgreSQL on ECS多雲盤的部署、快照備份和恢複》

實時監測業務注意,垃圾回收相關參數設置:

《垃圾回收設置避免IO波動》

最後更新:2017-08-28 10:32:37

  上一篇:go  音視圖(泛內容)網站透視分析 DB設計 - 阿裏雲(RDS、HybridDB) for PostgreSQL最佳實踐
  下一篇:go  如何破解中國交通擁堵? 世界頂級算法工程師都來了