海量實時計算+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、圖式搜索、文本搜索、圖像相似搜索、金融風控等)。
3、套餐管理
套餐管理屬於典型的OLTP係統,阿裏雲RDS PostgreSQL可以非常好的支持。
架構設計
設計以及性能指標參考:
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的數據增量》
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
流程如下:
建表和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 PG, HDB PG, OSS, redis等雲端產品,從“用電明細、實時監測、全網海量OLAP分析、套餐類OLTP管理”等方麵著手,可以很好的解決電網係統的需求。
參考
《PostgreSQL物理"備庫"的哪些操作或配置,可能影響"主庫"的性能、垃圾回收、IO波動》
《PostgreSQL 老濕機圖解平安科技遇到的垃圾回收"坑"》
《PostgreSQL on ECS多雲盤的部署、快照備份和恢複》
實時監測業務注意,垃圾回收相關參數設置:
最後更新:2017-08-28 10:32:37