订阅云计算RSS CSDN首页> 云计算

巨建华:基于MongoDB的大规模高频金融交易数据处理

发表于2011-11-26 12:00| 来源CSDN| 作者CSDN

摘要:巨建华认为高频金融交易数据的主要特点是实时性和大规模,目前沪深两市每天4个小时的交易时间会产生3亿条以上逐笔成交数据,随着时间的积累数据规模非常可观,与一般日志数据不同的是这些数据在金融工程领域有较高的分析价值,金融投资研究机构需要经常对历史和实时数据进行挖掘创新,以创造...

时至今日,“Big data”(大数据)时代的来临已经毋庸置疑,尤其是在电信、金融等行业,几乎已经到了“数据就是业务本身”的地步。这种趋势已经让很多相信数据之力量的企业做出改变。恰逢此时,为了让更多的人了解和使用分析大数据,CSDN独家承办的大数据技术大会于今日在北京中旅大厦召开。本次大会汇集Hadoop、NoSQL、数据分析与挖掘、数据仓库、商业智能以及开源云计算架构等诸多热点话题。包括百度、淘宝、新浪等业界知名专家与参会者齐聚一堂,共同探讨大数据浪潮下的行业应对法则以及大数据时代的抉择。

ymall.com技术总监巨建华

巨建华认为高频金融交易数据的主要特点是实时性和大规模,目前沪深两市每天4个小时的交易时间会产生3亿条以上逐笔成交数据,随着时间的积累数据规模非常可观,与一般日志数据不同的是这些数据在金融工程领域有较高的分析价值,金融投资研究机构需要经常对历史和实时数据进行挖掘创新,以创造和改进数量化交易模型,并将之应用在基于计算机模型的实时证券交易过程中,因此一般的数据库系统无法满足如此大规模和实时性,灵活性的要求。

同时巨建华表示应用复杂性(包括高可用性、高性能,低延迟实时数据呈现、任意历史盘中实时数据挖掘和支持用户自定义脚本实现数据提取与运算)和数据规模(包括财务,金融+历史汇总交易数据、新闻资讯及研报以及每个交易日数据增量等)是数据存储方案面临的挑战。

以下为文字实录

非常荣幸今天能有机会站在这里跟大家分享一下,最近三年以来一直在做的一项工作,就是高频金融交易数据分析和处理。在这之前,跟刘工讲做的工作有点相似,我今天分享过程中不会讲我们如何去分析,如何去形成更好的模型来对数据做,拿着一些有用模型。如何高效对数据进行分析和处理存储,然后来解决大规模数据的挖掘问题。这是我今天主要给大家讲的,在开始之前大家会看到目前我从事主要是电子商务方面的工作,主要因为在前三年,主要是在做证券方面交易处理。可能在座如果是有做像这方面同仁,我们可能会认识。

在开始之前,因为这个行业比较特殊,在我们之前CSDN有CTO俱乐部,我们在做相应活动的时候,实际上我们遇到的同事非常少。也就是说,这个领域如果我要向大家介绍如何使用MongoDB解决这个领域问题的时候,我需要给大家做一些关于这个行业背景的介绍。首先第一个证券,或者金融这个行业数据类型是非常复杂的,而且这个数据对于结构化,有些数据结构化是非常差的,大多数都是一些PDF,甚至是一些文本文档。但是有一部分数据结构还是非常强的,就是交易数据,也就是我们证券成交数据。大家炒股的时候都在用金融终端看我们股票数据变化等等情况,如果如果有一些高起点客户会用技术指标,来进行数据分析。

在做数据分析的时候会接触,我们数据里面有资金持仓项目,有机构评级报告,还有新闻咨询,交易龙虎榜。如果我们平时接触少大家感觉不会很熟悉,所谓基金持仓,我们所有基金公司对市场上的股票持有情况,也就是说,每一个每个咨询公司手上拿着什么样股票进行发布,这样数据连续20多年沉淀下来,数据沉淀非常强。研究报告主要是机构,我们大家都知道很多分析师,每过一段时间就会编制一些研究报告,对每一支股票进行分析,这主要是文本类型的,主要以文本来展现。

