一個垃圾信息過濾系統的進化之道
原創【51CTO 2月15日外電頭條】編者按:每一個網站的維護人員多少都被垃圾信息困擾。本文介紹的這個垃圾信息過濾系統只是眾多可以選擇的方案之一,但是觀察這個系統的架設與成長的過程無疑會對大家有所啟發。本文是HighScalability網站的作者Todd Hoff寫的一篇垃圾信息過濾系統的介紹文章,原文標題為“Mollom架構:以每秒處理100個請求的速度查殺3730萬條垃圾信息”,內容主要圍繞系統的技術設計。當然,根據Todd的說法,100rps并不是Mollom吸引他的地方(這并不是一個高的驚人的數字),Mollom的吸引力在于它的智能學習能力,提供針對“人”的服務。下面為正文:
每個開發人員在絞盡腦汁尋找一家切實可行的SaaS新興公司,而Mollom正是他們夢想創辦的其中一家很酷的SaaS公司。Mollom的盈利方式依賴于一項實用的服務:垃圾信息過濾,而一小批開發人員分散在不同地方。Mollom有助于保護近40000個網站遠離垃圾信息,包括本人的一個網站,我也因此有機會初次了解Mollom。為了竭力阻止垃圾信息出現在我的一個Drupal網站上(不管使用怎樣的驗證碼,結果都無濟于事),我花了約10分鐘安裝好Mollom,它立即開始發揮功效。這正是我所尋求的即可即用的體驗。
自從Mollom打開其數字檢查系統以來,它就拒絕了3730萬條以上的垃圾信息;在這個過程中,它也明白了多達90%的信息是垃圾信息。處理這么多垃圾信息的只有兩臺機器,分布在不同地方,它們每秒可處理100個請求;都運行Java應用服務器和Cassandra系統。所需要的資源極少,因為Mollom建立了一套非常高效的學習系統。這不是很酷嗎?那么,Mollom是如何做到的呢?
為了一探究竟,我采訪了Mollom的創辦人之一Benjamin Schrauwen以及Glassfish和Java Enterprise方面的專家Johan Vos。Mollom的總部位于比利時(比利時還有其他好東西:大偵探波洛、巧克力和華夫餅),這證明了軟件不分國界的道理。
統計數字
◆Mollom服務于40000個活躍網站,其中許多是大客戶,比如索尼音樂公司、華納兄弟、福克斯新聞網和《經濟學家》雜志社。有許多大品牌,有許多大網站,還有許多評論。
◆每天查出50萬條垃圾信息。
◆每秒處理100個應用編程接口(API)調用。
◆垃圾信息檢查方面的延遲很低,用時在30至50毫秒。最慢的連接用時500毫秒。5%以下的延遲是250毫秒。它確實為了提高速度進行了優化。
◆垃圾信息的分類效率高達99.95%。這意味著,在10000條垃圾信息中只有5條沒有被Mollom發現。
◆歐洲的社交網站Netlog在其數據中心實施了自己的Mollom系統。Netlog每天處理約400萬條信息,所用的自定義分類器經受數據方面的訓練。
平臺
◆兩臺生產服務器在兩個不同的數據中心運行,確保故障切換。
◆一臺服務器放在美國東海岸,另一臺放在西海岸。
◆每臺服務器配備英特爾至強四核2.8GHz處理器、16GB內存和4只采用RAID 10配置的300 GB硬盤。
◆SoftLayer—機器由SoftLayer托管。
◆Cassandra—選擇了NoSQL數據庫,原因是寫入性能高,還能夠跨多個數據中心來操作。
◆Glassfish—面向Java EE平臺的開源應用服務器。Mollom選擇Glassfish的理由是,它具有企業就緒功能,比如復制和故障切換。
◆Hudson—提供了跨所有服務器,不斷測試和部署后端系統的功能。
◆Java—Mollom一開始就是用Java編寫而成的。
◆Munin—用于測量和描繪關于服務器運行狀況的度量標準。
◆MySQL—JPA(Java持久性API)用于普通的數據集,Cassandra則用于龐大的數據集。
◆Pingdom—用于監測正常運行時間。
◆Zendesk—用于支持。
◆Drupal—用于使用自定義電子商務模塊的主網站。
◆Unfuddle—分布式開發團隊使用Subversion托管來控制源代碼。
Mollom是什么?
Mollom是一項Web服務,用于將各種類型的垃圾信息從用戶生成的內容中過濾掉,這些內容包括:評論留言、論壇帖子、博客帖子、民意調查、聯系表單、登記表單和密碼請求表單。確定垃圾信息的依據不僅僅有所發的內容,還有發帖者過去的行為和信譽。Mollom的機器學習算法為你充當24 x 7不間斷的數字版主,所以你不必操心。
Mollom是怎么使用的?
比如說,Drupal等應用程序使用模塊(Module)來整合Mollom;模塊可以將自己安裝到內容編輯集成點上,那樣可以在內容寫到數據庫之前,先檢查內容里面有沒有垃圾信息。這個過程就像這樣:
◆用戶將評論提交到網站上后,對后端服務器進行API調用。
◆內容經過分析;如果是垃圾信息,就會告知網站阻止內容;或者如果后端服務器不確信,它會建議網站顯示驗證碼,后端服務器同時會提供驗證碼。
◆驗證碼正確填寫后,內容將得到接受。在大多數情況下,人是看不到驗證碼的,內容將直接作為非垃圾信息的正常信息(ham)而被接受。ham是好的內容,而垃圾信息是不好的內容。
◆只有機器學習算法不是百分之百確信的情況下,才會顯示驗證碼;所以通常來說,不會給人帶來不便。
儀表板
Mollom為每個帳戶包含了相當簡潔的儀表板,可以顯示你有多少非垃圾信息的正常信息已被接受,有多少垃圾信息已被拒絕。你在圖表中看到的垃圾信息數量之多確實很令人沮喪。
操作過程
◆安裝。對于Drupal來說,安裝很容易。可以把它當作其他任何模塊那樣來安裝。先在Mollom網站上設一個帳戶。獲得一對安全密鑰,把這些密鑰配置到該模塊中,然后選擇你想用Mollum來保護系統中的哪些部分。就是這樣。
◆日常操作。我定期檢查,看看垃圾信息有沒有進入。無法做到百分之百有把握,一些垃圾信息還是會進入,但數量很少。要是垃圾信息的確進入,就要有辦法告訴Mollom:這個帖子其實是垃圾信息;應予以刪除。這是你無論如何要做的工作,但這個過程其實在幫助訓練Mollom的機器學習算法,明白什么是垃圾信息。
◆允許匿名用戶交互。借助良好的垃圾信息檢查工具,就有可能做到人們在網站上,能夠以匿名方式進行交互,使用某幾類網站的許多人其實很喜歡這樣。一旦你需要注冊,用戶的參與熱情就會大大減低,注冊無論如何也阻止不了垃圾信息發送者。
不是一切看上去都很美
處理誤報是Mollom最大的弱項。檢測垃圾信息是一項高難度的平衡藝術,需要在拒絕非垃圾信息的正常信息與接受垃圾信息之間掌握好度。Mollom的機器學習算法效果似乎相當好,但存在一個問題,那就是有時好的帖子被拒絕:你提交的內容觸發了垃圾信息過濾器,不會被接受。目前沒有什么好的辦法。分明是好好的評論,卻被誤作垃圾信息而被拒絕,沒有比這更讓人惱火的了。用戶只好嘗試幾次避開這個問題,但結果只好放棄、敗興而歸。
問題是,沒有辦法解決這個問題。為了保護機器學習算法以防被人操縱,Mollom不允許你提供一段示例性的應該被接受、卻誤被拒絕的內容,不過他們正致力于在將來增添這項功能。
這是個艱難的決定。一旦網站遭到了嚴重攻擊,靜態驗證碼系統根本不管用;靜態驗證碼系統是指只要求用戶通過一次測試即可提交內容的系統。用戶注冊不管用。考慮到一個網站每天可能會有成千上萬條電子信息,審查每個帖子會面臨非常重的負擔,對于“業余愛好”網站來說尤為如此。而垃圾信息會完全要了網站的命,所以要在有可能激怒一些用戶與由于網站被垃圾信息擠爆,到頭來沒有一個用戶之間掌握好度。
經營模式
◆讓Mollom成為不二選擇的秘訣就是它免費試用。只有一旦你的網站每天接受的非垃圾信息的正常信息開始超過100條,才需要付費。對于小型網站來說,這種可能根本不會出現。
◆一旦你需要付費,可以選擇Mollom Plus(每天1歐元)和Mollom Premium(每個網站每年3600歐元)這兩個價位,價位似乎很合理。
◆免費網站并不像你想象的那樣很耗費資源,其實它們提供了有助于訓練算法的關鍵數據。所有使用Mollom的網站不斷地將數據反饋給后端的分類器。使用Mollom的人越多,通過從用戶處得到的所有反饋訓練算法的效果就越好。要是沒有免費網站,Mollom的準確性不會像現在這么高。
架構
◆Mollom非常注重技術設計。Mollom過去很重視在代碼和服務器資源使用方面盡可能高效。
◆實際上,每臺服務器都能處理所有請求,但它們都有完整的故障切換機制。工作負載在多臺機器之間分配。如果一臺機器出了故障,那么工作負載會轉移到另一臺機器上。
◆Mollom過去有三臺服務器,但由于大大提升了性能,所以可以將第三臺服務器用作登臺服務器(staging server)。
◆每臺服務器每秒能夠處理整整100個連接,每個連接執行整個流程:全文本分析、計算作者的信譽以及提供驗證碼。
◆真正為低延遲進行了優化。由于垃圾信息檢測是內容提交到網站的整個過程的一部分,要是檢測所花時間很長,用戶會覺得很煩人。
◆Mollom經歷了幾個發展階段:
1、最初,只有兩個人的小團隊業余時間開發算法、分類器以及Mollom要解決的真正的商業問題。為了擴建后端系統上的基礎架構,他們實施了自己開發的線程池、連接池和資源管理機制。他們發現,用于支持這一切、確保可以擴展的時間太多了。隨后他們改用Glassfish這種Java應用服務器,那樣他們基本上不用太擔心內存管理、REST處理、XML解析和數據庫連接池。
2、過去的主要問題是磁盤帶寬。Mollom需要跟蹤互聯網上所有IP地址和所有URL的信譽,所以這是一個隨機訪問頻繁的龐大數據存儲區。
3、在早期日子,Mollom使用廉價的虛擬機,一切都放在無法進行擴展的MySQL中。
4、隨后,Mollom又改用固態磁盤,把一切存儲在文件中。固態磁盤解決了寫入問題,但存在這些問題:
◆價格很昂貴。
◆對于所安裝的文件系統的類型非常敏感。
◆寫入速度快,但是對數據進行迭代處理(經常需要這么做),以便清理數據,或者通過成千上萬個小對象來訓練新的分類器,這個過程的速度還是相當慢。
5、隨后,Mollom由固態磁盤改用Cassandra。
◆Cassandra現用作寫入密集型工作負載的數據庫,并用作一個緩存層:
◆運行在RAID 10磁盤配置上(經條帶化和鏡像處理),非常適合于密集的讀/寫操作。
◆Cassandra針對寫操作進行了優化,Mollom面臨的寫操作比讀操作多得多。
◆被設計成可以在數據中心里面分布,也可以跨數據中心分布。
◆一個缺點是沒有標準的NoSQL接口,因而很難編寫應用程序。
◆Cassandra的行緩存(row caching)讓Mollom不必往系統中添加另一個緩存層,這消除了好多的應用程序代碼。
◆Cassandra擁有老化功能:經過一段時間后,會自動刪除數據。歐洲訂有嚴格的隱私法,要求某些數據在一段時間后必須予以清除。這項功能因而大受歡迎。這是一項成本極其高昂的操作;Cassandra可以處理這項工作,消除了好多的應用程序代碼。
◆博客評論在整個系統中的路徑如下:
◆請求可能來自任何客戶端。客戶端跨服務器對請求進行負載均衡處理。這部分稍后解釋。典型的客戶端是Drupal系統。請求可能是XML-RPC請求或REST請求。
◆請求由GlassFish應用服務器來處理,遵循典型的應用服務器工作流程:請求由服務器小程序來處理,并委托給會話組件(session bean)。
◆付費客戶優先得到服務,免費客戶遇到的延遲可能比較長。
◆請求經過解析和分析;后面詳細介紹這一點。垃圾信息分數確定后,返回給用戶。所以,Mollom有不同的功能部分:垃圾信息檢查和驗證碼處理。驗證碼包括:生成、提供和處理響應。不同的會話組件負責Mollom功能的不同部分。
◆分類器完全在內存中。一小塊內容被拆開來,分成了成千上萬個可識別垃圾信息的小標記(token)。這些分類器在內存中大約有幾百萬個標記。分類器需要高速運行,所以它們必須在內存中。
◆Cassandra里面保存的是信譽分數、頻率、URL和IP地址。Cassandra新的行緩存功能現在充當其緩存層。以前Mollom實施了內部緩存,但現在內存緩存被拿掉了。
◆兩個數據中心中的兩臺機器都運行Cassandra和Glassfish應用服務器。Cassandra在數據中心之間不斷數據。
◆內存中的數據結構并不直接復制。它們寫入到Cassandra,再由Cassandra來復制。另一端的緩存有超時機制,所以它會訪問Cassandra,獲取新的數據。內容最終是一致的。有一小段時間會出現不一致,但是在這么短的時間里,數據模型并未受到負面影響。
◆視具體情況來管理一致性。對于信譽和IP地址來說,最終一致性很好。包括驗證碼會話的會話數據嚴格做到完全一致,那樣機器進行故障切換時,數據會正確遷移過去。
◆客戶端負載均衡
◆Mollom使用的客戶端負載均衡基于延遲等標準來分配負載。作為一家新興公司,Mollom沒有錢來買大型負載均衡工具。他們還有一個目標:能夠在多個數據中心之間進行全局負載均衡,這就需要安裝一套昂貴又復雜的系統。
◆客戶列表通過API來進行管理。每個客戶都有一份服務器列表,列出了可以使用的服務器。
◆每個客戶可以使用不同的服務器。為付費客戶提供了位置更近的服務器,以縮短延遲。
◆當一臺服務器發生故障時,客戶會嘗試連接列表中的下一臺服務器。
◆客戶端負載均衡有助于從舊系統遷移到基于Glassfish的新系統。新用戶獲得了遷移后的機器的地址,老用戶仍在舊機器上工作,只要更新服務器列表,就可以有條不紊地遷移過去。這就允許進行測試,那樣用戶就可以測試功能,然后測試擴展性和性能。他們觀察響應時間、連接隊列中有多少個連接,以及連接在隊列中停留多長時間。他們可以測試:如果增加線程池中的線程、改變JDBC連接的數量以及其他配置,會出現什么樣的情況。一旦每個人都遷移完畢,舊服務器就被關閉。遷移過程中遇到的停機時間極短,這對于高可用性的系統來說很關鍵。系統停運期間,垃圾信息還是在進來。
◆客戶端方法的一個缺點是,要是第三方客戶軟件編得很差,就會有問題。比如說,客戶獲得服務器列表后,可能以相反的順序對列表進行迭代處理,這其實是不對的。現在Mollom與客戶的開發人員緊密合作,提供優質的參考代碼示例,那樣開發人員可以學習最佳實踐。
機器學習
◆Mollom是一套學習系統。一個獨立的驗證碼解決方案既不考慮用戶的行為,也不考慮信息源自何處,是根本無法獲得這種保護級別的,通常需要用戶解答每個帖子的驗證碼。而使用Mollom的文本分析功能,用戶只要在Mollom對帖子不確信時解答驗證碼就行。
◆信息的平均長度是大約500個字符,每一條信息被分解成了3000個特征。信息是不是垃圾信息,只要看看IP地址或Open ID的信譽就能確定。Mollom會查看用戶ID、情感、語言、褻瀆語言、特定的詞語和詞語組合,還會查看文本寫得多合乎文法,等等。這一切都基于分類器。一些分類器本身就具有統計功能,所以能夠自動學習。一些分類器基于規則,可確保根本不會出錯。到頭來,確定垃圾信息分數的是所有這些測試的組合。
◆Mollom從這個過程中不斷學習,分類器和內部度量標準實時更新。
◆Glassfish負責工作調度,旨在可以處理多核工作負載。
◆關鍵是設計出一種框架,以便并行處理盡可能多的工作,確保鎖定窗口盡可能小。
◆并發HTTP連接的數量經過了調整,以便擁有大小合適的可用連接池。
◆每臺服務器使用16個線程。
◆大多數調用由無狀態會話組件來處理,無狀態會話組件很適合并發管理。
◆Mollom把許多會話組件保留在池中,但是讓Glassfish來決定池中應該有多少會話組件。在峰值負載下,池中會有更多的會話組件,以便高效地處理請求。在任何一個既定的時間,32個會話組件可以并行運行。
◆所有分類器實際上是不同線程重復使用的會話組件。
◆每個會話組件都有自己的客戶端連接至Cassandra,所以它們不會彼此阻塞。
◆當用戶沒有響應驗證碼時,該會話被清理,Mollom就明白這可能是垃圾信息。
◆存在每臺服務器一個分類器的情況。
◆會話清理方面存在一個很短的鎖定爭用期間,此時分類器被更新。
◆更新后的分類器每半小時被寫回到Cassandra。
應用程序集成
◆Mollom使用開放的API,可以集成到任何系統中。
◆庫:Java、PHP、Ruby及更多庫。
◆集成的解決方案:Drupal、Joomla、WordPress及其他內容管理系統。
◆第三方基于Mollom創建的示例代碼,生成新的綁定。
◆要監測服務器的運行狀況,Mollom使用Munin來不斷監測:
◆廢料收集后堆的大小有多大?
◆可用連接的數量有多少?
◆線程池中可用線程的數量有多少?確保沒有一個線程在等待很長的時間以至于造成鎖定。
◆如果你看一下Mollom的架構,就會發現Mollom在努力建立一種可以跨多個數據中心透明地運行的架構,以便在單一服務器系統無法滿足發展需要時,能夠向外擴展:
◆客戶端負載均衡用于選擇和故障切換服務器。
◆Glassfish集群將用于應用層的故障切換,并且便于添加和移除機器。
◆Cassandra將用于跨數據中心來管理數據層。
◆Netlog安裝的Mollom具有值得關注的一些特點。它處理的不僅僅是Mollom.com主服務器,但垃圾信息的分布是完全不同的,因為人與人的溝通是社交網絡的一部分。在Netlog上垃圾信息的分布如下:90%是非垃圾信息的正常信息,10%是垃圾信息,而博客界的實際情況恰好與之相反。值得關注的是,處理非垃圾信息的正常信息所用的資源比較少,所以實際上可以在同樣的服務器上處理更多的工作。
◆Netlog最初試過虛擬服務器,還想到了利用亞馬遜的服務,但后來發現,輸入/輸出是使用共享式的虛擬服務器存在的主要瓶頸。輸入/輸出延遲和帶寬是重大問題,于是Netlog決定向上擴展,使用更大型的機器和更大容量的硬盤。
◆令人驚訝的是,它們不受處理器的約束。8個處理器核心中只有兩個負責計算;其余幾個核心完全負責輸入/輸出。
◆Mollom的流量相當穩定,所以使用專用服務器更具成本效益。亞馬遜服務主要是用來處理峰值負載。
發展過程
◆Mollom是分布式團隊。三個人在比利時,另幾個人在得克薩斯州、波士頓和德國。
◆Scrum用作開發方法,Mollom的人員對它覺得非常滿意。下午兩點通過Skype召開Scrum會議。他們發現,隨著自身規模不斷變大,需要更多的開發方法。
◆開發人員在本地開發,然后將代碼提交到Unfuddle。
◆Hudson用作Mollom的持續集成環境。Hudson讓Mollom更容易從舊的Glassfish系統遷移到新的Glassfish系統,因為只有先通過測試,才可以部署。Mollom沒有損失太多的時間,因為在部署到生產環境之前就可以發現問題。
◆Mollom有很多測試:單元測試、系統測試和Drupal測試。只有Hudson通過這些測試,才可以部署系統。
◆部署仍是手動進行,以縮短潛在的停機時間。
◆每當Mollom發現廢料收集時間存在問題,總是歸因于應用程序存在內存泄漏。若出現內存泄漏的情況,Mollom就會分析核心轉儲(core dump)文件。要分析來自16GB機器的核心轉儲文件并不那么容易,你可能無法在本地機器上分析它,所以Mollom采取的做法是,在亞馬遜上租用一個龐大的內存實例來分析轉儲文件。處理堆轉儲文件大約需要2個小時。Mollom比較兩個轉儲文件,一個是執行10小時后的,另一個是執行20個小時后的。要是兩者存在重大區別,那么很可能是由于內存泄漏。
未來方向
◆Mollom API使用XML-RPC,Mollom現正在測試REST實施方法,以便服務更容易與Mollom進行混搭。
◆由于Mollom現已改用Cassandra,那樣發展形勢需要時,更容易向外擴展。
◆即將發布企業級功能,那樣有可能把幾百個網站作為一個整體來管理。這將很容易根據情感、垃圾信息分數來審查一批網站,或者刪除來自某些IP地址的所有評論。
◆Mollom已經談論了如何進入到流數據領域,比如Twitter,但受到了歐洲比較嚴格的隱私政策的限制。
◆Mollom將嘗試使用Glassfish用于每個數據中心的負載均衡。
◆如果負載加大10倍,Mollom將不得不添加更多的Cassandra節點。磁盤輸入/輸出是瓶頸。只有當發展需求增加10倍以上,才需要添加更多的應用服務器。
經驗教訓
◆高效率才會帶來滿意的結果。Mollom非常重視高性能的技術。讓Mollom人員引以為豪的是,Mollom極具成本效益。它可以在一臺服務器上處理好多請求,延遲低,因而讓客戶滿意、高興,因為他們沒必要維護眾多的機器,成本又低。Mollom一開始就把這當作頭等大事,選擇了合適的技術來實現其目標。這讓Mollom能夠將創造的利潤用于投入到市場營銷、建立用戶群以及開發基于Mollom的新產品。
◆廣泛數據免費,深入數據收費。機器學習需要大量的示例數據,那樣才能成功地檢測出垃圾信息。為了獲得這些數據,Mollom為客戶提供了一項免費服務,因為客戶提供了更好地訓練學習算法所需的廣泛數據;客戶在源源不斷地提供寶貴信息和反饋意見。大客戶貢獻了收入,同時得益于從免費客戶處獲得的數據。這種模式似乎特別適合龐大數據和機器學習;正如我們所知,數據和機器學習是一切的未來。
◆消除非特定領域的障礙。龐大系統需要處理基礎架構方面的許多工作。基礎架構工具常常讓人們沒空處理產品中真正創造價值的與特定領域相關的部分(分類器、信譽系統和客戶庫)。Mollom選擇了Cassandra和Glassfish,就是為了盡量減少基礎架構方面的工作。
◆對于客戶端代碼要小心。客戶端代碼很吸引人,因為它可以使用別人的資源,而不是你自己的資源。問題是,代碼可能寫得不好,結果讓你的系統看起來很糟糕。與客戶的開發人員緊密合作,提供優質的參考代碼示例,那樣開發人員就能學習最佳實踐。
◆優先對待付費客戶。付費客戶得到更好的服務質量。他們在隊列中優先得到處理,整個系統中遇到的延遲比較短。付費客戶可以訪問故障切換服務器,而免費客戶只能訪問一臺服務器。
◆讓堆棧來處理繁重任務,以減少代碼。在早期,Mollom代碼庫要比現在大得多。Cassandra可以處理復制和行緩存,因而清除了好多復雜代碼;Glassfish可以處理集群,也因而清除了好多應用程序代碼。代碼庫慢慢簡化下來。
◆盡量減少有鎖爭用。Mollom花了很多時間來盡量減少GlassFish服務器中的有鎖爭用,因為這成了主要瓶頸。盡量減少有鎖爭用,才有可能保持真正的并行處理。
原文:Mollom Architecture - Killing Over 373 Million Spams At 100 Requests Per Second
【編輯推薦】