zoukankan      html  css  js  c++  java
  • 【Memcached】原理、体系架构、基本操作及路由算法

    1. 什么是Memcached

        要了解Memcached首先要到官网上去看官方对它的描述。Memcached的官网网站是:http://memcached.org/,官方对Memcached的描述如下图:

        从官方的描述中可以总结出,Memcached是一个高性能分布式的内存对象缓存系统。它将数据以key-value形式存储的存储在内存中,极大的提高了效率。但是Memcached的缺点在于不支持持久化(不支持写入磁盘),所以一旦断电,内存中的全部数据都会丢失。而Redis弥补了这个缺点,既在内存中存取数据,又支持持久化,所以Memcached可以理解为是Redis的前身,关于Redis的技术,后续会发新的文章论述,这里不展开讨论。

    2. Memcached基本原理和体系架构

        实际上,Memcached是在内存中维护一张巨大的Hash表。这张Hash表的结构是由多个slab组成,每个slab的大小是1M;每个slab中存在多个chunk,chunk是数据最终存储的单位。chunk采用预分配的方式提高性能,在保存数据之前,需要制定chunk的大小来分配内存。如add key *** 3



    3. Memcached 集群

     3.1 背景

        Memcached官方版本不支持集群搭建Memcached彼此之间不进行通信,也就是把一个数据存到一个Memcached上,一旦这个Memcached宕掉了,不能从其它Memcached上读取这些数据,会造成数据丢失。

        但是,一个日本工程师改写了官方Memcached,使它能够支持集群此时,Memcached之间可以进行通信,数据存储到一个Memcached实例上,可以同步到其它Memcached实例,防止数据丢失。

     

    3.2 基本操作

     3.2.1 命令行
     
    (1) 启动并连接memcached

        

    (2) 添加数据:set、add(当存在相同key值时,set会覆盖value,add会报错);获取数据:get

        

    (2) 查看slab信息
        
     3.2.2 JavaAPI

        1. 首先创建一个Java项目,然后添加memcached的jar包,如果网上找不到jar包的话可以在这个链接下载:https://download.csdn.net/download/xin93/10482424

           2. 创建一个简单的Person信息类,用于存储到Memcached。

    package com.nova;
    
    import java.io.Serializable;
    /**
     * 
     * @author Supernova
     * @date 2018/06/16
     * 
     */
    public class Person implements Serializable{
        private String name;    //姓名
        private String sex;        //性别
        
        public Person() {
            
        }
        public Person(String name, String sex) {
            super();
            this.name = name;
            this.sex = sex;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getSex() {
            return sex;
        }
        public void setSex(String sex) {
            this.sex = sex;
        }
        
    }

            3. 添加、获取

    package com.nova;
    
    import java.net.InetSocketAddress;
    import java.util.concurrent.Future;
    
    import org.junit.Test;
    
    import net.spy.memcached.MemcachedClient;
    /**
     * 
     * @author Supernova
     * @date 2018/06/16
     *
     */
    public class MemcachedOperation {
        /*
         * 向memcached添加数据
         */
        @Test
        public void addData() throws Exception {
            // 创建Memcached客户端
            MemcachedClient client = new MemcachedClient(new InetSocketAddress("192.168.243.11", 11211));
            // 插入数据
            Future<Boolean> future= client.set("name", 0, "Supernova");
            //判断执行操作后返回的Boolean值
            if(future.get().booleanValue()) {
                //插入成功
                
                client.shutdown();
            }
        }
    
        /*
         * 获取memcached数据
         */
        @Test
        public void getData() throws Exception{
            // 创建Memcached客户端
            MemcachedClient client = new MemcachedClient(new InetSocketAddress("192.168.243.11",11211));
            // 获取对应key值的value
            String name = client.get("name").toString();
            System.out.println(name);
        }
        /*
         * 向memcached存储一个对象
         */
        @Test
        public void insertObject() throws Exception{
            // 创建Memcached客户端
            MemcachedClient client = new MemcachedClient(new InetSocketAddress("192.168.243.11",11211));
    
            Person person = new Person("Supernova","man");
            // 插入对象
            Future<Boolean> future = client.set("person", 0, person);
            
            if(future.get().booleanValue()) {
                //插入成功
                
                client.shutdown();
            }
        }
    
    }

    3.2 路由算法

        既然Memcached实例可以有多个,那么当客户端发送一条数据的时候,这条数据要存储到哪个Memcached实例中?所以这就涉及到了Memcached路由算法,由它来决定数据最终存储在哪个Memcached上。注意:Memcached路由算法是由客户端实现的。在Memcached中有两种路由算法

     3.2.1 求余数

         【基本原理】将key做hash运算,对memcached数量进行求余数,根据余数来决定存储到哪个Memcached实例。

        如:有 4 台Memached,将对4进行求余数

            8%4 = 0

            7%4 = 3

            6%4 = 2

            5%4 = 1

            ……

          这样根据余数路由的优点在于,能够使数据均匀分布在每个Memcached上,但是也有很大的缺点,一旦某个Memcached宕机,或有新的memcached加入就会找不到数据,出现严重的数据丢失

        【数据丢失的原因】:

              比如原先有3个Memcached:1%3=1, 2%3=2, 3%3=0, 4%3=1,……

              新增之后为4个Memcached:1%4=1, 2%4=2, 3%4=2, 4%4=0,……

               原先3存在0号,4存在1号,但是新增后,3变成2号,4变成0号。导致了存取的目标位置不一样,在0号存,去2号取就会找不到数据。

    3.2.2 一致性Hash

        一致性hash能够将丢失的数据减小到最小,但不能完全解决宕机造成的数据丢失。

        【基本原理】:

        如下图所示,数据分段在Memcached上存储,当扩容的时候,1~6666的数据将不受影响。同理,当有机器宕机的时候也一样。

            

  • 相关阅读:
    Server.UrlEncode UrlDecode 动态绑定gridview列发送接收乱码的问题
    gridview新用法,一直不知道gridview可以这么用
    vm workstation15 迁移至ESXi6.7步骤
    http 502与504的区别
    Asp.net项目部署ActiveReport
    不能在 Page 回调中调用 Response.Redirect 解决方法
    JQuery TextExt 控件使用
    通过ashx获取JSON数据的两种方式
    jQuery Mobile对话框插件
    替换文本框title提示文本
  • 原文地址:https://www.cnblogs.com/snova/p/9195688.html
Copyright © 2011-2022 走看看