Memacached教程

一、基础知识

1.1 什么是Memcached

Memcached:是一个免费开源的、高性能的、具有分布式内存对象的缓存系统,它通过减轻数据库负载加速动态Web应用;

Memcached的特性:
本质上就是一个内存key-value缓存;
协议简单,使用的是基于文本行的协议;
不支持数据的持久化,服务器关闭之后数据全部丢失;
Memcached简洁而强大,便于快速开发,上手较为容易;
互不通信的Memcached之间具有分布特征(节点与节点之间不做任何通信) ;
没有安全机制

1.2 使用场景

适合:

变化频繁,查询频繁,但不需要入库的场景
变化不频繁,查询频繁
读多邪少的场景中用于页面缓存

不适合:

pv值不高(就是page view页面展示次数不多),不考虑使用Memcached
变化频繁且需要入库(因为Memcached不能持久化,所以入库的场景不用考虑Memcached)
过大的数据不宜放在Memcached中(因为过大的数据本身就不宜放在内存中)

1.3 与Redis对比

在这里插入图片描述
首先来看下线程模型,Redis是单进程单线程的模式,而memcached是单进程多线程,这肯定memcached性能比redis要好那么一点,这样的差距反应在QPS/TPS的比较中,不过这个差别也不是特别的大。没错,这么一比较memcached也并不是一无是处,但这也就是memcached唯一的可圈可点之处了。其他的基本redis超过memcached一大截。

Redis集群与Memcached集群比较
在这里插入图片描述
redis集群,不管是redis中的哨兵还是cluster集群,服务与服务之间是可以有数据的同步的,master的节点数据会通过slaveof的配置参数进行同步
在这里插入图片描述
首先会通过一个Memcached的“应用程序”去访问客户端(中间那一块),这个客户端就是我们的java代码,是这个客户端负责和各个节点之间进行通信的,节点与节点之间是不进行通信的,所以它不支持高可用。

1.4 安装

1.4.1 单机安装
第一步:准备工作
在linux根目录创建soft文件夹(根据自己习惯),输入命令 mkdir /soft
在soft目录里面上传课件里面的两文件 libevent-2.1.8-stable.tar.gz和memcached-1.5.12.tar.gz
第二步:安装libevent
安装Memcached应该先安装好libevent依赖,在soft目录里面执行命tar -xzvf libevent-2.1.8-stable.tar.gz
进入libevent的目录,开始安装libevent,输入以下三条命令

./configure -prefix=/soft/libevent
make
make install

通过上述命令,libevent已经安装到/soft/libevent目录了
在这里插入图片描述
第三步:安装Memcached
在soft目录解压上传的memcached,输入命令tar -zxvf memcached-1.5.12.tar.gz
注意:编译的时候需要指定动态链接库,需要linux把libevent/lib目录加载进来,下面的步骤特别重要
vi /etc/ld.so.conf
在ld.so.conf目录中增加libevent/lib所在目录,wq保存退出

增加(请根据libevent实际安装目录设置)
/soft/libevent/lib
在这里插入图片描述
执行下面命令让上面的修改生效
ldconfig

下面可以正式安装memcached,需要指定libevent的安装位置

./configure -prefix=/soft/memcached --with-libevent=/soft/libevent
make
make install

测试是否安装成功
进入memcached的安装目录下的bin目录
执行:
./memcached -h
在这里插入图片描述
发现有如上界面说明memcached 已经安装成功

Memcached的启动
进入memcached的安装目录下的bin目录
输入以下命令

./memcached -m 16 -p 11211 -d -c 1024 -u root

-d 选项是启动一个守护进程,
-m 是分配给Memcache使用的内存数量,单位是MB,这里是1024MB,默认是64MB
-u 是运行Memcache的用户,这里是root
-l 是监听的服务器IP地址,默认应该是本机
-p 是设置Memcache监听的端口,默认是11211,最好是1024以上的端口
-c 选项是最大运行的并发连接数,默认是1024,这里设置了1024,按照你服务器的负载量来设定
-P 是设置保存Memcache的pid文件位置
-h 打印帮助信息
-v 输出警告和错误信息
-vv 打印客户端的请求和返回信息

查看Memcached是否启动成功,输入命令 ps -ef | grep memcached 查看
在这里插入图片描述

1.4.2 集群安装
memcached 可以安装到多台机器上,安装方式与上面一样。这里就不分别安装了,就在当前的节点上启动多个memcached 实例。
memcached -m 16 -p 11212 -d -c 1024 -u root

