`

Memcached 集群,客户端自动Hash到不同服务器的实现

 
阅读更多

首先分析一下Java client 启动时的部分代码

Memcached 支持直接设置多个servers属性 来实现多个memcahced均衡,对应还有一个属性是weights,字面意思就是权重,分析了一下代码,和我想的是一样的

启动memcached的代码通常是这样的

Java代码
  1. SockIOPoolpool=SockIOPool.getInstance(poolname);
  2. pool.setServers(servers);
  3. pool.setWeights(weights);
  4. pool.setInitConn(initConn);
  5. pool.setMinConn(minConn);
  6. pool.setMaxConn(maxConn);
  7. pool.setMaxIdle(maxIdle);
  8. pool.setMaxBusyTime(maxBusyTime);
  9. pool.setMaintSleep(maintSleep);
  10. pool.setSocketTO(socketTO);
  11. pool.setSocketConnectTO(socketConnectTO);
  12. pool.setNagle(nagle);
  13. pool.setHashingAlg(SockIOPool.NEW_COMPAT_HASH);
  14. pool.initialize();
  15. MemCachedClientclient=newMemCachedClient(poolname);



servers 和 weights 都是一个数组,就是说可以同时设置多个server

然后看一下 pool.initialize() 做了什么

Java代码
  1. availPool=newHashMap<String,Map<SockIO,Long>>(servers.length*initConn);
  2. busyPool=newHashMap<String,Map<SockIO,Long>>(servers.length*initConn);
  3. deadPool=newIdentityHashMap<SockIO,Integer>();
  4. hostDeadDur=newHashMap<String,Long>();
  5. hostDead=newHashMap<String,Date>();
  6. maxCreate=(poolMultiplier>minConn)?minConn:minConn/poolMultiplier;//onlycreateuptomaxCreateconnectionsatonce
  7. if(log.isDebugEnabled()){
  8. log.debug("++++initializingpoolwithfollowingsettings:");
  9. log.debug("++++initialsize:"+initConn);
  10. log.debug("++++minspare:"+minConn);
  11. log.debug("++++maxspare:"+maxConn);
  12. }
  13. //ifserversisnotset,oritempty,then
  14. //throwaruntimeexception
  15. if(servers==null||servers.length<=0){
  16. log.error("++++tryingtoinitializewithnoservers");
  17. thrownewIllegalStateException("++++tryingtoinitializewithnoservers");
  18. }
  19. //initalizeourinternalhashingstructures
  20. if(this.hashingAlg==CONSISTENT_HASH)
  21. populateConsistentBuckets();
  22. else
  23. populateBuckets();


看到这里就是开辟一些连接池的空间,然后调用了根据我们选择的hash 算法 执行populateBuckets();或者populateConsistentBuckets();

hash算法共有4种

Java代码
  1. //nativeString.hashCode();
  2. publicstaticfinalintNATIVE_HASH=0;
  3. //originalcompatibilityhashingalgorithm(workswithotherclients)
  4. publicstaticfinalintOLD_COMPAT_HASH=1;
  5. //newCRC32basedcompatibilityhashingalgorithm(workswithotherclients)
  6. publicstaticfinalintNEW_COMPAT_HASH=2;
  7. //MD5Based--Stopsthrashingwhenaserveraddedorremoved
  8. publicstaticfinalintCONSISTENT_HASH=3;



我们通常用的是 NEW_COMPAT_HASH,这个保证可以wokrs with other clients

所以看一下populateBuckets()做了什么

Java代码
  1. this.buckets=newArrayList<String>();
  2. for(inti=0;i<servers.length;i++){
  3. if(this.weights!=null&&this.weights.length>i){
  4. for(intk=0;k<this.weights[i].intValue();k++){
  5. this.buckets.add(servers[i]);
  6. if(log.isDebugEnabled())
  7. log.debug("++++added"+servers[i]+"toserverbucket");
  8. }
  9. }
  10. else{
  11. this.buckets.add(servers[i]);
  12. }
  13. //createinitialconnections
  14. for(intj=0;j<initConn;j++){
  15. SockIOsocket=createSocket(servers[i]);
  16. if(socket==null){
  17. break;
  18. }
  19. addSocketToPool(availPool,servers[i],socket);
  20. }
  21. }



假如我们设置的servers是 192.168.0.1:44444和192.168.0.2:22222
然后我们设置了weights是 5和3 那么
buckets list的值最终会是
[
192.168.0.1:44444,
192.168.0.1:44444,
192.168.0.1:44444,
192.168.0.1:44444,
192.168.0.1:44444,
192.168.0.2:22222,
192.168.0.2:22222.
192.168.0.2:22222.
]
然后就开始根据initCon初始连接数按servers分别创建socket
那么究竟这个buckets做什么用呢?

在我们使用set存放对象时会调用

Java代码
  1. SockIOPool.SockIOsock=pool.getSock(key,hashCode);



看一看pool.getSock的代码

Java代码
  1. //getinitialbucket
  2. longbucket=getBucket(key,hashCode);
  3. Stringserver=(this.hashingAlg==CONSISTENT_HASH)
  4. ?consistentBuckets.get(bucket)
  5. :buckets.get((int)bucket);



其中有段代码是这样的,看看getBucket

Java代码
  1. privatelonggetBucket(Stringkey,IntegerhashCode){
  2. longhc=getHash(key,hashCode);
  3. if(this.hashingAlg==CONSISTENT_HASH){
  4. returnfindPointFor(hc);
  5. }
  6. else{
  7. longbucket=hc%buckets.size();
  8. if(bucket<0)bucket*=-1;
  9. returnbucket;
  10. }
  11. }



先不管key和hashCode,我们看到首先算出一个hc值后会直接做hc%buckets.size()实际上就是根据buckets的数量散列,最终值一定是buckets.size()范围里的一个值
然后最终server值就根据buckets.get( (int)bucket )得到,那么假如我们得到bucket是3,则参照上面buckets 里的值,得到 list.get(3)=192.168.0.1:44444 所以会根据weight设置的值的不同得到不同的server ,如果 weights设置10:1 那buckets里就是10个相同的server和另一个不同的,将来散列得到的server很大可能性是servers里设置的第一个server。

 

原文地址:http://bachmozart.javaeye.com/blog/211836

分享到:
评论

相关推荐

    memcached集群linux搭建

    总结来说,构建Memcached集群并在Linux上实现淘宝月光宝盒架构是一项涉及多个步骤的任务,包括安装Memcached、配置集群、设置客户端以及部署和管理MoonBox架构。理解这些概念和技术对于优化大规模Web应用的性能至关...

    Memcached内存分析、调优、集群.pptx

    1. 一致性Hash:Memcached使用一致性Hash算法来实现分布式缓存。 2. 集群:Memcached支持集群模式,多台服务器组成一个集群,提供高可用性和高性能。 Memcached客户端 1. Memcached客户端:Memcached提供了多种...

    Memcached 内存分析、调优、集群

    这些客户端提供了方便的API,使得开发者能够轻松地集成Memcached服务到自己的应用中。 - **C/C++客户端**:如libmemcached、libmemcache、apr_memcache等。 - **PHP客户端**:如PECL/memcached、PECL/memcache等。 ...

    Memcached内存分析、调优、集群

    ### Memcached内存分析、调优、集群:深入理解与实践 #### 1. Memcached背景与概述 Memcached是一款高性能的分布式内存缓存服务器,它最初由LiveJournal的运营人员开发,现已成为开源社区中不可或缺的一部分。其...

    Linux下Nginx+Memcached+Tomcat负载均衡集群服务搭建所需jar包

    - **IP哈希(IP Hash)**:根据客户端IP地址进行分配,保证同一客户端的请求总是被分配到同一台服务器。 5. **会话持久化**: 为了确保用户在访问过程中不因服务器切换而丢失会话,可以启用Nginx的会话持久化功能...

    Memcached内存分析、调优、集群.pdf

    在高可用和负载均衡的场景下,通常需要部署Memcached集群。通过将多台Memcached服务器组成集群,可以提高系统的整体吞吐量和可用性。常见的集群解决方案包括: - **一致性Hash:** 用于数据分片。 - **客户端路由:...

    nginx+tomcat7+memcached session会话保持

    Nginx的配置中,我们可以通过“ip_hash”指令来实现基于客户端IP的会话保持,这样相同IP的请求会被转发到相同的后端服务器。配置示例如下: ```nginx http { upstream backend { ip_hash; server server1....

    集群Nginx+Tomcat+Memcached

    此配置示例中,Nginx将请求分发给三个不同的Tomcat服务器,并通过`proxy_set_header Cookie`和`proxy_hash`指令实现了Session的持久化和共享。 ### 结论 综上所述,通过使用Nginx作为前端负载均衡器,结合Tomcat...

    数据平台前端缓存技术方案Memcached-Redis.v1.0[汇编].pdf

    - **Google的Memcached实现**:基于Whalin的开源实现,提供接口化、配置文件初始化、集群支持和本地缓存功能。优化SocketIO以提高性能,通过配置文件指定集群节点,实现软负载均衡和数据冗余存储。 - **Spring+...

    memcached应用疑惑

    一致性哈希算法(Consistent Hashing)是memcached用于节点管理的关键技术,其目的是在memcached集群节点变动时,尽可能减少受影响的节点数量和数据重新分配的工作量,以此实现节点的动态增加或删除而对整体性能影响...

    memCache源码java客户端

    3. **HashAlgorithm**: 用于计算key在服务器集群中的哈希值,确保数据均匀分布。 4. **ConnectionPool**: 连接池管理连接,提高连接复用,减少创建和销毁连接的开销。 ### 三、连接与配置 在使用spymemcached时,...

    jar包.zip(Nginx的Session一致性,使用memcached解决所需要的jar包)

    1. **安装与配置memcached**:首先,需要在服务器集群中安装memcached,并确保其稳定运行。配置memcached时,可以设置监听的端口和内存大小等参数。 2. **配置Nginx**:在Nginx的负载均衡配置中启用`sticky`或`ip_...

    nginx集群配置-测试通过

    在以上配置中,我们利用了`proxy_set_header`指令传递客户端的cookie信息,并通过`proxy_cache`模块将session信息存储在Memcached集群中,确保在所有服务器之间共享。 总结来说,这个【nginx集群配置-测试通过】的...

    Java开发中的Memcache原理及实现

    1. 数据分片:通过一致性哈希策略,合理分配数据到不同的Memcached服务器,避免热点数据集中在少数节点。 2. 键值设计:键应尽可能短且有意义,值的大小要适度,避免过大的数据导致内存浪费或性能下降。 3. 缓存...

    负载均衡集群中的session解决方案.docx

    `ip_hash`基于客户端IP的哈希结果分配请求,确保同一客户端始终连接到同一服务器。而在Haproxy中,可以设置源地址Hash或使用Cookie识别,如`balance source`和`cookie`指令,分别根据用户IP或特定Cookie进行会话保持...

    memcached代码分析详解.docx

    - **分布式**: memcached支持多服务器环境,能自动将数据分发到各个节点。 - **内存存储**: 所有数据存储在内存中,读写速度极快,但数据易丢失,适用于不需持久化的场景。 - **简单协议**: 使用简单的文本协议,...

    最新Nginx1.9.4+Tomcat+Memcached负载均衡配置.rar

    4. **IP哈希(IP Hash)**:基于客户端IP地址的哈希结果决定请求分配,使来自同一IP的请求总是被定向到同一台服务器,适合保持会话状态。 5. **健康检查(Health Checks)**:定期检查后端服务器的状态,将故障...

    Liferay集群负载均衡配置

    - **IP哈希(IP Hash)**:根据客户端IP地址进行哈希,使同一客户端的请求始终落在同一服务器,保持会话持久性。 5. **缓存同步**: Liferay的缓存系统(如Velocity Cache或OSCache)也需要在集群间同步,以确保...

    神级memcached源代码分析文档_1.4.0代码分析

    Memcached采用经典的C/S架构,这里的client并非传统意义上的用户客户端,而是作为处理应用程序请求的中间服务器。工作流程分为两阶段哈希:首先,应用将请求发送给client,client通过哈希算法选择一个特定的...

Global site tag (gtag.js) - Google Analytics