开发者学堂课程【PostgreSQL云上开发实践:阿里云PostgreSQL_案例介绍1】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/528/detail/7100
阿里云PostgreSQL_案例介绍1
内容介绍:
一、OLTP Benchmark(56 Core ECS, PG 10)
二、OLAP Benchmark(56 Core ECS, PG 10)
三、HDB PG OLAP Benchmark(1 Host)
四、HDB PG OLAP Benchmark(50 Host)
五、Case1(标签-多值类型)
六、Case1(标签-多值类型)
七、案例—架构设计、代码、实操手册
一、OLTP Benchmark(56 Core ECS, PG 10)
CASE |
数据量 |
并发 |
TPS |
平均响应时间 |
点查,KEY值查询 |
1亿 |
112 |
69万 |
0.16毫秒 |
键值更新 |
1亿 |
56 |
22万 |
0.25毫秒 |
合并写入(有则更新、无则写入) |
1亿 |
56 |
22.8万 |
0.245毫秒 |
秒杀-单杀记录并发更新 |
1 |
56 |
23万 |
0.48毫秒 |
空间包含,菜鸟精准分包、共享单车等 |
1亿个多边形 |
112 |
27.9万 |
0.4毫秒 |
搜索空间附近对象,LBS,O2O |
10亿个经纬度点 |
112 |
13.7万 |
0.8毫秒 |
空间数据、位置更新(滴、菜鸟、饿) |
1亿 |
56 |
18万 |
0.3毫秒 |
图示搜索(N度搜索、最短路径) |
50亿,3度搜索,单次响应2.1毫秒 |
64 |
1万 |
6.6毫秒 |
全文检索、写入、实时索引 |
500万词库,每行64个词,并发写入 |
56 |
9.3万 |
0.6毫秒 |
数组、写入、实时索引 |
500万词库,每行64个词,并发写入 |
56 |
10万 |
0.5毫秒 |
前后模糊查询、实时索引、并发写 |
128个随机字符 |
56 |
14.4万 |
0.38毫秒 |
字符串查询、前缀like‘x%’ |
1亿,128个随机字符 |
112 |
14万 |
0.8毫秒 |
字符串查询、后缀like‘%x’ |
1亿,128个随机字符 |
112 |
17.8万 |
0.63毫秒 |
字符串查询、前后百分号like‘%x%’ |
1亿,128个随机字符 |
56 |
8.1万 |
0.68毫秒 |
字符串查询、相似查询similary(str,‘x’) |
1亿,128个随机字符 |
56 |
1531 |
35毫秒 |
字符串查询、全文检索ts@@tsquery |
1亿 |
56 |
5.14万 |
1毫秒 |
流式处理-阅后即焚-消费 |
10亿,消费395.2万行/s |
56 |
3952 |
14毫秒 |
物联网-阅后即焚-读写并测 |
写入:193万行/s,消费:418万行/s |
56 |
|
|
物理网-阅后即焚-JSON+函数流计算-读写并测 |
写入:180万行/s,消费:145.8万行/s |
56 |
|
|
单表,无索引,单事务单条写入 |
单行110字节 |
56 |
26万 |
0.2毫秒 |
单表,有索引,单事务单条写入 |
单行110字节 |
56 |
10万 |
0.5毫秒 |
单表,无索引,单事务多条批量写入 |
单行110字节,每次提交1000条 |
56 |
180万/s |
30.9毫秒 |
单表,有索引,单事务多条批量写入 |
单行110字节,每次提交1000条 |
56 |
16.7万/s |
334毫秒 |
多表,无索引,单事务单条写入 |
动态SQL成为瓶颈 |
56 |
18万行/s |
0.3毫秒 |
多表,有索引,单事务单条写入 |
动态SQL成为瓶颈 |
56 |
17万行/s |
0.3毫秒 |
多表,无索引,单事务单条写入 |
每次提交1000条 |
56 |
262.7万行/s |
21毫秒 |
多表,有索引,单事务单条写入 |
每次提交1000条 |
56 |
145万行/s |
38毫秒 |
无日志多表,无索引,单事务多条写入 |
每次提交1000条 |
56 |
813万行/s |
6.8毫秒 |
无日志多表,有索引,单事务多条写入 |
每次提交1000条 |
56 |
733万行/s |
7.6毫秒 |
二、OLAP Benchmark(56 Core ECS, PG 10)
CASE |
数据量 |
并发 |
TPS |
平均响应时间 |
多表JOIN |
10张1000万的表 |
112 |
10万 |
1.08毫秒 |
大表JOIN,统计 |
2张1亿,1张100万 |
56 |
2.2万 |
2.5毫秒 |
大表OUTER JOIN、统计 |
1千万OUTER JOIN 1亿 |
|
|
1千万left join 1亿:11秒 反之:8秒 |
用户画像-数组包含、透视 |
1亿,每行16个标签 |
56 |
1773 |
31毫秒 |
用户画像-数组相交、透视 |
1亿,每行16个标签 |
56 |
113 |
492毫秒 |
用户画像-varbitx |
1万行,2000亿BIT,与或非 |
|
|
2.5秒 |
用户画像-多字段任意搜索/聚合、透视 |
1亿,32个字段,任意字段组合查询 |
56 |
3.6万 |
1.56毫秒 |
物联网-线性数据-区间实时聚合、统计 |
1万传感器,10亿记录 |
56 |
6266 |
8.9毫秒 |
排序 |
1亿 |
32 |
|
1.4秒 |
建索引 |
1亿 |
|
|
PG10:38秒;PG11:15.5秒 |
并行扫描 |
1亿 |
32 |
|
0.88秒 |
并行聚合 |
1亿 |
32 |
|
0.9秒 |
并行过滤 |
1亿 |
32 |
|
1秒 |
并行JOIN+聚合 |
1000万JOIN1000万 |
32 |
|
PG10:5.4秒;PG11:1秒 |
并行JOIN+聚合 |
1亿JOIN1亿(双表过滤到1000万) |
32 |
|
PG10:6.3秒;PG11:1.2秒 |
并行JOIN+聚合 |
1亿JOIN1亿(单表过滤到1000万) |
32 |
|
PG10:8.5秒;PG11:2秒 |
并行JOIN+聚合 |
1亿JOIN1亿(无条件JOIN) |
32 |
|
PG10:58.3秒;PG11:10.7秒 |
并行JOIN+聚合 |
10亿JOIN10亿(双表过滤到1000万) |
32 |
|
PG10:12秒;PG11:1秒 |
并行HASH AGG |
10亿(PG 11) |
61 |
|
11秒 |
VOPS+异步并行 |
10亿,聚合查询(PG 10) |
56 |
|
2秒 |
多表并行扫描(parallel append) |
2亿(PG 11) |
64 |
|
0.6秒 |
求TOP-K |
100亿(PG 11) |
64 |
|
40秒 |
OLAP Benchmark(56 Core ECS,PG 10)
测试详情:
https://github.com/digoal/blog/blob/master/201711/readme.md
https://github.com/digoal/blog/blob/master/201801/20180102_04.md https://github.com/digoal/blog/blob/master/201802/20180204_01.md https://github.com/digoal/blog/blob/master/201802/20180204_03.md
https://github.com/digoal/blog/blob/master/201802/20180201_01.md https://github.com/digoal/blog/blob/master/201802/20180202_02.md https://github.com/digoal/blog/blob/master/201802/20180210_01.md
手机行业通用场景:
(1)APP商店(实时 UV 、TOP-K 、FEED 数据透视分析、用户画像。)(2)支付平台(可靠性)
(3)对账平台(游标、数据处理逻辑复杂、FUNCTION )
(4)虚拟货币平台
(5)认证平台
(6)好友关系平台(图式搜索、好友推荐、GIS )
(7)聊天系统(文本控掘)
(8)OA 系统
(9)分析库(大数据、实时、离线计算、用户画像)
(10)游戏库(角色类、棋牌类(炸金花短平快、数据库写入、更新量大))
三、HDB PG OLAP Benchmark(1 Host)
CASE |
数据量 |
并发 |
TPS |
平均响应时间 |
非分布键group by,TOP-K |
10亿、列存、压缩、101个元素 |
1 |
|
1.8秒 |
非分布键count(distinct) |
10亿、列存、压缩、101个元素 |
1 |
|
1.8秒 |
非分布键order by,TOP-K |
10亿、列存、压缩、索引 |
1 |
|
50毫秒 |
非分布键JOIN,group by,TOP-K |
10亿、列存、压缩、101个元素 |
1 |
|
56毫秒 |
非分布键JOIN,count(distinct) |
10亿、列存、压缩、101个元素 |
1 |
|
53毫秒 |
非分布键JOIN,order by,TOP-K |
10亿、列存、压缩 |
1 |
|
141毫秒 |
分布键group by,TOP-K |
10亿、列存、压缩、10亿元素 |
1 |
|
1.67毫秒 |
分布键order by,TOP-K |
10亿、列存、压缩、索引 |
1 |
|
42毫秒 |
分布键JOIN,order by,TOP-K |
10亿、列存、压缩、10亿元素 |
1 |
|
119毫秒 |
海量数据导入,走OSS(带系统干扰时) |
100亿,5.5TB,单行576字节 |
<1% |
重复度 |
1250秒(压缩后360秒) |
海量数据内部生成 |
1000亿,55TB,单行576字节 |
|
|
2112秒 |
1000亿,前后模糊查询 |
|
|
|
246秒 |
并发前缀查询100亿+写入目标(2.5亿) |
100亿,5个并发前缀查询,写入 |
|
|
149秒 |
复杂统计+模糊查询+写入目标(0.5亿) |
100亿,统计伴随,模糊查询写 |
|
|
64秒 |
海量导入+模糊查询+写入目标(0.5亿) |
100亿,统计伴随,模糊查询写 |
|
|
56秒 |
海量导入+510字节模糊查询+写入(0.5亿) |
100亿,统计伴随,模糊查询写 |
|
|
59秒 |
100亿JOIN5000万,双可变字段510字节+写 |
写0.5亿 |
|
|
109秒 |
100亿,双可变字段510字节,聚合写 |
写100亿 |
|
|
481秒 |
四、HDB PG OLAP Benchmark(50 Host)
CASE |
数据量 |
并发 |
TPS |
平均响应时间 |
海量数据导入,走OSS(带系统干扰时) |
100亿,5.5TB,单行576字节 |
<1% |
重复度 |
1250秒(压缩后360秒) |
海量数据内部生成 |
1000亿,55TB,单行576字节 |
|
|
2112秒 |
1000亿,前后模糊查询 |
|
|
|
246秒 |
并发前缀查询100亿+写入目标(2.5亿) |
100亿,5个并发前缀查询,写入 |
|
|
149秒 |
复杂统计+模糊查询+写入目标(0.5亿) |
100亿,统计伴随,模糊查询写 |
|
|
64秒 |
海量导入+模糊查询+写入目标(0.5亿) |
100亿,统计伴随,模糊查询写 |
|
|
56秒 |
海量导入+510字节模糊查询+写入(0.5亿) |
100亿,统计伴随,模糊查询写 |
|
|
59秒 |
100亿JOIN5000万,双可变字段510字节+写 |
写0.5亿 |
|
|
109秒 |
100亿,双可变字段510字节,聚合写 |
写100亿 |
|
|
481秒 |
100亿,批量(JOIN)删除100万 |
|
|
|
53秒 |
100亿,批量(join)删除100万 |
更新41秒,更新结果写入B,49秒 |
|
|
|
100亿,流式返回5000万末尾100万行 |
游标技术 |
|
|
1.4秒 |
100亿,任意字段组合排序 |
|
|
|
54秒 |
100亿,表达式排序 |
|
|
|
|
100亿,任意经纬度点,任意多边形包含查询 |
返回最近100条 |
|
|
0.16秒 |
100亿,任意经纬度点,任意多边形包含查询 |
聚合 |
|
|
4.5秒 |
修改表结构-加字段加默认值 |
100亿 |
|
|
3.5秒 |
修改表结构-扩展长度 |
100亿 |
|
|
17秒 |
修改表结构-删除字段 |
100亿 |
|
|
0.01秒 |
非结构化数据,100亿 |
展示功能 |
|
|
|
|
|
|
|
|
五、Case1(标签-多值类型)
·多值类型与GIN索引应用
——Array, Hstore, JSON
用户画像-数组包含、透视 |
1亿,每行16个标签 |
56 |
1773 |
31毫秒 |
案例:(难以结构化)
· XX单车、新零售-XX小店。
· 人群标签 -{标签:结束时间,...}
· 透视人群、求交并差 - 包月人群
- 促销人群
· 痛点 - 无法结构化
· RDS for PG
- 多值类型解决结构化难点问题
-
arr@>array[?,?,...]
- arr&&array[?,?,...]
- not
arr@>array[?,?,...]
· 搜索加速
- GIN倒排,(标签元素倒排索引)
- udf1(标签s)->[1维数组] , udf2(标签s)->[2维数组]
postgres=# select * from tbl where get_label(info)@>array['a'] and get_weight(info,'a')::float8 >20;
id |
info |
1 |
{a:100,b:10} |
(1 row)
postgres=# select * from tb1;
id |
info |
1 |
{a:100,b:10} |
2 |
{a:15,b:20,c:99} |
3 |
{c:78,b:100} |
(3 rows)
· XX生物科技
—几万列浮点
—几十万行
—100GB左右
—计算任意组合(物种、序列分段)的欧式空间距离
—采用 float8[]存储几万列浮点,UDF,计算XX距离。
postgres=# select * from compute_eu_dist(array[1,2,3,4,5])
kind1 |
Kind2 |
euc_dist |
2 |
1 |
57768.4024741692 |
1 |
3 |
57866.2845528097 |
1 |
4 |
57632.9837382263 |
5 |
1 |
57779.36595061 |
3 |
2 |
58004.3926579964 |
4 |
2 |
57593.0783041254 |
5 |
2 |
57802.9690538283 |
3 |
4 |
57837.6707750057 |
3 |
5 |
57921.5524014271 |
4 |
5 |
57818.9181109456 |
(10rows)
Time:100.582 ms
案例-架构设计、代码、实操手册
· 数组类型和操作符、函数、索引
https://www.postgresql.org/docs/10/static/arrays.html
https://www.postgresql.org/docs/10/static/functions-array.html
· 多重含义数组 UDF 检索
https://github.com/digoal/blog/blob/master/201801/20180124_02.md
· 生物科技
https://github.com/digoal/blog/blob/master/201712/20171227_01.md
六、Case2(搜索-GIN)
· 搜索需求分类
—全文检索
—模糊搜索、前缀、后缀、前后模糊
—相似搜索
—任意字段组合搜索
全文检索、写入、实时索引 |
500万词库,每行64个词,并发写入 |
56 |
9.3万 |
0.6毫秒 |
前后模糊查询、实时索引、并发写 |
128个随机字符 |
56 |
14.4万 |
0.38毫秒 |
字符串查询、前缀like‘x%’ |
1亿,128个随机字符 |
112 |
14万 |
0.8毫秒 |
字符串查询、后缀like‘x%’ |
1亿,128个随机字符 |
112 |
17.8万 |
0.63毫秒 |
字符串查询、前后百分号like‘%x%’ |
1亿,128个随机字符 |
56 |
8.1万 |
0.68毫秒 |
字符串查询、全文检索ts@@tsquery |
1亿, |
56 |
5.14万 |
1毫秒 |
字符串查询、相似查询similary(str,‘xx’) |
1亿,128个随机字符 |
56 |
1531 |
35毫秒 |
用户画像-多字段任意搜索/聚合、透视 |
1亿,32个字段,任意字段组合查询 |
56 |
3.6万 |
1.56毫秒 |
案例:(难以加速,难以同步一致性)
· XXX域名服务
—模糊查询、相似查询
—10亿级记录模糊搜索
· XXX某 CRM 系统
—任意字段全文检索、模糊查询
—词汇( phase )查询
—10亿级记录多字段任意组合搜索
· 新零售-营销、分销链路
—多值类型检索
—10亿级记录数组&|搜索
· QA (医疗行业、搜索、知识库)
—相似问题、相似地址、相似病例。。。
· GA
—车牌模糊搜索
痛点:
· 全文检索无法支持“模糊查询”
—(例如域名并非分词)
· 数据库与搜索引擎一致性维护麻烦
云产品方案、效果:
· RDS PG
— gin 倒排索引,
· 支持多值类型、多字段任意条件检索
— bloom 索引
· 支持多字段任意组合等值条件过滤
— 多索引 bitmap scan
· 多个索引合并扫描
— pg_trgm 支持
· 模糊查询、相似查询、正则查询
— zhparser 中文分词插件支持中文分词
1. GIN 复合(倒排+聚集)索引
2. 分词索引
3. bloom 复合索引
4. pg_trgm,fuzzymatch
全文检索技术
全文检索技术—词距离条件
select*from tbl where ts @@'速度<距离值>激情'::tsquery;
如:select* from tbl where ts @@'速度<1>激情'::tsquery;
‘优质服务’:9'公司:8'出租汽车:7'创业:6'创新:2'北京':5坚持':3'小花':10 '激情’:1 ‘絮’:11 '速度':4 ‘激情’:3‘电影’:1'破':5‘票房’:4‘速度':2
带距离
postgres=# select*from ts_test where ts @@'速度<1>激情'::tsquery;
id |
info |
ts |
1 |
电影速度与激情8的票房破亿 |
‘激情’:‘3'电影’:1'破’:5‘票房’:4'速度’:2 |
(1 row)
不带距离
postgres=# select*from ts_test where ts @@ '速度 & 激情’'::tsquery limit 5;
id |
info |
|
1 |
激情,创新,坚持,速度--北京北方创业出租汽车公司优质服务小花架 |
‘优质服务’:9‘公司’:8‘出租汽车’:7‘创业’:6
|
1 |
电影速度与激情8的票房破亿 |
‘激情’:3'电影':1'破':5‘票房':4'速度’:2
|
2 |
激情,创新,坚持,速度--北京北方创业出租汽车公司优质服务小花架 |
‘优质服务’:9‘公司’:8‘出租汽车’:7‘创业’:6
|
2 |
激情,创新,坚持,速度--北京北方创业出租汽车公司优质服务小花架 |
‘优质服务’:9‘公司’:8‘出租汽车’:7‘创业’:6
|
2 |
激情,创新,坚持,速度--北京北方创业出租汽车公司优质服务小花架 |
‘优质服务’:9‘公司’:8‘出租汽车’:7‘创业’:6
|
(5 rows)
按距离范围搜索
自定义 UDF , RANGE 相交操作判断。
全文检索技术—内置 ranking
UPDATE tt SET ti =
setweight(to_tsvector(coalesce(title, ’ ’) ),‘A’)
setweight(to_tsvector(coalesce(keyword,’ ’) ), ‘B’)
setweight(to_tsvector(coalesce(abstract,’ ’) ),‘C’)
setweight(to_tsvector(coalesce(body, ’ ’) ),’D');
LIMIT 10;
title |
rank |
Neutrinos in the Sun |
3.1 |
The Sudbury Neutrino Detector |
2.4 |
A MACHO View of Galactic Dark Matter |
2.01317 |
Hot Gas and Dark Matter |
1.91171 |
The Virgo Cluster:Hot Plasma and Dark Matter |
1.90953 |
Rafting for Solar Neutrinos |
1.9 |
NGC 4650A:Strange Galaxy and Dark Matter |
1.85774 |
Hot Gas and Dark Matter |
1.6123 |
Ice Fishing for Cosmic Neutrinos |
1.6 |
Weak Lensing Distorts the Universe |
0.818218 |
全文检索技术—自定义 ranking
1.店铺标签表
create table tb1 (
Shop_ id int8 primary key, --店铺ID
tegs tex[], --数组,标签1,标签2,......
scores flost8[] --数组,评分1,评分2,......
);
create index idx_tbl_1 on tb1 using gin(tags);
国民_足浴,国民_餐饮,娱乐_KTV
0.99,0.1,0.45
2.标签权值表:
create table tb1_ weight(
tagid int primary key, --标签ID
tagname name, --标签名
besc tent, --标签描述
weight flost8 --标签权值
);
t |
rank |
It looks like a beautiful place |
8.22467 |
The situation is most beautiful |
16.4493 |
It is a beautiful |
16.4493 |
(3 rows)
前缀模糊查询背景技术
· create index idx on tbl (col text_patten ops);
· select *from tbl where {col ~'^前缀’ | like '前缀%'};
· 自动
- postgres=# explain select * from pre where c1 like'你%';
- QUERY PLAN
- Index Scan using idx_pre on pre(cost=0.29..2.71 rows=1 width=21)
- IndexCond:((c1~>=~'你'::text)AND(c1~<~'佡'::text))
- Filter:(c1~~'你%'::text)
(3 rows)
- postgres=# select chr(ascii(‘你’)+1);
- chr
- ------
- 佡
- (1 row)
后缀模糊查询背景技术
· postgres=# create indexidx_pre1 on pre(reverse(c1)text_ pattern_ops);
· CREATE INDEX
- postgres=# select reverse(‘你好abcd ’);
- reverse
- --------
- dcba好你
- (1 row)
- postgres=# explain select * from pre where reverse(c1) like reverse('结尾')||'%';
- QUERY PLAN
- Index Scan using idx_ pre1 on pre(cost=029..45.93rows=50width=21)
- Index Cond:((reverse(c1)~>=~'尾结::text)AND(reverse(c1)~<~'尾绔'::text))
- Filter:(reverse(c1)~~'尾结%’::text)
- (3 rows)
前后模糊查询背景技术
· postgres=# create index idx_pre2 on pre using gin (c1 gin_trgm_ops);
· CREATE INDEX
- postgres=# select show_trgm('abcde');
相似查询
· create or replace function get_res(
· text,--要按相似搜的文本
· int8,--限制返回多少条
· float4 default 0.3,--相似度阙值,低于这个值不再搜搜
· float4 default 0.1 --相似度递减步长,直至阙值
· )returns setof record as $$
· declare
· lim float4:= 1;
· begin
· -- 判定
· if not ($3<= 1 and $3 >0) then
· raise notice '$3 must >0 and <=1';
· return;
· end if;
· loop
· --设置相似度阈值
· perform set_limit(lim);
·
· return query select similarity(info,$1)as sml,* from tbl where info % $1 order by sml desc limit $2;
· -- 如果有,则退出 loop
· if found then
· return;
· end if;
·
· --否则继续,降低阈值
· --当阈值小于0.3时,不再降阈值搜索,认为没有相似。
任意字段组合条件搜索
· 多个独立的索引的BITMAP SCAN(或单个GIN多字段复合索引(using gin(c1,c2,...)))
- select * from table where col1 =? and col2 =?;
- 合并扫描后,访问的数据块非常少,速度很快。
全文检索 + RDS PG sharding
dblink 异步调用并行
https://github.com/digoal/blog/blob/master/201802/20180202_01.md https://github.com/digoal/blog/blob/master/201802/20180205_03.md
七、案例—架构设计、代码、实操手册
· 全文检索
https://github.com/digoal/blog/blob/master/201603/20160310_01.md https://github.com/digoal/blog/blob/master/201712/20171206_01.md https://github.com/digoal/blog/blob/master/201712/20171205_02.md https://www.postgresql.org/docs/10/static/textsearch.html
https://github.com/digoal/blog/blob/master/201801/20180123_01.md(含距离搜索) https://github.com/digoal/bloa/blob/master/201612/20161231_ 01.md
· 模糊、正则查询
https://www.postgresql.org/docs/10/static/pgtrgm.html
· 相似查询
https://www.postgresgl.org/docs/10/static/pgtrgm.html
算法:contrib/pg_trgm/trgm_regexp.c
https://github.com/digoal/blog/blob/master/201802/20180202_ 01.md https://github.com/digoal/blog/blob/master/201802/20180205_ 03.md
· 多字段任意组合查询
https://www.postgresgl.org/docs/10/static/indexes-bitmap-scans.htm https://www.postaresal.org/docs/10/static/bloom.html https://www.postaresgl.org/docs/10/static/btree-gin.html
· sharding
https://github.com/digoal/blog/blob/master/201608/20160824_02.md https://github.com/digoal/blog/blob/master/201110/20111025_01.md httos://github.com/digoal/blog/blob/master/201512/20151220_02.md https://github.com/digoal/blog/blob/master/201512/20151220_03.md https://github.com/digoal/blog/blob/master/201512/20151220_04.md