最近接到上级指令,需要做一个数据匹配的工作。需求的产生是因为客户有大批量的采购需求,数据有十几二十多万条(Excel表格),这表格记录的是采购方去年的采购记录。今年客户还需要根据这个采购数据上的数据去采购,我们公司提供的是一个采货与供货之间交易的平台,俗称B2B。老板希望能让采购方(我们的衣食父母)的采购操作便捷一点,毕竟十几万条数据,让客户一条条去筛选的确是很费劲的,所以让我一个做C#开发的码农研究一个工具,能通过分析采购方的采购数据,去遍历查询我们自有供货商电商数据,筛选出能各方面满足客户购物需求的数据。
首先,我对这种需求是懵逼的,以前的职业生涯种很少接触这方面的工作的,做的最多的就是通过各种框架实现各种业务的增删改查,然后稍微高级一点的就是抵御变态的高并发和丧心病狂的DDOS的打击等等,但是我发现这些经验在这种需求面前毫无用处。其次就是这个需求的变态之处, 如果我用关系数据库的方案,inner,left,right这种链接查询,通过某个条件来做等于查询,这个效率高速度快,但是好像上级对这个结果不满意,因为采购数据有的数据是“维达卫生纸”,但是电商数据是“卫生纸维达”,这两样物品实际上是一个东西,如果单纯的用联查出来的结果的的确确不是用户想要的数据,这样也会为公司损失很多本来应该有但是没查询出来的数据。
这下子我就有点傻眼了,自己一直赖以生存的.NET开发面对这个需求怎么会毫无用处了?
page1,我第一个想到的先是用mongodb和c#来实现这个需求,首先我把数据库里面的电商数据导出来批量添加到mongodb的服务器里面(A),然后把采购方的采购数据批量导入到mongodb服务器里面(B)。通过mongo官方提供C#SDK文档,我通过C#对两种数据进行嵌套循环匹配,数据源是Mongodb,然后我发现,这样做的确是能完成匹配工作的。但是那恐怖的耗时有点长,18万to64万,平均1条数据要循环遍历64万次(5min),那18万条数据得查询多少次?这个时间复杂度我不敢想象,在跑了三小时无果之后我就放弃了!期望找寻另一个解决方案
tip,通过询问很多那些工作了十几二十多年的老鸟,给我的方案有多种,有教我用搜索引擎去思考问题的,有教我用平面数学去思考问题的,有教我换语言去做这件事的。
page2,根据老鸟们的经验, 我首先用搜索引擎的思路去思考这个问题,但是我发现,我根本没有做过搜索引擎方面的开发经验,如果我用分词的思路去思考,那么18万的客户数据可能会变成36万,62万,N万,这样查询效率会变得更加低下。主要是因为我没有搜索引擎的经验,不知道怎么善用它。
page3,当我放弃了用搜索引擎的思路去思考这个需求,我又开始陷入了懵逼中,如何才能实现这中需求呢?好在我了解到了python,一个强大的语言。了解到了python的一个pandas插件,一个强大的插件,该工具是为了解决数据分析任务而创建的,pandas提供了大量能使我们快速便捷地处理数据的函数和方法,提供了高效地操作大型数据集所需的工具。于是我用pandas来导入采购方数据和电商数据进行匹配,但是我发现,依旧无法解决这个效率问题,他还是需要执行非常长的时间来出结果数据,中间程序还不能出现崩溃,崩溃了又得重新跑。
于是我开始了解python语言,了解这个语言的开发,了解它的线程(python真的很简单),python在处理I/O密集性这一块真的比C#强了不止一点半点,一条语句就能实现C#N多条语句无法完成的事情。然后我通过线程来解决效率问题,了解后发现,python根本没有线程一说(对window平台而言),因为python语言自带一种叫做‘GIL’全局锁的东西,这个全局锁的意思是解释器被一个全局解释器锁保护着,它确保任何时候都只有一个Python线程执行。也就是我用了多线程,它实际上内部还是单线程再跑,只是A线程跑完B线程跑,B线程跑完C线程跑,C线程跑完A线程跑。这和单线程毫无差别,甚至在内部线程切换的那一瞬间,还降低的程序执行的效率。
page4,于是我又开始陷入了懵逼状态,然后通过强大的google了解到,原来python如果不支持多线程,他还是支持多进程的,这个多进程对于python的意义上,理解就和多线程一样,这下子我算是终于找到了解决方案,我新建了一个配置表,存放需要比对的两个文件名,比对的字段,字段之间的匹配度,以及需要开启几个进程等等的配置。当我写完以后,根据我电脑的配置,跑了一下,把原本要跑102min的程序缩减到了10min出数据,我的内心激动万分。终于看到了胜利的曙光
虽然基本的解决了效率的问题,但是各位看官难免发现,这个程序还是需要10min的时间才执行完,所以我还是在不停的找方案,期望能从10min的时间降低到1分钟,10s,1s,乃至最低,技术的探索应该无穷无尽。。
尾声,在研究这些技术的同时,我对两个文件表也进行了条件拆分,按照客户采购商品的分类来对18万条数据进行拆分,拆分成了30多个不同分类的表格,每个表大概有几千条数据,然后对自有电商数据进行了表拆分,同样也拆成了30,40个不同分类的表,这样能有效的把数据源降低,通过人为的进行某个分类对于某个分类的匹配,通过借用公司同事的电脑,在他们下班之后,把程序运行到他们的电脑上(20多台机器同步运行),通过多进程来匹配数据,然后结果推送到局域网中的我的电脑上,实现效率最大化。
一个老鸟笑称,人工分布式。
后记,然后我还做了一个工具,提供给采购方的,通过采购数据,匹配上面做的工作产生的结果数据,进行标记,然后导出真正想购买,能购买到的数据,然后提供给客户方的开发人员,我方提供接口进行批量采购的工作。
(以上文字相当于本人两周工作的总结,因为缺乏相关经验,所以只能做到这里,期望有这方面经验的大牛们看到了能给我评论和批评,教小弟怎么能更加从容的快速的去解决这个需求)
--END--
原文地址:https://www.cnblogs.com/mondeo/p/10063219.html