開源分布式計算引擎 & 開源搜索引擎 Iveely 0.5.0 為大數據而生


Iveely Computing

產生背景

  08年的時候,我開始接觸搜索引擎,當時遇到的第一個難題就是大數據實時並發處理,當時實驗室的機器我們可以隨便用,至少二三十台機器,可以,卻沒有程序可以將這些機器的計算性能整合起來,后來聽說了Hadoop,但是當時的hadoop還很脆弱(記得沒錯是0.2.0),源碼量也很少,用了很久,發現它不適合我們的搜索引擎。
  后來沒辦法,我在程序中將爬蟲和數據處理寫成分布式網絡通信的。但是導致代碼非常臃腫,而且每一個應用程序的運行,都需要寫一套網絡通信和任務分布。09年下半年,中某地區斷網半年,只能訪問該地區本地的網絡,然后想到我們搜索引擎的商業運營的機會來了,當時用了大約10台機器(實驗室超低配置機器,內存512M,單核),可是訪問量大了之后,系統直接崩潰,調試和運營都遇到巨大的挑戰。后來我不斷的重構搜索引擎,發現怎么做都很困難。
  於是,我一直在思考,我們需要一個平台或者叫計算引擎,讓程序員寫的程序,這些程序渾然天成的支持分布式計算,這還不夠,還希望能夠實時返回計算結果,而程序員卻不知道有多少台機器在為運行它的程序
  這就是我構思的分布式計算引擎,而今天,它已經實現,盡管不完美。它是我承諾的Iveely Search Engine 0.5.0 的分布式搜索引擎的基礎,它的名字叫Iveely Computing,一款開源分布式計算引擎,為大數據實時處理而生(Iveely是“I void everything,except love you!”的首字母簡寫)。開源主頁、源碼下載:https://github.com/Fanping/iveely/releases。最初我們命名的開發代號叫:Dream,Dream平台曾經在新華網出現過,早期版本的數據分析。

 基本結構

  整個Iveely Computing的基礎庫是Iveely Framework,Iveely Framework基礎結構如下圖所示:

  主要是在進程,文本處理、日志、網絡、算法和數據結構上,進行了二次封裝,整個底層框架依然是.NET Framework。Iveely Framework與Iveely Computing是兩個project,但是Computing對Framework會有依賴。Iveely Computing基礎結構如下圖所示:

     整個過程涉及6個主要exe文件,每個exe都是Iveely Computing中非常重要的一環。
     Iveely.CloudComputing.Cacher.exe:分布式緩存。用於分布式存放小數據。采用一致性hash算法。
     Iveely.CloudComputing.Merger.exe:全局運算器。在分布式計算中,常常會涉及到全局運算,每一個節點都在計算,那么當遇到全局求和、求平均等等之類的時候,就需要Merger來操作。
     Iveely.CloudComputing.StateCenter.exe:狀態控制中心。用於當前所有worker、Merger的控制運算中心。
     Iveely.CloudComputing.Worker.exe:用戶任務的真正執行者。
     Iveely.CloudComputing.Supervisor.exe:用於監控Worker的執行情況,倘若Worker異常中斷,則自動重啟worker。
     Iveely.CloudComputing.Client.exe:用戶的控制台操作程序,用戶提交程序,查看自己應用程序的運行狀態。

