Tomcat memcached和msm 小节5

124 阅读5分钟

@[TOC](Tomcat memcached和msm 小节5)

NoSQL

NoSQL是对非SQL、非传统关系型数据库的统称。

NoSQL一词诞生于1998年,2009年这个词汇被再次提出指非关系型、分布式、不提供ACID的数据库设计模式。

随着互联网时代的到来,数据爆发式增长,数据库技术发展日新月异,要适应新的业务需求。

随着移动互联网、物联网的到来,大数据的技术中NoSQL也同样重要。

db-engines.com/en/ranking

分类

  • Key-value Store
    • redis、momcached
  • Document Store
    • mongodb、CouchDB
  • Column Store列存数据库,Column-Oriented DB
    • HBase、CAssandra
  • Graph DB
    • Neo4j
  • Time Series时序数据库
    • influxDB

Memcached

Memcached只支持能序列化的数据类型,不支持持久化,基于Key-Value的内存缓存系统。

内存分配机制

应用程序运行需要使用内存存储数据,但对于一个缓存系统来说,申请内存、释放内存将十分频繁,非常容易导致大量内存碎片,最后导致无连续可用内存可用。

Memcached采用了Slab Allocator机制来分配、管理内存。

  • Page:分配给Slab的内存空间,默认为1MB,分配后就得到一个Slab。Slab分配之后内存按照固定字节大小等分成chunk。
  • Chunk:用于缓存记录kv值的内存空间。Memcached会根据数据大小选择存到哪一个chunk中,假设chunk有128bytes、64bytes,数据只有100bytes存储在128bytes中,存在些浪费。
    • chunk最大就是Page的大小,即一个Page中就一个Chunk
  • slab Class: Slab按照大小分组,就组成不同的Slab Class

图片.png

如果有100bytes要存,那么Memcached会选择上图中Slab Class2存储,因为它是120bytes的Chunk。Slab之间的差异可以使用Growth Factor控制,默认1.25。

懒过期Lazy Expiration

memcached不会监视数据是否过期,而是在取数据时才看是否过期,过期的把数据有效期限标识为O,并不清除该数据。以后可以覆盖该位置存储其它数据。

LRU

当内存不足时,memcached会使用LRU (Least Recently Used)机制来查找可用空间,分配给新纪录使用。

集群

Memcached集群,称为基于客户端的分布式集群。

Memcached集群内部并不互相通信,一切都需要客户端连接到Memcached服务器后自行组织这些节点,并决定数据存储的节点。

安装

t1和t2

]# yum install memcached -y

]# rpm -ql memcached 
/etc/sysconfig/memcached
/usr/bin/memcached
/usr/bin/memcached-tool
/usr/lib/systemd/system/memcached.service
/usr/share/doc/memcached-1.4.15
/usr/share/doc/memcached-1.4.15/AUTHORS
/usr/share/doc/memcached-1.4.15/CONTRIBUTORS
/usr/share/doc/memcached-1.4.15/COPYING
/usr/share/doc/memcached-1.4.15/ChangeLog
/usr/share/doc/memcached-1.4.15/NEWS
/usr/share/doc/memcached-1.4.15/README.md
/usr/share/doc/memcached-1.4.15/protocol.txt
/usr/share/doc/memcached-1.4.15/readme.txt
/usr/share/doc/memcached-1.4.15/threads.txt
/usr/share/man/man1/memcached-tool.1.gz
/usr/share/man/man1/memcached.1.gz


#前台显示看效果
]# memcached -u memcached -p 11211 -f 1.25 -vv
#-U表示设置UDP监听端口,0表示禁用UDP
]# memcached -u memcached -p 11211 -f 2 -U 0 -vv

修改memcached运行参数,可以使用下面的选项修改/etc/sysconfig/memcached文件

  • -u username memcached运行的用户身份,必须普通用户
  • -p 绑定的端口,默认11211
  • -m num最大内存,单位MB,默认64MB
  • -c num最大连接数,缺省1024
  • -d 守护进程方式运行
  • -f增长因子Growth Factor,默认1.25
  • -v详细信息,-vv能看到详细信息
  • -M内存耗尽,不许LRU
  • -U设置UDP监听端口,0表示禁用UDP
]# memcached -u memcached -p 11211 -f 2 -U 0 -vv

