Memcached 实战

零. 简介
Memcached 是一款开源、 分布式内存对象缓存系统, 用于加快动态网站响应, 降低数据库负载

Memcached 使用简单, 支持多种语言的 API, 解决面对大量数据的缓存问题


一. 设计哲学
(1) 键值对存储
服务器不关心数据是什么样的。 存储单元由 key、 过期时间、 可选的标记和数据组成。 它不懂数据结构, 传输数据前需要序列化。

(2)一半逻辑在客户端, 另一半逻辑在服务端
客户端知道如何选择(哈希)哪个服务端去读/写存储单元, 并且知道如何处理无法连到服务端的情况
服务端知道如何存储和获取数据单元, 并且它知道如何清除或者重用内存。

(3)服务端彼此之间不通信
即服务端之间没有同步、 没有多播、 没有复制。 增加服务器就是增加可用内存。 但是正因为这个特性, Memcached 存在单点故障, 如果需要做高可用, 需要使用 Magent 这样的代理服务软件去实现高可用。

(4)时间复杂度 O(1)
所有的命令都被尽量实现为快速和对锁友好,提供了近乎确定的查询速度。 在慢的机器上查询时间低于 1ms, 在高端服务器上可以达到百万/s 的吞吐量

(5)遗忘是一种特性
Lazy Expiration + LRU :不检测 item 对象是否超时,get 时检查 item 对象是否应该删除;
删除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到指定文件
-m 默认 64,不包含memcached本身占用,单位为 MB
-M   内存不够时禁止 LRU
-n 48  初始 chunk=key+suffix+value+32 结构体,默认 48 字节
-f 1.25  增长因子,默认1.25
-L  启用大内存页,可以降低内存浪费,改进性能
-l  监听的 IP 地址, 服务器有两个网卡一个对内一个对外, 如果设置为 127.0.0.1 则只能本地访问 memcached, 设置外网 ip 则可以接受外来的访问
-p 11211  TCP端口,默认为11211
-U 11211 UDP端口,默认为11211,0为关闭
-c 1024 最大并发连接数,默认1024,最好是200
-t 4  线程数,默认4
-R 20  每个event连接最大并发数,默认20
-C  禁用CAS命令(可以禁止版本计数,减少开销)
-vv 打印交互式详细信息, 可以看到连接进来的人正在做什么操作

(4) 检查 Memcached 是否成功启动:
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)
STAT reclaimed 52732799


三. 客户端的选择
客户端有三种选择: spymemcached、 java-memcached、 xmemcached
具体看  https://xmemcached.googlecode.com/svn/trunk/benchmark/benchmark.html 有性能对比图, 当然因为是 xmemcached 自己的性能测试报告, 不一定和每个人使用的时候场景一样, 具体可以自己测试后再作出选择。

引入 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 使用事务, 保证一系列命令的原子性。
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要查询Memcached中的所有key,可以使用`stats items`命令。这个命令将返回所有存储在Memcached中的item的统计信息,包括key和其他有用的信息。 具体步骤如下: 1. 连接到Memcached服务器。可以使用telnet或nc等工具,也可以使用Memcached客户端库连接。 2. 发送`stats items`命令。 3. 服务器会返回一些统计信息,其中包括`STAT items`和`STAT keys`。`STAT items`表示存储在Memcached中的所有item的数量,`STAT keys`表示所有key的数量。 4. 可以解析返回的信息,提取出所有的key。 下面是一个使用telnet查询所有key的示例: ```shell $ telnet localhost 11211 stats items STAT items:1:number 1 STAT items:1:age 120 STAT items:1:evicted 0 STAT items:1:evicted_nonzero 0 STAT items:1:evicted_time 0 STAT items:1:outofmemory 0 STAT items:1:tailrepairs 0 STAT items:1:reclaimed 0 STAT items:2:number 1 STAT items:2:age 120 STAT items:2:evicted 0 STAT items:2:evicted_nonzero 0 STAT items:2:evicted_time 0 STAT items:2:outofmemory 0 STAT items:2:tailrepairs 0 STAT items:2:reclaimed 0 STAT items:3:number 2 STAT items:3:age 120 STAT items:3:evicted 0 STAT items:3:evicted_nonzero 0 STAT items:3:evicted_time 0 STAT items:3:outofmemory 0 STAT items:3:tailrepairs 0 STAT items:3:reclaimed 0 STAT items:4:number 2 STAT items:4:age 120 STAT items:4:evicted 0 STAT items:4:evicted_nonzero 0 STAT items:4:evicted_time 0 STAT items:4:outofmemory 0 STAT items:4:tailrepairs 0 STAT items:4:reclaimed 0 END ``` 在这个例子中,Memcached中存储了4个item,它们的key分别为1、2、3和4。注意,这里的key并不是我们使用set命令时指定的那个字符串,而是Memcached内部生成的一个数字。但是这个数字也可以用来唯一地标识一个item。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值