Memcached

Memcached

一、NoSQL介绍

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

NoSQL一词诞生于1998年,2009年这个词汇被再次提出指非关系型、分布式、不提供ACID的数据库设计模式。随着互联网时代的到来,数据爆发式增长,数据库技术发展日新月异,要适应新的业务需求。而随着移动互联网、物联网的到来,大数据的技术中NoSQL也同样重要。

数据库排名:

https://db-engines.com/en/ranking

NoSQL 分类

  • Key-value Store k/v数据库
    • 性能好 O(1) , 如: redis、memcached
  • Document Store 文档数据库
    • mongodb、CouchDB
  • Column Store 列存数据库,Column-Oriented DB
    • HBase、Cassandra,大数据领域应用广泛
  • Graph DB 图数据库
    • Neo4j
  • Time Series 时序数据库
    • InfluxDB、Prometheus

二、Memcached

  • 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等

Memcached 官网:

http://memcached.org/

三、Memcached 和 Redis 比较

比较类别Redismemcached
支持的数据结构哈希、列表、集合、有序集合纯kev-value
持久化支持
高可用支持redis支持集群功能,可以实现主动复制,读写分离官方也提供了sentinel集群管理工具,能够实现主从服务监控,故障自动转移,这一切,对于客户端都是透明的,无需程序改动,也无需人工介入需要二次开发
存储value容量最大512M最大1M
内存分配临时申请空间,可能导致碎片预分配内存池的方式管理内存,能够省去内存分配时间
虚拟内存使用有自己的VM机制,理论上能够存储比物理内存更多的数据,当数据超量时,会引发swap,把冷数据刷到磁盘上所有的数据存储在物理内存里
网络类型非阻塞IO复用模型,提供一些非KV存储之外的排序聚合功能,在执行这些功能时,复杂的CPU计算,会阻塞整个IO调度非阻塞IO复用模型
水平扩展支持redis cluster 可以横向扩展暂无
多线程Redis6.0之前是只支持单线程Memcached支持多线程,CPU利用方面Memcache优于redis
单机QPS约10W约60W
源代码可读性代码清爽简洁可能是考虑了太多的扩展性,多系统的兼容性,代码不清爽
适用场景复杂数据结构、有持久化、高可用需求、value存储内容较大纯KV,数据量非常大,并发量非常大的业务

四、Memcached 工作机制

1、内存分配机制

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

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

  • Page:分配给Slab的内存空间,默认为1MB,分配后就得到一个Slab。Slab分配之后内存按照固定字节大小等分成chunk。

  • Chunk:用于缓存记录k/v值的内存空间。Memcached会根据数据大小选择存到哪一个chunk中,假设chunk有128bytes、64bytes等多种,数据只有100bytes存储在128bytes中,存在少许浪费。

  • Chunk最大就是Page的大小,即一个Page中就一个Chunk

  • Slab Class:Slab按照Chunk的大小分组,就组成不同的Slab Class, 第一个Chunk大小为 96B的Slab为Class1,Chunk 120B为Class 2,如果有100bytes要存,那么Memcached会选择下图中Slab Class 2 存储,因为它是120bytes的Chunk。Slab之间的差异可以使用Growth Factor 控制,默认1.25。

查看Slab Class

#-f, --slab-growth-factor=<num> chunk size growth factor (default: 1.25)
[root@centos7 ~]#memcached -u memcached -f 2 -vv
slab class   1: chunk size        96 perslab   10922
slab class   2: chunk size       192 perslab    5461
slab class   3: chunk size       384 perslab    2730
slab class   4: chunk size       768 perslab    1365
slab class   5: chunk size      1536 perslab     682
slab class   6: chunk size      3072 perslab     341
slab class   7: chunk size      6144 perslab     170
slab class   8: chunk size     12288 perslab      85
slab class   9: chunk size     24576 perslab      42
slab class  10: chunk size     49152 perslab      21
slab class  11: chunk size     98304 perslab      10
slab class  12: chunk size    196608 perslab       5
slab class  13: chunk size    524288 perslab       2
<27 server listening (auto-negotiate)
<28 server listening (auto-negotiate)

2、懒过期 Lazy Expiration

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

3、LRU(最近最少使用算法)

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

4、 集群

  • Memcached集群,称为基于客户端的分布式集群,即由客户端实现集群功能,即Memcached本身不支持集群

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

五、安装和启动

官方安装说明

https://github.com/memcached/memcached/wiki/Install

1、yum 安装

yum info memcached
#查看memcached软件包的详细信息

yum install -y memcached
#安装memcached