memcached -m 16 -p 11213 -d -c 1024 -u root

通过上面两条命令,实际又启动了2个memcached实例,加上上面启动的,总共启动了3个memcached实例

ps -ef | grep memcached 查看
在这里插入图片描述
停止Memcached
Kill -9 进程号
例如现在我要杀掉上图的端口号为11211的Memcached,那么命令是Kill -9 10763

二、客户端使用

2.1 telnet

2.1.1 安装Telnet
安装telnet部分转自https://www.cnblogs.com/sz-jack/p/9760030.html

[root@iZ8vb4ukto7mbo5xsnb2ecZ ~]# rpm -qa xinetd #检查是否安装过
xinetd-2.3.15-13.el7.x86_64
[root@iZ8vb4ukto7mbo5xsnb2ecZ ~]# rpm -qa telnet-server #检查是否安装过
telnet-server-0.17-64.el7.x86_64
[root@iZ8vb4ukto7mbo5xsnb2ecZ ~]# rpm -e --nodeps xinetd-2.3.15-13.el7.x86_64 telnet-server-0.17-64.el7.x86_64 #卸载已经存在的安装文件


[root@iZ8vb4ukto7mbo5xsnb2ecZ ~]# yum list |grep telnet
dcap-tunnel-telnet.x86_64 2.47.12-4.el7 epel
libguac-client-telnet.x86_64 1:0.9.14-1.el7 epel
libtelnet.x86_64 0.21-5.el7 epel
libtelnet-devel.x86_64 0.21-5.el7 epel
libtelnet-utils.x86_64 0.21-5.el7 epel
telnet.x86_64 1:0.17-64.el7 base
telnet-server.x86_64 1:0.17-64.el7 base


[root@iZ8vb4ukto7mbo5xsnb2ecZ ~]# yum list |grep xinetd
xinetd.x86_64 2:2.3.15-13.el7 base

3,执行安装语句
    yum -y install telnet-server.x86_64
    yum -y install telnet.x86_64
    yum -y install xinetd.x86_64

4,设置开机自启:

systemctl enable xinetd.service
systemctl enable telnet.socket#这个命名如果第一次执行报错,再执行下即可。 

5,开启service:

systemctl start telnet.socket
systemctl start xinetd

2.1.2 使用telnet操作Memcached
1,连接Memcached(注意在telnet中删除是要按着ctrl键进行删除的看):
命令telnet ip 端口
例如 telnet 127.0.0.1 11211
输入telnet命令之后回车然后输入stats再回车
在这里插入图片描述
2,Memcached的命令:
在这里插入图片描述
例如存储命令语法格式举例:

set key flags exptime bytes [noreply] 
    value 

参数解释(这些参数不仅适用于set命令):

key:键值 key-value 结构中的 key,用于查找缓存值。
flags:可以包括键值对的**整型**参数,客户机使用它存储关于键值对的额外信息 。
exptime:在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)
bytes:在缓存中存储的字节数
noreply(可选): 该参数告知服务器不需要返回数据
value:存储的值(始终位于第二行)(可直接理解为key-value结构中的value)

输出信息:

STORED:保存成功后输出。
ERROR:保存出错或语法错误。
EXISTS:在最后一次取值后另外一个用户也在更新该数据。
NOT_FOUND:Memcached 服务上不存在该键值

例如在这里插入图片描述
replace,如果不存在此key,则失败
set,如果存在此key则是修改,不存在则新增

轻量级的所机制CAS机制(本质就是一个乐观锁)
解释:Check and set,即保存之前进行版本检查,memcache1.2.4新增的特性
在这里插入图片描述
在这里插入图片描述
有了版本号之后就可以用CAS更新了

查找相关命令
在这里插入图片描述

2.2 Java客户端

在这里插入图片描述

2.2.1 Memcached-Java-Client
在这里插入图片描述在这里插入图片描述
2.2.2 spymemcach
2.2.3 XMencached
2.2.4 Spring Cache集成实战

三、原理

3.1 一致性Hash算法(重点)

3.1.1 Hash算法
如果不是在分布式环境下就不要选择一致性Hash。memcached的单节点是有存储局限的,所以有时候需要用到多节点,那么集群memcached就有一个分布式存储与分布式读取的问题,不管是写入还是读取,肯定要通过某种算法来把写入或读取操作定位到某个固定的节点。
在这里插入图片描述
3.1.2 余数分散(普通Hash)
在这里插入图片描述
整个过程可以看出公式
公式:m = hash(o) mod n
在这里插入图片描述
3.1.3 一致性Hash算法
在这里插入图片描述
一致性hash是为了解决普通hash的问题,使用一个环状结构,具体可以分层4步骤。
步骤1:构建环形hash空间
在这里插入图片描述
说明:
一致性hash算法通过一个叫作一致性hash环的数据结构实现
这个环的起点是0,终点是2^32 - 1,并且起点与终点连接,环的中间的整数按逆时针分布
这个环的整数分布范围是[0, 2^32-1]

步骤二:把对象映射到环形hash空间

假设现在我们有4个对象,他们的key分别为o1,o2,o3,o4,通过这些key可以找到对应的对象,
使用hash函数计算这4个对象的hash值(范围为0 ~ 2^32-1)
在这里插入图片描述
步骤三:把cache节点映射到hash空间
使用同样的hash函数,我们将机器也放置到hash环上。
假设我们有三台缓存机器,分别为 c1,c2,c3,一般使用节点对应的ip作为c1,c2,c3
使用hash函数计算这3台机器的hash值
在这里插入图片描述
步骤四:对象映射到cache节点
将对象和机器都放置到同一个hash环后
在hash环上顺时针查找距离这个对象的hash值最近的机器,即是这个对象所属的机器。
在这里插入图片描述
步骤五:增加一个节点的情况
在这里插入图片描述增加机器c4的部署并将机器c4加入到hash环的机器c3与c2之间。
只有对象o4被重新分配到了c4
其他对象仍在原有机器上

步骤六:删除一个节点的情况
在这里插入图片描述
将机器c1下线(当然,也有可能是机器c1宕机)
只有对象o2被重新分配到机器c3
其他对象仍在原有机器上

步骤七:虚拟节点
仅仅使用真实的节点来形成环的结构可能会导致数据的倾斜,为了解决这种数据不对称的现象,可以在原理缓存的机器的基础上,增加相应的虚拟节点,这样数据就会均匀的打散到其他节点中。
在这里插入图片描述
这个时候客户端进行数据存取的时候找的就是虚拟节点,而不是真实的物理节点服务器。
在这里插入图片描述
这样增加节点会删除节点虽然命中率会降低,却很好的解决了数据倾斜问题。

3.2 内存管理策略

Memcached采用Slab Allocator(Slab分配器)进行内存管理
3.2.1 Slab
在这里插入图片描述

内存被拆分为多个SlabClass
每个Slab Class中有多个Slab 每个Slab=1M
每个Slab下有多个大小相等的Chunk
不同Slab中的Chunk大小不等
数据存储在Chunk中

3.2.2 增长因子
步骤一:启动Memcached,启动时加上-vv参数
memcached -p 11211 -d -u root -vv
其中-vv显示memcached的内存分配情况,如下图所示

在这里插入图片描述
这里会显示memcached内存会分配的情况。
每一行的显示如下
slab class 1: chunk size 96 perslab 10922
其中chunk size 为96,总共有10922个块

96*10922=1048512/1024/1024 = 0.9999 M

步骤二:客户端测试
使用telnet 连接上服务端
telnet 127.0.0.1 11211

查看内存分布情况
stats slabs
在这里插入图片描述
可以看到激活的slabs的数目为0,可以分配的内存也是0

新增一个数据
add k1 0 0 10
1234567890

在使用stats查看内存分布情况
在这里插入图片描述
再新增一个数据
add k2 0 0 10
1234567890
在这里插入图片描述
这个时候发现已经用了2个块。
新增一个数据
add k3 0 0 100
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
在这里插入图片描述
启动时指定增长-f(growth factor)因子,就可以在某种程度上控制slab之间的差异,默认值为1.25 命令
memcached -p 11211 -f 2 -d -u root -vv
在这里插入图片描述
注意:真实项目中,要均衡数据的大小,如果数据之间大小差别不大建议增长因子设置比较小,而数据之间大小悬殊,数据的增长因子可以考虑增大。

3.3 缓存过期策略

MC不会主动删除过期数据,而是采用lazy策略
Memcached不会释放已分配的内存,其存储空间可以重复使用
Memcached内部不会监视数据是否过期,而是在get时查看数据的时间戳,查看数据是否过期。被称为lazy expiration(惰性过期)
Memcached内存空间不足,即无法从slab class中获取到新的空间时,就从最近未被使用的数据中搜索,将其空间分配给新的数据。(如果要禁用LRU,使用-M参数,超出会报错)

以上内容来自“腾讯享学课堂”笔记整理 | 转载请保留此段文字

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值