3000万业务数据导入的性能调优始末

4

Posted by Alex | Posted in 其它 | Posted on 19-06-2009

“3000万业务数据导入的性能调优始末” 这项工作开始于本周一,对即将在SAP R/3系统中导入3000w数据进行性能调优,最低目标是可以达到每天200w导入数据量,而事实上,我们舍弃了一小部分功能,从而达到了超过800w/天的导入能力。本文将向您讲述这段性能调优功能的始末。

首先我们简单说一下导入的数据,物料主数据的基础视图是先前已经创建好的,我们所要做的是扩展到所有的工厂下,因此调用BAPI: BAPI_MATERIAL_SAVEDATA,但是由于有一个视图plant stock不能通过BAPI创建,我们使用了BDC方法。

1. 问题的出现

问题出现于上周五,30w物料主数据,将被扩展到约95个工厂下,也就是说将会产生约3000w条工厂级物料数据,那么如何能保证每天200w导入能力的最低目标成为一个难题。

200w/天 ≈ 83333 / 小时 ≈ 1388 / 分钟 ≈ 23 / 秒 合 每条数据只有0.04秒的时间

而事实上,最初我接手时的程序在开发机仅能达到2.6秒/条的速度,那么很显然,2.6与0.04之间相差65倍,接近2个数量级,自然我们首先想到的就是并发,一般来讲,20进程并发,应可提升一个数量级的速度。但是我们仍然相差接近一个数量级。

2. 第一天

第一天我们做了很多无用功,但是这是后来证明的,在一开始,我们都很有信心。首先我们通过简单的观察程序和测试运行发现,有一个包含BDC过程的子程序占用了超过60%的运行时间,根据常理我们也都认可BDC速度远远低于BAPI,即使是简单的操作。因此我们把第一个重点放在了如何解决这段BDC。于是我们把第一天的全部时间都用在了如何将BDC那段功能用BAPI实现。

第一天我们三个人一直搞到晚上10点多,头晕脑胀也没能解决问题,这其间还遇到一些假象,但后来证实行不通,由于本文重点在于讲述性能优化,这段故事就不详细说了。但是结果并不理想,我们也没有达到预期的目标。

对于第一天来说,最漫长的已经过去,但最重要的还没有到来,之所以说第一天做了很多无用功,是因为第二天一大早的一个重大发现。

3. 第二天

在我们基本放弃解决BDC的问题后,我开始仔细的看程序,因为程序不是我写的,我并不是很熟悉。正当一筹莫展之际,我发现了第一个重大发现,在实现BDC功能的子程序中,居然有一条这样的语句:WAIT UP TO 2 SECONDS。这让人无法接受,后来证实,是先前一位经验不足的开发人员为了避免锁定的问题写上的,看到这里,你一定和我们当时想的一样,2.6-2 = 0.6秒,3600 / 0.6 * 24 = 14.4w,也就是说一个进程一天可以跑14.4w数据,20个进程并发就可以达到288w。

在去掉了WAIT UP TO 2 SECONDS后的第二天,我们的重点转向了并发情况下的性能测试,之所以要测试,是因为简单的将14.4 * 20计算是不合理的,因为并发将导致进程之间竞争资源,从而使得单个进程效率下降,但是下降多少,我们并不知道。我们的开发机是一台4C 8核的1.6 GHz的P520,测试数据如下:

  • 1进程*100条数据 47s
  • 4进程*100条数据 65s

从上面的数据可以看到,4进程并发,虽然单位实现效率上升约190%,但是单个进程效率下降近38.3%,这让我们很担心,40个进程并行的时候但个进程性能会下降多少?是否还能达到总效率提升的效果呢?由于开发机只设置了4个后台进程,因此只能测试到4进程并发,我们非常期待在生产机测试。

除了并发可能导致效率下降,还必须考虑由于一次导入的数据量增加,会否使程序的效率恶化,虽然在此时我们还没有预见到程序中有一个致命的问题,但是这种考虑显然帮了我们大忙。我们决定在第二天晚上,跑一个4w条数据的量,看看执行效率如何,该进程在这一天晚上午夜12点启动了,同时也希望能测试一下服务器负载较低时,数据导入的效率能否更好一些。

