注:数据尽可能模拟现场,环境亲手搭建,测试结果真实有效,转载请注明版权所有—作者:周源(网名 源神)
医疗Presto和GreenPlum选型测试报告
本次测试针对现有Oracle(12c)、Hive(3.1.0)、SparkSQL(2.3.2)、Presto(0.229)、TiDB(3.0.8)、GreenPlum(6.1.0) 基础性能测试。我们采用单大表和多表关联,分别对比不同组件在查询性能方面的测试
模拟医疗现场患者数据和就诊记录,oracle表情况如下:
|
表名 |
行数 |
数据量 |
患者数据 |
ORG_PATIENT_INFO_BIG |
158,220,288 |
10,048M |
就诊记录1 |
INP_MR_PAGE_BIG1 |
44,083,200 |
24,230M |
就诊记录2 |
INP_MR_PAGE_BIG2 |
88,166,400 |
48,460M |
注:因oracle存储磁盘空间有限,目前只创建3张大表数据
本次测试方案的大数据Ambari 2.7.3版本,操作系统为CentOS 7.4,基础硬件配置信息如下表:
服务器IP |
服务器域名 |
核心数 |
内存 |
单块磁盘空间 |
**.**.**.8 |
host8 |
24 |
128G |
279G |
**.**.**.5 |
host5 |
40 |
128G |
1.7T |
**.**.**.6 |
host6 |
40 |
128G |
1.7T |
**.**.**.7 |
host7 |
40 |
128G |
1.7T |
Oracle部署信息:
服务器IP |
服务器域名 |
核心数 |
内存 |
磁盘空间 |
**.**.**.46 |
host46 |
24 |
64G |
251G |
Hive部署信息:
服务器IP |
服务器域名 |
Hive Metastore |
HiveServer2 |
Hive Clients |
**.**.**.5 |
host5 |
√ |
√ |
√ |
**.**.**.6 |
host6 |
√ |
√ |
√ |
**.**.**.7 |
host7 |
|
|
√ |
SparkSQL部署信息:
服务器IP |
服务器域名 |
Spark2 History Server |
Spark2 Thrift Server |
Spark2 Clients |
**.**.**.5 |
host5 |
√ |
√ |
√ |
**.**.**.6 |
host6 |
|
|
√ |
**.**.**.7 |
host7 |
|
|
√ |
Presto部署信息:
服务器IP |
服务器域名 |
Coordinator |
Worker |
**.**.**.5 |
host5 |
√ |
√ |
**.**.**.6 |
host6 |
|
√ |
**.**.**.7 |
host7 |
|
√ |
备注:每台机器查询限额内存50G,3台机器总共最大内存额度150G
TiDB部署信息:
服务器IP |
服务器域名 |
TiDB Server |
PD |
TiKV |
**.**.**.8 |
host8 |
√ |
√ |
|
**.**.**.5 |
host5 |
|
|
√ |
**.**.**.6 |
host6 |
|
|
√ |
**.**.**.7 |
host7 |
|
|
√ |
备注: 1、TiDB Server负责计算层 2、PD负责调度管理 3、TiKV负责存储数据,未采用要求固态硬盘SSD存储,读写性能一般
GP部署信息:
服务器IP |
服务器域名 |
Master |
Standby |
Segment |
**.**.**.5 |
host5 |
√ |
|
|
**.**.**.6 |
host6 |
|
√ |
√ |
**.**.**.7 |
host7 |
|
|
√ |
备注:**.**.**.6和**.**.**.7每台机器配置Segment实例数为4,2台机器共8个Segment
2. 性能测试
Spark、Presto均采用的是Hive元数据, Greenplum未使用压缩,Oracle、Hive、TiDB和GP性能测试连接工具采用SQuirreL SQL Client,SparkSQL和Presto则采用后台执行,性能分析部分我们分为两部分,第一部分是单大表查询对比测试,第二部分是多大表关联查询对比测试。
单表Sql语句
Sql1-count |
select count(*) from org_patient_info_big1 |
Sql2-where |
select count(*) from org_patient_info_big1 where patient_id='AA000001||0002949972' |
Sql3-min max |
select min(patient_id), max(patient_id) from org_patient_info_big1 where sex_name='男' |
Sql4-group by 根据支付方式分组统计人数 |
select count(distinct patient_id), pay_way_name from INP_MR_PAGE_BIG1 group by pay_way_name |
Sql5-sum |
select sum(nvl(t.total_payments,0)) from inp_mr_page_big1 t where to_char(t.birthday,'yyyy-mm-dd') >= '1988-01-01' and to_char(t.birthday,'yyyy-mm-dd') <= '1988-01-31' Hive语法: select sum(nvl(t.total_payments,0)) from inp_mr_page_big1 t where t.birthday >= '1988-01-01' and t.birthday <= '1988-01-31' SparkSQL 语法:同上Hive Presto语法: select sum(cast((case when t.total_payments is null then '0.0' else t.total_payments end) AS DOUBLE)) from inp_mr_page_big1 t where t.birthday >= timestamp '1988-01-01 00:00:00' and t.birthday <= timestamp '1988-01-31 23:59:59'; GP语法: select sum(to_number(t.total_payments,'9999999999999999999')) from public."INP_MR_PAGE_BIG1" t where to_char(t.birthday,'yyyy-mm-dd') >= '1988-01-01' and to_char(t.birthday,'yyyy-mm-dd') <= '1988-01-31' |
Sql6-group by |
select t.age_year, sum(nvl(t.total_payments,0)) as payments from inp_mr_page_big1 t where to_char(t.birthday,'yyyy-mm-dd') >= '1988-01-01' and to_char(t.birthday,'yyyy-mm-dd') <= '1988-12-31' group by age_year HAVING age_year <= 99 ORDER BY payments, age_year |
Sql7 |
同Sql4上,把INP_MR_PAGE_BIG1替换成INP_MR_PAGE_BIG2,即此表数据量增加一倍 |
Sql8 |
同Sql5上,把INP_MR_PAGE_BIG1替换成INP_MR_PAGE_BIG2,即此表数据量增加一倍 |
Sql9 |
同Sql6上,把INP_MR_PAGE_BIG1替换成INP_MR_PAGE_BIG2,即此表数据量增加一倍 |
单表查询对比测试(单位时间为秒s)
Sql语句 |
Oracle |
Hive(orc) |
SparkSQL |
Presto |
TiDB |
GP |
Sql1 |
4 |
5 |
3.6 |
1 |
— | 3.3 |
Sql2 |
4.9 |
5.2 |
4 |
1 |
— | 3.2 |
Sql3 |
9 |
10.9 |
12.5 |
5 |
— | 11.5 |
Sql4 |
195 |
13.1 |
14.5 |
1 |
— |
3.7 |
Sql5 |
201 |
21.7 |
32.8 |
1 |
— |
8.1 |
Sql6 |
171 |
22.2 |
33.5 |
3 |
— |
8.0 |
Sql7 |
228 |
13.7 |
16.5 |
2 |
— |
7.8 |
Sql8 |
242 |
32 |
53 |
1 |
— |
15.5 |
Sql9 |
245 |
33 |
67 |
2 |
— |
15.2 |
—表示未执行
单表测试结论:
注:一个有趣的结论是新版本hive 3.1.0,在数据量稍大时竟然比spark要快
多表关联Sql语句
Sql1 |
select count(*) from ORG_PATIENT_INFO_BIG pat left join INP_MR_PAGE_BIG1 page on pat.patient_id = page.patient_id |
Sql2 |
同Sq1上,把INP_MR_PAGE_BIG1替换成INP_MR_PAGE_BIG2,即此表数据量增加一倍 |
Sql3 统计各科室就诊人数并排名 |
select dishospital_dept_name,count(1) as zrs from ( select page.dishospital_dept_name from ORG_PATIENT_INFO_BIG1 pat left join INP_MR_PAGE_BIG page on (pat.patient_id = page.patient_id) group by page.dishospital_dept_name,pat.patient_id ) a group by dishospital_dept_name order by zrs desc |
Sql4 |
同Sql2上,把INP_MR_PAGE_BIG1替换成INP_MR_PAGE_BIG2,即此表数据量增加一倍 |
因之前在现场测试,通过TiDB测试大表join出现超时或者报其他异常,复杂的SQL或者OLAP型官方建议是TiSpark,医疗业务SQL复杂故暂不采用TiDB进行对比,另一方面也是TiDB未采用固态硬盘SSD插入数据效率不高入库耗时过长。
多表关联查询对比测试(单位时间为秒s)
Sql语句 |
Oracle |
Hive(orc) |
SparkSQL |
TiDB |
Presto |
GP |
Sql1 |
4,998 |
159 |
— |
— |
65 |
1,306 |
Sql2 |
12,368 |
285 |
— |
— |
133 |
3,023 |
Sql3 |
14,474 |
5,397 |
— |
— |
592 |
2,561 |
Sql4 |
22,441 |
9,807 |
— |
— |
1,081 |
5,390 |
—表示未执行
多表关联测试结论:
在实际测试中,不同的存储格式对presto性能影响较大,测试中orc格式比text文本格式读取性能要快不少,且减少了presto数据量读取(压缩比基本能达到90%以上),执行某些相同SQL语句耗时会快好几倍甚至一个数量级。
|
表名 |
oracle原始数据 |
Hive orc格式(占用空间M) |
压缩率%(压缩后:压缩前) |
患者数据 |
ORG_PATIENT_INFO_BIG |
10,048M |
8.1 M |
0.08 |
就诊记录1 |
INP_MR_PAGE_BIG1 |
24,230M |
133.2 M |
0.55 |
就诊记录2 |
INP_MR_PAGE_BIG2 |
48,460M |
266.5 M |
0.55 |
医疗现场,数据汇聚到Hive默认text文本格式而非orc格式,因存在网络带宽瓶颈,过大文件内部传输耗时过多,导致Presto性能不佳,建议换成orc格式。
个人最终结论:选型Presto(同时结合Alluxio分布式缓存系统),采用orc格式存储