另外由于用户习惯不同,我们股票在变化过程当中,不同用户都采用不同周期K线数据来看盘,比如分钟,月,周年进行统计,形成所谓日K线数据,就是统计出来在某一个时间段第一个价格,也就是开盘价,最高价格,以及最低,收盘价,包括成交量,成交额等等。这样的数据之所以会形成这样统计的原因,一个是用户习惯,第二这个差异数据量实在太庞大了,如果我们不提前做统计的话,在形成这样大量交易,我们想在盘中持续拿到这样统计数据,系统都会很吃力,特别是在我们之前数据库系统,以及分布式运算方式没有根本性改变的时候,最佳解决方案当时也就是预先把这些数据统计出来,如果说我们突然想之前,我们假设没有提供33分钟的数据,我们想对历史数据进行回归,这是一个非常庞大,这个时间会非常长。

也就是说,如果我们计算,甚至说这样认为是不可完成的,在我们没有引入更好计算机制和存储机制之前,也是这个行业一直以来面临的问题。关于盘口和成交明细不多说了,都是非常多数据。之前数据实际应用中会不会通过终端展现出来,我们可以看到证券简单截图,我们看到前面各种类型通过相应软件UI来展现,左侧分析图是通过分众线实现,当前买一卖一,包括后面买实卖实等等。这些数据按照目前上交所更新频率,基本上可以保持每3秒钟有一个数据更新,都有新增变更。每天我们大约有20条左右的数据变更,这样变更之前由于没有能力去分析,最终都被通过统计的形式,只是取得一部分,比如我们刚才说的汇总值,大部分数据都丢掉。

实际上这种数据都以整个金融模型分析,包括怎么通过股票数据盈利都是非常有用的,在国外也有大量对冲基金在做这些事情,发现庞大数据发现某种交易规律,最终发现盈利,这是其中一个应用场景。

第二就是我们刚才谈到如何通过这些数据进行自动,机器自动交易。当然机器自动交易优势大家都可以知道,首先第一个分析数据非常快,我们人脑根本不可能对那么多股票数据,A股有140多支股票,如果在美国股市是有1万多支股票,这么大股票交易过程中如果没有相应的机器来代替人脑做一些事情,根本就没有太多精力能抓住那么多交易机会。

另外我们人在做判断的时候,很受形式的影响。如果大家有炒股精力,当你股票涨一点,跌一点,或者涨停,爹跌停的时候大脑不受你操作,机器就可以避免。即使我们机器能够做这样自动交易的事情,也可以想像,如果每天用21条逐笔成交数字,我们一年两年下来之后这个数据量非常庞大,这样一个庞大数据,不是说我们只是通过机器就能搞定,实际上是一个非常大的工程型问题,从数据如何去存储,到这些数据如何建模,计算,到最后形成结果之后如何应用这些数据,那都是非常庞大的工程。

所以说,在这里我们首先需要解决,这么大数据,我怎么能够有能力把他非常好的存储起来,根据我的业务需求能够非常快速的把这个数据拿出来使用,而不是说我要使用这个数据的时候,我需要非常长的时间,甚至我根本就拿不出这个数据出来。

我们知道具体的应用场景之后,接下来我们来看一下目前行业内主要采用的这种数据存储方案,以及他们的一些优缺点。这个应该是在04年以前大多数公司采用的这种,对证券行情数据处理的方式。我们都可以看到,基本上从交易所过来的数据,从交易所网关过来的数据全部通过自定义文件系统写到文件里面去。前端会通过另外一个进程,这个进程为相应客户端提供服务,为了能够保证性能做法,同样数据被写到无数台机器上,重复写到N多台机器上。我们在座有做金融数据公司都很熟悉这个模型,把所有交易数据按照相应的统计方法,统计完之后把统计结果直接写到文件系统里,每天数据会形成一个文件,到收盘之后在归档到最大文件里。