cat /etc/sysconfig/memcached
#查看memcached配置文件
PORT="11211"     #监听端口
USER="memcached" #启动用户
MAXCONN="1024"  #最大连接数
CACHESIZE="64"  #最大使用内存
OPTIONS="" #其他选项

image-20240314114659033

image-20240314114835926

2、编译安装

yum -y install gcc libevent-devel
#安装

wget http://memcached.org/files/memcached-1.6.6.tar.gz
#下载

tar xvf memcached-1.6.6.tar.gz
#解压

cd memcached-1.6.6/
#切换目录

./configure --prefix=/apps/memcached
#指定安装目录

make -j2 && make install
#编译及安装

echo 'PATH=/apps/memcached/bin:$PATH' > /etc/profile.d/memcached.sh
#编辑脚本

. /etc/profile.d/memcached.sh
#执行

useradd -r -s /sbin/nologin memcached
#新建用户

#编辑配置文件
cat >    /etc/sysconfig/memcached    << eof
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS=""
eof

#准备service文件,使用systemctl管理服务
cat  > /lib/systemd/system/memcached.service    << eof
[Unit]
Description=memcached daemon
Before=httpd.service
After=network.target
[Service]
EnvironmentFile=/etc/sysconfig/memcached
ExecStart=/apps/memcached/bin/memcached -p  \${PORT} -u \${USER} -m \${CACHESIZE} -c \${MAXCONN} \$OPTIONS
[Install]
WantedBy=multi-user.target
eof

systemctl daemon-reload
#重新加载配置文件

systemctl start memcached.service
#开启服务

systemctl status memcached.service
#查看状态

memcached --version
#查看memcached版本

memcached -u memcached -m 1024 -c 65536 -d
#将memcached服务放入后台执行

image-20240314120104713

image-20240314120229887

image-20240314120359919

image-20240314120542126

3、memcached 启动程序说明

  • 修改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

1、memcached 开发库和工具

  • 与memcached通信的不同语言的连接器。libmemcached提供了C库和命令行工具。
#客户端操作步骤
yum install  libmemcached -y 
#安装工具包

memping --help
#可以查看memeping命令的帮助

memping --server 192.168.10.11
#检测连接服务器
echo $?
0

[root@localhost ~]#systemctl stop memcached.service
#关闭服务端的memcached服务

memping --server 192.168.10.11
#检测连接服务器
echo $?
1

memstat --servers=192.168.10.11
#可以查看memcached服务端的详细信息

image-20240314122416979

2、memcached 操作命令

memcached操作命令

cat /usr/share/doc/memcached-1.4.15/protocol.txt
#查看memcached相关操作命令

image-20240314135333477

四种基本 memcached 命令执行最简单的操作

  • set:重新设置
  • add:新加一个数据
  • get:调用数据
  • delete:删除数据
#前三个命令是用于操作存储在 memcached 中的键值对的标准修改命令,都使用如下所示的语法:
command <key> <flags> <expiration time> <bytes>
<value>

#参数说明如下:
command set/add/replace
key    #用于查找缓存值
flags     #可以包括键值对的整型参数,客户机使用它存储关于键值对的额外信息
expiration time     #在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)
bytes     #在缓存中存储的字节数
value     #存储的值(始终位于第二行)
#增加key,过期时间为秒,bytes为存储数据的字节数
add key flags exptime bytes  
2.1 显示服务状态
[root@liuyanfen12 ~]#telnet 192.168.10.11 11211
Trying 192.168.10.11...
Connected to 192.168.10.11.
Escape character is '^]'.

stats
#显示当前服务状态

stats items
#显示各个 slab 中 item 的数目和存储时长(最后一次访问距离现在的秒数)。

stats slabs
#用于显示各个slab的信息,包括chunk的大小、数目、使用情况等

image-20240314141421463

2.1 添加数据
[root@liuyanfen12 ~]#telnet 192.168.10.11 11211
Trying 192.168.10.11...
Connected to 192.168.10.11.
Escape character is '^]'.
add name 1 0 4
xxxx
STORED

#相关说明
add  	#添加
name  	#键的名字
1    	#flages标志,描述信息
30   	#超时时间(默认秒,0代表永久有效)
4    	#字节数(数据的大小)
xxxx 	#具体的值

image-20240314140311703

2.3 修改
#修改数据
set name 1 0 2
qi
STORED

image-20240314140711367

2.4 调用数据
#调用数据
get name
VALUE name 1 4
xxxx
END

image-20240314140454606

2.5 删除
get name
#调用
VALUE name 1 2
qi
END

