memcache

Linux下的Memcache安装:http://www.ccvita.com/257.html
Windows下的Memcache安装:http://www.ccvita.com/258.html
Memcache基础教程:http://www.ccvita.com/259.html
Discuz!的Memcache缓存实现:http://www.ccvita.com/261.html
Memcache协议中文版:http://www.ccvita.com/306.html
Memcache分布式部署方案:http://www.ccvita.com/395.html

PHP的Memcache


.为什么要使用memcache

 由于网站的高并发读写需求,传统的关系型数据库开始出现瓶颈,例如:

1)对数据库的高并发读写:

关系型数据库本身就是个庞然大物,处理过程非常耗时(如解析SQL语句,事务处理等)。如果对关系型数据库进行高并发读写(每秒上万次的访问),那么它是无法承受的。

2)对海量数据的处理:

对于大型的SNS网站,每天有上千万次的数据产生(如twitter, 新浪微博)。对于关系型数据库,如果在一个有上亿条数据的数据表种查找某条记录,效率将非常低。


使用memcache能很好的解决以上问题。

在实际使用中,通常把数据库查询的结果保存到Memcache中,下次访问时直接从memcache中读取,而不再进行数据库查询操作,这样就在很大程度上减少了数据库的负担。

保存在memcache中的对象实际放置在内存中,这也是memcache如此高效的原因。




package com.alisoft.sme.memcached;
 
import java.util.Date;
 
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
 
public class MemCachedManager {
 
// 创建全局的唯一实例
protected static MemCachedClient mcc = new MemCachedClient();
 
protected static MemCachedManager memCachedManager = new MemCachedManager();
 
// 设置与缓存服务器的连接池
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 MemCachedManager() {
 
}
 
/**
* 获取唯一实例.
*
* @return 
*/
public static MemCachedManager getInstance() {
    return memCachedManager;
}
 
/**
* 添加一个指定的值到缓存中.
*
* @param key
* @param value
* @return 
*/
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);
}
 
/**
* 根据指定的关键字获取对象.
*
* @param key
* @return 
*/
public Object get(String key) {
    return mcc.get(key);
}
 
public static void main(String[] args) {
    MemCachedManager cache = MemCachedManager.getInstance();
    cache.add( "hello" , 234 );
    System.out.print( "get value : " + cache.get( "hello" ));
}
}
windows下memcache服务器启动  

将memcache服务器安装包解压到C:\memcached文件夹后,使用cmd命令窗口安装。 

1>开始>运行:CMD(确定) 

2>cd C:\memcached(回车) 

3>memcached -d install(回车 这步执行安装) 

4>memcached -d start(回车 这步执行启动memcache服务器,默认分配64M内存,使用11211端口) 

此时memcache服务器已经可以正常使用了。 

memcache服务器安全: 

Memcache服务器端都是直接通过客户端连接后直接操作,没有任何的验证过程,这样如果服务器是直接暴露在互联网上的话是比较危险,轻则数据泄露被其他无关人员查看,重则服务器被入侵,况且里面可能存在一些我们未知的bug或者是缓冲区溢出的情况,这些都是我们未知的,所以危险性是可以预见的。为了安全起见,做两点建议,能够稍微的防止黑客的入侵或者数据的泄露。 

现在就关于修改memcache服务器配置的问题说明如下: 

1>用内网ip的方式提供web应用服务器调用,不允许直接通过外网调用,如将memcache服务器放在192.168.1.55的服务器上 

2>修改端口,如改为11200 

3>分配内存,如分配1024M(1G内存) 

方法如下: 



1>开始>运行:CMD(确定) 

2>cd C:\memcached(回车) 

3>memcached -m 1024 -p 11200 -l 192.168.1.55(回车) 

注意,此时命令行不会回到C:\memcached>状态,并且实际上memcache服务器悄悄变为stop状态了。此窗口不可以关闭。新开一个cmd窗口 

4>开始>运行:CMD(确定) 

5>cd C:\memcached(回车) 

6>memcached -d start(回车)可以关闭此cmd窗口。 

此时可以使用新配置的memcache服务器了。 