編譯部署

  我在微軟一年多,離開的時候才發現,學到最多的不是程序、不是架構,而是用戶體驗,總結一句話:你的程序,不要消極用戶心情。所以我在部署的時候,依然采用了“一鍵式本地部署”。在開源社區,這是很多開源人需要學習微軟的一點,很多開源程序,搭建編譯部署步驟非常繁瑣,很容易消極使用者心情。
  編譯
  編譯之前,請先在開源主頁上下載0.5.0源碼。無須下載其它任何第三方軟件,你所下載的源碼,將會是Iveely Computing中任何dll的源碼。下載后解壓,直接用Visual Studio 2012以上版本打開整個解決方案(Iveely.sln),打開之后,你平時怎么編譯,現在就怎么編譯。為了更好的在開發中盡可能測試到Iveely Computing,Debug Build和Release Build有一定區別:
  Debug Build:解決方案中,所有代碼均會被編譯,包括測試代碼,編譯后生成的文件在..\ Iveely\Iveely.CloudComputing\Debug。
  Release Build:解決方案中,只有被使用到的代碼會被編譯,編譯后生成的文件在..\Iveely\Iveely.CloudComputing\Release。
  本地部署

  在本地,一鍵式部署,只需要在你編譯生成的文件加下找到“Deploy-Local-Environment.bat”雙擊,整個本地環境將會全部搭建完畢。“Deploy-Local-Environment.bat”文件中的批處理內容如下:

              start "StateCenter" Iveely.CloudComputing.StateCenter.exe
              start "Supervisor" Iveely.CloudComputing.Supervisor.exe
              start "Worker:8001" Iveely.CloudComputing.Worker.exe 8001
              start "Worker:8002" Iveely.CloudComputing.Worker.exe 8002
              start "Merger" Iveely.CloudComputing.Merger.exe
              start "Cacher" Iveely.CloudComputing.Cacher.exe

  其實就是啟動應用程序的命令,Worker的數量可根據自己機器的性能進行調整。當然也有相應的關閉的批處理文件,也是在編程生成的文件夾下“Stop-Local-Environment.bat”,文件中的批處理內容如下:

              @taskkill /fi "WINDOWTITLE eq StateCenter"
              @taskkill /fi "WINDOWTITLE eq Supervisor"
              @taskkill /fi "WINDOWTITLE eq Worker:8001"
              @taskkill /fi "WINDOWTITLE eq Worker:8002"
              @taskkill /fi "WINDOWTITLE eq Merger"
              @taskkill /fi "WINDOWTITLE eq Cacher"

  當在啟動的時候,如果Worker的數量自己有調整,請記得在“Stop-Local-Environment.bat”文件中也做相應調整。

  集群部署
  在實際應用當中,更多的是集群部署整個Iveely Computing。不管如何部署,請把編譯后的文件夾“..\Iveely\Iveely.CloudComputing\Release”拷貝到你的目標機器上。Merger和StateCenter請拷貝到性能較好的機器中去,並首先雙擊運行。Worker根據任務的多少去部署,一般100G的數據,部署在4台內存4G、CPUi5雙核的機器上就很容易處理,每台機器啟動兩個worker。Cache根據項目緩存是否經常用到,如果經常用到,建議多放在幾台之中,如果整個過程你認為你不會用到緩存,至少請部署一台,但是緩存適合非常高效的小數據交換。建議整個過程中,多用緩存,少用Merge。

編寫自己分布式程序

  編寫您的應用程序之前,您必須了解,Iveely Computing有哪些指令Client.exe支持直接Main函數傳遞方式和普通命令行方式,二者效果一致。命令行指令格式如下:

  1) submit[file path][namespace.classname][app name]
  提交應用程序指令。[file path]是指應用程序的腳本路徑;[namespace.classname]是指代碼腳本中,執行的命名空間和類名;[app name]是這個應用程序的名稱。例如:
Submit C:\\Example.cs MyNameSpace.ClassName ExampleApp
  2) split[file path][remote path][split string] [partition keys]
切分本地大數據文件到各個節點指令。[file path]是本地大文件的路徑;[remote path]是結點里面的路徑。例如:
Split C:\\BigData.txt /Data/big.txt
[split string]與[partition keys]屬於可選項,當沒有此參數時,partition按照大小平均分配,如果有這兩個參數,則按照partition key進行分配,有可能數據不均勻。例如:
Split C:\\BigData.txt /Data/big.txt , 2 3
含義是切分本地文件C:\\BigData.txt到遠程服務器結點,命名為/Data/big.txt 切分符號為“,”,按照第二列和第三列進行partition。
  3) download[remote path][file path]
