Memcached

Memcached有什么用

 

 

 

介绍Memcached

 Memcached是一套利用系统内存进行数据缓存的软件,常用于在动态Web集群,系统后端,数据库前端处使用。

用处:

  1. 可以临时缓存Web系统查询过的数据库数据,当用户请求查询数据时,由Memcached优先提供服务,从而减少Web系统直接请求数据库的次数,大大的降低后端数据库的压力,从而提升网站系统的性能。

  2. Memcached是通过分配指定的内存空间存取数据,比起MySQL要快很多(MySQL读写磁盘)

  3. Memcached也用来共享存储集群架构所有Web阶段服务器的session会话数据。

Memcached是一个开源的,支持高性能,高并发的分布式内存缓存系统,由C语言开发。从软件名称上看,mem就是内存的缩写,cache就是缓存的意思,最后一个字符d就是daemon的意思,表示该软件是守护进程模式内存缓存。

Memcached分为服务器和客户端两部分。

Memcached是以LiveJournal旗下Danga Interactive公司的Brad Fitzpatric为首开发的一款软件。现在已成为mixi、hatena、Facebook、Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素。

Memcached是一种基于内存的key-value存储,用来存储小块的任意数据(字符串、对象)。这些数据可以是数据库调用、API调用或者是页面渲染的结果。

Memcached简洁而强大。它的简洁设计便于快速开发,减轻开发难度,解决了大数据量缓存的很多问题。它的API兼容大部分流行的开发语言。

本质上,它是一个简洁的key-value存储系统。

一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。

 

 

 

Memcached作用

传统场景下,多数Web应用都将数据保存到关系型数据库中(MySQL),Web服务器从该数据库中读取数据给与用户响应,显示在浏览器中。

但是随着数据库的增大,集中式的访问,关系型数据库的负担会加重,导致响应缓慢,造成网站打开延迟等问题,影响用户体验。

此时在MySQL前面试用Memcached的作用就出现了,通过Memcached在内存中缓存MySQL的查询结果,减少MySQL的访问,提升整体网站架构性能。

生产环境下Memcached也被用来保存经常需要读取的数据,好比我们的浏览器也会对网页数据缓存一样,通过内存缓存的读取速度要远快于磁盘。

内存缓存软件

软件 类型 作用 数据场景
Memcached 纯内存 缓存网站后端各类数据 缓存用户重复请求的动态数据,如博客,帖子,用户session信息
Redis,MemcacheDB 持久化+内存 缓存后端数据库数据,作为关系型数据库的补充 除了用户重复请求的动态数据,以及当做数据库使用,存储如点赞数,排行榜,计数器,粉丝统计等需要持久化的数据
Squid,Nginx 内存+磁盘 缓存Web前端数据 用户缓存静态数据,如图片,文件,JS,CSS,HTML,代码等,提供CDN功能。

网站更新缓存工作流

  1. 当程序需要更新或删除数据时,首先会处理后端数据库中的数据。

  2. 处理后端数据库的同时,也会通知Memcached,它的缓存的数据过期了,因此要保证Memcached的数据和数据库中保持一致,这个一致性非常重要。

场景1:电商数据

 

 

 

上述流程图,例如Memcached用来存储商品分类功能的数据,一般商品分类是很少变动的,
因此可以提前把该数据放在Memcached,Web后端直接读取Memcached即可,无须访问
mysql,减轻数据库压力,还能提升访问速度。

若是商品分类有了变化,公司内部管理人员需要更新数据库后,再同时更新到缓存
Memcached里。

  

场景2:热点数据缓存

热点数据缓存指的是如淘宝的卖家,在卖家新增商品后,网站程序会吧这个商品写入后端数据库,同时吧这部分的数据,放入Memcached内存,下一次访问该商品的请求,就直接从Memcached里读取,这个方式用来缓存网站的热点数据,也就是会被用户经常访问的数据。

 

 

 

 

这种形式一般通过程序实现,也可以在MySQL上做设置,直接由MySQL吧数据更新到Memcached中,实现例如从库的效果。

 

 

 

如果碰到电商双11,秒杀高并发的业务场景,必须要事先预热各种缓存,包括前端的Web缓存和后端的数据库缓存。

也就是先把数据放入内存预热,然后逐步动态更新。此时,会先读取缓存,如果缓存里没有对应的数据,再去读取数据库,然后把读到的数据放入缓存。如果数据库里的数据更新,需要同时触发缓存更新,防止给用户过期的数据,当然对于百万级别并发还有很多其他的工作要做。

