Memcached 实战
                 gu043695
                 10年前
            
                    来自: http://blog.csdn.net/wenniuwuren/article/details/50826656
零. 简介 
  Memcached 是一款开源、 分布式内存对象缓存系统, 用于加快动态网站响应, 降低数据库负载 
  Memcached 使用简单, 支持多种语言的 API, 解决面对大量数据的缓存问题 
  一. 设计哲学 
  (1) 键值对存储 
  服务器不关心数据是什么样的。 存储单元由 key、 过期时间、 可选的标记和数据组成。 它不懂数据结构, 传输数据前需要序列化。 
  (2)一半逻辑在客户端, 另一半逻辑在服务端 
  客户端知道如何选择(哈希)哪个服务端去读/写存储单元, 并且知道如何处理无法连到服务端的情况 
  服务端知道如何存储和获取数据单元, 并且它知道如何清除或者重用内存。 
  (3)服务端彼此之间不通信 
  即服务端之间没有同步、 没有多播、 没有复制。 增加服务器就是增加可用内存。 但是正因为这个特性, Memcached 存在单点故障, 如果需要做高可用, 需要使用 Magent 这样的代理服务软件去实现高可用。 
  (4)时间复杂度 O(1) 
  所有的命令都被尽量实现为快速和对锁友好,提供了近乎确定的查询速度。 在慢的机器上查询时间低于 1ms, 在高端服务器上可以达到百万/s 的吞吐量 
  (5)遗忘是一种特性 
      </div>  
    
    
    
    
    
      
-f 1.25 增长因子,默认1.25    
    
    
      
    
      
    
  
  
    
    
    
                
                
            
        
      
       
    
    
    
    
    
    
 
    
    
    
    
    
    
    
    
    
删除item对象时,不释放内存,作删除标记,指针方式 slot 回收插槽,下次分配的时候直接使用; 
  (6)缓存无效 
  客户端通过 hash 直接告诉服务端缓存数据无效, 而不是多播让所有服务器的该 item 缓存无效 
  二. Memcached 实战 
  (1) 安装 memcached 很简单, 如果是 CentOS 或者 Red Hat 直接
yum install memcached
如果是 Ubuntu/Debian 则使用 apt-get 
  (2) 检查 Memcached 是否安装成功:可以查看到帮助信息说明安装成功  
  memcached -h
(3) 启动 Memcached (假设 138.138.138.11 是你的外网 ip, 在 CentOS7 上设置 11211 默认端口访问不了, 查看也没被占用, 很奇怪, 所以下面监听 11222 端口)  
    memcached -d -u root -l 138.138.138.11 -p 11222 -vv
-d   以守护程序(daemon)方式运行 
  -u root  指定用户,如果当前为 root ,需要此参数指定用户 
  -P /tmp/a.pid 保存PID到指定文件 
  </div>  -m 默认 64,不包含memcached本身占用,单位为 MB 
  -M   内存不够时禁止 LRU 
  -n 48  初始 chunk=key+suffix+value+32 结构体,默认 48 字节 -f 1.25 增长因子,默认1.25
-L  启用大内存页,可以降低内存浪费,改进性能 
  </div>  -l  监听的 IP 地址, 服务器有两个网卡一个对内一个对外, 如果设置为 127.0.0.1 则只能本地访问 memcached, 设置外网 ip 则可以接受外来的访问 
  -p 11211  TCP端口,默认为11211 
  -U 11211 UDP端口,默认为11211,0为关闭 
  </div>  -c 1024 最大并发连接数,默认1024,最好是200 
  -t 4  线程数,默认4 
  -R 20  每个event连接最大并发数,默认20 -C  禁用CAS命令(可以禁止版本计数,减少开销) 
  -vv 打印交互式详细信息, 可以看到连接进来的人正在做什么操作 
  (4) 检查 Memcached 是否成功启动: 
  </div>  ps -ef | grep memcached
(5) 远程连接 Memcached: 连接成功显示 Connected to 138.138.138.11. Escape character is '^]'.  
  telnet 138.138.138.11 11222
