我一直怀疑SAP宣称的主存数据库HANA能够实现OLTP。因为内存是会“挥发”的,一旦断电,便什么都没了。这也许对OLAP来说没什么,毕竟数据可以重新从源系统中抽取,而且OLAP的业务紧迫性似乎也从来没有来得比OLTP重要。所以我也一直相信内存计算只会充单BI 加速器的功能,因此也就对之“意兴阑珊”了——一个做报表的的系统又能挑起什么样的惊涛骇浪呢?
有段时间我把更多的注意力放在C-STORE上,一种基于网格(多节点,异地部署)的列式数据库方案。在处理扩展性和可用性方面,它通过Projection Overlapping(射影重叠冗余)技术实现K-Saftey(即能容忍K个节点同时挂掉);在处理更新操作方面(列式数据库的难点便是更新),它通过一个巧妙的混合架构合并了一个写优化库(WS)和一个读优化库(RS)。WS通常保持很小的数据量,以便获得更高的更新性能;RS则是专门为查询优化过的数据结构。需要值得注意的是WS 也是列式的,而非行式,这样做的主要目的为了避免写两个不同的查询优化器,同时更加方便的将WS自动的转换城RS(Tuple Mover)。C-STORE是一种应付大数据很好的方案,很明显该方案似乎更适合主存架构,因此后来发展成H-STORE(商用VoltDB)也就顺理成章。所有的这些让我更加坚定主存数据库只有架构在网格上(或者说“云”)才能更好的实现其商业应用价值。
而HANA从一开始让我更相信它会秉承SAP的传统,以INSTALL-BASE的模式交付,然后靠License获得收入。这种on-premises模式相较于on-demand模式让我觉得它老气横秋。就像那种令人讨厌又根深蒂固的老传统那样值得被唾弃。这种主观的偏见也一直蒙蔽了我,让我没有真正花时间去了解它。这次借和SAP合作培训的机会,我深入的了解这个代表SAP未来,也许是整个企业应用行业未来的主存数据库技术——HANA。
我这里不想累述HANA的具体架构,这些信息大家都可以从SAP发布的官方文档上去了解。SAP也在最近正式发布了 HANA的学术报告。了解后会发现跟我上面所述的C-STORE有许多异曲同工之处。我在这里想给大家一个参照,以帮助大家了解主存数据库到底有多快,以及我们以后该如何抉择?
既然要参照,不能只参考SAP给的数据或者SAP BW等应用跑出的结果。HANA被公布成一种崭新的数据库,那么就让我们用数据库的公开基准测试标准TPC-H来测试它,并将结果与传统的行式数据库(ORACLE)进行对比。我这次用到的是TPC-H 2.8的数据结构和22个SQL查询。性能测试主要包含以下4个内容1)数据加载,作为暂时主打数据集市的数据库,数据加载能力是我们关注的重要指标;2)数据压缩,一则经常作为列式数据库的卖点,二则HANA是按内存大小来收费的,可是直接关乎成本的;3)查询性能,内存数据库的主要卖点,是这次基准测试的重头戏;4)增量更新,是数据仓库非常重要的指标,也能从侧面让我们看到HANA的OLTP能力,否则就只能成为Larry所说的“wacko”,而不够“transformative”了。
TPC-H是一个业界公认的数据库性能测试基准,比较公正和中立,它定义了8个标准数据库表:customer, lineitem, nation, orders, partsupp, part, region, supplier,各表之间的关系可见tpc.org官方文档。从tpch.org官网上下载源代码,编译后得到一个数据生成工具(dbgen)和一个查询生成工具(qgen)。TPC-H定义了不同的数据库容量(size),用命令dbgen –s 10就可以生成10GB的数据,其中最大的表Lineitem行数达到59986052行。Qgen可以随机产生相同条件的不同取值的22个SQL查询。
本次测试HANA的运行环境如下:
硬件HP DL980, 内存512G, CPU Xeon X7560 2.27GHZ 32核
操作系统SUSE Linux Enterprise Server 11.1
HANA版本1.00.25.358341
1) 数据加载
用dbgen –s 10命令生成外部的*.tpl文件(CSV格式), 其中lineitem.tpl文件大小为7.3GB。手工创建对应的*.ctl文件,该文件为HANA所特有的导入参数文件,具体格式如下:
INTO TABLE VINCEN.LINEITEM
From lineitem.tbl FIELDS DELIMITED BY ‘|’
ERRO LOG LINEITEM.tbl.txt
将lineitem.tpl和lineitem.ctl文件上传到HANA服务器上(/media/tpc-h/),然后在SAP HANA Studio里面打开一个SQL Editor窗口,输入如下命令:
IMPORT FROM '/media/tpc-h/lineitem.ctl' WITH THREADS 10 BATCH 50000
WITH TABLE LOCK WITHOUT TYPE CHECK;
update VINCENT.LINEITEM MERGE DELTA INDEX;
WITH THREADS 10 BATCH 50000是指以10个线程并行导入,每50000条提交一次。这个是SAP所推荐的基于列式数据库导入的一个组合,我也尝试过其他组合,得到得结果也差不多。需要注意的是HANA最多容许256个并行线程。WITH TABLE LOCK 和WITHOUT TYPE CHECK同样可以起到加快数据加载速度的效果。最后还需要有个MERGE DELTA INDEX的动作,就像C-STORE一样,为了提高更新速度,HANA是先对一个DELTA index进行更新,然后再将之MERGE到主index上。
以同样的方式对其他表进行数据加载操作。
下表是针对lineitem进行加载的时间对比,单位为秒(s)。
HANA |
ORACLE |
616 |
680 |
HANA的时间是import和merge的时间之和。可见在数据加载方面,HANA的性能是不亚于常规ORACLE的。HANA不仅仅是将数据加载到内存中,它还需同时在HDD(硬盘)和SSD(高速闪存)上对数据进行快照存储和日志记录。这方面HANA在保证了数据完整性的同时,也实现了列式数据库更新方面的超越是非常值得肯定的。
在数据加载后设置每个表的主码和创建相关列的索引,用到语句如下:
ALTER TABLE VINCENT.LINEITEM ADD PRIMARY KEY (L_ORDERKEY,L_LINENUMBER);
CREATE INDEX ORDERKEY1 ON VINCENT.LINEITEM (L_ORDERKEY);
CREATE INDEX PARTSUPPKEY1 ON VINCENT.LINEITEM (L_PARTKEY,L_SUPPKEY);
针对表lineitem 59986052条数据集,上述3个语句执行的总时间在300秒左右。
2) 数据压缩
在SAP HANA Studio中选中lineitem表,然后右键->Open Definition->Runtime Information可查看到lineitem的大小。我们将原来CSV格式的外部文件大小除以数据库表的大小的结果作为压缩率,即:压缩率 = CSV文件大小(7.3G)/ 数据表大小。数据表大小又分为不加索引、纯数据的大小以及包含索引的大小。具体结果如下:
项目 |
HANA |
ORACLE |
不加索引大小 |
1.67G |
5.14G |
不加索引压缩率 |
4.37 |
1.42 |
加索引大小 |
3.17G |
9.84G |
加索引后的压缩率 |
2.3 |
0.74 |
由上表可见HANA具有非常出色的数据压缩能力,在不加索引的情况下能将外部的CSV格式的文件压缩4.37倍。可见列式数据库在数据压缩方面的优越性。需要说明的是这次ORACLE的版本是11g R2, 也用到了其最新的行式压缩技术,但跟HANA比起来明显不是一个层次的。
3) 查询性能
用qgen产生22个SQL查询语句并对其做了简单的语法调整,例如调整ADD_MONTHS等时间处理函数,尽量不改变语句原来的结构。将这22个查询复制到SAP HANA Studio的SQL Editor中运行即可获得每个查询语句执行的时间。
测试结果以及和ORACLE对比如下(单位:毫秒ms)
查询 |
HANA |
ORACLE |
提高倍数 |
1 |
4727 |
66240 |
14.01 |
2 |
1320 |
3830 |
2.9 |
3 |
1349 |
28440 |
21.08 |
4 |
1203 |
22180 |
18.44 |
5 |
1623 |
30760 |
18.95 |
6 |
738 |
16500 |
22.36 |
7 |
1104 |
25100 |
22.74 |
8 |
1041 |
20830 |
20.01 |
9 |
12896 |
60020 |
4.65 |
10 |
2213 |
26060 |
11.78 |
11 |
805 |
3700 |
4.6 |
12 |
987 |
22860 |
23.16 |
13 |
2963 |
70980 |
23.96 |
14 |
1950 |
19080 |
9.78 |
15 |
1437 |
17280 |
12.03 |
16 |
927 |
6060 |
6.54 |
17 |
860 |
15400 |
17.91 |
18 |
3177 |
58000 |
18.26 |
19 |
695 |
18930 |
27.24 |
20 |
728 |
20670 |
28.39 |
21 |
16702 |
47880 |
2.87 |
22 |
1294 |
6310 |
4.88 |
总时间 |
60739 |
607110 |
10 |
提高倍速 = ORACLE的执行时间 / HANA的执行时间
可以看到HANA每个查询都比传统的行式数据库快很多,22个查询总体时间也正好是ORACLE的十分之一。对于有些查询,速度提升非常明显,例如第19和20个查询。深入调查发现这2个查询都涉及到对最大表lineitem的查询和聚合计算。可见HANA对越大的表查询提升的性能越明显。例外情况是第21个查询,虽然也涉及到了对lineitem的查询,但该语句包含了3次lineitem的自连接(self-join),进一步深入发现凡是对lineitem有join操作的 SQL查询HANA的性能都表现得相对不尽如人意。可见HANA对join处理还需要进一步提高,SYBASE IQ在这方面有许多值得HANA去借鉴的地方。
4) 增量更新
这次增量更新也是更加偏向于性能,而不是我们通常要求的ACID原则。先通过以下语句删除表lineitem中的6000000行记录:
DELETE FROM VINCENT.LINEITEM WHERE L_ORDERKEY BETWEEN 1 AND 6000000;
删除6000000记录耗时29秒。
用dbgen –s 1重新产生第1到6000000行记录的CSV文件,上传到HANA服务器上(/media/tpc-h1/),用以下导入命令完成对数据的加载:
IMPORT FROM '/media/tpc-h1/lineitem.ctl' WITH THREADS 10 BATCH 50000;
update VINCENT.LINEITEM MERGE DELTA INDEX;
跟初始导入所不同的是,这次导入是不会锁表的,并且有主码重复的检查和索引的同步更新消耗。导入时间40秒,融合时间为124秒。可以看出增量更新的速度(36000行每秒)不如初始导入时候的速度(97000行每秒),不过这个速度也是相当不错的。融合(MERGE)过程耗去了大部分的时间。
总结:
这次拿ORACLE和HANA做对比,没有任何贬低ORACLE的意思。ORACLE是传统RDBMS的翘楚,它代表了在这个领域最好的技术;而HANA是主存数据库的代表,是SAP孤注一掷的筹码。这样的对比能让我们更加清楚的看清未来数据库的发展趋势。也许熟悉ORACLE的人会说最新的版本11g支持并行查询,或许能获得和HANA相差不多的查询性能。但我们更应该看到主存数据库强大的潜力。SAP不大可能一蹴而就,但它似乎正在按照自己的步骤一步一步向前。在一次针对销售的培训上,我向一位德国的顾问提问“为什么不把HANA架构在云上?”,他半开玩笑的说:“啊!SAP应该马上把你招进来。实际上我们正在朝这个方向发展,但现在这种情况只是个开始。”
实际上我已经看到了BW on HANA,这也确实向大家证明:至少现在Netweaver平台是可以完全运行在HANA上的。我也知道 HP的硬件目前可支持16个节点8 TB容量的内存。因此我也有理由相信Hasso真能带领着他的200人近卫军改变当前沉闷的氛围和乏味的游戏规则。Business Suite on HANA 将是R4, Business ByDesign on HANA将是R5, HANA on Cloud就是R6, …… 希望SAP的Realtime能一直坚持下去,能给我们足够的惊喜!