最后我们就只提供,一个我们提供历史的统计结果,把非常大的21条数据整合到可能只有2千条,3千条数据给用户进行显示。第二对于详细数据我们处理方式,原来处理方式,我可能只提供一周数据,你如果想看更详细,对不起看不了,因为我们系统,整个系统不支持这样的操作。在这样一个模型下,他的缺点,我们可以知道,因为数据量非常庞大也比较复杂,就能导致这个程序开发起来非常低效。而且为了追求效率,这样系统都会用C++来开发,这个时候整个开发周期会非常长,开发完成之后,当你面对几十种数据类型文件定义不同结构去操作的时候,你会发现想要产生一点变更,某一天想增加一个新的数据类型,这个代码内容会非常恐怖。

虽然说我没有很好管理方案,我们会做一些好的测试框架,从开发到测试周期也是很长的。实际应用过程中我们会发现不同,实际上有一个职业叫金融工程师,金融工程师他的工作主要是结合计算机和数学这样的专业,包括金融这样专业来提出一些新的模型,对数据进行挖掘。如果我们直接进入这样专职,当然这个在国内目前还不是很多,可能很多研究所都已经不少,假如我们仅仅提供这么一个系统来支撑的,我们想出一个模型进行测试的时候,根本没有办法支持,你在多工程师都没有办法完成程序编写,包括中间还涉及到测试一整套过程。

即使这样一个比较差的架构,实际上现在大多数公司,包括你们用的很多股票软件还是在前面这种方式,因为比较成熟,也比较稳定。第二,这些软件已经很久,不管你看界面,后台逻辑很久不用变化。因为对普通用户来说,可能已经比较足够了,对于高端用户还是很缺的。

第二解决方案,我们现在知道上交所跟国内公司在采用Timesten解决方案,比关系系 型数据库能够快10倍,这是一个Oracle类型数据库解决方案,软件和硬件成本会非常贵,因为他只支持通过Repllcation,没有办法解决横向扩展问题。当我数据量增长的时候,我必须要做两个处理,第一个是我可能内存没有那么大存那么多数据,我只能把过期历史数据还要存到,持久化相应数据库里去,或者其他存储结构力。如果一旦放到关于云数据库之后,问题就来了,每天数十条问题处理起来非常,10年,20年,甚至再过30,50年之后这些数据怎么处理,最终又变成一个看起来我们都有存储,实际上就没有办法可用的数据。在这种情况下,当然我们还要去做很多复杂的开发,我需要去写代码来实现,把Memary相应数据库,相应结构,同时也要去解决一些,因为使用,当然我在提这个的时候,实际上已经有一些解决方案能够把数据库同时写到硬盘上。

我相信Oracle的这项技术,了解的人都非常少,我们很难找到真正熟悉使用这个技术的人。我觉得这个方案也不是特别好,我需要自己写程序来实现,写非常复杂的逻辑就为了程序扩展,我觉得这个也不太好用。

因此,在了解这个之后,我们就知道,实际上目前我们的架构面临的挑战一个是应用的复杂性,也就是说这个复杂到,他首先需要一定高可用。因为当你客户全部在拿着你的终端,或者你的产品炒股,或者在看数据的时候,如果你中间出现中断,性能比较低下情况,很快你就会丢掉所有客户。同时,如果是在一个投资公司里边使用这个产品,出现商用不可用,或者效率低的情况,直接影响到可能就是投资收入。如果一个咨询公司拿着这样一个系统操作,我们都知道他们手上钱是非常多的,随便是小点事故就可能导致大量损失。

第二,由于目前金融工程,我们说的发展,我们会发现不同的金融工程师经常会提出一些需求,对任意历史和数据进行挖掘,这个挖掘需求出来之后,我们都知道不管你用什么,可能你一个读取会把很多硬件资源全部站掉,导致其他服务受影响,如果有大量用户在做挖掘,不管我们系统怎么拆分其实都是很困难的。