上述方法虽然解决了修改默认配置的问题,但是始终会有一个cmd窗口不可以关闭,否则就回到11211端口的默认配置。 

更好的解决方案是通过修改服务的注册表配置: 

1>开始>运行:regedit(回车) 

2>在注册表中找到:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\memcached Server 

3>默认的ImagePath键的值是:"c:\memcached\memcached.exe" -d runservice,改为:"c:\memcached\memcached.exe" -d runservice -m 512 -p  11200 -l 192.168.1.55(确定,关闭注册表) 

4>我的电脑(右键)>管理>服务 找到memcache的服务,重新启动一次即可生效。 



 
此时,同网段内的电脑仍然可以利用这台 memcache服务器,我们限定指定的web应用服务器才能够使用,通过防火墙的方式。如只允许 192.168.1.2这台Web服务器对Memcache服务器的访问,能够有效的阻止一些非法访问,相应的也可以增加一些其他的规则来加强安全性,这个可以根据自己的需要来做。

使用LRU(last recently used)算法淘汰数据:

附:阿里2014笔试题一道:

某缓存系统采用 LRU淘汰算法,假定缓存容量为4,并且初始为空,那么在顺序访问一下数据项的时候:1,5,1,3,5,2,4,1,2出现缓存直接命中的次数是?,最后缓存中即将准备淘汰的数据项是?

答案:3, 5
解答:
  1. 1调入内存 1
  2. 5调入内存 1 5
  3. 1调入内存 5 1(命中 1,更新次序)
  4. 3调入内存 5 1 3
  5. 5调入内存 1 3 5 (命中5)
  6. 2调入内存 1 3 5 2
  7. 4调入内存(1最久未使用,淘汰1) 3 5 2 4
  8. 1调入内存(3最久未使用,淘汰3) 5 2 4 1
  9. 2调入内存 5 4 1 2(命中2)
因此,直接命中次数是3,最后缓存即将准备淘汰的数据项是5

Memcache的安全
我们上面的Memcache服务器端都是直接通过客户端连接后直接操作,没有任何的验证过程,这样如果服务器是直接暴露在互联网上的话是比较危险,轻则数据泄露被其他无关人员查看,重则服务器被入侵,因为Mecache是以root权限运行的,况且里面可能存在一些我们未知的bug或者是缓冲区溢出的情况,这些都是我们未知的,所以危险性是可以预见的。为了安全起见,我做两点建议,能够稍微的防止黑客的入侵或者数据的泄露。

内网访问
最好把两台服务器之间的访问是内网形态的,一般是Web服务器跟Memcache服务器之间。普遍的服务器都是有两块网卡,一块指向互联网,一块指向内网,那么就让Web服务器通过内网的网卡来访问Memcache服务器,我们Memcache的服务器上启动的时候就监听内网的IP地址和端口,内网间的访问能够有效阻止其他非法的访问。
# memcached -d -m 1024 -u root -l 192.168.0.200 -p 11211 -c 1024 -P /tmp/memcached.pid
Memcache服务器端设置监听通过内网的192.168.0.200的ip的11211端口,占用1024MB内存,并且允许最大1024个并发连接

设置防火墙
防火墙是简单有效的方式,如果却是两台服务器都是挂在网的,并且需要通过外网IP来访问Memcache的话,那么可以考虑使用防火墙或者代理程序来过滤非法访问。
一般我们在Linux下可以使用iptables或者FreeBSD下的ipfw来指定一些规则防止一些非法的访问,比如我们可以设置只允许我们的Web服务器来访问我们Memcache服务器,同时阻止其他的访问。
# iptables -F
# iptables -P INPUT DROP
# iptables -A INPUT -p tcp -s 192.168.0.2 --dport 11211 -j ACCEPT
# iptables -A INPUT -p udp -s 192.168.0.2 --dport 11211 -j ACCEPT
上面的iptables规则就是只允许192.168.0.2这台Web服务器对Memcache服务器的访问,能够有效的阻止一些非法访问,相应的也可以增加一些其他的规则来加强安全性,这个可以根据自己的需要来做。



你可能感兴趣的:(框架)