下載各個節點的數據到本地指令。[remote path]是節點中的數據路徑;[file path]是本地存儲的路徑。例如:
Download /Data/big.txt C:\\BigData.txt
  4) delete[remote path]
刪除某個數據指令。刪除操作將會在整個系統的每一個節點中刪除,[remote path]是節點中數據的路徑。例如:
Delete /Data/big.txt
  5) rename[file path][new file Name]
  重命名操作指令。[file path]是在遠程節點中的文件路徑名稱。[new file Name]重新命名的名字。例如:
Rename /Data/big.txt newbig.txt
更改后的實際文件名:/Data/newbig.txt。
  6) list[/folder]
顯示文件目錄指令。[/folder]是指目錄路徑,默認是根目錄。例如:
  7) kill [task name]
  用於停止正在運行的程序。
  8) task
  顯示所有正在運行的程序。
  9) exit
  退出指令。
  現在開始你的編程之旅,方法及其簡單,新建你的C#應用程序,並且添加Iveely.CloudComputing.Client引用如下圖


  Iveely.Framework和NDatabase也是允許添加的,其它非.NET引用添加將會導致錯誤。在你的C#工程中,添加一個類,繼承類Application,並實現該類的方法Run。this.Init(args)方法需要顯示添加。
  在這之下,你可以按照您以前的思維編寫任意的程序了,寫完之后,按照下面的方法提交:


  1. 雙擊Iveely.CloudComputing.Client.exe。
  2. 按照submit命令提交您的程序。