另外关于数据规模,刚才也提到,数据规模里面关于财务数据和金融一些历史数据,他们规模不是很大,毕竟中国股市时间还不是太长,现在算起来也就40多个G,新闻咨询与研报是文本数据,怎么来存。但是存在数据库里也有公司这么做,现在实际上真正我们所谓高品质数据,高频交易数据,指的就是目前上交所和信交所所推出来,能够真实把每一笔交易完全发送过来。前我们拿到都是一个每5秒一次的快照,自从06年上交所Level-2推出来之后,我们就能拿到完整交易名类,每天增长容量有1.5-2G之间,这个还在不断增长。

所以,我们面临问题如何能够很好,先不说怎么挖掘这些数据,如何快速存储这些数据,快速提取诗句,为挖掘做准备。在这个过程中我们做了很多方案,甚至我们也考虑自己来编写相应的系统来实现,通过最终考察和我们对整个项目评估之后,我们选择了以MongoDB作为高频数据存储。具体我们为什么会选择的原因?这个项目大家都可以从这个过程中知道,我们最关注的是性能。当我们看到当时是1.4版本的MongoDB漂亮的Benchmark,大概是在09年左右,我们可以发现他的性能非常强大,我们知道不稳定性,丢数据的情况,我们项目构想非常相似,就希望把数据存到内存中,在适当的时候选择硬盘,来保证数据实时性。至于安全性方面,最好在这个过程当中,我们发现我们想法跟MongoDB不谋而合,已经有一个很好产品没有自己去造车轮,我们引进过来,不是说马上使用,而是通过一步步探索甚至是研究,我们认为可以在产品使用的时候才引入。

最早我们注意还是Benchmark,很多人推广的时候不去提其性能,确实已经非常好了。我们在发现,刚才讲到非常符合我们业务需求系统特征,除了这些之外,我们发现其实有很多都是我们在构建这个系统的时候需要考虑的,这是第一个,而且MongoDB已经做的非常好,他支持复制级,能够自动Failover,第二能够支持轻松删除数据结点。意味着,当数据量不够的时候,在一个复制结里面,或者说当我们数据压力比较大的时候,我们就能够快速通过添加新的结点来解决分布读取压力,当然我们在复制级里通过删除结点。第二是自对分片,在MongoDB也可以直接支持动态添加和删除分片,而且能够在添加和删除分片自动进行迁移,这就实现了我们一直都需要的一个数据存在内存里面,但是我们可以通过添加更多结点来实现数据横向扩展特征。

这个分片,MongoDB有自动分片机制,不需要写代码,只需要写相应规则,就可以自动分配,而且过程当中会自动平衡,自动迁移不同的窗口。在数据管理还有一个更好的特性,对单个文档做原子更新,我可能对文档当中某一个属性进行递增,或者可以对文档整个资料进行唯一变更,而不会担心这个文档会被多个线程,多数更新出现不一致情况,一个文档更新的时候一致性可以得到保证。

因为这个数据每天20多亿条逐笔,意味着都是很小数据,每一条数据大概在20-32个字节之间,这种小的数据,如果我们的存储引擎不支持小数据量控制利用率,我们会发现非常浪费空间。也就是说,我们最后会发现一天下来之后,不说内存,硬盘空间都很少用。还有数据扩展之后,考虑快速查询,我们发现在MongoDB里面查询语法是非常丰富,基本上可以跟我们使用有一拼,查询习惯很一致,转过来以后没有很难的转换过程。

大家都用MongoDB,或者其他数据库很多,我们发现他的监控和优化机制比较简单,MongoDB我们除了看到有这些功能之外,还有整体数据库缓存利用率,以及数据在磁盘,内存中命中效率,甚至可以跟踪到具体某一个集合,或者某一个操作上导致问题,这对我们来说可以迅速定位到当数据库产生问题的时候可以马上找到,而不是做很多分析。

当然还有一些理由,他的文档非常完善。我们不需要去买任何书,也不需要去找任何资料,我们只需要在官方网站上就能找到我们所有要的答案,这可能是大多数开源产品做的不是特别好的地方。另外,最好他的客户端API支持我们现在用的开发语言,也就是我们当时主要的开发语言是C++,同时有一大部分工作用其他来做,包括有一些net,js,有一些外部界面通过js展现给用户,最好全部支持,而且官方提供,根本不用担心稳定性问题。另外版本更新速度一直非常快,基本上2,3个月就有一次,这在每一个开源上做的比较小,就因为更新比较快面对一些风险,有时候会带来一些风险,但是这两年已经非常好了。

