第1章 memcached
1 memcached前言
1.1 memcached诞生的原因
2003年诞生了memcached
Web1.0 2005以前 企业提供内容为主。
Web2.02005-2012 企业只提供平台,用户参与上传下载内容。
memcached 内存缓存软件,内存比磁盘快。
传统场景中,多数web应用都将数据保存在关系型数据库中(如mysql),web服务器从中读取数据并在浏览器中显示。但是随着数据量增大,访问的集中,关系型数据库的负担就会加重,响应缓慢,导致网站打开延迟等问题,影响用户体验。
1.2 memcached的作用
解决高并发访问的问题,减轻传统数据库mysql的压力。
不关注数据可靠性,只关心高并发读写。
使用memcached的重要目的是通过自身内存中缓存关系型数据库的查询结果,减少数据库被访问的次数,提高动态web应用的速度,提高网站架构的并发能力和可扩展性。
memcached服务的运行工作原理:通过事先规划好的系统内存空间中临时缓存数据库中的各类数据,以达到减少前端业务服务对数据库的直接高并发访问,从而提升大规模网站集群中动态服务的并发能力。
生产场景中的memcached服务一般用来保存网站中被经常读取的对象或数据,就像客户端浏览器会把经常访问的网页缓存起来,通过内存缓存来存取对象或数据要比磁盘存取快很多,因为磁盘是机械的。
2 memcached的特点与工作机制
2.1 memcached的特点
协议简单。
采用的是基于文本行的协议,能通过Telnet/nc等命令直接操作memcached服务存取数据。
支持epoll/kqueue异步I/O模型,使用libevent作为事件处理通知机制。
采用key/value键值形式存在。
全内存缓存,效率高。
memcached管理内存的方式非常高效,即全部的数据都存放于memcached服务预先分配好的内存中,无持久化存储的设计,和系统的物理内存一样,当重启memcached或系统时,memcached内存中的数据就会丢失。
如果希望重启后,数据依然能保存,那么就可以采用redis这样的持久性内存缓存系统。
可支持分布式集群。
memcached没有向mysql那样的主从复制方式,分布式memcached集群的不同服务器之间是互不通信的,每一个节点都独立存取数据,并且数据内容不一样。通过对web应用端的程序设计或通过支持hash算法的负载均衡软件,可以让memcached支持大规模海量分布式缓存集群应用。
memcached工作原理与机制
memcached是一套类似于C/S模式架构的软件,在服务器端启动memcached守护进程,可以指定监听本地的IP地址,端口号,并发访问连接数,以及分配了多少内存来处理客户端请求。
socket事件处理机制
数据存储机制
内存管理机制
多线程处理机制
2.2memcached常见用途工作流程
网站读取memcached数据时的工作流程
web程序首先检查客户端请求的数据是否在memcached缓存中存在,如果存在,直接把请求的数据返回给客户端,此时不再请求后端数据库。
如果请求的数据在memcached缓存中不存在,则程序会去请求数据库服务,把从数据库中取到的数据返回给客户端,同时把新取到的数据缓存一份到memcached缓存中。
2.3.网站更新memcached数据时的工作流程
具体流程如下:
当程序更新或删除数据时,会首先处理后端数据库中的数据。
在处理后端数据库中数据的同时,也会通知memcached,告诉他对应的旧数据失效,从而保证memcached中缓存的数据始终和数据库中一致,这个数据一致性非常重要,也是大型网站分布式缓存集群最头疼的问题所在。
如果是在高并发读写场合,除了要程序通知memcached过期的缓存失效外,还可能要通过相关机制,例如在数据库上部署相关程序(如在数据库中设置触发器使用UDFs),实现当数据库有更新时就把数据库更新到memcached服务中,这样一来,客户端在访问新数据时,因预先把更新过的数据复制到memcached中缓存起来了,所以可以减少第一次查询数据库带来的访问压力,提升memcached中缓存的命中率,甚至新浪门户网站还会把持久化存储redis做成mysql数据库的从库,实现真正的主从复制。
2.4.memcached在企业中的应用场景
数据库前端的缓存。
读数据:
开发程序从逻辑上,首先访问(读)memcahced,如果没有数据在访问mysql。
写数据:
如果写数据,那么再写数据库的同时,把数据写入到memcached,或者写入到mysql的同时,由mysql复制到memcached。
Linux运维角色:
搭建memcached服务,提供服务(使用信息问开发)
1.3.2.2 集群后端的共享会话session。
session门票。如果网站内有了这个门票,就可以浏览任意页面。
解决共享会话方案
1、nginx的调度算法ip_hash(缺点:导致负载不均)
2、通过memcahced做共享会话。
3、cookies(放在用户浏览器端)。
优点,可以大并发,缺点:容易篡改,不安全。
参考内容:
http://oldboy.blog.51cto.com/2561410/1331316
http://oldboy.blog.51cto.com/2561410/1323468
第2章 memcached服务安装
2.1 安装livevent及连接memcached工具nc
2.1.1 准备环境及libevent安装
[root@db01-51 ~]# cat /etc/redhat-release
CentOS release 6.8 (Final)
[root@db01-51 ~]# uname -r
2.6.32-642.el6.x86_64
[root@db01-51 ~]# uname -m
x86_64
[root@db01-51 ~]#
yum install libevent-devel -y
rpm -qa libevent-devel
2.1.2 安装memcached
yum install memcached -y
rpm -qa memcached
2.1.3 启动memcached服务
[root@db01 ~]# memcached -m 16m -c2048 -u root -p 11211 -d
[root@db01 ~]# netstat -lntp|grepmemcache
tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 4026/memcached
tcp 0 0 :::11211 :::* LISTEN 4026/memcached
2.1.3.1memcached启动命令相关参数说明
2.1.4 向memcached中写入数据并检查
2.1.4.1向memcached中写入数据实战
通过Telnet命令写入数据
安装Telnet工具
yum install telnet nc -y
telnet 127.0.0.1 11211
通过Telnet向memcached中写入数据。
[root@db01 ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
set k1 0 0 6
oldboy
STORED
get k1
VALUE k1 0 6
oldboy
END
delete k1
DELETED
get k1
END
通过printf配合nc向memcached中写入数据,命令如下:
printf "set key008 0 06\r\noldboy\r\n"|nc 127.0.0.1 11211
printf "set key008 0 010\r\noldboy0987\r\n"|nc 127.0.0.1 11211
通过printf配合nc向memcached中删除数据,命令如下
printf "delete key008 0 06\r\noldboy\r\n"|nc 127.0.0.1 11211
2.2 客户端软件安装
php所在服务器上安装memcache客户端,程序才能访问到memcached。
2.2.1 解压编译安装
tar zxf memcache-2.2.5.tgz
cd memcache-2.2.5
/application/php/bin/phpize
./configure --enable-memcache --with-php-config=/application/php/bin/php-config
make
make install
cd ../
ls -l/application/php-5.5.32/lib/php/extensions/no-debug-non-zts-20121212/
注意:有时候make安装时会出现下面的错误,这时候执行make clean即可
2.2.1.1make、clean、distclean的用法讲解
makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
makefile带来的好处就是--“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,VisualC++的nmake,Linux下GNU的make.可见,makefile都成为了一种在工程方面的编译方法。
make
根据Makefile文件编译源代码、连接、生成目标文件、可执行文件。
make clean
清除上次的make命令所产生的object文件(后缀为“.o”的文件)及可执行文件。
make install
将编译成功的可执行文件安装到系统目录中,一般为/usr/local/bin目录。
make dist
产生发布软件包文件(即distribution package)。这个命令将会将可执行文件及相关文件打包成一个tar.gz压缩的文件用来作为发布软件的软件包。
它会在当前目录下生成一个名字类似“PACKAGE-VERSION.tar.gz”的文件。PACKAGE和VERSION,是我们在configure.in中定义的AM_INIT_AUTOMAKE(PACKAGE, VERSION)。
make distcheck
生成发布软件包并对其进行测试检查,以确定发布包的正确性。这个操作将自动把压缩包文件解开,然后执行configure命令,并且执行make,来确认编译不出现错误,最后提示你软件包已经准备好,可以发布了。
make distclean
类似make clean,但同时也将configure生成的文件全部删除掉,包括Makefile文件。
2.2.2 配置PHP访问memcached
配置:
vim /application/php/lib/php.ini ##最后一行追加两行下面内容
extension_dir = "/application/php-5.5.32/lib/php/extensions/no-debug-non-zts-20121212/"
extension = memcache.so
重启Php
pkill php-fpm
/application/php/sbin/php-fpm
2.2.3 编写测试memcached服务的PHP脚本
[root@web02 php]# cat/application/nginx/html/blog/a.php
<?php
phpinfo();
?>
通过页面:blog.etiantian.org/a.php检查mc的配置情况。
搜索memcache页面内容,如果有结果,表示成功。
补充:开发php访问memcached代码
<?php
$memcache = new Memcache;
$memcache->connect('10.0.0.51', 11211) or die ("Could notconnect Mc server");
$memcache->set('key', 'oldboy book');
$get= $memcache->get('key');
echo $get;
?>
2.3 通过memcached php工具展示memcached状态信息
2.3.1 部署memcached php 工具
因为这个软件时基于PHP程序的,因此需要有PHP环境才行。
2.3.2 采用IP或解析好的域名进行访问
第3章 memcached内存管理
3.1 memcached内存管理机制深入剖析
malloc全称memory allocation,中文名称动态内存分配,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态分配内存。早期的memcached内存管理是通过malloc分配的内存实现的,使用完通过free来回收。
3.1.1 slab内存管理机制(重点)
现在的memcached是利用slab allocation机制来分配和管理内存的。过程如下:
提前将大内存分配大小为1MB的若干个slab,然后针对每个slab再进行小对象填充,这个小对象称为chunk,避免大量重复的初始化和清理,减轻了内存管理器的负担。
slab allocation内存分配的原理:按着预先规定的大小,将分配给memcached服务的内存预先分割成特定长度的内存块(chunk),再把尺寸相同的内容块分成组(chunk slab class),这些内存块不会释放,可以重复利用。
新增数据对象存储时,因为memcached服务器中保存着slab内空闲的chunk的列表,他会根据该列表选择chunk,然后将数据缓存其中。当有数据存入时,memcached根据接受到的数据的大小,选择最适合数据大小的slab 分配一个能存下这个数据的最小内存块(chunk)
1.1.1slab内存管理机制的特点
提前分配大内存slab 1MB,再进行小对象填充chunk。
避免大量重复的初始化和清理,减轻内存管理器负担。
避免频繁malloc/free内存分配导致的碎片。
内存管理机制小结:
mc的早期内存管理机制为malloc(动态内存分配)
malloc(动态内存分配)产生内存碎片,导致操作系统性能下降。
slab 内存分配机制可以解决内存碎片的问题。
memcached服务的内存预先分割成特定长度的内存块,称为chunk,用于缓存数据的内存空间或内存块,相当于磁盘的block,只不过磁盘的每一个block都是相等的,而chunk只有在同一个slab class内才是相等的。
slab class 指特定大小(1MB)的包含多个chunk的集合或组,一个memcached包含多个slab class,每个slab class包含多个相同大小的chunk。
slab机制也有缺点,如chunk的空间会有浪费。
memcached slab allocator内存管理机制的缺点
chunk 存储item浪费空间
slab 尾部剩余空间
memcached的过期检测与删除机制
memcached懒惰检测对象过期机制
memcached不会主动检测item对象是否过期,而是在进行get操作时检查item对象是否过期及是否应该删除。
因为不会主动加测item对象是否过期,自然不会释放已经分配给对象的内存空间了,除非为添加的数据设定过期时间或内存缓存满了,在数据过期后,客户端不能通过key取出他的值,其存储空间将被重新利用。
mcached使用的这种策略为懒惰检测对象过期策略,即自己不监控存入的key/value对是否过期,而是在获取key值时查看记录的时间戳,从而检查key/value对空间是否过期,这种策略不会再过期检查上浪费CPU资源。
3.1.2.2memcached懒惰删除对象机制
当删除item对象时,一般不会释放内存空间,而是做删除标记,将指针放入slot回收插槽,下次分配的时候直接使用。
memcached在分配空间时,会优先使用已经过期的key/value对空间,若分配的内存空间占满,memcached就会使用LRU算法来分配空间,删除最近很少使用的key/value对,从而将其空间分配给新的key/value对。
memcached删除机制小结:
q 不主动监测item对象是否过期, 而是在get时才会检查item对象是否过期以及是否应该删除。
q 当删除item对象时,一般不释放内存空间,而是做删除标记,将指针放入slot回收插槽,下次分配的时候直接使用。
q 当内存空间满的时候,将会根据LRU算法把最近很少使用的item对象删除。
q 数据存入可以设定过期时间,但是数据过期不会立即删除,而是在get时检查item对象是否过期以及是否应该删除。
q 如果不希望系统使用LRU算法清除数据,可以使用-M参数。
Memcached就会使用LRU算法来分配空间,删除最近最少使用的key/value对,从而将其空间分配给新的key/value对。
网站缓存:squid,nginx,varnish
缓存图片、视频等。 缓解后端存储系统的压力
NOSQL库:Redis,Memcached,MongoDB,HBase,Cassandra
Memcached 缓存数据库的数据
Redis:除了当内存用,还可以放到磁盘
1、缓存功能
2、辅助存储数据(好友关注、粉丝、投票)
MongoDB 可以直接放数据
本文转自写个博客骗钱博客51CTO博客,原文链接http://blog.51cto.com/dadonggg/1949297如需转载请自行联系原作者
菜鸟东哥