绝大多数的网站动态数据都是保存在数据库当中的,每次频繁地存取数据库,会导致数据库性能急剧下降,无法同时服务更多的用过户(比如MySQL特别频繁的锁表就存在此问题),那么,就可以让Memcached来分担数据库的压力。增加Memcached服务的好处除了可以分担数据库的压力以外,还包括无须改动整个网站架构,只须简单地修改下程序逻辑,让程序先读取Memcached缓存查询数据即可,当然别忘了,更新数据时也要更新Memcached缓存。

作为集群节点的session会话共享存储

也就是吧客户端用户请求多个前端应用服务器集群产生的session信息,统一存储到一个Memcached缓存中。

 

 

 

 

 

 

 

 

 

 

 

session/cookie是什么

 

 

简单来说Cookies就是服务器暂存放在你的电脑里的资料让服务器辨认电脑,很多购物网站的购物车功能、论坛自动登录功能都是靠Cookie实现。

cookie是什么

Cookie的英文直译是饼干,在计算机术语中是指一种能够让网站服务器把少量数据储存到客户端的硬盘或内存,或是从客户端的硬盘读取数据的一种技术。Cookie可以为用户带来很多便捷,但同时,它也会给用户制造一些麻烦。

  【浏览器中的cookie】

当你浏览某网站时,由Web服务器置于你硬盘上的一个非常小的文本文件,它可以记录你的用户ID、密码、浏览过的网页、停留的时间等信息。当你再次来到该网站时,网站通过读取Cookie,得知你的相关信息,就可以做出相应的动作,如在页面显示欢迎你的标语,或者让你不用输入ID、密码就直接登录等等。如果你清理了Cookie,那么你曾登录过的网站就没有你的修改过的相关信息。Cookie是非常常见的, 基本上你的浏览器中都会存储了成百上千条Cookie信息。

 

 

 

Memcached特点

作为高并发,高性能的缓存服务,具有如下特点:

  1. 协议简单。Memcached的协议实现很简单,采用的是基于文本行的协议,能通过telnet/nc等命令直接操作memcached服务存储数据。

  2. 支持epoll/kqueue异步I/O模型,使用libevent作为事件处理通知机制。

  3. 简单的说,libevent是一套利用c开发的程序库,它将BSD系统的kqueue,Linux系统的epoll等事件处理功能封装成一个接口,确保即使服务器端的连接数增加也能发挥很好的性能。Memcached就是利用这个libevent库进行异步事件处理的。

  4. 采用key/value键值数据类型。被缓存的数据以key/value键值形式存在,例如:

benet–>36,key=benet,value=36
yunjisuan–>28,key=yunjisuan,value=28
#通过benet key可以获取到36值,同理通过yunjisuan key可以获取28值

  5. 全内存缓存,效率高。Memcached管理内存的方式非常高效,即全部的数据都存放于Memcached服务事先分配好的内存中,无持久化存储的设计,和系统的物理内存一样,当重启系统或Memcached服务时,Memcached内存中的数据就会丢失。

  6. 如果希望重启后,数据依然能保留,那么就可以采用redis这样的持久性内存缓存系统。

  7. 当内存中缓存的数据容量达到服务启动时设定的内存值时,就会自动使用LRU算法(最近最少被使用的)删除过期的缓存数据。也可以在存放数据时对存储的数据设置过期时间,这样过期后数据就自动被清除,Memcached服务本身不会监控数据过期,而是在访问的时候查看key的时间戳判断是否过期。

  8. 可支持分布式集群Memcached没有像MySQL那样的主从复制方式,分布式Memcached集群的不同服务器之间是互不通信的,每一个节点都独立存取数据,并且数据内容也不一样。通过对Web应用端的程序设计或者通过支持hash算法的负载均衡软件,可以让Memcached支持大规模海量分布式缓存集群应用。

 

下面是利用Web端程序实现Memcached分布式的简单代码: #建立了一个数组

"memcached_servers" ==>array(
'10.4.4.4:11211',
'10.4.4.5:11211',
'10.4.4.6:11211',
)

下面使用Tengine反向代理负载均衡的一致性哈希算法实现分布式Memcached的配置。

http {
  upstream test {
      consistent_hash $request_uri;
      server 127.0.0.1:11211 id=1001 weight=3;
      server 127.0.0.1:11212 id=1002 weight=10;
      server 127.0.0.1:11213 id=1003 weight=20;
  }
}

提示:
Tengine是淘宝网开源的Nginx的分支,上述代码来自:
http://tengine.taobao.org/document_cn/http_upstream_consistent_hash_cn.html

  

Memcached预热重启理念