另外对社区关注度非常高,我们都知道对整个社区非常关注,包括各种AK等等处理非常及时,回复也很全。另外我比较看好,实际上已经获得像红杉比较著名投资机构投资,3千多万美金,我们根本不用担心后续项目会死掉,或者失去保障,让我们用了这个产品之后会面临很大的风险。这是我们在选择他的时候,我们认为比较重要的理由,当然大家在自己实际业务当中也会自己一些想法,这个就需要根据实际情况来定了。

在选择了之后,我们经过一些使用,总结一些经验,作为一些要点跟大家进行分享。因为这是一个分布式数据库,我们在规划的时候,基本上目前还不能够脱离CP,AP,CA的理论。我们到底要采用那种模式,我们数据采用什么方式来分布,而在我们MongoDB里面有三种方式可以通过配置。我打开replicaSet开启SlaveOk查询,设置写入节点书等于replicaSet数据节点数,我们保持一致性。如果采用AP,可用性和分区容错之间,只需要把W等于1,每次写入数据至少只需要写入一个节点,并且把查询slaveOk打开,可以保证系统在任何时候都是可用的,而且我们是能够达到。当他实现原则,当我们指数写入为1,某一个节点失败,我们可以通过slave功能,把第二个节点进行提供服务。在这种情况下,只要我们重节点足够多,我们服务是一直可用的。而且我们数据由于使用了replicaSet,数据有多份,达到了容错标准。

第三是关于CA要求一致性和可用性的时候是一样的,只是我们在查询的时候使用了slaveOk,在重节点上不做查询,所有查询都在主节点上完成。这就意味着我们一旦要求一致性,最终导致一致性和可用性的时候,我们性能就会下降。到底采用哪种模式,我们做系统的时候需要考虑好。当然我们可以看到在这里面AP和CA这两种方式我们是可以通过在程序中动态切换,我一套系统只需要一个配置就能实现AP和CA两模式,甚至两种模式变形,这是我有的时候需要可用性,一致性,有的时候需要可用性和容错。这一点对我们来说非常有帮助,当我想保持一些重要数据的时候就通过CA的方式保存,在代码里面写下来就可以。

第二个是关于系统容量规划部分,在系统容量规划,我们MongoDB有一个非常重要,索引要求全部都加入到内存里,如果不能放到内存中,我们发现也很多警告信息,甚至性能会急剧下降。第二是热数据最好能全部装载内存,在MongoDB所有数据管理,如果说我们数据没有有效,或者不是把数据放在内存,会导致不停的切换内存和硬盘的页面,这时候就会导致,基本上系统就没法正常工作。所以说,我们在做基于MongoDB系统优化的时候,一定要考虑到哪些数据经常使用,类似于容量一定要能够覆盖到内存数据,使整个性能得到一定保证。

还有很关键一定不能在性能和容量都达到瓶颈的时候去考虑增加资源,你再去增加资源,在MongoDB里面已经不行了,除非你停机不提供服务。因为他就已经自动的分片机制,后台在不停做相应数据,我们可以称之为移动或者平衡,如果一旦市场压力很大,没有足够空间提供使用,他就在数据移动和平衡过程中,分布过程中就会失败,没有办法让系统停止服务,这是我们在最初过程中,包括其他人也整理出来的一些经验。

在我们刚开始之前,没有之间把MongoDB拿到生产环境中去。我们最开始只是拿它来做广告点击的数据存储和统计,最后我们拿它来做Web Server Session数据,在这个过程中都非常稳定,效率非常高,逐步我们对MongoDB比较有信心,在这个过程中我们积累一些使用和运维经验。最后就开始逐步利用到金融数据处理上去,我们可以看到,我们最开始的时候是有4台服务器直接建立4个分片,在这过程中没有使用任何冗余。我们追求把最近一个月数据高效放进去,能够提供给数据挖掘的使用。当我们在使用接近一年左右时间时候,我们就切换到9个分片,27台服务器组成,把我们之前采用文件系统加入完全抛弃了,在这样一种情况下我们提供交易性能已经非常高了,我们发现从我们两次扩容达到27台之后,我们对整个数据未来增长完全就放心了。

