第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数据时的工作流程

                            wKiom1lwOlqAJ2zEAADYyBKOWGA772.jpg

  • web程序首先检查客户端请求的数据是否在memcached缓存中存在,如果存在,直接把请求的数据返回给客户端,此时不再请求后端数据库。

  • 如果请求的数据在memcached缓存中不存在,则程序会去请求数据库服务,把从数据库中取到的数据返回给客户端,同时把新取到的数据缓存一份到memcached缓存中。

  • 2.3.网站更新memcached数据时的工作流程

具体流程如下:

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

  • 在处理后端数据库中数据的同时,也会通知memcached,告诉他对应的旧数据失效,从而保证memcached中缓存的数据始终和数据库中一致,这个数据一致性非常重要,也是大型网站分布式缓存集群最头疼的问题所在。

  • 如果是在高并发读写场合,除了要程序通知memcached过期的缓存失效外,还可能要通过相关机制,例如在数据库上部署相关程序(如在数据库中设置触发器使用UDFs,实现当数据库有更新时就把数据库更新到memcached服务中,这样一来,客户端在访问新数据时,因预先把更新过的数据复制到memcached中缓存起来了,所以可以减少第一次查询数据库带来的访问压力,提升memcached中缓存的命中率,甚至新浪门户网站还会把持久化存储redis做成mysql数据库的从库,实现真正的主从复制。

  • 2.4.memcached在企业中的应用场景

  • 数据库前端的缓存。

  • 读数据:

   开发程序从逻辑上,首先访问(读)memcahced,如果没有数据在访问mysql

  1. 写数据:

   如果写数据,那么再写数据库的同时,把数据写入到memcached,或者写入到mysql的同时,由mysql复制到memcached

   Linux运维角色:

   搭建memcached服务,提供服务(使用信息问开发)

1.3.2.2         集群后端的共享会话session

session门票。如果网站内有了这个门票,就可以浏览任意页面。

解决共享会话方案

1nginx的调度算法ip_hash(缺点:导致负载不均)

2、通过memcahced做共享会话。

3cookies(放在用户浏览器端)。

   优点,可以大并发,缺点:容易篡改,不安全。

参考内容:

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启动命令相关参数说明

wKiom1lwPQvy9TmxAAJc3PwHues320.jpg-wh_50

wKioL1lwPQywNI65AAFySlSqTfo929.jpg-wh_50


 

2.1.4 memcached中写入数据并检查

2.1.4.1memcached中写入数据实战

  1. 通过Telnet命令写入数据

安装Telnet工具

yum install telnet nc -y

 

telnet 127.0.0.1 11211

通过Telnetmemcached中写入数据。

[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

  1. 通过printf配合ncmemcached中写入数据,命令如下:

 

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配合ncmemcached中删除数据,命令如下

printf "delete key008 0 06\r\noldboy\r\n"|nc 127.0.0.1 11211

 wKioL1lwPVjiUOnEAAF_DZAaoFs959.jpg-wh_50

 

 

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即可

wKiom1lwPX6SC8qFAAGgbciAe_E189.jpg-wh_50

2.2.1.1makecleandistclean的用法讲解

makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。

makefile带来的好处就是--“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphimake,VisualC++nmake,LinuxGNUmake.可见,makefile都成为了一种在工程方面的编译方法。

make

根据Makefile文件编译源代码、连接、生成目标文件、可执行文件。

make clean

清除上次的make命令所产生的object文件(后缀为.o的文件)及可执行文件。

make install

将编译成功的可执行文件安装到系统目录中,一般为/usr/local/bin目录。

make dist

产生发布软件包文件(即distribution package)。这个命令将会将可执行文件及相关文件打包成一个tar.gz压缩的文件用来作为发布软件的软件包。

它会在当前目录下生成一个名字类似“PACKAGE-VERSION.tar.gz”的文件。PACKAGEVERSION,是我们在configure.in中定义的AM_INIT_AUTOMAKEPACKAGE, 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页面内容,如果有结果,表示成功。

wKiom1lwPpSBjlw9AADn0vsFQtY159.jpg

补充:开发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内存管理机制(重点)

wKioL1lwSXjQgsQoAAHVgWLoALA450.jpg-wh_50

现在的memcached是利用slab allocation机制来分配和管理内存的。过程如下:

  1. 提前将大内存分配大小为1MB的若干个slab,然后针对每个slab再进行小对象填充,这个小对象称为chunk,避免大量重复的初始化和清理,减轻了内存管理器的负担。

    

        slab   allocation内存分配的原理:按着预先规定的大小,将分配给memcached服务的内存预先分割成特定长度的内存块(chunk,再把尺寸相同的内容块分成组(chunk slab class),这些内存块不会释放,可以重复利用。


  1.  新增数据对象存储时,因为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对。

wKiom1lwSuKSPn-MAAGB0uBZOPg243.jpg-wh_50

 

 

网站缓存:squid,nginx,varnish

缓存图片、视频等。 缓解后端存储系统的压力

NOSQL库:Redis,Memcached,MongoDB,HBase,Cassandra

Memcached 缓存数据库的数据

Redis:除了当内存用,还可以放到磁盘

1、缓存功能

2、辅助存储数据(好友关注、粉丝、投票)

MongoDB 可以直接放数据