当网站架构需要大面积重启Memcached时,首先要在前端控制网站入口的访问流量,然后重启Memcached集群,并且进行数据预热,当所有数据预热完毕后,再逐步开放前端网站入口的流量。

Memcached安装

[root@memcached01 ~]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
[root@memcached01 ~]# uname -r
3.10.0-862.el7.x86_64

  系统初始化

wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

yum install -y bash-completion vim lrzsz wget expect net-tools nc nmap tree dos2unix htop iftop iotop unzip telnet sl psmisc nethogs glances bc ntpdate  openldap-devel git python-pip  gcc automake autoconf python-devel vim sshpass lrzsz readline-devel lsof

  安装libevent

yum install -y libevent libevent-devel nc 

# 在centos 7 系统上 nc命令改为了nmap-ncat

[root@memcached01 ~]# rpm -qa libevent libevent-devel nmap-ncat
libevent-devel-2.0.21-4.el7.x86_64
libevent-2.0.21-4.el7.x86_64
nmap-ncat-6.40-19.el7.x86_64

  安装Memcached

[root@memcached01 ~]# yum install memcached -y

[root@memcached01 ~]# rpm -qa memcached
memcached-1.4.15-10.el7_3.1.x86_64

  启动Memcached

[root@memcached01 ~]# which memcached
/usr/bin/memcached

# 启动第一个memcached实例
[root@memcached01 ~]# memcached -m 16m -p 11211 -d -u root -c 8192

  检查服务启动

[root@memcached01 ~]# lsof -i :11211
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
memcached 11937 root   26u  IPv4  62741      0t0  TCP *:memcache (LISTEN)
memcached 11937 root   27u  IPv6  62742      0t0  TCP *:memcache (LISTEN)
memcached 11937 root   28u  IPv4  62745      0t0  UDP *:memcache
memcached 11937 root   29u  IPv6  62746      0t0  UDP *:memcache

[root@memcached01 ~]# netstat -antup | grep 11211
tcp        0      0 0.0.0.0:11211           0.0.0.0:*               LISTEN      11937/memcached
tcp6       0      0 :::11211                :::*                    LISTEN      11937/memcached
udp        0      0 0.0.0.0:11211           0.0.0.0:*                           11937/memcached
udp6       0      0 :::11211                :::*                                11937/memcached

[root@memcached01 ~]# ps -ef | grep memcached | grep -v grep
root      11937      1  0 02:50 ?        00:00:00 memcached -m 16m -p 11211 -d -u root -c 8192

  可同时启动多实例

[root@memcached01 ~]# memcached -m 16m -p 11212 -d -u root -c 8192

  检查服务

[root@memcached01 ~]# ps -ef | grep memcached | grep -v grep
root      11937      1  0 02:50 ?        00:00:00 memcached -m 16m -p 11211 -d -u root -c 8192
root      11959      1  0 02:53 ?        00:00:00 memcached -m 16m -p 11212 -d -u root -c 8192

  若想要开机就自动运行实例,可以加入开机启动文件

[root@memcached01 ~]# tail -2 /etc/rc.local
memcached -m 16m -p 11211 -d -u root -c 8192
memcached -m 16m -p 11212 -d -u root -c 8192

  

Memcached启动命令相关参数说明

进程与连接设置

命令参数 说明
-d 以守护进程(daemon)方式运行服务

-u

指定运行memcached的用户,如果当前用户为root,需要使用此参数指定用户
-l 指定memcached进程监听的服务器ip地址,可以不设置此参数
-p 指定memcached服务监听TCP端口号,默认为11211
-P 设置保存memcached的PID文件,保存pid到指定文件

内存相关设置:

命令参数 说明
-m 指定memcached服务可以缓存数据的最大内存,默认时64MB
-M memcached服务内存不够时禁止LRU,如果内存满了会报错
-n 为KEY+value----flags分配的最小内存空间,默认为48字节
-f chunk size增长因子,默认为1.25
-L 启用大内存页,可以降低内存浪费,改进性能

并发连接设置:

并发连接设置 说明
-c 最大的并发连接数
-t 线程数,默认4,由于memcached采用的时NIO,所以太多线程作用不大
-R 每个event最大请求数,默认20
-C 禁用CAS

测试参数:

-v 打印较少的error/warnings
-vv 打印非常多调试信息和错误输出到控制台
-vvv 打印极多的调试信息和错误输出,也打印内部状态转发

memcached -h 查看更多参数

写入Memcached数据

Memcached中添加数据时,注意添加的数据一般为键值对的形式,例如:key1–>values1,key2–>values2

  

测试Memcached语句

