2000w的數據在網上搞得沸沸揚揚,作為技術宅的我們也來湊湊熱鬧.
據了解網上有兩個版一個是數據庫文件另一個是CSV文件的,前者大小有好幾個G后者才幾百M.對於不是土豪的我們當然下載幾百M的.至於在哪下載,請各位發揮吊絲精神GOOGLE一下吧,我們這里只探討技術,呵呵.
下載后解壓的文件如下:
數據被拆分為11個CSV文件,這樣我們可以寫一個簡單的程序對這些文件進行簡單的搜索,如搜索姓名,手機號或身份證等.一般我們會采用多線程進行處理,最簡單就是每個線程處理一個文件,這個相信大家都會...所以我們這里不討論多線程,而是多進程.說到多進程處理相對於多線程有什么好處?以下是本人的一些劣見,有什么不妥請指正:
- 多進程占有獨立的內存空間,不用擔心數據同步問題
- 多進程處理時,當一個進程崩掉時不影響別的進程運行
- 多進程處理能更好的利用系統資源,特別在多核的機子上時
- 大家補充...
現在我們將采用多進程對有2000w記錄的文本文件進行簡單的搜索,為什么說是簡單搜索,因為我們不追求搜索效率,只要達到搜索目的,並不那么慢就OK了.不知大家對一次關鍵字搜索5分鍾左右能不能接受?不過不接受也沒辦法,我們這里不研究算法,只介紹多進程處理.
JVMPart是一個開源的Java多進程處理工具,中文應該叫JVM分拆/割吧,不過我覺得叫"雙P"更合適,因為里面要實現關鍵的兩個接口——Partitioner和Processor.更多請了解:https://code.google.com/p/jvmpart/
JVMPart使用非常簡單,只要實現Partitioner和Processor兩個接口.Partitioner的作用就是決定數據怎么分拆,並把分拆出來的參數傳給Processor,Processor就是利用Partitioner傳過來的參數進行具體的處理.就我們要實現的這個搜索,Partitiner就是讀取CSV目錄里的文件並把文件路徑和關鍵字傳給Processor,Processor就根據文件路徑讀取文件並利用關鍵字搜索該文件找到了就顯示出來.下面是"雙P"的代碼實現:
Partitioner:
public class Hotel2000WPartitioner extends SimplePartitioner { private String keyword = null; private String dir = null; private String[] filenames = null; public Hotel2000WPartitioner(String dir, String keywords) { this.dir = dir; this.filenames = findFilenames(new File(dir)); this.keyword = keywords; } private static String[] findFilenames(File dir) { String[] filenames = dir.list(new FilenameFilter() { public boolean accept(File dir, String filename) { return filename.toUpperCase().endsWith("CSV"); } }); return filenames; } /** * 決定分為幾個進程處理 */ @Override public int getTotalProcessor() { return filenames.length; } /** * 把參數傳給Processor */ @Override public Map<String, Object> processorParams(int index) { Map<String, Object> params = new HashMap<String, Object>(); params.put("filename", dir+File.separator+filenames[index]); params.put("keyword", keyword); return params; } }
Processor:
public class Hotel2000WProcessor extends AbsProcessor { /** * 讀取文件並利用關鍵字搜索該文件 */ @Override public void doExecute() throws JvmProcessException { String keyword = getParams().get("keyword"); String filename = getParams().get("filename"); File f = new File(filename); BufferedReader dr = null; try { dr = new BufferedReader(new InputStreamReader( new FileInputStream(f), "UTF-8")); while (dr.readLine() != null) { String line = dr.readLine(); if(line!=null&&line.indexOf(keyword)!=-1) { System.out.println(line); } } } catch (IOException e) { e.printStackTrace(); } finally { if(dr!=null) try { dr.close(); } catch (IOException e) { } } } }
使用JVMPart工具運行:
public static void main(String[] args) throws JvmProcessException { String dir = "D:\\我的文檔\\下載\\2000W"; String keyword = "土豪"; JvmProcessPatitionHandler handler = null; // 同時並發三個進程,當其中一個運行完成都踢出另一個運行 handler = new JvmProcessPatitionHandler(Hotel2000WProcessor.class, 3); Hotel2000WPartitioner partitioner = new Hotel2000WPartitioner(dir, keyword); System.out.println("搜索中,請稍后..."); long time = System.currentTimeMillis(); handler.handle(partitioner); System.out.println("花費時間(分):"+((System.currentTimeMillis()-time)/(1000*60))); }
當程序運行時,我們可以通過任務管理器看到有四個java進程在運行(其中一個為主進程).如圖:
至此, 我們對2000w數據的搜索已完成,多進程處理就這么簡單.運行截圖如下(2000w數據果然厲害,土豪也能找到,哈哈):
下面附件如果你是WIN32的系統不用安裝JRE,直接運行即可. WIN64沒測試,如不能運行請自行安裝64位JRE再運行.
附件使用方式(前提你已下載了CSV版的數據):
1.解壓后,把程序Hotel2000W拷到CSV文件所在目錄(這一步不做也可以,程序將提示輸入CSV目錄)
2.雙擊run.bat
3.按提示輸入搜索關鍵字(姓名,手機或身份證等)
4.等待搜索結果,如果找到將在屏幕中出現
附件:http://pan.baidu.com/s/19qqvU
注:此為本人在博客園的處女作,希望大家多頂幾下,以示鼓勵!