再开一个窗口

]# # yum install memcached -y

协议

]# telnet 127.0.0.1 11211
stats   <--状态

add mykey 1 60 4   <--add增加一个值、增加key、1标记、60秒后过期、4key对应的value值是几个字节
abcd    <--4个字节
STORED    <--存起来了
get mykey    <--去取
VALUE mykey 1 4
abcd
END
set mykey 1 40 5    <--set重置
12345
STORED
get mykey
VALUE mykey 1 5
12345
END
quit    <--退出
Connection closed by foreign host

add key flages exptime bytes,增加key,过期时间为妙,bytes为存储数据的字节数

session共享服务器

msm

msm (memcached session manager)提供将Tomcat的session保持到memcached或redis的程序,可以实现高可用。

目前项目托管在Github,https:l/github.com/magro/memcached-session-manager
支持Tomcat的6.x、7.x、8.x、9.x。

  • Tomcat的Session管理类,Tomcat版本不同
  • memcached-session-manager-2.3.2.jar
  • memcached-session-manager-tc8-2.3.2.jar
  • Session数据的序列化、反序列化类
  • 官方推荐kyro
  • 在webapp中WEB-INF/lib/下
  • 驱动类
  • memcached(spymemcached.jar)
  • Redis(jedis.jar)

安装

github.com/magro/memca…

t1和t2

server参考2.xml

]# cd /usr/local/tomcat/
]# vim conf/server.xml
#里面的集群不要了、所以直接删掉
]# rm -rf /data/webapps/ROOT/WEB-INF/web.xml 

配置

特别注意,t1配置中为failoverNodes="n1",t1配置中为failoverNodes="n2"

]# vim conf/context.xml 
<Context>
...
    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
       memcachedNodes="n1: 192.168.37.14:11211,n2:192.168.37.15:11211"
       failoverNodes="n2"
       requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
       transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
    />
...
</Context>

说明(上面配置处)

memcachedNodes="n1: host1.yourdomain.com:11211,n2:host2.yourdomain.com:11211"
memcached的节点们;n1、n2只是别名,可以重新命名。
failoverNodes故障转移节点,n1是备用节点,n2是主存储节点。另一台Tomcat将n1改为n2,其主节点是n1,备用节点是n2.

msm包kryo包(序列化)内容放到'/lib'下

]# pwd
/usr/local/tomcat
]# cd /lib
#按照时间排序、可以看到上传了11个
]# ll -t  
-rw-r--r-- 1 root root   72265 8月  26 21:35 reflectasm-1.11.9.jar
-rw-r--r-- 1 root root   55684 8月  26 21:35 objenesis-2.6.jar
-rw-r--r-- 1 root root   38372 8月  26 21:35 msm-kryo-serializer-2.3.2.jar
-rw-r--r-- 1 root root    5923 8月  26 21:35 minlog-1.3.1.jar
-rw-r--r-- 1 root root  126366 8月  26 21:35 kryo-serializers-0.45.jar
-rw-r--r-- 1 root root  285211 8月  26 21:35 kryo-3.0.3.jar
-rw-r--r-- 1 root root   53259 8月  26 21:35 asm-5.2.jar
-rw-r--r-- 1 root root  473774 8月  26 21:35 spymemcached-2.12.3.jar
-rw-r--r-- 1 root root   10826 8月  26 21:35 memcached-session-manager-tc8-2.3.2.jar
-rw-r--r-- 1 root root  167294 8月  26 21:35 memcached-session-manager-2.3.2.jar
-rw-r--r-- 1 root root  586620 8月  26 21:35 jedis-3.0.0.jar
...

]# ../bin/shutdown.sh 
]# ../bin/startup.sh 

]# systemctl start memcached
]# systemctl enable memcached

sticky模式

原理

当请求结束时Tomcat的session会送给memcached备份。即Tomcat session为主session,memcached session为session,使用memcached相当于备份了一份Session。

查询Session时Tomca会优先使用自己内存的Session,Tomcat通过jemRoute发现不是自己的Session,便从memcached中找到该Seesion,更新本机Session,请求完成更新memcached。

部署

