MemCache详解

一、关于Memcached

1.1 Memcached的介绍

MemCache是一个自由、源码开放、高性能、分布式的内存对象缓存系统,用于动态Web应用以减轻数据库的负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高了网站访问的速度。
MemCache是一个存储键值对的HashMap,在内存中对任意的 数据(比如字符串、对象等)所使用的key-value存储,数据可以来自数据库调用、API调用,或者页面渲染的结果,

1.2 Memcached的工作原理

由于它的工作机制是在 内存中开辟一块空间,然后建立一个HashTable,Memcached管理这些HashTable,所以速度非常快。

在这里插入图片描述

1.3 Memcached的作用

使用MemCache的网站一般流量都是比较大的,为了缓解数据库的压力,让MemCache作为一个缓存区域,把部分信息保存在内存中,在前端能够迅速的进行存取。那么一般的焦点就是集中在如何分担数据库压力和进行分布式,毕竟单台MemCache的内存容量是有限的。

二、Memcached服务端的安装(重点)

Memcached的安装
分为两个过程:
memcache服务器端的安装和memcache客户端的安装。

所谓服务器端的安装就是在服务器(一般都是Linux系统)上安装MemCache实现数据的存储。

所谓客户端的安装就是指Java(或者其他程序,memcache还有其他不错的api接口提供)去使用服务器端的memcache提供的函数,需要Java添加扩展。

2.1 Windows安装memcached(服务器端)

官网:下载地址

# 如果之前有MemCache的安装,删除它,启动cmd

sc delete "Memcached Server"

# 获取安装包、以管理员方式启动cmd、并进入安装包目录下:
d:
cd Java\memcache

# 安装MemCache
memcache.exe -d install

# 启动MemCache
memcache.exe -d start

#设置 memcached 最大的缓存配置为512M。
memcache.exe -d runservice -m 512

# 关闭MemCache
memcache.exe -d stop

# 卸载MemCache
memcache.exe -d uninstall

安装成功之后再Windows服务项目中查看是否有启动
在这里插入图片描述
测试安装是否成功
在MemCache服务成功启动后,可以使用telnet 127.0.0.1 11211测试连接是否成功;
如果连接成功后则使用stats命令可以查看MemCache的基本信息

(1)什么是Telnet
对于telnet的人事,不同的人持有不同的观点,可以吧telnet当成一种通信协议,但是对于入侵者而言,telnet只是一种远程登录的工具。一旦入侵者与远程主机建立了telnet连接,入侵者便可以使用目标主机上的软、硬件资源,而入侵者的本地机只相当于一个只有键盘和显示器的终端而已
(2)开启telnet功能
打开控制面板——>程序和功能——>启动或者关闭Windows功能——>开启telnet客户端
(3)telnet命令的使用

在这里插入图片描述
然后输入命令:
stats 查看memcache服务器的状态

2.2 Linux安装memcached(服务器端)

  1. 获取memcached的安装包:
    官网:下载地址
  2. 上传文件到Linux根目录software目录下
  3. 解压安装包
# 基本依赖
mount /dev/cdrom /media/CentOS
yum --disablerepo=\* --enablerepo=c6-media install gcc gcc-c++

# 安装libevent
tar zxvf libevent-2.0.21-stable.tar.gz
cd libevent-2.0.21-stable
./configure --prefix=/usr/local/libevent
make && make install

# 安装memcached
tar zxvf memcached-1.4.27.tar.gz
cd memcached-1.4.27
./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent
make && make install

# 创建一个用户:
useradd memcache
passed memcache

# 从root用户切换到memcached用户:
su - memcache

# 启动memcache服务:
cd /usr/local/memcache
./bin/memcache &  #后台启动服务器端memcached

# 查看memcached的服务器端是否启动 7413端口
ps -e |grep memcache

2.3 telnet请求命令格式(Windows下)

<command name> <key> <flags> <exptime> <bytes>\r\n <data block>\r\n

a)<command name>可以是"set","add","replace""set" 		表示按照相应的<key>存储该数据,没有的时候增加,有的覆盖。
"add" 		表示按照相应的<key>添加该数据,但是如果该<key>已经存在则会操作失败。
"replace"	表示按照相应的<key>替换数据,但是如果该<key>不存在则操作失败。