4. 第三天

一大早我们期望看到结果,然而等待我们的却是远远超出预期,而且还未结束的进程。这让我们不得不担心程序中存在随数据量增长以指数方式恶化的情况。

通过调试程序,我们发现程序中存在一段两重循环外加一个READ TABLE,也就是检索。正是这个两重循环导致这段逻辑成2次方指数恶化,而在此循环内部的READ TABLE命令,也将本已恶化的性能推向了崩溃的边缘。在一个GENERIC TABLE中做READ TABLE操作,平均命中率是一半,相当于半个循环。

虽然循环中基本都是ABAP命令,极少有数据库读取,但是数据量的增大仍然导致了不可接受的后果,让我们来简单计算一下:

  • 100条数据*50个字段 = 500,这个500就是本段循环的基础值,两重循环将使内部的循环次数达到500*500 = 25w
  • 4w条数据*50个字段 = 200w,两重循环将使内部的循环次数达到200w * 200w = 4亿
  • 500条数据的READ TABLE的平均查询次数为250次
  • 200w条数据的READ TABLE的平均查询次数则为100w次

从上面的数据不难看出,4w/100 = 400倍的数据量,而循环次数则提高了1600倍,read table的查询次数也提高了4000倍,仅read table一项的查询次数就比原来增加了640w倍,这就是三次方指数的恶化。

经过进一步的分析,我们认为,原计划4小时左右跑完的进程,即使是跑了9个小时,也还没有完成这一小段逻辑。而在整体运行过程中,这一小段逻辑,还占不到整个程序消耗时间的1/100。早先的测试都是重点在于功能,由于最大测试数据不超过20条,虽然比1条数据扩大了8000倍的运行时间,但由于绝对占比不到1/100,根本没能发现。

好在最后我们将这个问题解决了,将三重循环改为顺序处理,说到这里,很多次处理数据的时候,在效率方面,我都从大学时代的编译原理课程受益匪浅。

在解决了这个问题之后,程序的复杂度终于随数据量增大符合线性增长了,早上9点40解决了问题之后,我们启动了同一个4w数据的进程,结果在不到4个小时的时间顺利运行完,这一次测试,我们得到的数据是0.3s/条的导入速度。

这一天下午,生产机准备好了,我们将全部精力投入在在生产环境的测试上。由于生产系统的配置尚无法支持业务数据的导入,因此我们想到了一个办法,首先对数据库进行压力测试,测试方法为复制一个MARA表,然后对其进行大数据量写入,然后对大并发进行测试。请看下面的测试结果,顺便提一下,生产机应用程序服务器共5台P595做负载均衡2台16C 32核 128G内存,3台8C 16核 64G内存,主频都是2.2GHz ,数据库服务器是一台P595,16C 32核 2.2GHz主频 128G内存:

  • 1w条数据 * 1进程,开发机19s,生产机14s
  • 1w条数据 * 4进程,开发机平均22.5s
  • 1w条数据 * 10进程,生产机平均20s
  • 1w条数据 * 20进程,生产机平均31.45s
  • 10w条数据 * 20进程,生产机平均399s

从上面的测试数据看,生产机比开发机性能好,但是在生产机10进程并发和20进程并发分别下降42.8%和124.6%,10w条数据的写入时间换算后,进一步衰减177.7%,可见并发时的衰减还是很大的,并且也没能达到数量级的提升,这主要的原因是影响单个进程运行速度的主要因素是CPU速度、内存和磁盘速度,而生产机比开发机在单一性能上并没有强多少,因此生产机应该能在提供更大的吞吐量,我们猜测大量的并发可以提高总体效率。由于以上测试使用的程序几乎99%时间消耗在数据库上,因此我们推测,实际业务数据导入的时候,衰减会好一些。数据量加大后,同样是20进程,衰减再进一步扩大,这一点我们没有很好的解释,但依据次数据,我们推测导入业务数据时20进程的衰减应该在三者平均值约114%左右。

