粗談最近工作,做一件關於數據匹配的雜活
最近接到上級指令,需要做一個數據匹配的工作。需求的產生是因為客戶有大批量的采購需求,數據有十幾二十多萬條(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--
粗談最近工作,做一件關於數據匹配的雜活