`

Memcached服务器安装、配置、使用详解

 
阅读更多
原文地址:http://shiyanjun.cn/archives/873.html



我使用的是CentOS 6.4系统,安装的Memcached版本为1.4.20。这里,记录一下安装配置的过程,以及如何使用一些常用的客户端来访问Memcached存储的数据。

安装配置

首先,编译、安装、配置libevent库,执行如下命令:

1
wget https://github.com/downloads/libevent/libevent/libevent-1.4.14b-stable.tar.gz
2
tar xvzf libevent-1.4.14b-stable.tar.gz
3
ln -s /usr/local/libevent-1.4.14b-stable /usr/local/libevent
4
cd /usr/local/libevent
5
./configure
6
make
7
make install
然后,编译、安装、配置Memcached,执行如下命令行:

1
wget http://www.memcached.org/files/memcached-1.4.20.tar.gz
2
tar xvzf memcached-1.4.20.tar.gz
3
ln -s /usr/local/memcached-1.4.20 /usr/local/memcached
4
./configure --with-libevent=/usr/local/libevent/
5
make
6
make install
如果没有出错,安装成功。

管理memcached服务

启动Memcached
一般情况下,简单地可以使用类似如下形式,启动Memcached服务:

1
/usr/local/bin/memcached -d -m 64 -I 20m -u root -l 192.168.4.86 -p 11211 -c 1024 -P /usr/local/memcached/memcached.pid
上述命令行中,基于上面各个选项,以及其他一些选项的含义,说明如下表所示:

选项 含义说明
-d 指定memcached进程作为一个守护进程启动
-m <num> 指定分配给memcached使用的内存,单位是MB
-u <username> 运行memcached的用户
-l <ip_addr> 监听的服务器IP地址,如果有多个地址的话,使用逗号分隔,格式可以为“IP地址:端口号”,例如:-l 指定192.168.0.184:19830,192.168.0.195:13542;端口号也可以通过-p选项指定
-p <num> Memcached监听的端口,要保证该端口号未被占用
-c <num> 设置最大运行的并发连接数,默认是1024
-R <num> 为避免客户端饿死(starvation),对连续达到的客户端请求数设置一个限额,如果超过该设置,会选择另一个连接来处理请求,默认为20
-k 设置锁定所有分页的内存,对于大缓存应用场景,谨慎使用该选项
-P 保存memcached进程的pid文件
-s <file> 指定Memcached用于监听的UNIX socket文件
-a <perms> 设置-s选项指定的UNIX socket文件的权限
-U <num> 指定监听UDP的端口,默认11211,0表示关闭
-M 当内存使用超出配置值时,禁止自动清除缓存中的数据项,此时Memcached不可以,直到内存被释放
-r 设置产生core文件大小
-f <factor> 用于计算缓存数据项的内存块大小的乘数因子,默认是1.25
-n 为缓存数据项的key、value、flag设置最小分配字节数,默认是48
-C 禁用CAS
-h 显示Memcached版本和摘要信息
-v 输出警告和错误信息
-vv 打印信息比-v更详细:不仅输出警告和错误信息,也输出客户端请求和响应信息
-i 打印libevent和Memcached的licenses信息
-t <threads> 指定用来处理请求的线程数,默认为4
-D <char> 用于统计报告中Key前缀和ID之间的分隔符,默认是冒号“:”
-L 尝试使用大内存分页(pages)
-B <proto> 指定使用的协议,默认行为是自动协商(autonegotiate),可能使用的选项有auto、ascii、binary。
-I <size> 覆盖默认的STAB页大小,默认是1M
-F 禁用flush_all命令
-o <options> 指定逗号分隔的选项,一般用于用于扩展或实验性质的选项
停止Memcached
可以通过Linux的如下命令查询到Memcached的进程号:

1
ps -ef | grep memcached
然后杀掉Memcached服务进程:

1
kill -9 <PID>
-9表示强制杀掉进程。

Memcached启动以后,可以通过客户端来操作缓存中的数据,我们说明一些常用的客户端,及其使用方法。

Telnet客户端

Telnet客户端可以通过命令行的方式来监控查看Memcached服务器存储数据的情况。例如,Memcached的服务地址为192.168.4.86:11211,可以telnet到该服务端口:

1
telnet 192.168.4.86 11211
如果连接成功,可以使用如下一些命令:

stats命令
该命令用于显示服务器信息、统计数据等,结果示例数据(来自www.2cto.com网站),例如:

01
STAT pid 22362    //memcache服务器的进程ID  www.2cto.com
02
STAT uptime 1469315    //服务器已经运行的秒数
03
STAT time 1339671194    //服务器当前的unix时间戳
04
STAT version 1.4.9    //memcache版本
05
STAT libevent 1.4.9-stable    //libevent版本
06
STAT pointer_size 64    //当前操作系统的指针大小(32位系统一般是32bit,64就是64位操作系统)
07
STAT rusage_user 3695.485200    //进程的累计用户时间
08
STAT rusage_system 14751.273465    //进程的累计系统时间
09
STAT curr_connections 69    //服务器当前存储的items数量
10
STAT total_connections 855430    //从服务器启动以后存储的items总数量
11
STAT connection_structures 74    //服务器分配的连接构造数
12
STAT reserved_fds 20    //
13
STAT cmd_get 328806688    //get命令(获取)总请求次数
14
STAT cmd_set 75441133    //set命令(保存)总请求次数  www.2cto.com
15
STAT cmd_flush 34    //flush命令请求次数
16
STAT cmd_touch 0    //touch命令请求次数
17
STAT get_hits 253547177    //总命中次数
18
STAT get_misses 75259511    //总未命中次数
19
STAT delete_misses 4    //delete命令未命中次数
20
STAT delete_hits 565730    //delete命令命中次数
21
STAT incr_misses 0    //incr命令未命中次数
22
STAT incr_hits 0    //incr命令命中次数
23
STAT decr_misses 0    //decr命令未命中次数
24
STAT decr_hits 0    //decr命令命中次数
25
STAT cas_misses 0    //cas命令未命中次数
26
STAT cas_hits 0        //cas命令命中次数
27
STAT cas_badval 0    //使用擦拭次数
28
STAT touch_hits 0    //touch命令未命中次数
29
STAT touch_misses 0    //touch命令命中次数
30
STAT auth_cmds 0    //认证命令处理的次数
31
STAT auth_errors 0    //认证失败数目
32
STAT bytes_read 545701515844        //总读取字节数(请求字节数)
33
STAT bytes_written 1649639749866    //总发送字节数(结果字节数)
34
STAT limit_maxbytes 2147483648        //分配给memcache的内存大小(字节)
35
STAT accepting_conns 1            //服务器是否达到过最大连接(0/1)
36
STAT listen_disabled_num 0    //失效的监听数
37
STAT threads 4        //当前线程数
38
STAT conn_yields 14    //连接操作主动放弃数目
39
STAT hash_power_level 16    //
40
STAT hash_bytes 524288
41
STAT hash_is_expanding 0
42
STAT expired_unfetched 30705763
43
STAT evicted_unfetched 0
44
STAT bytes 61380700    //当前存储占用的字节数
45
STAT curr_items 28786    //当前存储的数据总数
46
STAT total_items 75441133    //启动以来存储的数据总数
47
STAT evictions 0    //为获取空闲内存而删除的items数(分配给memcache的空间用满后需要删除旧的items来得到空间分配给新的items)
48
STAT reclaimed 39957976    //已过期的数据条目来存储新数据的数目
49
END
上面给出了各个统计项的含义说明,不再累述。
stats命令有几个二级子项,说明如下表所示:

命令 含义说明
stats slabs 显示各个slab的信息,包括chunk的大小、数目、使用情况等
stats items 显示各个slab中item的数目和最老item的年龄(最后一次访问距离现在的秒数)
stats detail [on|off|dump] 设置或者显示详细操作记录;
参数为on,打开详细操作记录;
参数为off,关闭详细操作记录;
参数为dump,显示详细操作记录(每一个键值get、set、hit、del的次数)
stats malloc 打印内存分配信息
stats sizes 打印缓存使用信息
stats reset 重置统计信息
下面的命令,我们通过表格的形式说明,如下表所示:

命令 用法格式 含义说明 示例
get get <key>*\r\n 用于获取缓存的数据,键为key。 get name
VALUE name 0 7
shirdrn
END
gets gets <key>*\r\n 用于获取缓存的数据,键为一组key。 gets name hobby
VALUE name 1 7
1234567
VALUE hobby 0 25
tenis basketball football
END
set set <key> <flags> <exptime> <bytes> [noreply]\r\n<value>\r\n 向缓存中存储数据,不管key对应的值存在与否,都设置key对应的值。 set name 0 1800 7
shirdrn
STORED
get name
VALUE name 0 7
shirdrn
END
touch touch <key> <exptime> [noreply]\r\n 更新缓存中key对应的值的过期时间。 touch name 1800
delete delete <key> [<time>] [noreply]\r\n 给定键key,删除缓存中key对应的数据。 delete name 60
add add <key> <flags> <exptime> <bytes> [noreply]\r\n<value>\r\n 向缓存中存储数据,只有key对应的值不存在时,才会设置key对应的值。 add hobby 0 1800 10
basketball
STORED
get hobby
VALUE hobby 0 10
basketball
END
replace replace <key> <flags> <exptime> <bytes> [noreply]\r\n<value>\r\n 覆盖一个已经存在Key及其对应的Value,替换一定要保证替换后的值的长度原始长度相同,否则replace失败。 get name
VALUE name 0 7
shirdrn
END
replace name 0 1800 7
youak47
STORED
get name
VALUE name 0 7
youak47
END
append append <key> <flags> <exptime> <bytes> [noreply]\r\n<value>\r\n 在一个已经存在的数据值(value)上追加,是在数据值的后面追加。 get hobby
VALUE hobby 0 10
basketball
END
append hobby 0 1800 9
football
STORED
get hobby
VALUE hobby 0 19
basketball football
END
prepend prepend <key> <flags> <exptime> <bytes> [noreply]\r\n<value>\r\n 在一个已经存在的数据值(value)上追加,是在数据值的前面追加。 get hobby
VALUE hobby 0 19
basketball football
END
prepend hobby 0 1800 6
tenis
STORED
get hobby
VALUE hobby 0 25
tenis basketball football
END
incr incr <key> <value> [noreply]\r\n 计数命令,可以在原来已经存在的数字上进行累加求和,计算并存储新的数值。 set active_users 0 1000000 7
1000000
STORED
get active_users
VALUE active_users 0 7
1000000
END
incr active_users 99
1000099
decr decr <key> <value> [noreply]\r\n 计数命令,可以在原来已经存在的数字上进行减法计算,计算并存储新的数值。 get active_users
VALUE active_users 0 7
1000099
END
decr active_users 3456
996643
flush_all flush_all [<time>] [noreply]\r\n 使缓存中的数据项失效,可选参数是在多少秒后失效。 flush_all 1800
version version\r\n 返回Memcached服务器的版本信息。 version
quit quit\r\n 退出telnet终端。 quit
Java客户端

可以使用Java语言编写代码来访问Memcached缓存。目前,可以使用的Java客户端很多,这里简单介绍几个。

spymemcached客户端
示例代码,如下所示:

01
package org.shirdrn.spymemcached;
02

03
import net.spy.memcached.AddrUtil;
04
import net.spy.memcached.BinaryConnectionFactory;
05
import net.spy.memcached.MemcachedClient;
06
import net.spy.memcached.internal.OperationFuture;
07

08
public class TestSpymemcached {
09

10
     public static void main(String[] args) throws Exception {
11
          String address = "192.168.4.86:11211";
12
          MemcachedClient client = new MemcachedClient(new BinaryConnectionFactory(),
13
                    AddrUtil.getAddresses(address));
14
         
15
          String key = "magic_words";
16
          int exp = 3600;
17
          String o = "hello";
18
          // set
19
          OperationFuture<Boolean> setFuture = client.set(key, exp, o);
20
          if(setFuture.get()) {
21
               // get
22
               System.out.println(client.get(key));
23
              
24
               // append
25
               client.append(key, " the world!");
26
               System.out.println(client.get(key));
27
              
28
               // prepend
29
               client.prepend(key, "Stone, ");
30
               System.out.println(client.get(key));
31
              
32
               // replace
33
               o = "This is a test for spymemcached.";
34
               OperationFuture<Boolean> replaceFuture = client.replace(key, exp, o);
35
               if(replaceFuture.get()) {
36
                    System.out.println(client.get(key));
37
                   
38
                    // delete
39
                    client.delete(key);
40
                    System.out.println(client.get(key));
41
               }
42
          }
43
         
44
          client.shutdown();
45
     }
46

47
}
更多用法,可以参考后面的链接。

XMemcached客户端
示例代码,如下所示:

001
package org.shirdrn.xmemcached;
002

003
import java.io.File;
004
import java.io.IOException;
005
import java.io.Serializable;
006
import java.net.InetSocketAddress;
007
import java.util.Arrays;
008
import java.util.List;
009
import java.util.Map;
010
import java.util.concurrent.ExecutorService;
011
import java.util.concurrent.Executors;
012
import java.util.concurrent.TimeoutException;
013
import java.util.concurrent.atomic.AtomicLong;
014

015
import net.rubyeye.xmemcached.CASOperation;
016
import net.rubyeye.xmemcached.GetsResponse;
017
import net.rubyeye.xmemcached.MemcachedClient;
018
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
019
import net.rubyeye.xmemcached.command.BinaryCommandFactory;
020
import net.rubyeye.xmemcached.exception.MemcachedException;
021
import net.rubyeye.xmemcached.utils.AddrUtil;
022

023
public class UsingXMemcachedClient {
024

025
     public static void main(String[] args) throws IOException {
026
          String servers = "192.168.4.86:11211";
027
          // build and create a client
028
          XMemcachedClientBuilder builder = new XMemcachedClientBuilder(
029
                    AddrUtil.getAddresses(servers));
030
          builder.setCommandFactory(new BinaryCommandFactory());
031
          final MemcachedClient client = builder.build();
032
         
033
          // examples using client to operate
034
          final String key = "ghost";
035
          try {
036
               // add
037
               client.add(key, 0, "Ghost wind blows!");
038
               System.out.println("add & get: " + client.get(key));
039
              
040
               // append
041
               client.append(key, " It's a lie.");
042
               System.out.println("append & get: " + client.get(key));
043
              
044
               // prepend
045
               client.prepend(key, "Who's said?! ");
046
               System.out.println("prepend & get: " + client.get(key));
047
              
048
               // replace
049
               client.replace(key, 0, "Everything is nothing!");
050
               System.out.println("replace & get: " + client.get(key));
051
              
052
               // delete
053
               client.delete(key);
054
               System.out.println("delete & get: " + client.get(key));
055
              
056
               // gets
057
               List<String> keys = Arrays.asList(new String[] {
058
                         "key1", "key2", "key3"
059
               });
060
               for(String k : keys) {
061
                    client.set(k, 3600, "v:" + System.nanoTime());
062
               }
063
               Map<String, GetsResponse<Object>> values = client.gets(keys);
064
               for(Map.Entry<String, GetsResponse<Object>> entry : values.entrySet()) {
065
                    System.out.println("key=" + entry.getKey() + ", value=" + entry.getValue().getValue());
066
               }
067
              
068
               // cas
069
               final AtomicLong seq = new AtomicLong(System.nanoTime());
070
               ExecutorService pool = Executors.newCachedThreadPool();
071
               for(int i=0; i<10; i++) {
072
                    pool.execute(new Runnable() {
073
                         @Override
074
                         public void run() {
075
                              while(true) {
076
                                   CacheResult o = new CacheResult();
077
                                   o.file = new File("/opt/status/servers.lst");
078
                                   o.lastmodified = seq.incrementAndGet();
079
                                   System.out.println("#" + Thread.currentThread().getId() + "=>o: " + o);
080
                                   try {
081
                                        client.set(key, 0, o);
082
                                        Thread.sleep(100);
083
                                   } catch (TimeoutException e) {
084
                                        // TODO Auto-generated catch block
085
                                        e.printStackTrace();
086
                                   } catch (InterruptedException e) {
087
                                        // TODO Auto-generated catch block
088
                                        e.printStackTrace();
089
                                   } catch (MemcachedException e) {
090
                                        // TODO Auto-generated catch block
091
                                        e.printStackTrace();
092
                                   }
093
                              }
094
                         }
095
                    });
096
               }
097
               Thread.sleep(3000);
098
               for(int i=0; i<10; i++) {
099
                    client.cas(key, new CASOperation<CacheResult>() {
100
                         @Override
101
                         public int getMaxTries() {
102
                              return 3;
103
                         }
104
                         @Override
105
                         public CacheResult getNewValue(long arg0, CacheResult result) {
106
                              CacheResult old = result;
107
                              CacheResult nu = new CacheResult();
108
                              nu.file = old.file;
109
                              nu.lastmodified = seq.incrementAndGet();
110
                              System.out.println("cas: old=" + old + ", new=" + nu);
111
                              return result;
112
                         }
113
                    });
114
               }
115
               pool.shutdown();
116
              
117
               // flush_all
118
              client.flushAll();
119
              
120
               // stats
121
               List<InetSocketAddress> addresses = AddrUtil.getAddresses(servers);
122
               for(InetSocketAddress addr : addresses) {
123
                    Map<String, String> stats = client.stats(addr);
124
                    System.out.println(stats);
125
               }
126
              
127
          } catch (TimeoutException e) {
128
               e.printStackTrace();
129
          } catch (InterruptedException e) {
130
               e.printStackTrace();
131
          } catch (MemcachedException e) {
132
               e.printStackTrace();
133
          }
134
         
135
          synchronized(client) {
136
               try {
137
                    client.wait();
138
               } catch (InterruptedException e) {
139
                    e.printStackTrace();
140
               }
141
          }
142

143
     }
144
    
145
     static class CacheResult implements Serializable {
146
          private static final long serialVersionUID = 3349686173080590047L;
147
          private File file;
148
          private long lastmodified;
149
          @Override
150
          public String toString() {
151
               return "file=[" + file + ", lastmodified=" + lastmodified + "]";
152
          }
153
     }
154

155
}
Node.js客户端

Memcached客户端代码的逻辑都非常类似,这里对Node.js简单举例说明,代码如下所示:

01
#!/usr/bin/env node
02

03
var MemcachedClient = require('memcached');
04

05
// configure memcached client
06
var servers = ['192.168.4.86:11211'];
07
var client = new MemcachedClient(servers);
08

09
// access memcached servers
10
var key = 'ghost';
11

12
// set
13
var value = 'Ghost wind blows!';
14
client.set(key, 0, value, function(err) {
15
     var data = 'key=' + key + ', value=' + value;
16
     if(err) {
17
          console.error('Fail to set: ' + data);
18
     } else {
19
          console.log('Added: ' + data);
20
     }
21
});
22

23
// get
24
var valueGot = client.get(key, function(err, data) {
25
     var dataGot = 'key=' + key + ', valueGot=' + data;
26
     if(err) {
27
                console.error('Fail to get: ' + dataGot);
28
        } else {
29
                console.log('Got: ' + dataGot);
30
        }
31
});
参考链接

http://www.memcached.org
https://code.google.com/p/memcached/wiki/NewStart
http://www.memcached.org/files/memcached-1.4.20.tar.gz
https://code.google.com/p/memcached/wiki/Clients
https://github.com/downloads/libevent/
https://github.com/downloads/libevent/libevent/libevent-1.4.14b-stable.tar.gz
https://code.google.com/p/spymemcached/
https://code.google.com/p/xmemcached/
https://github.com/killme2008/xmemcached
https://code.google.com/p/memcached/wiki/NewCommands
http://www.2cto.com/os/201303/193264.html
http://tech.idv2.com/tag/memcached/
http://programcreek.com/java-api-examples/index.php?api=net.spy.memcached.MemcachedClient
http://lzone.de/articles/memcached.htm
http://blog.elijaa.org/?post/2010/05/21/Memcached-telnet-command-summary
https://github.com/3rd-Eden/node-memcached
https://www.npmjs.org/package/memcached
分享到:
评论

相关推荐

    linux环境下memcached安装以及配置使用

    ### Linux环境下Memcached安装及配置使用详解 #### 一、Memcached简介 Memcached是一款高性能、分布式内存对象缓存系统,用于加速动态Web应用程序的速度,减轻数据库负担。它通过在内存中缓存数据和对象来减少读取...

    Memcached 原理和使用详解

    1. **基于C/S架构**:Memcached采用客户端-服务器模型,客户端应用程序通过网络发送请求到Memcached服务器,服务器处理请求并返回结果。这种架构使得Memcached易于部署和扩展。 2. **简单的协议**:Memcached使用...

    Memcached的原理和使用详解

    Memcached集群是指将多台Memcached服务器组织在一起,形成一个逻辑上的统一缓存。客户端可以通过一致性哈希算法等策略来确定每个键对应的服务器节点,从而实现数据的分布存储和高可用性。集群模式下,开发者需要注意...

    Memcached_原理和使用详解

    - **分布式**:基于客户端的分布式机制,数据自动分散到多个Memcached服务器,实现负载均衡。 **2. Memcached的工作原理** - **键值对存储**:Memcached以键值对的形式存储数据,客户端通过键定位数据,如果数据不...

    安装Memcached及Memcached配置.doc

    以下是 Memcached 的安装和配置详解。 安装 Memcached 要想使用 Memcached 做缓存首先需要安装 Memcached 服务。安装方法如下: 1. 下载 Memcached:可以从 http://code.jellycan.com/memcached/ 下载最新版本的 ...

    Memcached原理和使用详解.docx

    * 使用Memcached:可以使用telnet或Memcached客户端工具连接 Memcached服务器 Memcached的优点: * 高性能:Memcached可以处理高并发请求,提高Web应用的速度 * 可扩展性好:Memcached支持分布式架构,易于水平...

    memcached的安装与配置

    ### Memcached的安装与配置详解 #### 一、Memcached简介 Memcached是一款高性能的分布式内存对象缓存系统,用于加速动态Web应用,减少数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高...

    Memcached基于Linux的安装详解以及需要的jar包

    使用提供的Java API与Memcached服务器通信,例如创建`MemcachedClient`实例,设置、获取、删除缓存项等。 4. **测试代码**: 压缩包中附带的测试Java代码可以用来验证Memcached客户端是否能正确连接到服务器并...

    memcached-1.2.1-windows系统 服务器端,外带详细配置说明

    **memcached-1.2.1 Windows服务器端详解** `memcached` 是一款高性能、分布式内存对象缓存系统,常用于减轻数据库负载,提高Web应用的响应速度。它的工作原理是将数据存储在内存中,以便快速访问,而无需频繁地读写...

    Memcached原理和使用详解

    **连接服务器**:在应用程序中需要先建立与Memcached服务器的连接,通常使用客户端库(如libmemcached)来简化这一过程。 2. **数据操作**:连接成功后,可以执行各种数据操作,如设置(set)、获取(get)、删除...

    apache+tomcat+memcached 全配置

    ### Apache + Tomcat + Memcached 全配置详解 #### 一、环境搭建概述 本文将详细介绍如何在 Ubuntu 操作系统下使用源代码安装并配置 Apache、Tomcat 和 Memcached,实现集群中的 Session 共享与负载均衡。由于采用...

    windows_net_memcached客户端+服务端(64位32位)+说明文档(代码示例、配置安装详解)

    windows下C#.net框架中memcached客户端+服务端(64位32位)+说明文档(代码示例、配置安装详解)!里面包括服务器详细安装配置启动,也包括客户端调用代码以以及动态链接库dll文件,本人在64为windows7系统下成功...

    Memcached使用--使用

    **Memcached 使用详解** Memcached 是一款高性能、分布式内存对象缓存系统,广泛应用于Web应用中,用于减轻数据库负载,提高网站性能。它通过在内存中存储数据,为应用程序提供快速的数据访问,避免了频繁读取...

Global site tag (gtag.js) - Google Analytics