这一天,我们再次干到快午夜才离开单位,明天生产系统中会准备好业务数据供我们进行实际测试,希望接下来一天的测试能给我们一些好消息。

5. 第四天

我们将程序改好后传输到生产系统,由于先前我们认为BDC仍然是影响速度的一个关键因素,最终我们通过沟通决定暂时不导入最后一这部分,这让我们的导入提升接近一倍。我们对100条数据、500条数据做了单进程测试,可以达到0.125秒/条的速度。在晚上下班后,我们又做了500条数据*10进程并发的测试,单进程速度衰减100%,比我们预测的要好一些,接下来再做200条*40进程并发测试,单进程速度衰减仍然是100%,这让我们看到了服务器高吞吐的能力,也让心里有了底。

这一天还有BASIS的两位同事帮我们在做测试的时候监控系统后台资源使用状况,我们曾考虑到一些可能影响性能的参数,经过几次调整,虽然没有大幅提升,但是让系统资源得到了充分的利用。我们尝试了关闭Oracle redolog,尝试了Oracle服务器的进程设置等等。

按照0.125/条速度,30进程并发,速度下降100%计算,一天24小时系统可以接受1036w的数据导入,即使是考虑到去掉的BDC功能再跑一次,也可以接收超过500w的数据,目标完成。接下来就是完善程序的功能,包括修改输出日志、增加可调参数等等。在这一切都完毕之后,我们遇到了新的问题,数据。

以第一个导入数据的子项目来说,6w主数据扩展到96个工厂,总共是576w条,如果按照4w/文件计算,需要创建144个文件,可是事实上将来只有一两个人会做这项工作,如何能在一天之内准备144个数据文件、定义后台作业成了难题,因此我们决定扩大单个文件的数据量,提高到19.2万条数据/文件,这样刚好是30个文件,30个进程,每个进程将运行14个小时左右,时间刚刚好,30个进程并发也刚好使我们的预期。

这里我们还在担心一些问题,19.2w数据的excel文件将达到200M,需要消耗内存超过300M,保存一次需要近1分钟,保存的文件约74M,转换有的txt文件约60M,对19.2w的数据进行操作很有可能因为资源不足无法Ctrl+Z,这必然给数据整理工作造成及其大的障碍,对于这一问题,我们暂时不考虑了,从技术的角度讲,系统已经达到1036w数据/天的导入速度,而剩下的则是人的工作了。

5. 第五天

这一天,我的大部分时间用来写这篇文章,像东总说的,这是一次非常有价值的Performance Tuning工作,虽然我们只是对程序做了少量的修改和调整,但这一切都是基于4天没日没夜的测试、评估与计算上,没有这四天一次一次的测试数据,我们也无从知道大数据量、大量并发的情况下系统将如何表现。

总的来说这次性能调优还是收获很大,当然除了本文总结的内容,还有很多值得总结的地方,今天时间太紧张,日后如有可能再补上吧。这很有可能是我此次暂离公司之前做的最后一件事情了,按计划,下周回来,我要去找人力经理办理离职手续了,在临近离开之前,做这样一件事,好像是老天安排我一个收官之作,希望一切顺利,一切安好。

在此,我想感谢在这次工作中一起奋斗ABAP兄弟,Allan Zhu和Jamey Qi,还有BASIS洪老大、小熊,没有你们我做不好这事,也做不了,谢谢!

截止到现在,我已经结束了本周的工作,即将启程去上海,宝贝已经在上海等我了。

ps. 本周只做了这一件事情,所以只写了一篇文章。

今天认识了Google App Engine服务

0

Posted by Alex | Posted in 其它 | Posted on 13-06-2009

Google App Engine