b)<key>客户端需要保存数据的key  username
set username 0 30 5

c)<flags>是一个16位的无符号的整数(以十进制的方式表示)。
该标志将和需要存储的数据一起存储,并在客户端get数据时返回。
客户可以将此标志用做特殊用途,此标志对服务器来说是不透明的。
一般的状态:0(字符串)和1(对象和数组)

d)<exptime>过期的时间。
若为0表示存储的数据永远不过时(但可被服务器算法LRU等替换)。
如果非0(Unix时间或者距离此时的秒数),当过期后,
服务器可以保证用户得不到该数据(以服务器时间为标准)。

e)<block>需要存储的字节数(不包含最后的"\r\n")。
当用户希望存储空数据时,<block>可以为0

f)最后客户端需要加上"\r\n"作为“命令头”的结束标志。
<data block>\r\n:输入的数据
紧接着“命令头”结束之后就要发送数据块(即希望存储的数据内容),
最后加上"\r\n"作为此次通讯的结束。

具体事例1:
打开cmd:

telnet 127.0.0.1 11211

# 设置一个键名:newname;0:字符串;30:过期时间;5:数据的长度
set newname 0 30 5

# 输入数据
peter

# 获取键名的值
get newname
# 返回的数据
peter

# 30秒后、得不到数据
get newname

2.4 memcached在Linux中的操作

XShell支持telnet(远程登录协议),连接MemCached服务器端进行操作。
使用telnet协议的客户端,即可充当memcached的客户端:
XShell可以发出ssh请求,同样也可以telnet请求

三、Java 连接 Memcached 服务

使用 Java 程序连接 Memcached,需要在你的 classpath 中添加 Memcached jar 包。

Google Code jar
包下载地址:spymemcached-2.10.3.jar

以下程序假定 Memcached 服务的主机为 127.0.0.1,端口为 11211。

连接实例

Java 连接 Memcached

MemcachedJava.java 文件:

import net.spy.memcached.MemcachedClient;
import java.net.*;
 
 
public class MemcachedJava {
   public static void main(String[] args) {
      try{
         // 本地连接 Memcached 服务
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         System.out.println("Connection to server sucessful.");
         
         // 关闭连接
         mcc.shutdown();
         
      }catch(Exception ex){
         System.out.println( ex.getMessage() );
      }
   }
}

该程序中我们使用 InetSocketAddress 连接 IP 为 127.0.0.1 端口 为 11211 的 memcached 服务。

执行以上代码,如果连接成功会输出以下信息:

Connection to server successful.

set 操作实例

以下使用 java.util.concurrent.Future 来存储数据

MemcachedJava.java 文件:

import java.net.InetSocketAddress;
import java.util.concurrent.Future;
 
import net.spy.memcached.MemcachedClient;
 
public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
         // 连接本地的 Memcached 服务
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         System.out.println("Connection to server sucessful.");
      
         // 存储数据
         Future fo = mcc.set("runoob", 900, "Free Education");
      
         // 查看存储状态
         System.out.println("set status:" + fo.get());
         
         // 输出值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));
 
         // 关闭连接
         mcc.shutdown();
         
      }catch(Exception ex){
         System.out.println( ex.getMessage() );
      }
   }
}

执行程序,输出结果为:

Connection to server successful.
set status:true
runoob value in cache - Free Education

add 操作实例

MemcachedJava.java 文件:

import java.net.InetSocketAddress;
import java.util.concurrent.Future;
 
import net.spy.memcached.MemcachedClient;
 
public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 连接本地的 Memcached 服务
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         System.out.println("Connection to server sucessful.");
 
         // 添加数据
         Future fo = mcc.set("runoob", 900, "Free Education");
 
         // 打印状态
         System.out.println("set status:" + fo.get());
 
         // 输出
         System.out.println("runoob value in cache - " + mcc.get("runoob"));
 
         // 添加
         fo = mcc.add("runoob", 900, "memcached");
 
         // 打印状态
         System.out.println("add status:" + fo.get());
 
         // 添加新key
         fo = mcc.add("codingground", 900, "All Free Compilers");
 
         // 打印状态
         System.out.println("add status:" + fo.get());
         
         // 输出
         System.out.println("codingground value in cache - " + mcc.get("codingground"));
 
         // 关闭连接
         mcc.shutdown();
         
      }catch(Exception ex){
         System.out.println(ex.getMessage());
      }
   }
}