这里把memcached添加,查询,删除等的命令和Mysql数据库做一个基本类比,见下表:

Mysql数据库管理 memcached管理
Mysql的insert语句 memcached的set命令
Mysql的select语句 memcached的get命令
Mysql的delete语句 memcached的delete命令

注意:

memcached的服务器客户端通信并不使用复杂的XML等格式,而使用简单的基于文本行的协议。

我们可以使用telnet、nc等命令,可以连接memcached服务端,进行数据操作。

 

通过printf配合nc向Memcached中写入数据,命令如下:

备注:
printf 是格式化打印的命令,printf 命令格式化输出。
nc  功能强大的网络工具

 

读写案例

# set命令设置的字符数量,必须准确,否则会报错,例如
# 对key1 设置值 chaogee ,字符是7个
[root@memcached01 ~]# printf "set key1 0 0 6\r\nchaogee\r\n"|nc 127.0.0.1 11211
CLIENT_ERROR bad data chunk
ERROR

# 字符数量正确后
[root@memcached01 ~]# printf "set key1 0 0 6\r\nchaoge\r\n"|nc 127.0.0.1 11211
STORED

  

[root@memcached01 ~]# printf "get key1\r\n" | nc 127.0.0.1 11211
VALUE key1 0 6
chaoge  # 读取到的值
END

  通过printf配合nc从memcached中删除数据,命令如下:

[root@memcached01 ~]# printf "delete key1\r\n" | nc 127.0.0.1 11211
DELETED  #出现它表示删除了

# 再次获取就已经找不到了
[root@memcached01 ~]#  printf "get key1\r\n" | nc 127.0.0.1 11211
END

  telnet连接Memcached:

1.安装telnet
[root@memcached01 ~]# yum install telnet -y

2.写入数据
[root@memcached01 ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
set user01 0 0 7          # 设置key与字节数
chaogee                                # 设置7个字符
STORED
get user01
VALUE user01 0 7
chaogee
END
delete user01
DELETED
get user01
END
quit
Connection closed by foreign host.
[root@memcached01 ~]#

  操作Memcached命令语法

 

 

 

 

 关闭Memcached服务

[root@memcached01 ~]#  ps -ef | grep memcached | grep -v grep
root      11937      1  0 02:50 ?        00:00:00 memcached -m 16m -p 11211 -d -u root -c 8192
root      11959      1  0 02:53 ?        00:00:00 memcached -m 16m -p 11212 -d -u root -c 8192

# 在启动memcached的时候,最好指定pid文件,关于启停管理。
[root@cache01 ~]# memcached -m 16m -p 11211 -d -u root -c 8192 -P /var/run/11211.pid
[root@cache01 ~]# memcached -m 16m -p 11212 -d -u root -c 8192 -P /var/run/11212.pid

# 杀死pid即可
[root@memcached01 ~]# ps -ef|grep memcached |grep -v grep |awk '{print $2}' | xargs kill

# 重启了服务端,数据也就丢了
[root@memcached01 ~]# memcached -m 16m -p 11211 -d -u root -c 8192 -P /var/run/11211.pid
[root@memcached01 ~]#
[root@memcached01 ~]#
[root@memcached01 ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
get key1
END
quit
Connection closed by foreign host.
[root@memcached01 ~]#

# 重新启动,查看数据
[root@memcached01 ~]# ps -ef | grep memcached | grep -v grep
root      13749      1  0 03:31 ?        00:00:00 memcached -m 16m -p 11211 -d -u root -c 8192 -P /var/run/11211.pid
[root@memcached01 ~]#
[root@memcached01 ~]#
[root@memcached01 ~]# kill `cat /var/run/11211.pid`
[root@memcached01 ~]# ps -ef | grep memcached | grep -v grep

  

企业工作场景中如何配置Memcached

在企业实际工作中,一般是开发人员提出需求,说要部署一个Memcached数据缓存。运维人员在接到这个不确定的需求后,需要和开发人员深入沟通,进而确定要将内存指定为多大,或者和开发人员商量如何根据具体业务来指定内存缓存的大小。此外,还要确定业务的重要性,进而决定是否采取负载均衡,分布式缓存集群等架构,最后确定要使用多大的并发连接数等。

对于运维人员,部署Memcached一般就是安装Memcached服务器端,把服务启动起来,做好监控,配好开机自启动,基本就OK了。

客户端的PHP程序环境一般在安装LNMP环境时都会提前安装Memcached客户端插件,Java程序环境下,开发人员会用第三方的JAR包直接连接Memcached服务。

posted @ 2021-01-22 01:45  时间的侵蚀  阅读(268)  评论(0)    收藏  举报