Google App Engine

        其实很早就听说过Google App Engine,但是我发现我一直就是后知后觉的,虽然一直会有各种各样的idea,但是总落后于时代,后来我把这种结果归结于自负,的确,很多时候,我都愿意自己去“创造”,可是我一直忽略了这个时代的进度,也就是说,绝大多数情况下,我一直是落后的,那么所谓的“创造”,最多也是上个时代的东西。

        我写文章,就爱写题外话,总是写跑题的,言归正传,今天要说的是Google App Engine,简称其为GAE。GAE是在2008年上半年上线的,上线的时候只是支持Python语言,现在支持Java了,每个Google Account支持3个应用程序,而现在已经支持10个,原来支持2G流量,现在支持10G了。不过我最大的感觉是Google App Engine简单来说就是一个虚拟主机,只是它支持的脚本语言是Python,跟一般虚拟主机策略不同,GAE只支持自己的BigTable,并不支持最流行的PHP,Mysql等流行开源技术,我的理解是GAE要建立自己的Web应用平台,而且GAE有绝对的自信,即使是不支持那些流行技术,同样可以做的很好。

        Google经常会给人们熟知的服务起一个新的名字,但是慢慢的,我发现,Google总是给它们赋予新的含义。GAE也是这样,既然叫App Engine,就必定不同于以往的虚拟主机,GAE希望能建立一个统一的Web应用平台,而这正是多年前Google曾希望的,将全世界的数据纳入同意平台管理一样。

        GAE现在为每个应用程序提供46.3CPU小时的时间,10G数据流量,1G数据存储,2000个Email发送,超过这个限制的,则要花费0.1美元/G流量,价格还是非常低廉的,和国内8元/2G/月的流量比起来的确很不错。

       GAE因为是支持Python为主,虽然支持Java了,但是对于大多数Web应用,我指的是blog、论坛、CMS等,是以PHP+MySQL为主,GAE的支持者转向python+bigtable仍需一定的理由,但在今天,我也的确发现了不少优秀的Blog程序,相信GAE会获得越来越多的支持。其实我一直关心的是,GAE在Google的战略中是一个怎样的地位。并不是怀疑,而是暂时还未看清。向我文章开头讲的,我一向后知后觉。

      最后,说完一大堆啰嗦的事情,简单说说GAE能做什么:

  • GAE像一般的虚拟主机一样,可以用于托管应用程序,但是目前支持Python和Bigtable数据存储
  • GAE可以让用户绑定自己的域名,以独立域名的方式访问服务
  • 每个GAE账户支持10个应用程序,每个应用程序可以免费占用1G存储空间、10G/日流量、2000Email/日发送,超出部分需要交纳费用
  • GAE可以用来建立Blog、图片共享等一切Web应用,也已经有人做过校内等SNS社区插件,效果不错

      Google App Engine的技术其实并不新鲜,无非是多了一种数据库、一种编程语言的支持,但是其蕴含的战略,的确值得关注。

       我发现我总是喜欢在文章最后再说点别的,GAE虽然不支持PHP,但是Google支持Java,而Java中的Resin或Jetty+quercus则可以完美支持PHP 5.2+,所以,从这个角度讲,在GAE上跑PHP也是没有问题的。

微信息时代的Short URL服务

0

Posted by Alex | Posted in 其它 | Posted on 12-06-2009

        大概是半年前的时候第一次听说Tiny URL,当时没理解,为什么要把网址缩短,反正都是复制粘,何苦呢?今天我恍然大悟了,原来是因为微信息时代催生了对Short URL的需求。

        什么是Short URL?中文称为“缩短网址”,就是将一个很长很长的网址缩短为十几个字符的短网址,比如本文的地址是http://www.alicenalex.com/2009/06/short-url-service-with-tiny-blog/,共67个字符,通过bit.ly可以缩短为:http://bit.ly/yMIeo

        过去的几年里,越来越多的网址超过50个字符,而在SNS与微信息的这个时代,缩短的网址变得越来越重要。看看Twitter的信息长度限制为140个字符,叽歪的信息长度为70字符就能明白为什么了。

        Short URL服务是合适开始出现的呢?要追踪Short URL的历史,我从Google Blog Search中翻阅过去的言论。”Short URL”第一次出现于2006年1月22日一篇博客日志中,当时提供缩短网址服务的那个网站是Orz.net,现在已经无法访问了。2006年1月~6月共有11篇文章与此有关;“缩短网址”的中文关键字,第一次出现在2006年6月30日的一篇日志中,提到的是www.kuso.cc,这是一个繁体中文的网站,现在仍然健在。此后“Short URL”2007、2008以及2009年截止到目前查询的数据则分别为1557、14723、14831,从这个数据中我们可以看出Short URL服务是在2006年初开始出现的,2007年~2008年每年都以接近10倍的速度被人们谈论着。而Short URL服务的网站也从最初的个位数激增到数十家。

        Short URL作为一项服务,事实上我很关心的一个事情就是它将如何盈利。目前大多数Short URL服务还都没有明显的盈利模式,少部分则在用户访问缩短的url时并非直接跳转到目标网址,而是附投放展示广告或一些B2C平台的产品销售广告,这种模式在很多Web2的服务中已经被无数次验证其可行性,而创建Short URL的用户则也可以从中分成。

        我曾不止一次在互联网上探寻简单而又具有巨大需求的功能,缩短网址算是十分符合预期的一个。记得哪位投资人事讲过商业模式简单的恰恰是容易成功的。不过Short URL服务商要想长期、健康的生存下去恐怕并非十分容易,毕竟门槛不高,同质化竞争会逐渐加剧,行业洗牌在所难免。

