莊周夢蝶

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

          Xmemcached的FAQ和性能調整建議

          Posted on 2010-07-08 18:37 dennis 閱讀(20465) 評論(35)  編輯  收藏 所屬分類: java 、my open-source
              一些常見的關于xmemcached的問題,收集整理,集中解答在此。事實上這里的大部分問題都可以在用戶指南里找到。

          一、XMemcached是什么?
          經常碰到的一個問題是很多朋友對memcached不了解,誤以為xmemcached本身是一個緩存系統。Memcached是一個開源的,C寫的分布式key-value緩存,XMemcached只是它的一個訪問客戶端。Memcached通過網絡協議跟客戶端交互,通過客戶端你才可以去使用memcached,xmemcached是它的java客戶端之一。

          二、為什么要選擇xmemcached?

          memcached的java客戶端有多個選擇,為什么要選擇xmemcached?理由如下:

          1、支持所有的文本協議和二進制協議,支持連接KestrelTokyoTyrant等memcached協議兼容的系統并作特殊處理。
          2、支持動態添加和刪除memcached節點。
          3、支持客戶端統計
          4、支持JMX監控和統計,可以通過JMX增刪節點。
          5、高性能
          6、支持節點的權重設置
          7、支持nio的連接池,在高負載環境下提高吞吐量。

          三、對jdk版本有什么要求?

          Xmemcached僅支持jdk1.5及以上版本。

          四、使用的時候需要創建多個MemcachedClient對象嗎?MemcachedClient是不是線程安全?

          MemcachedClient是線程安全的,由于xmemcached的網絡層實現是基于nio長連接的,因此你并不需要重復創建多個MemcachedClient對象,通常來說將MemcachedClient設置為全局的唯一單例的服務使用,如果是使用spring配置,那更是簡單,在spring配置文件里配置一個MemcachedClient,其他對象引用即可使用。

          五、為什么會拋出java.util.TimeoutException?

          這是由于xmemcached的通訊層是基于非阻塞IO的,那么在請求發送給memcached之后,需要等待應答的到來,這個等待時間默認是1秒,如果超過1秒就拋出java.util.TimeoutExpcetion給用戶。如果你頻繁拋出此異常,可以嘗試將全局的等待時間設置長一些,如我在壓測中設置為5秒:
          MemcachedClient  memcachedClient=……
          memcachedClient.setOpTimeout(
          5000L);

          請注意,setOpTimeout設置的是全局的等待時間,如果你僅僅是希望將get或者set等操作的超時延長一點,那么可以通過這些方法的重載方法來使用:
          <T> T get(java.lang.String key,long timeout)

          boolean set(java.lang.String key, int exp,java.lang.Object value,
                      
          long timeout)

          ……


          六、Kestrel和TokyoTyrant不支持flag字段,xmemcached是怎么解決的?

          Xmemcached在存儲的value前面自動加上和去除4個字節的flag,這一切對應用來說是透明的。具體請看用戶指南。


          七、連接memcacheq,取出來的消息比放進去的多?


          這是由于memcacheq和kestrel一樣,不支持multi get協議,因此只要關閉xmemcached的multi get優化就可以了。

          memcachedClient.setOptimizeGet(false);

          所謂multi get優化是指xmemcached會將連續的單個get請求合并成一個multi get請求作批量獲取,提高效率。

          八、連接kestrel,為什么過一段時間會自動斷開并重連?

          你可能使用的是kestrel 1.2以下版本,kestrel 1.2才支持version協議,xmemcached是基于version協議做心跳檢測,因此當使用kestrel 1.2以下版本的時候會發生心跳檢測失敗并斷開連接重連的情況,你可以升級kestrel,也可以關閉心跳檢測:

          memcachedClient.setEnableHeartBeat(false);

          九、我使用maven,怎么引用xmemcached?

          xmemcached 1.2.5已經加入了maven的中心倉庫,因此你可以直接引用
            <dependency>
                
          <groupId>com.googlecode.xmemcached</groupId>
                
          <artifactId>xmemcached</artifactId>
                
          <version>1.2.5</version>
           
          </dependency>

          如果是之前版本,我推薦你升級,或者自己手工加入私人的maven倉庫。

          十、連接池是怎么回事?設置多大為好?

          在高負載環境下,nio的單連接也會遇到瓶頸,此時你可以通過設置連接池來讓更多的連接分擔memcached的請求負載,從而提高系統的吞吐量。設置連接池通過
          MemcachedClientBuilder builder = new    XMemcachedClientBuilder(AddrUtil.getAddresses("localhost:12000"));

          builder.setConnectionPoolSize(
          5);
          MemcachedClient client
          =builder.build();

          或者通過spring配置也可以。

          連接池通常不建議設置太大,我推薦在0-30之間為好,太大則浪費系統資源,太小無法達到分擔負載的目的。

          十一、性能建議及優化手段

              性能的調整只能給出一般性的原則,實際情況千差萬別,每次調整都需要做實際的測量才能確定是否帶來期望的效果。

          1、如果你的數據較小,如在1K以下,默認的配置選項已經足夠。如果你的數據較大,我會推薦你調整網絡層的TCP選項,如設置socket的接收和發送緩沖區更大,啟用Nagle算法等等:   
                      MemcachedClientBuilder builder = new XMemcachedClientBuilder(
                              AddrUtil.getAddresses(servers));
                      builder.setSocketOption(StandardSocketOption.SO_RCVBUF, 
          32 * 1024); // 設置接收緩存區為32K,默認16K
                      builder.setSocketOption(StandardSocketOption.SO_SNDBUF, 16 * 1024); // 設置發送緩沖區為16K,默認為8K
                      builder.setSocketOption(StandardSocketOption.TCP_NODELAY, false); // 啟用nagle算法,提高吞吐量,默認關閉

          默認如果連接超過5秒沒有任何IO操作發生即認為空閑并發起心跳檢測,你可以調長這個時間: 
            builder.getConfiguration().setSessionIdleTimeout(10000);  // 設置為10秒;

          更多網絡層配置選項請參見Configuration類。

          2、Xmemcached默認會做兩個優化:將連續的單個get合并成一個multi get批量操作獲取,將連續的請求合并成socket發送緩沖區大小的buffer發送。
          如果你對響應時間比較在意,那么可以將合并的因子減小,或者關閉合并buffer的優化:
              memcachedClient.setMergeFactor(50);   //默認是150,縮小到50
              memcachedClient.setOptimizeMergeBuffer(false);  //關閉合并buffer的優化

          如果你對吞吐量更在意,那么也可將合并因子調大,默認是150。但是也不可太大,太大可能導致平均響應時間延長。

          3、如果你對心跳檢測不在意,也可以關閉心跳檢測,減小系統開銷
          memcachedClient.setEnableHeartBeat(false);
          這個關閉,僅僅是關閉了心跳的功能,客戶端仍然會去統計連接是否空閑,禁止統計可以通過:
          builder.getConfiguration().setStatisticsServer(false);






          評論

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-07-09 08:34 by smxly53
          感謝指導

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-08-17 18:53 by AlexJ
          五、為什么會拋出java.util.TimeoutException?
          這個和Memcached服務端版本有關系,用最新的服務端就沒有這個問題,用1.4之前的Memcached版本會出現此問題,而且這個異常拋出來相當的不優雅~

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-08-25 23:32 by Santal Li
          非常好的項目,樓主實力很強。
          有個問題想問一下:
          >builder.setSocketOption(StandardSocketOption.TCP_NODELAY, false); // 啟用nagle算法,提高吞吐量,默認關閉
          剛看的資料,Set TCP_NODELAY = false確實可以啟用Nagle算法,而 Nagle算法可以合并多個小的TCP包為一個大包,以減少需要傳輸的總的小包量,可是好像所有的TCP Stack的實現都把TCP_NODELAY缺省的設置為True了呀,為什么要再設置一次呢?

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-08-26 09:26 by dennis
          @Santal Li
          默認的TCP選項,都是啟用nagle算法,也就是默認是false。
          xmemcached默認卻是禁止nagle算法,這是為了降低響應時間,特別是在數據比較小的情況下。

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-09-15 10:50 by leixiangjian
          摟主,你好!
          我使用memcached版本是1.4.5,服務器開了3個節點
          ip:192.168.166.156:11211
          ip:192.168.166.156:11212
          ip:192.168.166.156:11213

          客戶端使用xmemcached

          情況如下:
          當一個node失去,則會調用
          MemcachedConnector.removeSession()方法、還會調用定位器的updateSessions()方法,當我在MemcachedHandler.onSessionClosed方法中獲得相應的client后,在利用client的get方法對某個節點上的數據進行操作時,總是拋出如下異常:
          java.util.concurrent.TimeoutException: Timed out(5000) waiting for operation

          為什么???

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-09-15 11:05 by denniis
          @leixiangjian
          連接斷開了,你再往這個連接發送命令是沒用的,當然會超時。

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-09-15 11:13 by leixiangjian
          比如:斷開的node是192.168.166.156:11212
          我的get的node是192.168.166.156:11211

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-09-15 11:16 by leixiangjian
          雖然我的192.168.166.156:11212 節點是斷開的。
          但是我的192.168.166.156:11211 節點還在
          我直接利用那個client去訪問192.168.166.156:11211 節點上的數據,192.168.166.156:11211 節點上日志也反映出get ....但是程序中報出
          java.util.concurrent.TimeoutException: Timed out(5000) waiting for operation

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-09-15 11:24 by denniis
          @leixiangjian

          我不知道你是怎么指定Node去發送的,貌似xmemcached目前也不支持這個指定node發送的功能。另外就是在MemcachedHandler.onSessionClosed()方法中調用任何阻塞操作都是不當的,因為這是在IO線程上,你阻塞了,根本就發不出去命令,更何談響應的到達。

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-09-15 11:44 by leixiangjian
          在這個方法MemcachedHandler.onSessionClosed()被觸發時,我使用另一個線程用client來處理我的需求應該是可以的吧,這樣就不會對IO線程阻塞了。
          這樣可以吧!

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-09-15 11:51 by leixiangjian
          非常感謝你對給我的回答,剛剛那個問題已經解決了!

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-10-13 16:04 by commond
          記得以前用過 spyMemcached 其中的 future對象很好用 比如 我做一批數據的 remove 我可以將future put到一個map 中 ,然后再去看結果 ,是否remove成功,否則的話 一個一個remove 查看結果 還是阻塞的,效率很低,不知道在xmemcached中 可有什么好的解決方案?

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-10-17 15:53 by dennis
          @commond
          可以用deleteWithNoReply,不查看回復。
          xmc沒有future模式,同步跟異步future誰更快,你可以測試一下。

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-10-20 15:39 by commond
          感謝您的回復 xmemcached我還沒有測試 ,我們現在項目用的是spy 我測了一下 性能還是有很大區別的
          MemcachedClient mc = new MemcachedClient(AddrUtil.getAddresses(ip));
          long t = System.currentTimeMillis();
          for(int i = 0 ; i < 10000 ; i ++){
          mc_self.retryRemove(i+"");

          }
          long usingtime = (System.currentTimeMillis() - t);
          System.out.println(usingtime);



          t = System.currentTimeMillis();
          Map<String,Future<Boolean>> futureMap = new HashMap<String,Future<Boolean>>();
          for(int i = 0 ; i < 10000 ; i ++){
          Future<Boolean> future = mc.delete(i+"");
          futureMap.put(i+"", future);
          }
          for(String key : futureMap.keySet()){
          Future<Boolean> future = futureMap.get(key);
          try {
          future.get(1, TimeUnit.SECONDS);
          } catch (TimeoutException e) {
          future.cancel(true);
          System.out.println("TimeoutException");
          } catch (InterruptedException e) {
          System.out.println("remove object error:");
          } catch (ExecutionException e) {
          System.out.println("remove object error:");
          }
          }

          usingtime = (System.currentTimeMillis() - t);
          System.out.println(usingtime);

          11453ms
          TimeoutException
          1813ms

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-10-20 15:41 by denniis
          @commond
          這種場景我是建議用reply的,只是無法得到響應。

          另外,測試還是要模擬并發,單線程測試沒有多大意義。

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-10-20 15:42 by denniis
          @commond
          修正,是使用noreply

          # re: Xmemcached的FAQ和性能調整建議[未登錄]  回復  更多評論   

          2010-10-23 17:35 by xzh
          <bean id="cacheManager" class="*********" destroy-method="shutdown" depends-on="memcachedClient"> spring context關閉時,想在xmemcached 關閉之前先把數據提交memcached,然后在關閉xmemcached。但是發現在memcachedClient shutdown之前, 關閉鉤子已經在關閉session及報錯:Xmemcached is stopped。這個問題有怎么好的解決方案嗎? 源碼中的關閉鉤子,都去掉,會有什么樣的影響嗎?謝謝

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-10-25 09:52 by denniis
          Xmemcached is stopped的錯誤是在關閉了xmc之后才會拋出的,關閉的順序應當xmc放在最后吧。

          # re: Xmemcached的FAQ和性能調整建議[未登錄]  回復  更多評論   

          2010-10-26 19:47 by xzh
          xmc 的關閉順訊我控制不了。xmemcached加了三個關閉鉤子。。jvm 一退出。立馬就關閉了。spring 上的depends-on,沒有本質的作用

          # re: Xmemcached的FAQ和性能調整建議[未登錄]  回復  更多評論   

          2010-10-26 19:49 by xzh
          我把源碼中,三個關閉鉤子去掉了。是能夠按照我想的方式關閉。但是我不知道。去掉這個三個關閉鉤子,會不會有什么其它方面的影響。

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2010-10-28 17:20 by denniis
          @xzh
          應該不會有問題,這些鉤子只是為來保證萬一用戶沒有調用shutdown,則在jvm退出前嘗試關閉。

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2011-05-11 10:40 by Lucene
          現在通過Spring配置memcachedClient,如果要注入一些參數不太方便啊,比如設置Builder的SocketOption。希望作者可以改進一下。

          # re: Xmemcached的FAQ和性能調整建議[未登錄]  回復  更多評論   

          2011-08-21 10:27 by 蘇林
          我想問一下的是、
          使用二進制協議時候會出現超時異常:
          java.util.concurrent.TimeoutException: Timed out(1000) waiting for operation

          代碼就是:

          String addrs = "127.0.0.1:11211 127.0.0.1:11212 127.0.0.1:11213";
          MemcachedClientBuilder builder =
          new XMemcachedClientBuilder(AddrUtil.getAddresses(addrs));
          builder.addStateListener(new MemcachedListener(null));
          builder.setConnectionPoolSize(5);
          // builder.setFailureMode(true);
          builder.setSocketOption(StandardSocketOption.SO_SNDBUF, 16*1024);
          builder.setSocketOption(StandardSocketOption.TCP_NODELAY, false);
          // 使用二進制協議、使用的話會出現異常:Timed out(1000) waiting for operation
          builder.setCommandFactory(new BinaryCommandFactory());

          接下來就是通過builder獲取MemcachedClient了

          然而如果我使用文本協議的話就正常了。
          但是我想使用touch方法:
          boolean touch(java.lang.String key, int exp)
          如果不用二進制協議的話、 它會提示touch方法只支持二進制協議。

          這怎么解決奧

          還有一點就是、 二進制協議和文本協議各有什么優缺點啊,相對而言的

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2011-08-21 10:34 by 蘇林
          囧、 好像是我的Memcached是1.5的, 難道1.5不支持二進制?

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2011-09-17 22:04 by fuyou001
          builder.setSocketOption(StandardSocketOption.TCP_NODELAY, false); // 啟用nagle算法,提高吞吐量,默認關閉

          這是不是筆誤.因為你上面提到tcp默認是開啟TCP_NODELAY
          而我看源代碼發現是關閉TCP_NODELAY(即您設置成了false)

          如果有要開啟TCP_NODELAY,是不是應該設置成true,但你上面卻是false???

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2011-09-17 22:25 by fuyou001
          @fuyou001
          我自己弄錯了,請刪除或忽略

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2011-09-29 09:49 by storm
          超時時間我也設置15000L,但是有時不到這個時間,還是會出現java.util.TimeoutException

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2012-02-08 11:52 by 李丹
          樓主厲害,小弟初學,請問下樓主,如果采用spring3.0的配置,使用builder作為工廠類獲取client的bean,那么您提到這這些通過編碼方式優化性能的方法如何實現?

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2012-02-09 17:43 by scelong
          請問一下,我的代碼:
          List<InetSocketAddress> addresses = AddrUtil
          .getAddresses("132.122.1.204:11511 132.122.1.204:11512 132.122.1.204:11513");
          MemcachedClientBuilder builder = new XMemcachedClientBuilder(addresses);
          上面就是說,有三個Memcached服務器,我想在set操作時(默認是某一個服務器),把數據同時緩存到另外兩個服務,xmemcachde有木有這個接口呢?還是通過其他的方式?謝謝

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2012-02-15 11:22 by 黎某人
          請問下,Java使用xmemcached去連接ttserver的時候,就會報錯Timed out waiting for operation
          java是怎么使用xmemcached連接ttserver的

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2012-02-15 11:26 by dennis
          @黎某人
          參見 http://code.google.com/p/xmemcached/wiki/User_Guide_zh#%E4%B8%8Etokyotyrant%E4%BA%A4%E4%BA%92

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2012-02-23 11:04 by 郭建軍
          我目前有多臺memcached做tomcat的session管理,假如A,B,C三個memcached結點. 目前想做一個memcached的failedover功能.

          當前的實現思路,存儲在A的Session,同時備份一個到B機器,存儲在B上的Session,同時備份一份到C,以次成環形備份.

          看了xmemcached的接口,沒有找到可以指定key存儲到哪個memcached 結點的方法.
          請給一個參考意見.

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2012-09-11 13:08 by ai983
          目前的set,和replace方法接口都必須要傳入一個int exp 的參數。
          我想對已有key的value做出替換,但是不想更改原有key的過期時間,請問要如何實現呢?

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2014-02-13 11:53 by lianzerog
          請問xmemcached和libmemcached(C客戶端)是否兼容,如果可以應該如何操作?新手求助,非常感謝

          # re: Xmemcached的FAQ和性能調整建議  回復  更多評論   

          2015-03-26 14:39 by 落塵
          @leixiangjian
          您好!我想請問下java.util.concurrent.TimeoutException: Timed out(5000) waiting for operation 這個問題是如何處理的!

          /** 設置與緩存服務器的連接池 */
          MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddressMap(serverAddress));
          try {
          //啟用failure模式。
          builder.setFailureMode(true);
          builder.setSessionLocator(new KetamaMemcachedSessionLocator());
          builder.setConnectionPoolSize(poolSize);
          builder.setHealSessionInterval(healConnectionInterval);
          mcc = builder.build();
          if(mcc!=null){
          mcc.setConnectTimeout(soTimeout);
          mcc.setOpTimeout(soTimeout);
          }
          log.info("Memcache initialization successful!"+serverAddress);
          } catch (IOException e) {
          log.error("初始化memcache連接失敗:" + e.getLocalizedMessage(), e);
          }

          我這里也會出現超時的現象,xmemcached2.0 .網絡肯定沒問題的。

          謝謝!
          主站蜘蛛池模板: 囊谦县| 吐鲁番市| 沭阳县| 吉木乃县| 泉州市| 芦溪县| 乌拉特中旗| 宣恩县| 遂宁市| 鲜城| 延长县| 鲁山县| 吐鲁番市| 太白县| 靖州| 天峨县| 分宜县| 宜城市| 清远市| 广德县| 安泽县| 元江| 三河市| 黄陵县| 金乡县| 修水县| 唐山市| 临安市| 砚山县| 库伦旗| 朔州市| 武胜县| 鹤峰县| 新源县| 西和县| 义马市| 韶关市| 星座| 喀喇| 鄯善县| 洪泽县|