<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Chan Chen Coding...

    memcached 客戶端代碼 Java memcached client學習

    Refer to:http://makemyownlife.iteye.com/blog/1439581

    java memcached client
    源碼,總的代碼量還是很少的 
    主要是如下兩個類: 
    MemcachedClient.java 
    SockIOPool.java

    好 先看推薦的測試代碼: 
    Java代碼  收藏代碼
    /** 
     * Copyright (c) 2008 Greg Whalin 
     * All rights reserved. 
     * 
     * This library is free software; you can redistribute it and/or 
     * modify it under the terms of the BSD license 
     * 
     * This library is distributed in the hope that it will be 
     * useful, but WITHOUT ANY WARRANTY; without even the implied 
     * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     * PURPOSE. 
     * 
     * You should have received a copy of the BSD License along with this 
     * library. 
     * 
     * 
    @author greg whalin <greg@meetup.com>  
     
    */  
    package com.meetup.memcached.test;  
      
    import com.meetup.memcached.*;  
    import org.apache.log4j.*;  
      
    public class TestMemcached  {    
        public static void main(String[] args) {  
                  // memcached should be running on port 11211 but NOT on 11212  
      
            BasicConfigurator.configure();  
            String[] servers = { "localhost:11211"};  
            SockIOPool pool = SockIOPool.getInstance();  
            pool.setServers( servers );  
            pool.setFailover( true );  
            pool.setInitConn( 10 );   
            pool.setMinConn( 5 );  
            pool.setMaxConn( 250 );  
            pool.setMaintSleep( 30 );  
              //這是開啟一個nagle 算法。改算法避免網絡中充塞小封包,提高網絡的利用率  
            pool.setNagle( false );  
            pool.setSocketTO( 3000 );  
            pool.setAliveCheck( true );  
            pool.initialize();  
      
            MemcachedClient mcc = new MemcachedClient();  
      
            // turn off most memcached client logging:  
            com.meetup.memcached.Logger.getLogger( MemcachedClient.class.getName() ).setLevel( com.meetup.memcached.Logger.LEVEL_WARN );  
      
            for ( int i = 0; i < 10; i++ ) {  
                boolean success = mcc.set( "" + i, "Hello!" );  
                String result = (String)mcc.get( "" + i );  
                System.out.println( String.format( "set( %d ): %s", i, success ) );  
                System.out.println( String.format( "get( %d ): %s", i, result ) );  
            }  
      
    }  
    其實 對于我來說 我很想明白的是連接池是如何配置的,關鍵在于 pool.initialize(); 這個方法如何初始化的。 

    Java代碼  收藏代碼
    /**  
         * Initializes the pool.  
         
    */  
        public void initialize() {  
      
            synchronizedthis ) {  
      
                // check to see if already initialized  
                if ( initialized  
                        && ( buckets != null || consistentBuckets != null )  
                        && ( availPool != null )  
                        && ( busyPool != null ) ) {  
                    log.error( "++++ trying to initialize an already initialized pool" );  
                    return;  
                }  
      
                // pools  
                availPool   = new HashMap<String,Map<SockIO,Long>>( servers.length * initConn );  
                busyPool    = new HashMap<String,Map<SockIO,Long>>( servers.length * initConn );  
                deadPool    = new IdentityHashMap<SockIO,Integer>();  
      
                hostDeadDur = new HashMap<String,Long>();  
                hostDead    = new HashMap<String,Date>();  
                maxCreate   = (poolMultiplier > minConn) ? minConn : minConn / poolMultiplier;       // only create up to maxCreate connections at once  
      
                if ( log.isDebugEnabled() ) {  
                    log.debug( "++++ initializing pool with following settings:" );  
                    log.debug( "++++ initial size: " + initConn );  
                    log.debug( "++++ min spare   : " + minConn );  
                    log.debug( "++++ max spare   : " + maxConn );  
                }  
      
                // if servers is not set, or it empty, then  
                
    // throw a runtime exception  
                if ( servers == null || servers.length <= 0 ) {  
                    log.error( "++++ trying to initialize with no servers" );  
                    throw new IllegalStateException( "++++ trying to initialize with no servers" );  
                }  
      
                // initalize our internal hashing structures  
                if ( this.hashingAlg == CONSISTENT_HASH )  
                    populateConsistentBuckets();  
                else  
                    populateBuckets();  
      
                // mark pool as initialized  
                this.initialized = true;  
      
                // start maint thread  
                if ( this.maintSleep > 0 )  
                    this.startMaintThread();  
            }  
        }  
    如上代碼流程如下: 
    1  檢測是否已經被初始化 
    2  定義可用鏈接 ,繁忙鏈接池 
    3  判斷是否一致性hash算法 還是普通的算法 
    4  定義一個后臺線程 ,來維護 
    好 ,首先來分析下一致性hash算法。 

    從如下代碼來分析 : 
    Java代碼  收藏代碼
      if (   
             this.hashingAlg == CONSISTENT_HASH )  
            populateConsistentBuckets();  
    }

    Java代碼  收藏代碼
    /** 將server添加到一致性hash的2的32次 圓環  **/  
        private void populateConsistentBuckets() {  
            if ( log.isDebugEnabled() )  
                log.debug( "++++ initializing internal hashing structure for consistent hashing" );  
      
            // store buckets in tree map   
            this.consistentBuckets = new TreeMap<Long,String>();  
      
            MessageDigest md5 = MD5.get();  
            //得到總的權重  
            if ( this.totalWeight <= 0 && this.weights !=  null ) {  
                for ( int i = 0; i < this.weights.length; i++ )  
                    this.totalWeight += ( this.weights[i] == null ) ? 1 : this.weights[i];  
            }  
            else if ( this.weights == null ) {  
                this.totalWeight = this.servers.length;  
            }  
              
          
            for ( int i = 0; i < servers.length; i++ ) {  
                //每臺服務器的權重  
                int thisWeight = 1;  
                if ( this.weights != null && this.weights[i] != null ) {  
                    thisWeight = this.weights[i];  
                }  
                  
                //有興趣的朋友可以參考平衡Hash 算法的另一個指標是平衡性 (Balance) ,定義如下:    平衡性 平衡性是指哈希的結果能夠盡可能分布到所有的緩沖中去,這樣可以使得所有的緩沖空間都得到利用  
                
    //了解決這種情況, consistent hashing 引入了“虛擬節點”的概念,它可以如下定義: “虛擬節點”( virtual node )是實際節點在 hash 空間的復制品( replica ),一實際個節點對應了若干個“虛擬節點”,這個對應個數也成為“復制個數”,“虛擬節點”在 hash 空間中以 hash 值排列。  
                double factor = Math.floor(((double)(40 * this.servers.length * thisWeight)) / (double)this.totalWeight);  
                  
                for ( long j = 0; j < factor; j++ ) { //加密規則類似 127.0.0.1_1    
                    byte[] d = md5.digest( ( servers[i] + "-" + j ).getBytes() ); //轉化成16位的字節數組  
                    
    //16位二進制數組每4位為一組,每組第4個值左移24位,第三個值左移16位,第二個值左移8位,第一個值不移位。進行或運算,得到一個小于2的32 次方的long值  
                    for ( int h = 0 ; h < 4; h++ ) { //因為是16位   
                        Long k =  //實際上每個字節進行了運算  
                              ((long)(d[3+h*4]&0xFF) << 24)   
                            | ((long)(d[2+h*4]&0xFF) << 16)   
                            | ((long)(d[1+h*4]&0xFF) << 8)    
                            | ((long)(d[0+h*4]&0xFF));  
      
                        consistentBuckets.put( k, servers[i] );  
                        if ( log.isDebugEnabled() )  
                            log.debug( "++++ added " + servers[i] + " to server bucket" );  
                    }                 
                }  
                  
                  
      
                // create initial connections  
                if ( log.isDebugEnabled() )  
                    log.debug( "+++ creating initial connections (" + initConn + ") for host: " + servers[i] );  
      
                //創建鏈接  
                for ( int j = 0; j < initConn; j++ ) {  
                    SockIO socket = createSocket( servers[i] );  
                    if ( socket == null ) {  
                        log.error( "++++ failed to create connection to: " + servers[i] + " -- only " + j + " created." );  
                        break;  
                    }  
                    //加入socket到連接池 這里慢慢談  
                    addSocketToPool( availPool, servers[i], socket );  
                    if ( log.isDebugEnabled() )  
                        log.debug( "++++ created and added socket: " + socket.toString() + " for host " + servers[i] );  
                }  
            }  
              
        }  
    好 比如說 我們調用了 如下代碼: 
    Java代碼  收藏代碼
    MemcachedClient mcc = new MemcachedClient();  
    mcc.set("6", 1);  

    這里key 如何定位到一臺server呢?我先把一致性hash算法的定位方法說下。 
    Java代碼  收藏代碼
    //得到定位server的Socket封裝對象  
    SockIOPool.SockIO sock = pool.getSock( key, hashCode );  

    Java代碼  收藏代碼
    //計算出key對應的hash值(md5) ,然后  
    long bucket = getBucket( key, hashCode );  

    Java代碼  收藏代碼 
    //得到大于hash的map,因為treemap已經排好序了。調用tailMap可以得到大于等于這個hash的對象 ,然后調用firstKey得到圓環上的hash值  
    SortedMap<Long,String> tmap =  
                this.consistentBuckets.tailMap( hv );  
            return ( tmap.isEmpty() ) ? this.consistentBuckets.firstKey() : tmap.firstKey();  



    -----------------------------------------------------
    Silence, the way to avoid many problems;
    Smile, the way to solve many problems;

    posted on 2013-04-19 12:16 Chan Chen 閱讀(451) 評論(0)  編輯  收藏 所屬分類: Memcached


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


    網站導航:
     
    主站蜘蛛池模板: 精品亚洲成α人无码成α在线观看| 国产一卡二卡四卡免费| 免费看小12萝裸体视频国产| 亚洲sss综合天堂久久久| 四虎精品视频在线永久免费观看| 亚洲av午夜福利精品一区人妖| 中文成人久久久久影院免费观看| 亚洲三区在线观看无套内射| 国产午夜精品理论片免费观看| 亚洲尤码不卡AV麻豆| 国产一级淫片a免费播放口| 久久亚洲综合色一区二区三区| 无码免费一区二区三区免费播放| 久久精品亚洲综合专区| 曰批全过程免费视频网址 | 免费一区二区三区| 亚洲精选在线观看| 国产成在线观看免费视频| 亚洲成aⅴ人片久青草影院按摩| 国产精品免费视频播放器| 一级一级一级毛片免费毛片| 亚洲国产精品不卡在线电影| 男女做羞羞的事视频免费观看无遮挡| 自拍日韩亚洲一区在线| 日韩免费福利视频| 精品国产污污免费网站入口| 亚洲蜜芽在线精品一区| 午夜免费福利在线观看| 国产国产人免费人成成免视频| 亚洲色偷偷偷鲁综合| 3d成人免费动漫在线观看 | 日韩免费在线中文字幕| 亚洲乱码国产一区三区| 免费A级毛片无码A∨免费| 日本亚洲中午字幕乱码| 亚洲成熟xxxxx电影| 免费观看男人免费桶女人视频| 国产无限免费观看黄网站| 久久久久亚洲精品日久生情| 狠狠久久永久免费观看| 欧洲人免费视频网站在线|