放翁(文初)的一畝三分地

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            210 隨筆 :: 1 文章 :: 320 評論 :: 0 Trackbacks

              在大型網(wǎng)站中常常會遇到大流量的數(shù)據(jù)輸出問題,過于頻繁的輸出到DB、文件、第三方系統(tǒng)都會帶來不穩(wěn)定性和低效率。因此需要采用一定的方式來解決這個問題,其實這部分內(nèi)容的簡單處理框架早就用在實際項目中,不過今天正好有外部的朋友問起我,我就整理了一下作為google的開源代碼放上去了,這里也簡單介紹一下,有興趣的朋友可以去看看,最好是能夠給一些建議。

            

          場景:

                   應(yīng)用頻繁訪問接口服務(wù)器,需要控制每個應(yīng)用在可配置時間段內(nèi)(例如一分鐘)對于某一服務(wù)的訪問次數(shù),同時需要記錄每一次訪問內(nèi)容到數(shù)據(jù)庫中。

          幾個點:

          1. 高并發(fā)情況下,集群服務(wù)器需要全局計數(shù)。(需要將更新和判斷作為原子操作,而非兩階段操作,保證高并發(fā)事務(wù))

          2. 異步日志批量輸出。防止高頻率訪問第三方系統(tǒng)(DB,本地IO),提高性能。

          3. 采用黑名單簡化計數(shù)器判斷。

          1,3通過memcache就可以實現(xiàn),如果需要使用客戶端可以看看google code上的:http://code.google.com/p/memcache-client-forjava/

          這里主要在說一下2,在很多場景中都會有這樣的需求,一些需要輸出到DB或者文件的內(nèi)容需要緩存起來異步批量操作,提高性能也降低對于第三方系統(tǒng)的壓力。大致設(shè)計結(jié)構(gòu)圖如下:

           

           自上而下來看,ThreadA,B,C都是程序中其他模塊的線程,他們需要輸出記錄到數(shù)據(jù)庫或者DB中。當有數(shù)據(jù)到達需要輸出時,僅僅只是將數(shù)據(jù)放入阻塞隊列中,而有一個消費者線程池中的線程發(fā)現(xiàn)隊列中有數(shù)據(jù)就將數(shù)據(jù)寫入其中某一個線程的數(shù)據(jù)分頁中(每一個線程維護一個自己的內(nèi)存分頁,當頁滿或者到達了配置的輸出間隔時間以后就將頁內(nèi)數(shù)據(jù)交給輸出線程池中的輸出線程完成批量數(shù)據(jù)輸出)。


                  

          下面是三個類圖,囊括了這個小工具框架的所有類:

           

                   上圖是對外提供的異步輸出模板,其他模塊可以直接使用模板來輸出數(shù)據(jù)。

          上圖是異步輸出器包,是異步輸出模板的內(nèi)置邏輯實現(xiàn),其他線程直接使用異步輸出模板來輸出記錄。

                   上圖是消費者和輸出線程的接口和默認實現(xiàn)類,可以替換及擴展。

          整個框架基本都可以通過配置文件擴展每一個角色(異步輸出類,消費者,寫出者),擴展方式就是通過在classpath下增加目錄META-INF/services/然后將需要擴展的接口作為文件名稱,內(nèi)容就是接口的實現(xiàn)類,這樣既可擴展和替換任何一個角色的具體實現(xiàn)。

          具體的代碼和測試用例可以去http://code.google.com/p/asynwriter/ 下載。

          posted on 2009-02-12 21:09 岑文初 閱讀(2482) 評論(5)  編輯  收藏

          評論

          # re: 大流量數(shù)據(jù)異步輸出 2009-02-13 03:53 GhostDog
          請問這和直接寫到內(nèi)存數(shù)據(jù)庫比有多少性能差別? 感覺都放內(nèi)存,應(yīng)該差不多,線程還要多耗點資源。  回復(fù)  更多評論
            

          # re: 大流量數(shù)據(jù)異步輸出 2009-02-13 05:17 岑文初
          如果使用內(nèi)存數(shù)據(jù)庫,的卻寫出的頻度可以比普通的數(shù)據(jù)庫要快,但是就算是內(nèi)存數(shù)據(jù)庫,它的連接資源還是有限的,就算使用連接池,其實在每天幾十億的數(shù)據(jù)量下還是撐不住的.這里雖然用了線程,但是采用的是比較單一的使用方式,線程切換代價不大.不過這個可以測試一下看看,采用mysql內(nèi)存數(shù)據(jù)庫,然后每來一條數(shù)據(jù)就寫,與批量異步寫看看對于系統(tǒng)壓力以及性能來說是否有變化。  回復(fù)  更多評論
            

          # re: 大流量數(shù)據(jù)異步輸出 2009-02-15 23:33 micstart
          請問你的類圖用什么工具畫的?挺不錯的  回復(fù)  更多評論
            

          # re: 大流量數(shù)據(jù)異步輸出[未登錄] 2009-03-23 21:52 Patrick He
          @GhostDog
          采用異步 IO 的好處是服務(wù)程序可以不需要等待 IO 操作執(zhí)行結(jié)束即可返回,這樣可以大大提高服務(wù)層的吞吐量。  回復(fù)  更多評論
            

          # re: 大流量數(shù)據(jù)異步輸出 2009-04-07 23:18 srboyzj
          你的類圖是用EA畫的嗎?  回復(fù)  更多評論
            


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 永和县| 军事| 商城县| 万宁市| 巢湖市| 肇源县| 永州市| 丰原市| 西丰县| 桓台县| 安阳市| 双鸭山市| 苏州市| 崇阳县| 遂溪县| 安龙县| 平果县| 武隆县| 揭阳市| 闵行区| 丰县| 金平| 江陵县| 寿光市| 栾城县| 宜良县| 麻城市| 大港区| 浦北县| 吴桥县| 新龙县| 克什克腾旗| 宣化县| 晋江市| 榆中县| 鞍山市| 西平县| 淳化县| 萨迦县| 新营市| 石嘴山市|