ERROR
delete name
#删除
DELETED

ERROR
get name
#调用
END

ERROR

image-20240314140852993

七、memcached 集群部署架构

1、Repcached 实现原理

项目站点

http://repcached.sourceforge.net/
  • 在 master上可以通过 -X 选项指定 replication port(默认为11212/tcp),在 slave上通过 -x 指定复制的master并连接,事实上,如果同时指定了 -x/-X, repcached先会尝试连接对端的master,但如果连接失败,它就会用 -X参数来自己 listen(成为master);如果 master坏掉, slave侦测到连接断了,它会自动 listen而成为 master;而如果 slave坏掉,master也会侦测到连接断开,它就会重新 listen等待新的 slave加入。

  • 从这方案的技术实现来看,其实它是一个单 master单 slave的方案,但它的 master/slave都是可读写的,而且可以相互同步,所以从功能上看,也可以认为它是双机 master-master方案

2、简化后的部署架构

  • magent已经有很长时间没有更新,因此可以不再使用magent,直接通过负载均衡连接到memcached,仍然有两台memcached做高可用,repcached版本的memcached之间会自动同步数据,以保持数据一致性,即使其中的一台memcached故障也不影响业务正常运行,故障的memcached修复上线后再自动从另外一台同步数据即可保持数据一致性。

3、部署repcached

yum -y install gcc libevent libevent-devel
#安装依赖环境

wget  https://jaist.dl.sourceforge.net/project/repcached/repcached/2.2.1-1.2.8/memcached-1.2.8-repcached-2.2.1.tar.gz
#下载需要的安装包(注意版本信息)

tar xf memcached-1.2.8-repcached-2.2.1.tar.gz
#解压

cd memcached-1.2.8-repcached-2.2.1
#切换目录

./configure --prefix=/apps/repcached --enable-replication
#指定安装目录

make 
#此时编译,会发生报错,需要修改配置文件

#修改配置文件
vim memcached.c
56 #ifndef IOV_MAX
57 #if defined(__FreeBSD__) || defined(__APPLE__)
58 # define IOV_MAX 1024
59 #endif
60 #endif

#改为如下内容,即删除原有的原第57,59行
56 #ifndef IOV_MAX
57 # define IOV_MAX 1024
58 #endif

make -j2 && make install 
#再次编译并安装

tree /apps/repcached/
#查看安装的文件

ln -s /apps/repcached/bin/memcached  /usr/bin/
#做软连接

memcached -h
#查看使用帮助
-x <ip_addr>  hostname or IP address of peer repcached

image-20240314144358946

image-20240314144606945

image-20240314144900948

image-20240314145053971

4、启动 memcached

4.1 server1 相关操作
  • 地址:192.168.10.12
useradd -r -s /sbin/nologin memcached
#创建用户

memcached -d -m 1024 -p 11211 -u memcached -c 2048 -x 192.168.10.11
#后台运行启动
-d后台运行
-m最大内存1024
-p指定端口号11211
-u指定用户身份是memcached
-c最大连接数2048
-x指定同步信息是192.168.10.11

ss -ntl
# 查看是否启动

image-20240314145836940

4.2 server2 相关操作
  • 地址:192.168.10.11
rsync -a /apps   192.168.91.101:/
#在server1上将整个目录拷贝到server2上(同步),apps注意不要加/  


##其余操作在server2服务器上进行
ln -s /apps/repcached/bin/memcached  /usr/bin/
#做软连接

useradd -r -s /sbin/nologin memcached
#创建用户

yum -y install gcc libevent libevent-devel
#安装依赖库,否则服务起不来

memcached -d -m 1024 -p 11211 -u memcached -c 2048 -x 192.168.10.12
#指定与server1同步,后台运行

ss -ntl|grep 11211
# 查看是否启动

image-20240314150354963

image-20240314151317734

4.3 查看 server1 和 server2 同步
  • 地址:192.168.10.13
#登录192.168.10.11
telnet 192.168.10.11 11211
Trying 192.168.10.11...
Connected to 192.168.10.11.
Escape character is '^]'.
#添加数据
add name 1 0 4
xxxx
STORED
quit
Connection closed by foreign host.

#登录192.168.10.12
telnet 192.168.10.12 11211
Trying 192.168.10.12...
Connected to 192.168.10.12.
Escape character is '^]'.
#调用数据,与192.168.10.11添加的数据相同,数据同步
get name
VALUE name 1 4
xxxx
END

ERROR
quit
Connection closed by foreign host.

image-20240314152749033