图片.png

t1和m1部署在一台主机上,t2和m2部署在同一台。

实验

如果配置成功,可以在logs/catalina.out中看到下面的内容

#可以看监控日志
]# cat /usr/local/tomcat/logs/catalina.out
27-Aug-2022 00:40:59.098 INFO [t2.123.com-startStop-1] de.javakaffee.web.msm.MemcachedSessionService.startInternal --------
-  finished initialization:
- sticky: true
- operation timeout: 1000
- node ids: [n1]
- failover node ids: [n2]
- storage key prefix: null
- locking mode: null (expiration: 5s)
--------

配置成功后,网页访问一下,页面中看到了Session。然后运行下面的Python程序,就可以看到是否存储到了memcached中了。

nginx

]# vim /etc/nginx/nginx.conf
...
#此处五行(添加)
    upstream tomcats {
        #ip_hash;    <--注释掉此行
        server t1.123.com:8080;
        server t2.123.com:8080;
    }
...

#重启服务
]# systemctl restart nginx
#查看端口是否开启
]# ss -ntlp|grep nginx

配置成功后,网页访问一下,页面中看到了Session。

图片.png

然后打开PyCharm,运行下面程序,就可以看到是否存储到了memcached中。

图片.png

non-sticky模式

原理

从msm1.4.0之后开始支持non-sticky模式。

Tomcat session为中转Session,n1为主session,n2为备session。产生的新的Session会发送给主、备memcached,并清除本地Session。

n1下线,n2转正。n1再次上线,n2依然时主Session存储节点。

memcached配置

t1和t2

放到'/conf/contesxt.xml'中

]# pwd
/usr/local/tomcat
]# vim conf/context.xml
<Context>
...
    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
       memcachedNodes="n1:192.168.37.14:11211,n2:192.168.37.15:11211"
       sticky="false"
       sessionBackupAsync="false"
       lockingMode="uriPattern:/path1|path2"
       requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
       transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
       />
</Context>

]# bin/shutdown.sh 
]# bin/startup.sh

Pycharm

图片.png

redis配置

下载jedis.jar,放到$CATALINA_HOME/lib/, 对应本次安装就是/usr/local/taomcat/lib

t1

]# yum install redis -y

]# vim /etc/redis.conf 
...
#bind 127.0.0.1
bind 0.0.0.0

]# systemctl start redis
#查看redis端口是否启动
]# ss -ntlp|grep redis
LISTEN     0      128          *:6379                     *:*                   users:(("redi-server",pid=10908,fd=4))

t1、t2

]# pwd
/usr/local/tomcat

]# vim conf/context.xml 
...
<Context>
    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
       memcachedNodes="redis://192.168.37.14:6379"
       sticky="false"
       sessionBackupAsync="false"
       lockingMode="uriPattern:/path1|path2"
       requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
       transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
       />
</Context>
...

]# bin/shutdown.sh
]# bin/startup.sh
...

redis-desktop-manager-0.8.8.384

图片.png 图片.png 图片.png

总结


通过多组使用,使用不同技术实现了session持久机制

  1. session绑定,基于IP或session cookie的。其部署简单,尤其基于session黏性的方式,粒度小,对负载均衡影响小。但一旦后端服务器有故障,其上的session丢失。
  2. session复制集群,基于tomcat实现多个服务器内共享同步所有session。此方法可以保证任意一台后端服务器故障,其余各服务器上还都存有全部session,对业务无影响。但是它基于多播实现心跳,TCP单播实现复制,当设备节点过多,这种复制机制不是很好的解决方案。且并发连接多的时候,单机上的所有session占据的内存空间非常巨大,甚至耗尽内存。
  3. session服务器,将所有的session存储到一个共享的内存空间中,使用多个冗余节点保存session,这样做到session存储服务器的高可用,且占据业务服务器内存较小,是一种比较好的解决session持久的解决方案。

以上的方法都有其适用性。生产环境中,应根据实际需要合理选择。

不过以上这些方法都是在内存中实现了session的保持,可以使用数据库或者文件系统,把session数据库储存起来,持久化。这样服务器重启后,也可以重新恢复session数据。不过session数据时有时效性的,是否需要这样做,视情况而定。