實踐示例

  詞頻統計(Word Count)應該是所有分布式計算中的“Hello World”程序,不管是Hadoop,還是Storm都是采用“Word Count”為大家打開初步認識。Iveely Computing依然采用“Word Count”作為初級入門應用。
  按照常用的邏輯思維,我們會考慮用一個哈希表來存放,如果插入的單詞存在,則+1,如果不存在則放入哈希表,次數為1。在Iveely Computing中也是采用這樣的方法進行計算。

 1 public override void Run(object[] args)
 2         {
 3             //0.先初始化
 4             this.Init(args);
 5 
 6             //1.虛擬數據構建
 7             string[] contents =
 8             {
 9                 "This is Iveely Computing",
10                 "Weclome here",
11                 "Iveely is I void every thing,except love",
12                 "Thanks,Iveely Team."
13             };
14             StringBuilder dataBuilder = new StringBuilder();
15             for (int i = 0; i < 1000; i++)
16             {
17                 Random random = new Random(i);
18                 int index = random.Next(0, 4);
19                 dataBuilder.AppendLine(contents[index]);
20             }
21 
22             string[] words = dataBuilder.ToString().Split(new[] { ' ', ',', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
23             WriteToConsole("local words count:" + words.Length);
24             int globalWordCount = Mathematics.Sum<int>(words.Length);
25             WriteToConsole("global words count:" + globalWordCount);
26 
27             //2.子節點處理數據
28             Hashtable table = new Hashtable();
29             foreach (string word in words)
30             {
31                 if (table.ContainsKey(word))
32                 {
33                     table[word] = int.Parse(table[word].ToString()) + 1;
34                 }
35                 else
36                 {
37                     table.Add(word, 1);
38                 }
39             }
40 
41             //3.歸並所有結點處理結果
42             WriteToConsole("local word frequency count:" + table.Keys.Count);
43             table = Mathematics.CombineTable(table);
44             WriteToConsole("global word frequency count:" + table.Keys.Count);
45 
46             //4.寫入文件
47             StringBuilder builder = new StringBuilder();
48             foreach (DictionaryEntry dictionaryEntry in table)
49             {
50                 builder.AppendLine(dictionaryEntry.Key + " " + dictionaryEntry.Value);
51             }
52             WriteText(builder.ToString(), "WordCount.result", true);
53         }
View Code

  這就是Iveely Computing中實際用到的代碼,唯一不同的地方在於最后一行代碼Mathematics.CombineTable(table),其實也就是開發需要清楚的知道,某些代碼是本地運行代碼,某些代碼是全局運行代碼。如果不執行Mathematic.CombineTable(table),則table將是本地運行的結果,而非全局運行的結果,結果理所當然是錯誤的。在此,再次說明,如果本地代碼運行完畢,需要生成全局數據,則需要調用Mathematic里面的方法,生成全局數據,調用完后的數據如果需要寫到文件,則記得global=true。反之,global=false。示例源碼請參見源碼包中的Example_WordCount.cs文件。演示視頻下載[8M]

Iveely Search Engine 0.5.0

      如果您覺得WordCount的示例,不足以為您證明Iveely Computing強大的能力,那么下面一個希望您能夠喜歡-遲來的Iveely Search Engine 0.5.0。Iveely SE沉寂了大半年,很多社區朋友,問我是否停止了Iveely SE前進的步伐,我說沒有,沉寂是為了更大一步的跨越。在0.4.0的時候,我說IveelySE的0.5.0版本要實現分布式。今天它結合Iveely Computing一起誕生了。源碼在這里下載。
IveelySE 0.5.0的代碼量不足800行,也許你覺得吃驚,但這正是Iveely Computing的魅力。先看下運行截圖。

 

     Iveely SE 0.5.0在0.4.0上的至少有下列三大突破:
     1. 強大的分布式計算引擎的支持,即Iveely Computing的支持。將0.4.0的獨立應用程序變成了分布式應用。將Iveely Computing中的分布式緩存、存儲、計算引入,使得0.5.0的計算性能獲得超越。基於Iveely Computing也使得容災處理變得自動化,而無須人工干涉。
     2. 插件式功能擴展,模塊更加獨立。在0.4.0中,若為搜索引擎添加了新的功能,則需要停止0.4.0然后重新啟動。在0.5.0中,添加的新功能將不會影響以前的功能正常運行,只需將新的功能寫成基於Iveely Computing的應用程序,隨時監控該功能的運行情況,也可隨時中止。
     3. 支持問題式搜索、關聯性搜索。問題式搜索是指,例如搜索“金正恩的姑父是誰?”的時候,答案直接能夠給出“張成澤”,下列截圖中的第一條記錄及時問題式搜索結構[更多這樣的示例,參見我的微博]。關聯性搜索,是指給出一個事或物,能夠直接給出與它相關聯的事物。下圖中的右邊關系圖即是。

      Iveely SE 0.5.0是基於Iveely Computing上運行起來的,因此在Iveely Computing環境搭建完畢之后,需要通過Iveely.CloudComputing.Client.exe提交搜索程序:submit Backstage.cs Iveely.SearchEngine.Backstage Searcher。如下圖所示:

        然后通過task指令,查看運行狀態,可以看到當前有兩個結點正在運行,這就表示搜索引擎已經在兩個結點運行起來。搜索頁面需要自己定制,在Iveely.SearchEngine中有一個Library類,可以直接調用。若您采用其它編程語言,可以調用Query.asmx這個Web Service。這樣很簡單的就把搜索引擎搭建好了。搜索效果如前面兩圖所示。

捐助我們

     也許您會很奇怪,為何需要捐助,我們需要服務器。數據量越來越大,我們自身的服務器已經不能繼續支撐我們的服務器,我們渴望將Iveely.com運行起來,可是硬件限制了我們。因此,我們懇請若您想在硬件上捐助我們,可以捐助服務器[這里捐助]或者支付寶資助[這里資助],我們將心存感激。我們正如wiki一樣,讓每個人平等自由的獲得知識,我們將繼續致力於開源事業,倘若達到一定條件,我們將會讓Iveely.com正式運行起來。

結    語

  世界變化很快,在我們這個浮躁的世界,我們希望自己能堅持理想,總有一天,我們都會逝去,不管是在過去,還是當前,甚至未來,我們需要的不僅僅的是生活的物質基礎,我們還需要生活的快樂,而最快樂的,莫過於為理想而奮斗。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM