Memcached分布式缓存
公司要使用Memcached来作为app的缓存使用,所以简单整理了下网上搜到的资料
Memcache简介
Memcache集群环境下缓存解决方案
Memcache是一个高性能的分布式的内存对象缓存系统,用于在动态应用中减少负载,提升访问速度。通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存中,然后从内存中读取,从而大大提高读取速度。
Memcached是以守护程序方式运行于一个或多个服务器中,随时会接收客户端的连接和操作。
Memcached的最新版是采用c语言进行开发和设计的,而且它是一个应用软件来的,是作为缓存服务器的服务器端运行在服务器上的,需要使用特定的语言编写客户端与其进行通信来进行数据的缓存和获取。
Memcached缺乏认证以及安全管制,这代表应该将Memcached服务器放置在防火墙后。
Memcache安装:
Memcache需要在服务器端安装和客户端安装。所谓服务器端的安装就是在服务器(一般都是linux系统)上安装Memcache实现数据的存储;所谓客户端安装就是指java,php等程序,去使用服务器端的Memcache提供的函数,需要php添加扩展。
首先Memcached用到libevent这个库用于socket的处理,所以必须先安装libevent。libevent-2.0.13-stable.tar.gz
1.分别把memcached和libevent下载回来放到/tmp目录下:
[root@hxqlinux ~]# cd /tmp
[root@hxqlinux tmp]# wget http://memcached.googlecode.com/files/memcached-1.4.13.tar.gz
[root@hxqlinux tmp]# wget https://github.com/downloads/libevent/libevent/libevent-2.0.17-stable.tar.gz
2.安装libevent
#tar zxvf libevent-2.0.13-stable.tar.gz
#cd libevent-2.0.13-stable
#./configure -prefix=/usr
#make
#make install
3.测试libevent是否安装成功
#ls -al/usr/lib | grep libevent 版本不同可能列表不同
4.安装memcached,同时需要安装中指定libevent的安装位置CentOS版
#cd /tmp
#tar zxvf memcached-1.4.20.tar.gz
#cd memcached-1.4.20
#./configure -with-libevent=/usr
#make
#make install
安装完成后会把memcached放到/usr/local/bin/memcached
5.测试是否成功安装memcached
#ls -al/usr/local/bin/mem*
6.memcached服务器的启动和关闭
A.直接命令行方式:启动
[root@hxqlinux ~]#/usr/local/bin/memcached -d -m 128 -u root -p 11211 -c 256 -P /var/run/memcached1.pid
[root@hxqlinux ~]# ps aux|grep memcached
关闭:
[root@hxqlinux ~]# kill `cat /var/run/memcached1.pid`
再通过ps aux|grep memcached进行查看
B.服务的方式:
新建启动和关闭脚本并赋予执行权限:
[root@hxqlinux ~]# cp /tmp/memcached-1.4.13/scripts/memcached.sysv /etc/init.d/memcached
[root@hxqlinux ~]# chmod 755 /etc/init.d/memcached
修改/etc/init.d/memcached文件
PORT=11212
USER=root
MAXCONN=256
CACHESIZE=128
OPTIONS=""
chown $USER /usr/local/bin/memcached
/usr/local/bin/memcached -d -p $PORT -u $USER -m $CACHESIZE -c $MAXCONN -P /var/run/memcached2.pid $OPTIONS
加入系统服务,并启动memcached服务,同时查看memcached服务是否启动成功:
[root@hxqlinux ~]# chkconfig --add memcached
[root@hxqlinux ~]# chkconfig --level 235 memcached on
[root@hxqlinux ~]# chkconfig --list memcached
启动memcached服务器并检查memcached是否启动,关闭memcached
[root@hxqlinux ~]# service memcached start
[root@hxqlinux ~]# ps aux|grep memcached
[root@hxqlinux ~]# service memcached stop
7.测试外部是否可以访问memcached服务器
通过telnet ip port来测试memcached是否可以访问,如果不能访问,应该是centos6的防火墙问题,进行如下修改:
[root@hxqlinux ~]# iptables -I INPUT -p tcp --dport 11211 -j ACCEPT;
[root@hxqlinux ~]# iptables -I OUTPUT -p tcp --sport 11211 -j ACCEPT;
[root@hxqlinux ~]# iptables-save
[root@hxqlinux ~]# service iptables save;
也可以通过netstat -anp|grep 1121* 来查看memcache是否启动;
此时外部程序应该可以访问memcached 服务器了
2.客户端安装(Windows系统)
下载Memcached的windows版本和java客户端的jar包
memcached-win32-1.4.4-14.zip和 java_memcached-release_1.6.zip分别解压后即可。
a.首先是安装运行memcached服务器
Cmd命令:
1.解压memcached-win32-1.4.4-14.zip 例如在“d:\Memcached\memcached-win32-1.4.4-14”
2.c:> d:\Memcached\memcached-win32-1.4.4-14\memcached.exe -d install安装
3.c:> d:\Memcached\memcached-win32-1.4.4-14\memcached.exe -d start启动
(卸载的话c:> d:\Memcached\memcached-win32-1.4.4-14\memcached.exe -d uninstall)以后作为windows的一个服务,每次开机自动启动。
通过修改注册表来达到这个修改端口的目的。
在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\memcached Server 下面找到一个 ImagePath 的字符串项,正好是服务的执行路径的字符串,双击该串,在后面加入 -l 192.168.1.135 -m 45 -p 12345 (访问ip为:192.168.1.135 使用45M内存,12345为端口),再启动服务。
现在来试试是否可以连接:
使用方法为“telnet ip 端口号”,登录后使用“stats”命令
cmd下
telnet 192.168.1.135 12345(注意:这里只能用IP 不能用 localhost 或127.0.0.1)
然后使用:stats命令可以看到memcached的使用情况如下:
STAT uptime 760
STAT time 1311913149
STAT version 1.2.1
STAT pointer_size 32
STAT curr_items 0
STAT total_items 0
STAT bytes 0
STAT curr_connections 4
STAT total_connections 6
STAT connection_structures 5
STAT cmd_get 0
STAT cmd_set 0
STAT get_hits 0
STAT get_misses 0
STAT bytes_read 63
STAT bytes_written 793
STAT limit_maxbytes 10485760
END
b.安装java客户端
1.java_memcached-release_2.6.3
依赖的jar
A.commons-pool-1.5.6.jar
B.java_memcached-release_2.6.3.jar
C.slf4j-api-1.6.1.jar
D.slf4j-simple-1.6.1.jar
将java_memcached-release_2.6.3.zip解压后的目录中的java_memcached-release_2.6.3.jar文件复制到java项目的lib目录下,然后编写代码
package utils.cache;import java.util.Date;import com.danga.MemCached.MemCachedClient;import com.danga.MemCached.SockIOPool;
//使用memcached的缓存实用类
public class MemCached
{
// 创建全局的唯一实例
protected static MemCachedClient mcc = new MemCachedClient(); protected static MemCached memCached = new MemCached(); // 设置与缓存服务器的连接池
static {
// 服务器列表和其权重
String[] servers = { " 127.0.0.1:11211 " };
Integer[] weights = { 3 };
// 获取socke连接池的实例对象
SockIOPool pool = SockIOPool.getInstance();
// 设置服务器信息
pool.setServers( servers );
pool.setWeights( weights );
// 设置初始连接数、最小和最大连接数以及最大处理时间 pool.setInitConn( 5 );
pool.setMinConn( 5 );
pool.setMaxConn( 250 );
pool.setMaxIdle( 1000 * 60 * 60 * 6 );
// 设置主线程的睡眠时间
pool.setMaintSleep( 30 );
// 设置TCP的参数,连接超时等
pool.setNagle( false );
pool.setSocketTO( 3000 );
pool.setSocketConnectTO( 0 );
// 初始化连接池
pool.initialize();
// 压缩设置,超过指定大小(单位为K)的数据都会被压缩 mcc.setCompressEnable( true );
mcc.setCompressThreshold( 64 * 1024 );
}
// 保护型构造方法,不允许实例化!
protected MemCached()
{
}
// 获取唯一实例.
public static MemCached getInstance()
{
return memCached;
}
//添加一个指定的值到缓存中.
public boolean add(String key, Object value)
{
return mcc.add(key, value);
}
public boolean add(String key, Object value, Date expiry)
{
return mcc.add(key, value, expiry);
}
public boolean replace(String key, Object value)
{
return mcc.replace(key, value);
}
public boolean replace(String key, Object value, Date expiry)
{
return mcc.replace(key, value, expiry);
}
//根据指定的关键字获取对象.
public Object get(String key)
{
return mcc.get(key);
}
public static void main(String[] args)
{
MemCached cache = MemCached.getInstance();
cache.add( " hello " , 234 );
System.out.print( " get value : " + cache.get( " hello " ));
}
}
那么我们就可以通过简单的像main方法中操作的一样存入一个变量,然后再取出进行查看,我们可以看到先调用了add,然后再进行get,我们运行一次 后,234这个值已经被我们存入了memcached的缓存中的了,我们将main方法中红色的那一行注释掉后,我们再运行还是可以看到get到的 value也是234,即缓存中我们已经存在了数据了。
对基本的数据我们可以操作,对于普通的POJO而言,如果要进行存储的话,那么比如让其实现java.io.Serializable接口,因为 memcached是一个分布式的缓存服务器,多台服务器间进行数据共享需要将对象序列化的,所以必须实现该接口,否则会报错的。比如我们写一个简单的测 试Bean如下:
class TBean implements java.io.Serializable
{
private static final long serialVersionUID = 1945562032261336919L ;
private String name;
public String getName()
{
return name;
}
public void setName(String name)
{
this .name = name;
}
}
然后我们在main方法中加入如下几行代码:
TBean tb = new TBean();
tb.setName( " 铁木箱子 " );
cache.add( " bean " , tb);
TBean tb1 = (TBean)cache.get( " bean " );
System.out.print( " name= " + tb1.getName());
tb1.setName( " 铁木箱子_修改的 " );
tb1 = (TBean)cache.get( " bean " );
System.out.print( " name= " + tb1.getName());
修改的对象并不是缓存中的对 象,而是通过序列化过来的一个实例对象,表明从缓存中获 取的对象是存入对象的一个副本,对获取对象的修改并不能真正的修改缓存中的数据,而应该使用其提供的replace等方法来进行修改。
常用设置:
-p <num> 监听的端口
-l <ip_addr> 连接的IP地址, 默认是本机
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
-u <username> 以<username>的身份运行 (仅在以root运行的时候有效)
-m <num> 最大内存使用,单位MB。默认64MB
-M 内存耗尽时返回错误,而不是删除项
-c <num> 最大同时连接数,默认是1024
-f <factor> 块大小增长因子,默认是1.25
-n <bytes> 最小分配空间,key+value+flags默认是48
-h 显示帮助