(6) 连接成功后输入  stats 可以查看服务整体状态 
  STAT pid 5013                                            memcache服务器的进程ID 
  STAT uptime 3524589                                服务器已经运行的秒数 
  STAT time 1453720323                              服务器当前的unix时间戳 
  STAT version 1.4.17                                   memcache版本 
  STAT libevent 2.0.16-stable                        
  STAT pointer_size 64                                 当前操作系统的指针大小(32位系统一般是32bit) 
  STAT usage_user 20513.015760               进程的累计用户时间 
  STAT rusage_system 45473.527888         进程的累计系统时间 
  STAT cur_connections 102                          当前打开着的连接数 
  STAT total_connections 60437                  从服务器启动以后曾经打开过的连接数 
  STAT connection_structures 243               服务器分配的连接构造数 
  STAT reserved_fds 20                                 
  STAT cmd_get 474507075                         get命令(获取)总请求次数 
  STAT cmd_set 334776915                         set命令(保存)总请求次数 
  STAT cmd_flush 97 
  STAT cmd_touch 0 
  STAT get_hits 301883351                          总命中次数 
  STAT get_misses 172623724                     总未命中次数 
  STAT delete_misses 208322                      
  STAT delete_hits 35095518 
  STAT incr_misses 0 
  STAT incr_hits 0 
  STAT decr_misses 0 
  STAT decr_hits 0 
  STAT cas_misses 0 
  STAT cas_hits 0 
  STAT cas_badval 0 
  STAT touch_hits 0 
  STAT touch_misses 0 
  STAT auth_cmds 0 
  STAT auth_errors 0 
  STAT bytes_read 268709016022            总读取字节数(请求字节数)  
  STAT bytes_written 754717253318        总发送字节数(结果字节数)  
  STAT limit_maxbytes 536870912            分配给memcache的内存大小(字节) 
  STAT accepting_conns 1 
  STAT listen_disabled_num 0 
  STAT threads 4                                        当前线程数 
  STAT conn_yields 17561 
  STAT hash_power_level 18 
  STAT hash_bytes 2097152 
  STAT hash_is_expanding 0 
  STAT malloc_fails 0 
  STAT bytes 473920740                            当前服务器存储items占用的字节数 
  STAT curr_items 265877                          服务器当前存储的items数量 
  STAT total_items 239409267                   从服务器启动以后存储的items总数量 
  STAT expired_unfetched 49973876 
  STAT evicted_unfetched 23514857 
  STAT evictions 27383392                        为获取空闲内存而删除的items数(分配给memcache的空间用满后需要删除旧的items来得到空间分配给新的items) 
  </div>  STAT reclaimed 52732799 
  三. 客户端的选择 
  客户端有三种选择: spymemcached、 java-memcached、 xmemcached 
  具体看  https://xmemcached.googlecode.com/svn/trunk/benchmark/benchmark.html 有性能对比图, 当然因为是 xmemcached 自己的性能测试报告, 不一定和每个人使用的时候场景一样, 具体可以自己测试后再作出选择。 
  </div>  引入 xmemcached-1.3.6.jar 的包 
  测试代码如下:  
  package com.wenniuwuren.memcached;    import net.rubyeye.xmemcached.MemcachedClient;  import net.rubyeye.xmemcached.XMemcachedClientBuilder;  import net.rubyeye.xmemcached.utils.AddrUtil;    import java.util.HashMap;  import java.util.Map;    /**   * Created by wenniuwuren on 16/3/6.   */  public class MemcachedTest {        public static void main(String[] args) {            try {              //New a XMemcachedClient instance              XMemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses("138.138.138.11:11222"));              MemcachedClient client = builder.build();              Map map = new HashMap<>();              map.put("1", "2");              client.set("key", 3000, map);                Map cachedMap = (Map)client.get("key");              System.out.println(cachedMap.get("1"));            } catch (Exception e) {              e.printStackTrace();          }      }  }四. Memcached 集群 
  因为 Memcached 设计哲学的极简, 所以集群不熟非常简单, 服务端新启动一个 Memcached 进程就行。 其他的交给客户端完成。 如果客户端使用普通的 Hash 算法,则新增 Memcached 会重新计算 Hash 值使旧的缓存失效。 如果客户端使用一致性 Hash 算法, 则不会影响旧的缓存数据。 
  新加个端口为 11333 的 Memcached 进程, 可以看到两个 Memcached 存储内容不同, 证明上述 Memcached 服务间不互相通信。 
  五. Memcached 局限性 
  (1)存储格式单一, 就是 <String, Object>, 想使用复杂点的数据结构(list、 set、 hash)一般会选用 Redis 
  (2)最大只能存储 1M 的 item, 而 
  (3)最大键长 250 字节  
  (4)只存在缓存, 数据重启丢失,而 Redis 支持持久化(但是也经常会丢数据), 并在此基础上实现主从同步, 而 Memcached 存在单点故障  
  (5) 数据一致性问题: Memcached 使用 CAS 保证。 而 Redis 使用事务, 保证一系列命令的原子性。