猫猫的微笑

0

Posted by Alex | Posted in 生活的味道 | Posted on 10-06-2009

猫猫的微笑

昨天下班路上,天空突然出现彩虹,那一定是猫猫的微笑

Life, Career and Interest

0

Posted by Alex | Posted in 生活的味道 | Posted on 09-06-2009

      还是和莫老师聊天。

      从7点一直聊到9点半,我一直觉得莫老师是一个超级好的倾听者,无论你怎样激情澎湃的大谈特谈,甚至有些自负,莫老师始终是一个忠实的倾听者。大部分时间都是我在说,从出国读书说到工作,从生活到职业生涯,再到专业的一些想法,莫老师在调研职业生涯,这让我想到了一个人:软银的老总孙正义,孙正义在二十一岁毕业后回到家乡,他用了一年的时间做了一件事情,模拟自己想成立的事业,分别编制出十年份的预估损益平衡表、资产负债表、资金周转表,还依时序的不同,编出不同型态的公司组织图,作出沙盘推演。莫老师在毕业之前调研职业生涯让我感到十分的敬佩,当年毕业时的我还不知道何谓职业生涯,更谈不上所谓的规划。

      谈到生活、事业与兴趣,我认为这三者狭义的构成了人生的90%。生活,是指家人、父母、亲戚和朋友;事业是指工作,升迁,薪水;兴趣,简单说就是喜欢的事情,业余时间想做的事情。可能很多人会认为,理想的状态是“因兴趣而工作,而工作又是生活的一部分”——这也是宝贝Alice帮忙总结的理想状态,而我确认为,追求理想状态可能反而会令人痛苦,又有可能因为无法达到而感到沮丧。相反,如果能退一步调整自己的心态,“以生活为中心,以事业为支撑,做自己想做的事情”也是不错的状态。

      家人是一直陪伴在我们身边,陪我们走完最后一段人生旅途的亲密伙伴;父母养育我们长大,我们理应用更多的时间去陪陪他们;亲戚朋友是我们生活中尝尝与之分享快乐,又在悲伤时替我们分担痛苦的伙伴;因此,生活是人生的中心。

      事业是人生中一个重要的阶段,从我们大多数人走出校园毕业的那一刻起,事业就占据了每天8小时甚至更多,然而倘若过多的期望工作能与兴趣有多大的重叠,则往往需要一些good luck,事实上,不少人不是因为兴趣在工作。倘若调整心态,在事业上做的更加职业化,化解工作与兴趣的冲突,则会有一个更好的心情,倘若薪水尚可,满足生活的需要,则大可不必追求完美。

      兴趣是很简单的东西,就是想做的事情,倘若给兴趣诸如太多与事业、生活相关的期待,则会显得沉重。倒不如在生活与事业之外,给自己留一点点空间,哪怕是只有自己感兴趣的事情,简简单单的尝试去做,也不会很有压力。

      当然,我并不否认理想的状态,只是作为一个“现实的快乐”者,我并不期望太多,我只是简单的希望我的家人能幸福安康,我的父母能享受天伦之乐,如何?