<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學(xué)習(xí)

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

    java memcached client
    源碼,總的代碼量還是很少的 
    主要是如下兩個(gè)類: 
    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 );  
              //這是開啟一個(gè)nagle 算法。改算法避免網(wǎng)絡(luò)中充塞小封包,提高網(wǎng)絡(luò)的利用率  
            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 ) );  
            }  
      
    }  
    其實(shí) 對于我來說 我很想明白的是連接池是如何配置的,關(guān)鍵在于 pool.initialize(); 這個(gè)方法如何初始化的。 

    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  檢測是否已經(jīng)被初始化 
    2  定義可用鏈接 ,繁忙鏈接池 
    3  判斷是否一致性hash算法 還是普通的算法 
    4  定義一個(gè)后臺線程 ,來維護(hù) 
    好 ,首先來分析下一致性hash算法。 

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

    Java代碼  收藏代碼
    /** 將server添加到一致性hash的2的32次 圓環(huán)  **/  
        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();  
            //得到總的權(quán)重  
            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++ ) {  
                //每臺服務(wù)器的權(quán)重  
                int thisWeight = 1;  
                if ( this.weights != null && this.weights[i] != null ) {  
                    thisWeight = this.weights[i];  
                }  
                  
                //有興趣的朋友可以參考平衡Hash 算法的另一個(gè)指標(biāo)是平衡性 (Balance) ,定義如下:    平衡性 平衡性是指哈希的結(jié)果能夠盡可能分布到所有的緩沖中去,這樣可以使得所有的緩沖空間都得到利用  
                
    //了解決這種情況, consistent hashing 引入了“虛擬節(jié)點(diǎn)”的概念,它可以如下定義: “虛擬節(jié)點(diǎn)”( virtual node )是實(shí)際節(jié)點(diǎn)在 hash 空間的復(fù)制品( replica ),一實(shí)際個(gè)節(jié)點(diǎn)對應(yīng)了若干個(gè)“虛擬節(jié)點(diǎn)”,這個(gè)對應(yīng)個(gè)數(shù)也成為“復(fù)制個(gè)數(shù)”,“虛擬節(jié)點(diǎn)”在 hash 空間中以 hash 值排列。  
                double factor = Math.floor(((double)(40 * this.servers.length * thisWeight)) / (double)this.totalWeight);  
                  
                for ( long j = 0; j < factor; j++ ) { //加密規(guī)則類似 127.0.0.1_1    
                    byte[] d = md5.digest( ( servers[i] + "-" + j ).getBytes() ); //轉(zhuǎn)化成16位的字節(jié)數(shù)組  
                    
    //16位二進(jìn)制數(shù)組每4位為一組,每組第4個(gè)值左移24位,第三個(gè)值左移16位,第二個(gè)值左移8位,第一個(gè)值不移位。進(jìn)行或運(yùn)算,得到一個(gè)小于2的32 次方的long值  
                    for ( int h = 0 ; h < 4; h++ ) { //因?yàn)槭?6位   
                        Long k =  //實(shí)際上每個(gè)字節(jié)進(jìn)行了運(yùn)算  
                              ((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] );  
      
                //創(chuàng)建鏈接  
                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] );  
                }  
            }  
              
        }  
    好 比如說 我們調(diào)用了 如下代碼: 
    Java代碼  收藏代碼
    MemcachedClient mcc = new MemcachedClient();  
    mcc.set("6", 1);  

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

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

    Java代碼  收藏代碼 
    //得到大于hash的map,因?yàn)閠reemap已經(jīng)排好序了。調(diào)用tailMap可以得到大于等于這個(gè)hash的對象 ,然后調(diào)用firstKey得到圓環(huán)上的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 閱讀(452) 評論(0)  編輯  收藏 所屬分類: Memcached


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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲精品国自产拍在线观看| 亚洲av无码一区二区三区天堂 | 日本免费一本天堂在线| 你是我的城池营垒免费看| 国产亚洲人成在线影院| 男女污污污超污视频免费在线看| 亚洲黄色在线视频| 国产亚洲av人片在线观看| 欧洲精品免费一区二区三区| 精品国产sm捆绑最大网免费站 | 永久免费av无码网站yy| 免费人成大片在线观看播放电影 | 成人在线免费看片| 97人妻精品全国免费视频| 粉色视频免费入口| 在线亚洲v日韩v| 亚洲色丰满少妇高潮18p| 亚洲另类春色校园小说| 久久精品国产精品亚洲毛片| 国产精品亚洲一区二区三区在线 | 亚洲五月六月丁香激情| 国产亚洲精品无码成人| 中文字幕精品亚洲无线码一区应用| 日韩a级毛片免费视频| 成人免费无码大片A毛片抽搐 | 国产亚洲自拍一区| 亚洲中文字幕视频国产| 亚洲国产成人爱av在线播放| 免费欧洲毛片A级视频无风险| 精品免费国产一区二区| 日本免费v片一二三区| 国产在线观看免费视频播放器| 好男人视频社区精品免费| 成年人在线免费观看| 高清国语自产拍免费视频国产| 最近中文字幕无吗免费高清| 成人免费a级毛片| 久久精品a一国产成人免费网站| 在线看片无码永久免费视频| 黄色成人免费网站| 成人免费无码大片a毛片|