对于一点,我们在说一下关于一些使用经验。这是我们搭建的架构,这个架构其实跟MongoDB官网推荐架构非常类似,我们有三台来提供信息存储,以及分片信息存储,我们可以看到里面有复制集,里面有9个,列了3个出来,每个集上有3台服务器存储,3台服务器都是数据节点,直接在3台服务器上跑数据。将来扩展只需要不停添加,复制集就行,基本上我们存储就不会有任何问题,当然这也是相对的,毕竟我们现在还没有跑到目前MongoDB官方所提供文档里的极限,当然测试的时候因为建立测试数据的时间比较长,我们现在还没有做很好环境测试,在目前环境下跑的比较流畅。

还有关于每个应用集上对一些历史数据进行缓存,这也是为了减少MongoDB本身数据压力。可以看到在每一个应用服务器深都有Mongo进程,直接放在服务器上。整个这套系统是没有任何单故障,不管是进程,还是数据节点等,我们随时都可以换到N多个节点不影响整个系统服务。同时,这些节点并不是仅仅作为备份存在,当我们获得高性能的时候所有人都会获得服务,根本上没有资源浪费。而这个东西搭起来非常容易,我觉得MongoDB相对来说最容易入手使用的数据库。

另外一个很关键,其实这也是我们做了很多次的测试之后得出来的结论。在分片键设选择上,证券代码和日期,保证均匀分布在多个分片上,在读取的时候进行访问操作。这里面原因,我们很多原因规则都是获得此证券代码在某一段时间,某种业务数据,和某一种数据都通过这样的方式分布之后,我们发现最好日期每一个分间200块大小,保证一个股票在这个块上存储,不会说超的特别离谱。所以,导致我们这个系统查询的效率非常高,很少有跨越多个片区查阅的情况。

另外,关于第二个应用模式,我们在这样一个下面怎么实现数据挖掘,可能跟二元不同,我们这里做了一个框架。我们的框架里面把相应每一个任务定义出来相应接口,当我们要做一个新的数据挖掘的时候,我们只需要实现相应的口有框架完成插件分发和运行,嘴尖向Master反馈结果。之所以要这样写,是因为现在金融工程数据分析,挖掘过程非常复杂,代码基本上很难实现,至少我认为这种模型在做数据挖掘的时候比较困难。比如说,一些聚类的算法,里面带着一些比较神奇的想法,我们很难通过这种艰难过程实现。

第二个我们会发现有时候,有些合作伙伴他们需要能够把自己写的代码,自己想出来的模型放到我们的数据库上跑,我们只需要把这一套接口规范提供给他们,把相应插件拿出来得到结果,而且这些结果有些是实时数据结果。当然了,刚才我在听到淘宝讲的时候提到里面有一个很好Redis应用,通过信息队列来实现数据分发,我们已经在使用这样的东西,也是在MongoDB里面。刚才我们看到股票软件有非常多数据需要每几秒更新一次,在没有使用之前我们进行定义,包括我们写相应服务端程序,这个服务端程序要考虑很大并发流量等等,需要写很多代码,在写这个的时候代码本身就写好了,不用定很多协议,至少定应用服务器和网端之间,不同类型数据没有任何要求,只要接上就可以,马上拿着相应数据展示给客户端,这个过程可以减少非常多开发量。

举个例子,如果我们想开发一个聊天室程序,一对多,或者多对多聊天,几分钟时间就可以开发一个聊天室出来,能够承受很大流量。这是我们关于使用MongoDB经验的一些集合,希望能够对大家有所帮助。最后运维监控,不是我核心要讲的问题,大家能够看很多文档,这是我平时常用的四种监控工具。MSS可以直接在手机上看,可以知道整个MongoDB运行状态,谢谢大家。

0
0
巨建华:基于MongoDB的大规模高频金融交易数据处理