replace 操作实例

MemcachedJava.java 文件:

import java.net.InetSocketAddress;
import java.util.concurrent.Future;
 
import net.spy.memcached.MemcachedClient;
 
public class MemcachedJava {
   public static void main(String[] args) {
   
      try {
         //连接本地的 Memcached 服务
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         System.out.println("Connection to server sucessful.");
 
         // 添加第一个 key=》value 对
         Future fo = mcc.set("runoob", 900, "Free Education");
 
         // 输出执行 add 方法后的状态
         System.out.println("add status:" + fo.get());
 
         // 获取键对应的值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));
 
         // 添加新的 key
         fo = mcc.replace("runoob", 900, "Largest Tutorials' Library");
 
         // 输出执行 set 方法后的状态
         System.out.println("replace status:" + fo.get());
 
         // 获取键对应的值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));
 
         // 关闭连接
         mcc.shutdown();
         
      }catch(Exception ex){
         System.out.println( ex.getMessage() );
      }
   }
}

append 操作实例

MemcachedJava.java 文件:

import java.net.InetSocketAddress;
import java.util.concurrent.Future;
 
import net.spy.memcached.MemcachedClient;
 
public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 连接本地的 Memcached 服务
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         System.out.println("Connection to server sucessful.");
 
         // 添加数据
         Future fo = mcc.set("runoob", 900, "Free Education");
 
         // 输出执行 set 方法后的状态
         System.out.println("set status:" + fo.get());
 
         // 获取键对应的值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));
 
         // 对存在的key进行数据添加操作
         fo = mcc.append("runoob", 900, " for All");
 
         // 输出执行 set 方法后的状态
         System.out.println("append status:" + fo.get());
         
         // 获取键对应的值
         System.out.println("runoob value in cache - " + mcc.get("codingground"));
 
         // 关闭连接
         mcc.shutdown();
         
      }catch(Exception ex) {
         System.out.println(ex.getMessage());
      ]
   }
}

prepend 操作实例

MemcachedJava.java 文件:

import java.net.InetSocketAddress;
import java.util.concurrent.Future;
 
import net.spy.memcached.MemcachedClient;
 
public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 连接本地的 Memcached 服务
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         System.out.println("Connection to server sucessful.");
 
         // 添加数据
         Future fo = mcc.set("runoob", 900, "Education for All");
 
         // 输出执行 set 方法后的状态
         System.out.println("set status:" + fo.get());
 
         // 获取键对应的值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));
 
         // 对存在的key进行数据添加操作
         fo = mcc.prepend("runoob", 900, "Free ");
 
         // 输出执行 set 方法后的状态
         System.out.println("prepend status:" + fo.get());
         
         // 获取键对应的值
         System.out.println("runoob value in cache - " + mcc.get("codingground"));
 
         // 关闭连接
         mcc.shutdown();
         
      }catch(Exception ex) {
         System.out.println(ex.getMessage());
      }
   }
}

CAS 操作实例

MemcachedJava.java 文件:

import java.net.InetSocketAddress;
import java.util.concurrent.Future;
 
import net.spy.memcached.CASValue;
import net.spy.memcached.CASResponse;
import net.spy.memcached.MemcachedClient;
 
public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 连接本地的 Memcached 服务
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         System.out.println("Connection to server sucessful.");
 
         // 添加数据
         Future fo = mcc.set("runoob", 900, "Free Education");
 
         // 输出执行 set 方法后的状态
         System.out.println("set status:" + fo.get());
            
         // 使用 get 方法获取数据
         System.out.println("runoob value in cache - " + mcc.get("runoob"));
 
         // 通过 gets 方法获取 CAS token(令牌)
         CASValue casValue = mcc.gets("runoob");
 
         // 输出 CAS token(令牌) 值
         System.out.println("CAS token - " + casValue);
 
         // 尝试使用cas方法来更新数据
         CASResponse casresp = mcc.cas("runoob", casValue.getCas(), 900, "Largest Tutorials-Library");
         
         // 输出 CAS 响应信息
         System.out.println("CAS Response - " + casresp);
 
         // 输出值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));
 
         // 关闭连接
         mcc.shutdown();
         
      }catch(Exception ex) {
         System.out.println(ex.getMessage());
      }
   }
}

