本文章主要介绍memcached,如何有效提高数据处理的效率,最后会有一个配合nginx以及tomcat的综合实验去教大家如何运用
介绍
Memcached 只支持能序列化的数据类型,不支持持久化,基于Key-Value的内存缓存系统。memcached 虽然没有像redis所具备的数据持久化功能,比如RDB和AOF都没有,但是可以通过做集群同步的方式, 让各memcached服务器的数据进行同步,从而实现数据的一致性,即保证各memcached的数据是一样的,即使有任何一台 memcached 发生故障,只要集群中有一台 memcached 可用就不会出现数据丢失。
当其他memcached 重新加入到集群的时候,可以自动从有数据的memcached 当中自动获取数据并 提供服务。 Memcached 借助了操作系统的 libevent 工具做高效的读写。
libevent是个程序库,它将Linux的epoll、 BSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥高 性能。
memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能 Memcached 支持最大的内存存储对象为1M,超过1M的数据可以使用客户端压缩或拆分报包放到多个 key中,比较大的数据在进行读取的时候需要消耗的时间比较长,memcached 最适合保存用户的 session实现session共享 Memcached存储数据时, Memcached会去申请1MB的内存, 把该块内存称为一个slab, 也称为一个page Memcached 支持多种开发语言,包括:JAVA,C,Python,PHP,C#,Ruby,Perl等
部署
/usr/local/tomcat/webapps/ROOT/
PORT表示监听端口,USER表示运行 Memcached 的系统用户,MAXCONN表示最大链接数,CACHESIZE表示最大内存容量(单位MB),OPTIONES表示监听的所有的IPv4和v6地址
systemctl enabled --now memcached
[root@tom1 ~]# netstat -lntup | grep memcached
tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 986/memcached
tcp6 0 0 ::1:11211 :::* LISTEN 986/memcached
常用命令
五种常用的存储命令
set、add、replace、get、delete
语法格式:
command <key> <flags> <expiration time> <bytes> <value>
key 用于查找缓存值,flags 可以包括键值对的整型参数,expiration time表示存储的时间长度
bytes 缓存中存储的字节数,value 存储的值
示例
[root@tom1 ~]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
add lab 0 60 4 #0 表示是否压缩 60过期时间 4字节长
test
STORED
get lab
VALUE lab 0 4
test
END
set lab 0 60 5 #修改
test1
STORED
add foo 0 60 5
one
delete foo
CLIENT_ERROR bad data chunk
ERROR
get foo
END
这个很简单,没什么好说的,直接上项目
实战
本实验用到三台主机,IP分别为192.168.118.171/172/173,mask 24。其中172,173作为tomcat主机,同时运行memcached,171运行nginx,复制调度
反向代理多机模式:
利用nginx的反向代理功能,将用户的请求全部转发给到同一个tomcat主机
部署tomcat
下面的操作在172/173这两台主机上面做
官方文档:Apache Tomcat 8 (8.5.100) - Documentation Index
#安装Java环境
yum install java-1.8.0-openjdk.x86_64 -y
[root@tom1 ~]# java -version
openjdk version "1.8.0_382"
OpenJDK Runtime Environment (build 1.8.0_382-b05)
OpenJDK 64-Bit Server VM (build 25.382-b05, mixed mode)
#解压生成tomcat的程序目录
[root@tom1 ~]# ls
anaconda-ks.cfg apache-tomcat-9.0.107.tar.gz
[root@tom1 ~]# tar -zxvf apache-tomcat-9.0.107.tar.gz -C /usr/local
编辑一份系统服务脚本vim /etc/systemd/system/tomcat.service
[Unit]
Description=Apache Tomcat Web Application Container
After=network.target
[Service]
Type=forking
Environment=CATALINA_PID=/usr/local/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/usr/local/tomcat
Environment=CATALINA_BASE=/usr/local/tomcat
EnvironmentFile=/usr/local/tomcat/conf/tomcat.conf
PrivateTmp=true
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
TimeoutStartSec=60
TimeoutStopSec=60
User=tomcat
Group=tomcat
[Install]
WantedBy=multi-user.target
然后直接启动:systemctl start mycat
[root@tom1 ~]# netstat -lntup | grep java
tcp6 0 0 127.0.0.1:8005 :::* LISTEN 3422java
tcp6 0 0 :::8080 :::* LISTEN 3422java
部署nginx
由于只是用到一个反向代理的功能,就不去专门编译安装了直接dnf install nginx -y
然后写一份反向代理的配置:vim /etc/nginx/conf.d/vhost.conf
upstream tomcat {
hash $cookie_JSESSIONID;
server 192.168.118.173:8080;
server 192.168.118.172:8080;
}
server {
listen 80;
server_name www.openlab.com; //虚拟主机的名词
root /web/test; //访问上面的虚拟主机时指定其根目录
location ~ \.jsp$ { //将jsp的请求丢给tomcat处理
proxy_pass http://tomcat;
}
}
上面提到了一个hash $cookie_JSESSIONID;,这个是针对于浏览器访问时携带的session做一个hash,保证处理浏览器持续访问的请求都是同一个后端tomcat处理的
结合
最后就是memcached和tomcat的配合,实现msm这个架构(memcached session manager)
这个主要功能就是提供将tomcat的session会话保持大豆memecached,然后实现高可用
参考链接:https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration
上面如果不能访问或者没法下载这个包话: https://pan.baidu.com/s/1KQsf7jJwi9zC8kMq2K5YZw 提取码: 2333
[root@tom1 ~]# unzip tomcat-memcache-jar.zip
[root@tom1 ~]# cd jar/
[root@tom1 jar]# ls
asm-5.2.jar minlog-1.3.1.jar
kryo-3.0.3.jar msm-kryo-serializer-2.3.2.jar
kryo-serializers-0.45.jar objenesis-2.6.jar
memcached-session-manager-2.3.2.jar reflectasm-1.11.9.jar
memcached-session-manager-tc9-2.3.2.jar spymemcached-2.12.3.jar
#将上面的全部丢给/usr/local/tomcat/lib/
[root@tom1 jar]# cp -p ./* /usr/local/tomcat/lib/
我们需要配置一下tomcat的context.xml文件,这个文件是针对于 web运行时的环境和资源环境,尤其常用于配置 JNDI 数据源、监听器和 Session 管理等。
添加这些配置
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.118.172:11211,n2:192.168.118.173:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"/>
上面主要是来自MSM插件,用来实现Session共享的,其中字段memcachedNodes定义了两个节点分别为172和173的11211端口,也就是memcached监听的端口。failoverNodes表示优先不使用的节点,也就是优先存储在n2节点,当n2不可用时,才用n1。注:这里有个技巧,也就时我们配置的优先不用的节点是和tomcat共同在一起的主机IP,也就是本台主机优先存储于其他的主机上面,实在不行后才存储在本台主机上。这种优先不用本机的策略可以避免单价故障导致数据丢失,是一种构建高可用集群的经典做法
大约这个位置,不要写出<Context>
准备一份jsp文件用来测试
[root@tom1 ~]# cat /usr/local/tomcat/webapps/ROOT/test.jsp
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info:
<%
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>
<%
out.println("<br> ID " + session.getId()+"<br>");
String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
out.print("<b>Session list</b>");
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println( name + " = " + value+"<br>");
System.out.println( name + " = " + value);
}
%>
<form action="test.jsp" method="POST">
name:<input type=text size=20 name="dataName">
<br>
key:<input type=text size=20 name="dataValue">
<br>
<input type=submit>
</form>
</body>
</html>
然后自己一定要关闭selinux和关闭firewalld
插入几组数据,然后刷新浏览器也是依旧在172这台主机
然后我们人为的关闭172着他主机,你会发现里面的存储数据也是一样的
这里的test=123没有了是由于它存储时间到了,不影响效果。可以看到起到了session保持的效果,即使一台主句挂了,也无所谓