使用背景
Memcached 不是一个数据库,而是一个高性能的分布式内存对象缓存系统。它主要用于减轻数据库负载,提高动态Web应用的速度、可扩展性和性能。Memcached 的工作原理是将数据存储在内存中,以提供快速的数据访问。当应用程序需要访问数据时,它首先检查内存中是否有这个数据。如果内存中有这个数据,应用程序就可以直接从内存中获取数据,而不需要访问数据库。这样可以大大提高数据访问的速度。
目录
一、Memcached 介绍
1. NoSQL介绍
NoSQL是对 Not Only SQL、非传统关系型数据库的统称。NoSQL一词诞生于1998年,2009年这个词汇被再次提出指非关系型、分布式、不提供ACID的数据库设计模式。随着互联网时代的到来,数据爆发式增长,数据库技术发展日新月异,要适应新的业务需求。而随着移动互联网、物联网的到来,大数据的技术中NoSQL也同样重要。
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
2. Memcached
Memcached 只支持能序列化的数据类型,不支持持久化,基于Key-Value的内存缓存系统。memcached 虽然没有像redis所具备的数据持久化功能,比如RDB和AOF都没有,但是可以通过做集群同步的方式,让各memcached服务器的数据进行同步,从而实现数据的一致性,即保证各memcached的数据是一样的,即使有任何一台 memcached 发生故障,只要集群中有一台 memcached 可用就不会出现数据丢失,当其他memcached 重新加入到集群的时候,可以自动从有数据的memcached 当中自动获取数据并提供服务。
Memcached存储数据时,Memcached会去申请1MB的内存,把该块内存称为一个slab,也称为一个page
Memcached 支持多种开发语言,包括:JAVA,C,Python,PHP,C#,Ruby,Perl等
Memcached 官网:memcached - a distributed memory object caching system
3. Memcached 和 Redis 比较
相似之处:
① 内存存储:Memcached 和 Redis 都是将数据存储在内存中,以提供快速的数据访问。
② 键值存储:Memcached 和 Redis 都是使用键值对的方式来存储数据。
③ 分布式:Memcached 和 Redis 都支持分布式存储,可以在多台服务器上运行。
不同之处:
比较类别 | Redis | memcached |
数据类型 | 支持更多的数据类型,包括字符串、列表、集合、有序集合、哈希表等 | 只支持字符串 |
持久化支持 | 支持数据持久化,可以将数据保存到磁盘上 | 不支持数据持久化,如果服务器重启,所有的数据都会丢失 |
高可用支持 | 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,数据量非常大,并发量非常大的业务 |
社区支持 | Redis 的社区支持更好,有更多的插件和工具可以使用 | 支持较少 |
4. Memcached 工作机制
① 数据存储:Memcached 将数据存储在内存中,以提供快速的数据访问。当应用程序需要访问数据时,它首先检查内存中是否有这个数据。如果内存中有这个数据,应用程序就可以直接从内存中获取数据,而不需要访问数据库。
② 数据分片:Memcached 将数据分片存储在多台服务器上。这样可以提高系统的可扩展性和性能。例如,如果你有 10 GB 的数据,你可以将这 10 GB 的数据分片存储在 10 台服务器上,每台服务器存储 1 GB 的数据。
③ 数据访问:当应用程序需要访问数据时,它首先计算数据的键,然后根据这个键选择一个服务器。然后,应用程序就可以直接从这个服务器获取数据。
④ 数据更新:当应用程序更新数据时,它首先计算数据的键,然后根据这个键选择一个服务器。然后,应用程序就可以直接在这个服务器上更新数据。
⑤ 数据失效:Memcached 有一个失效机制,当数据过期时,Memcached 会自动删除这个数据。这样可以避免内存被无用的数据占满。
虽然 Memcached 可以提供快速的数据访问,但它也有一些限制。例如,由于数据存储在内存中,所以 Memcached 的存储空间是有限的。另外,由于 Memcached 是一个分布式系统,所以它可能会受到网络延迟的影响。
二、 Memcached 部署
1. Yum 安装
① 直接命令安装
[root@localhost ~]# yum install -y memcached
[root@localhost ~]# systemctl start memcached.service
[root@localhost ~]# ss -natp | grep memcached
LISTEN 0 128 *:11211 *:* users:(("memcached",pid=6451,fd=26))
LISTEN 0 128 :::11211 :::* users:(("memcached",pid=6451,fd=27))
② 查看配置文件
[root@localhost ~]# vim /etc/sysconfig/memcached
PORT="11211" #监听端口
USER="memcached" #启动用户
MAXCONN="1024" #最大连接数
CACHESIZE="64" #最大使用内存
OPTIONS="" #其他选项
2. 编译安装
① 安装编译工具,下载安装
[root@localhost opt]# yum -y install gcc libevent-devel
[root@localhost opt]# wget http://memcached.org/files/memcached-1.6.6.tar.gz
[root@localhost opt]# tar xvf memcached-1.6.6.tar.gz
[root@localhost opt]# cd memcached-1.6.6/
[root@localhost memcached-1.6.6]# ./configure --prefix=/apps/memcached
[root@localhost memcached-1.6.6]# make -j 2 && make install
[root@localhost memcached-1.6.6]# echo 'PATH=/apps/memcached/bin:$PATH' > /etc/profile.d/memcached.sh
[root@localhost memcached-1.6.6]# . /etc/profile.d/memcached.sh
② 新建用户
[root@localhost ~]# useradd -r -s /sbin/nologin memcached
③ 编辑配置文件
[root@localhost ~]# cat > /etc/sysconfig/memcached << eof
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS=""
eof
④ 准备service文件
[root@localhost ~]# 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
⑤ 刷新配置,启动服务
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl enable --now memcached.service
⑥ 调整哈希表大小的参数
默认前台执行
[root@localhost ~]# memcached -u memcached -m 1024 -c 65536 -f 2 -vv
#从这个命令会以默认的前台模式启动 Memcached 服务
# -u memcached 参数表示以 memcached 用户的身份运行 Memcached 服务
# -m 1024 参数表示分配 1024 MB 的内存给 Memcached 服务
# -c 65536 参数表示允许 65536 个并发连接
# -f 2 参数表示增长因子为 2
# -vv 参数表示输出详细的日志信息。
以台方式执行
[root@localhost ~]# memcached -u memcached -m 1024 -c 65536 -d
# 这个命令会以台方式启动 Memcached 服务
# -d 参数表示以台方式运行 Memcached 服务,这意味着 Memcached 服务会在后台运行,而不会占用当前的终端。其他的参数的含义和默认前台执行的命令相同。
3. Memcached 启动程序说明
修改memcached 运行参数,可以使用下面的选项修改/etc/sysconfig/memcached文件,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 开发库和工具
① 安装工具包
[root@localhost ~]# yum install libmemcached -y
② 检测连接服务器
[root@localhost ~]# memping --servers 192.168.190.104
[root@localhost ~]# echo $?
0 # 检测在线
③ 获取 Memcached 服务的基本信息
[root@localhost ~]# memstat --servers=192.168.190.104
Server: 192.168.190.104 (11211)
pid: 3652
uptime: 856
……
2. Memcached 操作命令
四种基本 memcached 命令执行最简单的操作。这些命令和操作包括:
- set:重新加载
- add:添加一个数据
- get:调用
- delete:删除
前三个命令是用于操作存储在 memcached 中的键值对的标准修改命令,都使用如下所示的语法:
command <key> <flags> <expiration time> <bytes>
<value>
参数说明如下:
command set/add/replace
key # key 用于查找缓存值
flags # 可以包括键值对的整型参数,客户机使用它存储关于键值对的额外信息
expiration time # 在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)
bytes # 在缓存中存储的字节数
value # 存储的值(始终位于第二行)
add key flags exptime bytes #增加key,过期时间为秒,bytes为存储数据的字节数
示例:显示服务状态
[root@localhost ~]# telnet 192.168.190.104 11211
Trying 192.168.190.104...
Connected to 192.168.190.104.
Escape character is '^]'.
stats # 显示服务状态
stats items # 显示各个 slab 中 item 的数目和存储时长(最后一次访问距离现在的秒数)。
stats slabs # 用于显示各个slab的信息,包括chunk的大小、数目、使用情况等
示例:添加数据
[root@localhost ~]# telnet 192.168.190.104 11211
Trying 192.168.190.104...
Connected to 192.168.190.104.
Escape character is '^]'.
add num 1 10 4 # 1:说明信息,10:超时时间,4:字节数
6666
STORED
get num # 调用数据
VALUE num 1 4
6666
END
get num # 10秒后丢失
END
示例:修改
set num 2 5 6
666666
STORED
示例:删除
set num 1 0 2
66
STORED
get num
VALUE num 1 2
66
END
delete num
DELETED
get num
END
示例:清空
set num 1 0 2
66
STORED
get num
VALUE num 1 2
66
END
flush_all
OK
get num
END
四、Memcached 集群部署架构
Magent是google开发的项目,应用端通过负载均衡服务器连接到magent,然后再由magent代理用户应用请求到memcached处理,底层的memcached为双主结构会自动同步数据。通过负载均衡连接到memcached,有两台memcached做高可用,repcached版本的memcached之间会自动同步数据,以保持数据一致性,即使其中的一台memcached故障也不影响业务正常运行,故障的memcached修复上线后再自动从另外一台同步数据即可保持数据一致性。
1. 部署repcached
① 下载安装包编译安装
[root@localhost opt]# yum -y install gcc libevent libevent-devel
[root@localhost opt]# 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
[root@localhost opt]# tar xf memcached-1.2.8-repcached-2.2.1.tar.gz
[root@localhost opt]# cd memcached-1.2.8-repcached-2.2.1
[root@localhost memcached-1.2.8-repcached-2.2.1]# ./configure --prefix=/apps/repcached --enable-replication
[root@localhost memcached-1.2.8-repcached-2.2.1]# vim memcached.c
#改为如下内容,即删除原有的原第57,59行
56 #ifndef IOV_MAX
57 # define IOV_MAX 1024
58 #endif
[root@localhost memcached-1.2.8-repcached-2.2.1]# make -j 2 && make install
② 制作软链接,启动服务
[root@localhost ~]# ln -s /apps/repcached/bin/memcached /usr/bin/
[root@localhost ~]# memcached -d -m 1024 -p 11211 -u memcached -c 2048 -x 192.168.190.103
[root@localhost ~]# ss -ntl | grep 11211
LISTEN 0 128 *:11211 *:*
LISTEN 0 128 :::11211 :::*
③ 在 server1 上将整个目录拷贝到 server2 上
192.168.190.104:
[root@localhost ~]# rsync -a /apps 192.168.190.103:/
192.168.190.103:
[root@localhost ~]# useradd -r -s /sbin/nologin memcached
[root@localhost ~]# yum -y install gcc libevent libevent-devel
[root@localhost ~]# ln -s /apps/repcached/bin/memcached /usr/bin/
[root@localhost ~]# memcached -d -m 1024 -p 11211 -u memcached -c 2048 -x 192.168.190.104
[root@localhost ~]# ss -ntl | grep 11211
LISTEN 0 128 *:11211 *:*
LISTEN 0 128 :::11211 :::*
2. 数据同步
[root@localhost ~]# telnet 192.168.190.103 11211
Trying 192.168.190.103...
Connected to 192.168.190.103.
Escape character is '^]'.
add name 1 0 2
zs
STORED
quit
Connection closed by foreign host.
[root@localhost ~]# telnet 192.168.190.104 11211
Trying 192.168.190.104...
Connected to 192.168.190.104.
Escape character is '^]'.
get name
VALUE name 1 2
zs # 数据与103一致
END
3. 实现代理
① 配置haproxy代理
[root@localhost ~]# yum install -y haproxy.x86_64
[root@localhost ~]# vim /etc/haproxy/haproxy.cfg
listen mem
bind 192.168.190.100:11211
mode tcp
server m1 192.168.190.103:11211 check
server m1 192.168.190.104:11211 check
[root@localhost ~]# systemctl restart haproxy.service
[root@localhost ~]# ss -natp | grep 11211
LISTEN 0 128 192.168.190.100:11211 *:* users:(("haproxy",pid=2063,fd=7))
② 访问代理地址
[root@localhost ~]# telnet 192.168.190.100 11211
Trying 192.168.190.100...
Connected to 192.168.190.100.
Escape character is '^]'.
get name
VALUE name 1 2
zs # 实现调度获取数据
END