开发者学堂课程【Tomcat 服务器入门详解:Memcached 和 Msm】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/654/detail/10849
Memcached 和 Msm
一、Memcached 和 Msm
1、Memcached 只支持能序列化的数据类型,不支持持久化,基于 Key-Value 的内存缓存系统。
只能序列化的意思,就是说既然要进行存储,就必须将数据类型变成子块。
编程语言种内存当中它是有数据结构,不是所有的数据结构就可以直接把它搬出来,变成自己的,其实在内存中它是有结构。现在你将立体结构压扁了,拽着变成一条线。请注意,不是所有结构都可以。你要把它压紧,拉直变成一条线儿,所以极其麻烦。
而且不是所有的数据类型都支持这种序列化的概念。对于跨境通讯,必须进行序列化。对方收到的呢,必须进行反序列化。序列化与反序列化是必须的,序列化与反序列化的关系就跟国与国的关系一样。一定存在性能的损失,因为不能所有任务都让一个进程进行。序列化是前提。Redis也有这个前提,他的数据类型在存储之前就已经进行了序列化。
2内存分配机制
应用程序运行需要使用内存存储数据,但对于缓存系统来说,申请内存、常容易导致大量内存碎片,最后导致无连续可用内存可用。
内存分配机制。那么对于一个程序来讲。要存储东西。而且是高效得进行存储,并且像缓存一样使用,就有一个生命周期,就会有时长。三十分钟或者一分钟。周期要存进去,生命周期要到了,数据就必须离开内存。
内存中就会产生下述的现象。其实内存中经常会有这样的。尤其对于C语言这种没人回收,规整的内存来讲。所有的内存操作全部自己实现。那么说就有可能出现以下情况。比如说。假如在使用内存的时候,内存是连续编制的。
内存连续编制的的地址。如下图所示,这个房间呢,是一号二号,三号四号。5678,总共八个房间,内存总共就这么大,假如今天A客人来了,A客人是散客,B客人是两位,他们直接挨着房间住,C客人来了三个,
此时B客人退房,在真正内存中只需要标记内存无人使用即可,然后直接标记数据覆盖。
之后又来了D客人,为四个人,他们提出需要连续的房间,则就创建失败。这种内存我们就成为数据化内存,很多数据结构必须是连续的不能断开。
但是内存总余量是足够的,这种内存称为叫碎片化,那时候很多数据结构,就必须连续的,中间不能断。
四个人,要联系在一起就相当于三个模拟数字。这个数字来说,实际上内存的空余量是总容量还是有剩余容量还是头。但是开票那种区域直接报错。频繁的申请内存会释放内存,如果这个程序员仅仅就是像这样去使用。
如果对一个繁忙系统传递数据比较多,未来你就会发现。数据都是存在里面,但是它会出现很多不连续的区域。我们把这种不连续区域叫做内存中的空洞,目前进程中的空间,碎片化极为严重。总容量是够的。但是要开辟一个内存就不够使用。
假如现在来了E客人,E1分配到1位置,E2分配到2位置,假如再来一个人则没有位置可以分配。数组是可变的,也就是说数组是可以扩展。数字扩展一个一二可以在这儿,对于这种连续存放
的数据就会出问题。其实kv对也是连续存放的,而且开辟更大。
所以内存中其实大多数数据都是连续的。如果你感觉它好像存在数据,但只是感觉而已,所以这样没有连续的大片空间的话,就会导致我们的数据结构申请失败。会导致异常,甚至会影响整个进程。或者说没有内存可以使用,没办法扩展内存可用。所以碎片化是最不想看到的内容,建议用C语言和C++,而不建议使用python和Java,因为性能比较差。而C语言或者C++如何处理好,就是设置大小不一的架子,将合适的内容放进去,运行之后,架子不改变,之后遇到合适的再次放进去就可以。要是跟Java一样不停规整内存,就会更复杂一些。
Memcached采用了Slab Allocator机制来分配、管理内存。
Page:分配给Slab的内存空间,默认为1MB,分配后就得到一个Slab。Slab分配之后内存按照固定字节大小等分成chunk。
Chunk:用于缓存记录kv值的内存空间。Memcached会根据数据大小选择存到哪一个chunk中,假设chunk有128bytes、64bytes,数据只有100bytes存储在128bytes中,存在些浪费。
o Chunk最大就是Page的大小,即一个Page中就一个Chunk. Slab Class: Slab按照大小分组,就组成不同的Slab Class
3、内存模型
理解:采用一种叫Slab Allocator这样的机制。内存分配机制来管理。
把内存分页其实,就像之前例子种在墙上打不同的格子。但是机制也不知道未来你要打多少。所以会先打一个。然后留一部分,看你什么时候用就再打。
它采用这种机制,会先给内存分页儿,假如大概规定一兆为页。那分出来的这一页,名字就叫做Slab。或者将长条当作一块,是根据如何使用来划分的。
就像刚才画了个大的四个格子是吧,这四个格子上。上面两个,下面两个,就相当于一个step,是其中的一个。然后拿着一个之后呢,他在里面再打小格子,将数据存放在合适大小的格子里。这个格子叫做chunk,那些大小一样的格子就被分为一组,叫做Slab class就是一页一个啊,左上角这上面显示96啊,96。那就是说取到一个之后。那个一段之后。将一页分为96个字段,第二个再拿出一页,一页分为120个字段。
它是由增量的,但是这个增量不能为二倍增量。因为二倍之后就会有很大一个空挡,就浪费掉了,下一个Chunk比上一个Chunk大的内容就叫做增长因子。
在一个clunk里面所有的格子大小都是相同的。然后在格子里面再增加增量画格子。知道最后一兆一片。画到一兆会暂停一下,除非不够用。就全部放在一边不管,这就是待分配的页。
有个96字节,有个120字节,假如有个96字节,放在第一个里面刚刚好,假如有个5字节,只能放在96字节中。在塞得进去的前提下,一个小格子中只能放一个kv对。假如有个100字节就只能放在120中,因为比96大,比120小。
格子的大小是自己确定的,一个比一个大小的增量一般是合理的,符合你所存储数据的增量。要考虑你所存储的数据最小是多大,最多是多大,要查看分布,合理划分小格子,这样会更省空间。也就是提前碎片化,将他分为许多格子,将合适的大小放到合适的格子里面。假如没有内容就标记为空。
Memcached就是有一个内容就占一个格子,假如所有格子都被占用,就查看之前大小适用的格子,将过期的内容直接覆盖。
如果有100bytes要存,那么Memcached会选择上图中Slab Class 2存储,因为它是120bytes的Slab之间的差异可以使用Growth Factor控制,默认1.25。
懒过期Lazy Expiration
memcached不会监视数据是否过期,而是在取数据时才看是否过期,过期的把数据有效期限标识为0, 并不清除该数据。以后可以覆盖该位置存储其它数据。
LRU(最近最少使用)
当内存不足时,memcached会使用LRU (Least Recently Used)机制来查找可用空间,分配给新纪录使用。
集群
Memcached集群,称为基于客户端的分布式集群。
Memcached集群内部并不互相通信,- 切都需要客户端连接到Memcached服务器后自行组织这些节点,并决定数据存储的节点。
4、安装
# yum install Memcached
# rpm -ql Memcached
/etc/sysconfig/Memcached
/usr/bin/Memcached
/usr/bin/memcached-tool
[ root@nodex tomcat] # yum install Memcached
为依赖而安装:
li bevent x86_ 64 2.0.21-4.e17 base
(2)查看装了什么东西
[ root@nodex tomcat]# rpm -q1 memcached
/etc/ sysconf ig/ Memcached
/usr/bin/ Memcached
/usr/bin/ memcached-tool
/ usr/ 1ib/ systemd/ system/ memcached. Service
/ usr/ share/doc/ memcached-1.4.15
/ usr/ share/ doc/ memcached-1.4.15/ AUTHORS
/usr/ share/ doc/ memcached-l.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.mo
/ usr/ share/doc/ memcached-1.4.15/protocol.txt
/ usr/ share/doc/ memcached-1.4.15/resdm.txt
/usr/ share / man/ manl / memcached- tool.1.gz
/usr/ share/ man/ manl / memcached.1.gz
[root@nodex tomcat]# cat /usr/lib/ systemd/ system/me
memcached. service messagebus . service
[ root@nodex tomcat]# cat /usr/ 1ib/ systemd/ sys tem/ memcached. Service
[Unit]
Description-Memcached
Before-httpd. Service
After=network. Target
[Service]
Type=s imple
Envi ronmentFile=- /etc/sysconfig/Memcached
ExecStart= /usr/bin/ memcached -u $USER -P $PORT -m $CACHESIZE -C SMAXCONN SOPT IONS
[Install ]
WantedBy-multi -user. Target
[ root @nodex t omcat] #
告诉我们在运行之前要检查环境变量。
[ root@nodex tomcat]# cat /etc/ sysconf ig/ Memcached
PORT="11211"
USER= "memcached"
MAXCONN=" 1024"
CACHESIZE=" 64"
OPTIONS=""
手动也可以启动,就用它提供的用户。
[ root@nodex tomcat] # memcached -u memcached -P 11211 -VVV
slab class 1: chunk size 96 perslab 10922
slab class 2: chunk size 120 perslab 8738
以上就是分片。96 perslab就是将一个分片分为96字段,:10922
在这一片上分成了10922个小格子,然后以增长量为1.25进行分片,直到一兆一片。
[root@nodex tomcat]# Memcached-h
memcached 1.4.15
-P TCP port number to listen on (default: 11211)
-U UDP port number to listen on (default: 11211, 0 is off)
-s UNIX socket path to listen on (disables network support )
-a access mask for UNIX socket, in octal (default: 0700)
-1 interface to listen on (default: INADDR ANY, all addresses ) may be specified as host:port. If you don't specify
-m max memory to use for items
-f chunk size groeth factor(default:1.25)
[ root@nodex tomcat] # memcached -u memcached -P 11211 -VVV-f 2
很快就到1兆了,一般都是大家在线上运行一段时间之后,在线上统计一下数据,然后考虑数据如何分比较合适。
[root@nodex tomcat]# systemctl start memached
[root@nodex tomcat]# ss -tan1
客户端也很多,给他搞了一个驱动的api,通过编程的方式就可以直接访问。
[ root@nodex tomcat]# yum 1 ist 1 grep Memcached
mehcached.x86 64 1.4.15-10.e173.1 @base
1 i bmemcached.1686 1.0.16-5.e17 base
1 i bmemcached.x86_ 64 1.0.16-5.e17 base
1 i bmemcached-devel. i686 1.0.16-5.e17 base
1 i bmemcached-devel.x8664 1.0.16-5.e17 base
memcached-devel.1686 1.4.15-10.e17 3.1 base
memcached-devel.x86 64 1.4.15-10.e17 3.1 base
memcached-devel.1686 1.4.15-10.e17 3.1 base
opensips memcached.x86 64 1.4.15-10.e17 3.1 epe 1
php- ZendE r amewor k -Cache Backend Libmemcached . noarch
php- pecl一memcached.x8664 2.2.0-1.e17 epe 1
python- memcached. Noarch 1.48-4.e17 base
uwsgi一router -memcached.x86 64 2.0.17.1-2.e17 epe 1
上面就是ed库,可以用来分片,也可以直接用来调用memcached
python- memcached安装了之后就可以直接用python语言直接连接驱动库,就可以使用memcached来操作,这就是所说的python- memcached安装了之后就可以直接用python语言直接连接驱动库,就可以使用memcached来操作,这就是所说的题。
[ root@nodex tomcat]# yum install telnet
已加载插件: fas testmi r ror
软件包1 :telnet-0.17-64.e17.x8664安装 并且是最新版本
[ root@nodex tomcat]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Stas
运行结果:一些记录的信息
Add mykey 1 60 4
Test
STORED
Get mykey
Value mykey 1 4
Test
END
生命周期只有60秒,也就是说通过这种方式,我们可以存kv对,没有其他数据类型,可以认为存取的都是字符串,转换一下看就是一个字节,一个字节的,此为可以序列化的数据。
修改memcached运行参数,可以使用下面的选项修改/etc/sysconfig/memcached文件
-u username memcached运行的用户身份,必须普通用户
-P绑定的端口,默认11211
-m num最大内存,单位MB,默认64MB
-C num最大连接数,缺省1024
-d 守护进程方式运行
-f增长因子Growth Factor,默认1.25
-v详细信息,-v能看到详细信息
-M内存耗尽,不许LRU F(一般来说内存占完之后,是会将最近最少使用的合适大小格子中的内容换出,但是此行内容是不许使用)
-U设置UDP监听端口,0表示禁用UDP
协议
查看/usr/share/doc/memcached-1.4.15/protocol.txt
# yum install telnet
# telnet locahost 11211
Stats
add mykey 1 60 4
test
STORED
get mykey
VALUE mykey 1 4
Test
END
set mykey 1 60 5
test1
STO
RED
VALUE mykey 1 5
test1
END