zoukankan      html  css  js  c++  java
  • Memcached 群集高可用性(HA)架构

            Memcache本身并不实现集群功能。假设你想使用Memcahce集群需要使用第三方软件或编程来实现自己的设计,这里将被用来memagent实现代理,memagent也被称为magent。我们注意到,,这二者当成两种工具。至于memcache、magent的安装请參考文章   在Linux上安装Memcached服务和 magent编译安装及常见错误      

    总体架构

            直接上图:

    从图中能够看到有两个magent节点,两个memcached节点,每一个magent节点又分别代理两个memcached节点,应用系统端使用magent pool来调用memcache进行存储。

    硬件结构为两台linuxserver。每台server上分别安装magent和memcached服务,并设为开机启动。

    这样做的优点是不论什么一台server宕机后都不影响magent pool获取memcache信息,即实现了memcached的高可用(HA),假设两台机器都宕机了。仅仅能说明你RP太差了。

    当然。也能够用三台、四台或者很多其它server来提高HA。

    測试HA

            測试背景,本地局域网内两台server172.18.117.71(memcacheport11211,magentport11210),172.18.117.113(memcacheport11211,magentport11210),和两台server在同一局域网内的測试机器,下边是測试代码:

    import com.danga.MemCached.MemCachedClient;
    import com.danga.MemCached.SockIOPool;
    
    
    public class MainTest {
    	
    	public static void main(String[] arg){
    		SockIOPool pool = SockIOPool.getInstance();
    		//magent连接池
    		pool.setServers(new String[] { "172.18.117.71:11210","172.18.117.113:11210" });
    		pool.setSocketTO(3000);
    		pool.setNagle(false);
    		pool.setSocketConnectTO(0);
    		pool.initialize();
    		MemCachedClient memCachedClient = new MemCachedClient();
    		memCachedClient.set("becd0000", "測试样例");
    		//System.out.println(memCachedClient.get("becd0000"));
    		//System.out.println(memCachedClient.flushAll());
    	}
    
    }
    

    步骤1:将key为“becd0000”,value为“測试样例”通过magent的pool放到memcache中

    步骤2:改动magent连接池为单个memcache连接,代码例如以下

    import com.danga.MemCached.MemCachedClient;
    import com.danga.MemCached.SockIOPool;
    
    
    public class MainTest {
    	
    	public static void main(String[] arg){
    		SockIOPool pool = SockIOPool.getInstance();
    		//magent连接池
    		pool.setServers(new String[] { "172.18.117.71:11211"});
    		pool.setSocketTO(3000);
    		pool.setNagle(false);
    		pool.setSocketConnectTO(0);
    		pool.initialize();
    		MemCachedClient memCachedClient = new MemCachedClient();
    		//memCachedClient.set("becd0000", "測试样例");
    		System.out.println(memCachedClient.get("becd0000"));
    		//System.out.println(memCachedClient.flushAll());
    	}
    
    }
    

    能够看到单独訪问memcache是能够取到刚才所存储的值的。

    步骤3:改动

    pool.setServers(new String[] { "172.18.117.71:11211"});

    pool.setServers(new String[] { "172.18.117.113:11211"});
    再次运行能够看到和步骤2一样的结果,都能够取到值,说明通过magent代理存的值会分别放到两个memcache中

    步骤4:停止172.18.117.113上的memcached服务

    停止memcached服务命令:kill "cat /tmp/memcached.pid"

    步骤5:再次通过magent代理取值,代码例如以下:

    import com.danga.MemCached.MemCachedClient;
    import com.danga.MemCached.SockIOPool;
    
    
    public class MainTest {
    	
    	public static void main(String[] arg){
    		SockIOPool pool = SockIOPool.getInstance();
    		//magent连接池
    		pool.setServers(new String[] { "172.18.117.71:11210","172.18.117.113:11210" });
    		pool.setSocketTO(3000);
    		pool.setNagle(false);
    		pool.setSocketConnectTO(0);
    		pool.initialize();
    		MemCachedClient memCachedClient = new MemCachedClient();
    		//memCachedClient.set("becd0000", "測试样例");
    		System.out.println(memCachedClient.get("becd0000"));
    		//System.out.println(memCachedClient.flushAll());
    	}
    
    }
    

    可以看到依旧可以取到值。

    步骤6:启动刚才停掉的memcached服务,重新启动后memcache中全部信息将清空

    步骤7:再次通过magent代理池去取key为“becd0000”的值。代码例如以下:

    import com.danga.MemCached.MemCachedClient;
    import com.danga.MemCached.SockIOPool;
    
    
    public class MainTest {
    	
    	public static void main(String[] arg){
    		SockIOPool pool = SockIOPool.getInstance();
    		//magent连接池
    		pool.setServers(new String[] { "172.18.117.71:11210","172.18.117.113:11210" });
    		pool.setSocketTO(3000);
    		pool.setNagle(false);
    		pool.setSocketConnectTO(0);
    		pool.initialize();
    		MemCachedClient memCachedClient = new MemCachedClient();
    		//memCachedClient.set("becd0000", "測试样例");
    		System.out.println(memCachedClient.get("becd0000"));
    		//System.out.println(memCachedClient.flushAll());
    	}
    
    }
    

    能够看到这里取到的值为null。

    结果分析

            通过以上測试能够得出结论

    1、通过magent的连接池放的值会分别存在magent代理的全部memcached上去

    2、假设有一个memcached宕机通过magent代理方式还能取到值

    3、假设memcached修复重新启动后通过magent代理方式取到的值就会为Null,这是由于memcache重新启动后里边的值随着memcache服务的停止就消失了(由于在内存中)。可是magent是通过key进行哈希计算分配到某台机器上的。memcache重新启动后会还从这台机器上取值,全部取到的值就没空。

            解决的方法

    1、在每次memcache宕机修复后能够写一个程序把集群中的其它memcache的全部信息全给复制到当前宕机修复后的memcache中。

    2、自己写代理。当从一个memcached服务上取到的值为null时再去其它memcached上取值


    注意事项

            magent的调用方式同memcached一样。client能够不用改代码就可以实现切换到magent模式下


    版权全部分,转载请注明、资源。



    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    Jenkins的插件管理(安装和更新插件)
    [Flutter] MacOS/Windows Flutter 环境走一遍
    [Sw] 使用 Swoole Server task/协程 处理大数据量异步任务时注意
    [Sw] Swoole-4.2.9 可以尝试愉快应用 Swoole 协程
    [PHP] 常备的现代 PHP 项目开发准备
    [SF] Symfony 标准 HttpFoundationRequest 实现分析
    [Linux] umask 从三类人群的权限中拿走权限数字
    [Design] 后端程序的高并发与异步
    [Linux]系统管理: 进程管理(ps/top/pstree/kill/pkill), 工作管理, 系统资源查看, 系统定时任务
    [FE] 有效开展一个前端项目-V2 (vuejs-templates/webpack)
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4680866.html
Copyright © 2011-2022 走看看