莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          fqueue初步分析

          Posted on 2011-09-16 20:10 dennis 閱讀(9236) 評論(7)  編輯  收藏 所屬分類: java源碼解讀

              fqueue是國產的一個類似memcacheq,kestrel這樣的支持memcached協議的輕量級開源MQ。它的項目主頁:
          http://code.google.com/p/fqueue/downloads/list,介紹和特點都可以看主頁,我就不廢話了。

              今天老大提到, co了源碼看了下,寫個初步分析報告。

              首先是它的存儲層,主要是一個FQueue這么一個抽象隊列,內部實現是FSQueue,也就是基于文件的FIFO隊列。這個隊列是多個文件組成的。每個文件默認大小在150M,超過即切換一個新文件來寫。讀的時候如果讀到尾部,則查找下一個文件進行讀取。數據文件名以idb為后綴,并且從編號1開始遞增,除了數據文件外,每個隊列還有個db為后綴的索引文件,記錄當前寫和讀的數據文件編號和偏移量。目錄結構大概是這樣:
              --fqueue
                  --fqueuedata_1.idb
                  --fqueuedata_2.idb
                  --……
                  --icqueue.db

              文件的存儲比較有特色,采用MappedByteBuffer做文件讀寫,MappedByteBuffer是java nio引入的文件內存映射方案,讀寫性能極高,但是也有一定的問題,比如說內存占用,以及數據刷入設備的不確定性和關閉問題。在fqueue中,每隔10毫秒會強制force一次buffer,將修改過的數據刷入設備。對于關閉問題,則采用那個技巧,示例代碼:
          /**
               * 關閉索引文件
               
          */
              
          public void close() {
                  
          try {
                      mappedByteBuffer.force();
                      AccessController.doPrivileged(
          new PrivilegedAction<Object>() {
                          
          public Object run() {
                              
          try {
                                  Method getCleanerMethod 
          = mappedByteBuffer.getClass().getMethod("cleaner"new Class[0]);
                                  getCleanerMethod.setAccessible(
          true);
                                  sun.misc.Cleaner cleaner 
          = (sun.misc.Cleaner) getCleanerMethod.invoke(mappedByteBuffer,
                                          
          new Object[0]);
                                  cleaner.clean();
                              } 
          catch (Exception e) {
                                  log.error(
          "close logindexy file error:", e);
                              }
                              
          return null;
                          }
                      });
                      fc.close();
                      dbRandFile.close();
                      mappedByteBuffer 
          = null;
                      fc 
          = null;
                      dbRandFile 
          = null;
                  } 
          catch (IOException e) {
                      log.error(
          "close logindex file error:", e);
                  }
              }

              利用反射,并且使用了sun特有的類,不具有可移植性。MappedByteBuffer還有一個問題是map的代價比較高,可能在切換文件的時候fqueue會有一定程度的阻塞現象。

              存儲的性能,我在我的機器測試了下,似乎沒有作者宣稱的那么高,我的機器是5400轉的普通SATA盤,寫入1K數據的平均QPS在8000左右。我估計fqueue的性能跟磁盤有很大關系,如果使用15000轉的SAS盤應該能有很大改觀。

              網絡層直接使用了jmemcached的實現,jmemcached是一個java實現的memcached,通常用于單元測試之類。看情況fqueue也支持memcached的二進制協議了。網絡框架使用了netty3,這些就不多說了。自己看都明白。額外提一下,作者做的單元測試使用了xmemcached,咔咔,廣而告之。

              總體來說fqueue是一個整體上很清爽和輕量級的MQ實現,適合一些特定的場景,至于性能,我們下周準備做個壓測,到時候再談吧。

          評論

          # re: fqueue初步分析  回復  更多評論   

          2011-09-16 21:01 by fuyou001
          請問下 getCleanerMethod.setAccessible(true);
          sun.misc.Cleaner cleaner = (sun.misc.Cleaner) getCleanerMethod.invoke(mappedByteBuffer,
          new Object[0]);

          這個技巧,在哪有相關文檔,看的似懂非懂的?
          在java api里MappedByteBuffer 類里沒有cleaner方法,其父類也沒有

          # re: fqueue初步分析[未登錄]  回復  更多評論   

          2011-09-16 21:17 by dennis
          @fuyou001
          看 sun.nio.ch.DirectBuffer

          MappedByteBuffer是direct buffer的一種。

          # re: fqueue初步分析  回復  更多評論   

          2011-09-17 01:07 by 孫立
          我是Fqueue的作者。很高興看到你的分析。
          你提到的:可能在切換文件的時候fqueue會有一定程度的阻塞現象。
          這個起始有考慮,每次打開,會提前預分配下一個文件避免阻塞。sun.nio.ch.DirectBuffer這個東西的使用,是當時在windows下面出現無法刪除的問題,但是在linux下面似乎沒有這個問題。
          單個文件的大小,推薦設置為40M左右。
          Fqueue的存儲層性能直接取決于磁盤性能。我前兩天剛測試在服務器上sas上,1K的qps有19萬。

          # re: fqueue初步分析  回復  更多評論   

          2011-09-17 08:55 by tb
          學習了

          # re: fqueue初步分析  回復  更多評論   

          2011-09-17 12:59 by dennis
          @孫立
          感謝作者的回復,呵呵,我初步看了下,還不夠仔細。下周做個壓測再向你請教。

          # re: fqueue初步分析  回復  更多評論   

          2011-09-18 16:00 by vbg
          jmemcached 是memcached 的一個java實現。
          jmemcached 和 fqueue 有啥關系呀?

          它們是怎么配合的?

          # re: fqueue初步分析  回復  更多評論   

          2011-09-18 16:10 by vbg
          看了CacheStorage<String, LocalCacheElement> storage = new FSStorage();知道FSStorage是memcached實現的緩存存儲。
          主站蜘蛛池模板: 廉江市| 江口县| 都江堰市| 德庆县| 绥芬河市| 沿河| 南澳县| 安溪县| 西畴县| 杨浦区| 文昌市| 两当县| 双辽市| 来宾市| 墨竹工卡县| 芦山县| 赞皇县| 清河县| 玉环县| 辰溪县| 东山县| 哈尔滨市| 曲阳县| 花莲县| 安西县| 阳东县| 安庆市| 宝鸡市| 高青县| 运城市| 临潭县| 南平市| 梁河县| 永嘉县| 尼勒克县| 南城县| 南郑县| 黑龙江省| 方城县| 内丘县| 西峡县|