get 操作实例

MemcachedJava.java 文件:

import java.net.InetSocketAddress;
import java.util.concurrent.Future;
 
import net.spy.memcached.MemcachedClient;
 
public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 连接本地的 Memcached 服务
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         System.out.println("Connection to server sucessful.");
 
         // 添加数据
         Future fo = mcc.set("runoob", 900, "Free Education");
 
         // 输出执行 set 方法后的状态
         System.out.println("set status:" + fo.get());
 
         // 使用 get 方法获取数据
         System.out.println("runoob value in cache - " + mcc.get("runoob"));
 
         // 关闭连接
         mcc.shutdown();
         
      }catch(Exception ex) {
         System.out.println(ex.getMessage());
      }
   }
}

gets 操作实例、CAS

MemcachedJava.java 文件:

import java.net.InetSocketAddress;
import java.util.concurrent.Future;
 
import net.spy.memcached.CASValue;
import net.spy.memcached.CASResponse;
import net.spy.memcached.MemcachedClient;
 
public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 连接本地的 Memcached 服务
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         System.out.println("Connection to server sucessful.");
 
         // 添加数据
         Future fo = mcc.set("runoob", 900, "Free Education");
 
         // 输出执行 set 方法后的状态
         System.out.println("set status:" + fo.get());
            
         // 从缓存中获取键为 runoob 的值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));
 
         // 通过 gets 方法获取 CAS token(令牌)
         CASValue casValue = mcc.gets("runoob");
 
         // 输出 CAS token(令牌) 值
         System.out.println("CAS value in cache - " + casValue);
 
         // 关闭连接
         mcc.shutdown();
         
      }catch(Exception ex) {
         System.out.println(ex.getMessage());
      }
   }
}

delete 操作实例

MemcachedJava.java 文件:

import java.net.InetSocketAddress;
import java.util.concurrent.Future;
 
import net.spy.memcached.MemcachedClient;
 
public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 连接本地的 Memcached 服务
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         System.out.println("Connection to server sucessful.");
 
         // 添加数据
         Future fo = mcc.set("runoob", 900, "World's largest online tutorials library");
 
         // 输出执行 set 方法后的状态
         System.out.println("set status:" + fo.get());
 
         // 获取键对应的值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));
 
         // 对存在的key进行数据添加操作
        fo = mcc.delete("runoob");
 
         // 输出执行 delete 方法后的状态
         System.out.println("delete status:" + fo.get());
 
         // 获取键对应的值
         System.out.println("runoob value in cache - " + mcc.get("codingground"));
 
         // 关闭连接
         mcc.shutdown();
         
      }catch(Exception ex) {
         System.out.println(ex.getMessage());
      }
   }
}

Incr/Decr 操作实例

MemcachedJava.java 文件:

import java.net.InetSocketAddress;
import java.util.concurrent.Future;
 
import net.spy.memcached.MemcachedClient;
 
public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 连接本地的 Memcached 服务
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         System.out.println("Connection to server sucessful.");
 
         // 添加数字值
         Future fo = mcc.set("number", 900, "1000");
 
         // 输出执行 set 方法后的状态
         System.out.println("set status:" + fo.get());
 
         // 获取键对应的值
         System.out.println("value in cache - " + mcc.get("number"));
 
         // 自增并输出
         System.out.println("value in cache after increment - " + mcc.incr("number", 111));
 
         // 自减并输出
         System.out.println("value in cache after decrement - " + mcc.decr("number", 112));
 
         // 关闭连接
         mcc.shutdown();
         
      }catch(Exception ex) {
         System.out.println(ex.getMessage());
      }
   }
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

〆`杨陆原じ₯㎕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值