设为首页 收藏本站
查看: 1061|回复: 0

[经验分享] 高效缓存服务器Memcached(一)

[复制链接]

尚未签到

发表于 2018-12-25 11:09:22 | 显示全部楼层 |阅读模式
  一、Memcached
  1、memcached 是什么
  Memcached是一款开源、高性能、分布式内存对象缓存系统,可应用各种需要缓存的场景,其主要目的是通过降低对Database的访问来加速web应用程序。它是一个基于内存的“键值对”存储,用于存储数据库调用、API调用或页面引用结果的直接数据,如字符串、对象等。Memcached是以LiveJournal旗下Danga Interactive 公司的Brad Fitzpatric 为首开发的一款软件。现在已成为mixi、hatena、Facebook、Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素。
  许多Web应用都将数据保存到RDBMS(关系型数据库管理系统)中,应用服务器从中读取数据并在浏览器中显示。 但随着数据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、 网站显示延迟等重大影响。这时就该memcached大显身手了。memcached是高性能的分布式内存缓存服务器。 一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、 提高可扩展性。如下图:

  2、memcached 特点
  Memcached是一款开发工具,它既不是一个代码加速器,也不是数据库中间件。其设计哲学思想主要反映在如下方面:

  •   简单key/value存储:服务器不关心数据本身的意义及结构,只要是可序列化数据即可。存储项由“键、过期时间、可选的标志及数据”四个部分组成;
  •   功能的实现一半依赖于客户端,一半基于服务器端:客户负责发送存储项至服务器端、从服务端获取数据以及无法连接至服务器时采用相应的动作;服务端负责接收、存储数据,并负责数据项的超时过期;
  •   各服务器间彼此无视:不在服务器间进行数据同步;
  •   O(1)的执行效率 。
  •   清理超期数据:默认情况下,Memcached是一个LRU缓存,同时,它按事先预订的时长清理超期数据;但事实上,memcached不会删除任何已缓存数据,只是在其过期之后不再为客户所见;而且,memcached也不会真正按期限清理缓存,而仅是当get命令到达时检查其时长;
  3、memcached 基于libevent的事件处理
  libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥O(1)的性能。memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能。
  4、memcached 内置内存存储方式
  为了提高性能,memcached中保存的数据都存储在memcached内置的内存存储空间中。由于数据仅存在于内存中,因此重启memcached、重启操作系统会导致全部数据消失。另外,内容容量达到指定值之后,就基于LRU(Least Recently Used)算法自动删除不使用的缓存。memcached本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问题。

  •   数据存储方式:Slab Allocation   
  结构图如下:

  Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块(chunk),并把尺寸相同的块分成组,以完全解决内存碎片问题。但由于分配的是特定长度的内存,因此无法有效利用分配的内存。比如将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了。

  •   Slab Allocator 相关术语
  Page:分配给Slab的内存空间,默认是1MB。分配给Slab之后根据slab的大小切分成chunk。
  Chunk:用于缓存记录的内存空间。
  Slab Class:特定大小的chunk的组。
  memcached根据收到的数据的大小,选择最适合数据大小的slab。
  memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中。


  •   在Slab中缓存记录的原理
  下面说明memcached如何针对客户端发送的数据选择slab并缓存到chunk中。memcached根据收到的数据的大小,选择最适合数据大小的slab。 memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk, 然后将数据缓存于其中。如下图,

  实际上,Slab Allocator也是有利也有弊。下面介绍一下它的缺点。

  •   Slab Allocator的缺点
  Slab Allocator解决了当初的内存碎片问题,但新的机制也给memcached带来了新的问题。这个问题就是,由于分配的是特定长度的内存,因此无法有效利用分配的内存。 例如,将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了。如下图,

  对于该问题目前还没有完美的解决方案,但在文档中记载了比较有效的解决方案。就是说,如果预先知道客户端发送的数据的公用大小,或者仅缓存大小相同的数据的情况下, 只要使用适合数据大小的组的列表,就可以减少浪费。但是很遗憾,现在还不能进行任何调优,只能期待以后的版本了。 但是,我们可以调节slab class的大小的差别。 接下来说明growth factor(增长系数)选项。

  •   使用Growth Factor进行调优
  memcached在启动时指定 Growth Factor因子(通过 -f 选项), 就可以在某种程度上控制slab之间的差异。默认值为1.25。 但是,在该选项出现之前,这个因子曾经固定为2,称为“powers of 2”策略。
  让我们用以前的设置,以verbose模式启动memcached试试看:
[root@memcache ~]# memcached -f 2 -vv
下面是启动后的verbose输出:
slab class   1: chunk size    128 perslab  8192
slab class   2: chunk size    256 perslab  4096
slab class   3: chunk size    512 perslab  2048
slab class   4: chunk size   1024 perslab  1024
slab class   5: chunk size   2048 perslab   512
slab class   6: chunk size   4096 perslab   256
slab class   7: chunk size   8192 perslab   128
slab class   8: chunk size  16384 perslab    64
slab class   9: chunk size  32768 perslab    32
slab class  10: chunk size  65536 perslab    16
slab class  11: chunk size 131072 perslab     8
slab class  12: chunk size 262144 perslab     4
slab class  13: chunk size 524288 perslab     2  可见,从128字节的组开始,组的大小依次增大为原来的2倍。 这样设置的问题是,slab之间的差别比较大,有些情况下就相当浪费内存。 因此,为尽量减少内存浪费,追加了growth factor这个选项。来看看现在的默认设置(f=1.25)时的输出:
slab class   1: chunk size     88 perslab 11915
slab class   2: chunk size    112 perslab  9362
slab class   3: chunk size    144 perslab  7281
slab class   4: chunk size    184 perslab  5698
slab class   5: chunk size    232 perslab  4519
slab class   6: chunk size    296 perslab  3542
slab class   7: chunk size    376 perslab  2788
slab class   8: chunk size    472 perslab  2221
slab class   9: chunk size    592 perslab  1771
slab class  10: chunk size    744 perslab  1409  可见,组间差距比因子为2时小得多,更适合缓存几百字节的记录。 从上面的输出结果来看,可能会觉得有些计算误差, 这些误差是为了保持字节数的对齐而故意设置的。将memcached引入产品,或是直接使用默认值进行部署时, 最好是重新计算一下数据的预期平均长度,调整growth factor, 以获得最恰当的设置。内存是珍贵的资源,浪费就太可惜了。
  5、memcached 过期方式
  数据过期方式:Lazy Expiration + LRU

  •   Lazy Expirationmemcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期。这种技术被称为lazy(惰性)expiration。因此,memcached不会在过期监视上耗费CPU时间。
  •   LRUmemcached会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,此时就要使用名为 Least Recently Used(LRU)机制来分配空间。当memcached的内存空间不足时(无法从slab class 获取到新的空间时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。
  6、memcached 不互相通信的分布式
  memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。 各个memcached不会互相通信以共享信息。那么,怎样进行分布式呢? 这完全取决于客户端的实现。如下图,

  7、memcached 支持的平台

  •   Linux
  •   FreeBSD
  •   Solaris (memcached 1.2.5以上版本)
  •   Mac OS X
  •   另外也能安装在Windows上。
  

  二、memcached 安装与配置
  1、安装libevent
[root@hpf-linux ~]# tar -xf libevent-2.0.22-stable.tar.gz
[root@hpf-linux ~]# cd libevent-2.0.22-stable
[root@hpf-linux libevent-2.0.22-stable]# ./configure --prefix=/usr/local/libevent
[root@hpf-linux libevent-2.0.22-stable]# make && make install  2、安装memcached
[root@hpf-linux ~]# tar -xf memcached-1.4.24.tar.gz
[root@hpf-linux ~]# cd memcached-1.4.24
[root@hpf-linux memcached-1.4.24]# ./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent
[root@hpf-linux memcached-1.4.24]# make && make install  3、配置环境变量
[root@hpf-linux memcached-1.4.24]# vim /etc/profile.d/memcached.sh
export PATH=$PATH:/usr/local/memcached/bin/  
[root@hpf-linux memcached-1.4.24]# source /etc/profile.d/memcached.sh  4、memcached 启动选项

  •   -p TCP监听端口 (default: 11211)
  •   -U UDP 监听端口 (default: 11211, 0 is off)
  •   -s UNIX socket监听路径,不支持网络
  •   -a UNIX socket访问掩码, 八进制 (default: 0700)
  •   -l 监听的服务器IP地址 (default: all addresses)
  •   -d 启动一个守护进程
  •   -r 最大限度利用核心文件限制
  •   -u 运行memcached用户
  •   -m 最大的内存使用 (default: 64 MB)
  •   -M 内存耗尽返回错误
  •   -c 最大并发连接 (default: 1024)
  •   -k 锁定所有分页内存
  •   -v 输出警告和错误信息
  •   -vv 同时打印客户端请求和返回信息
  •   -vvv 打印内部状态转换信息
  •   -i 打印memcached 和 libevent 版本信息
  •   -P 设置保存pid文件, only used with -d option
  •   -f 块大小增长倍数 (default: 1.25)
  •   -n key+value+flags最小分配空间(default: 48)
  •   -L 如何有效,尝试使用大内存页。增加内存页大小可以减少失误的TLB数量,提高性能。
  •   -D 指定key和IDs的分隔符 default is “:” (colon). 如果指定此选项,统计信息收集自动开启;
  •   -t 使用的线程数量 (default: 4)
  •   -R 每个事件的最大请求数 (default: 20)
  •   -C 禁止使用 CAS
  •   -b 设置积压队列数限制 (default: 1024)、
  •   -B 绑定协议 – one of ascii, binary, or auto (default)
  •   -I 分配给每个slab页(default: 1mb, min: 1k, max: 128m)
  •   -o 配置额外选项
  5、启动memcached
[root@hpf-linux ~]# useradd -r -u 490 -s /sbin/nologin memcached
[root@hpf-linux ~]# memcached -d -m 64 -u memcached -l 192.168.1.6 -c 256 -P /tmp/memcached.pid -vvv  6、查看监听的端口
[root@hpf-linux ~]# ss -tunlp |grep memcached
udp    UNCONN     0      0            192.168.1.6:11211                 *:*      users:(("memcached",18379,27),("memcached",18379,28),("memcached",18379,29),("memcached",18379,30))
tcp    LISTEN     0      128          192.168.1.6:11211                 *:*      users:(("memcached",18379,26))  7、配置SysV脚本
  提供配置文件:
[root@hpf-linux ~]# vim /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"  
CACHESIZE="128"  
OPTIONS=""[root@hpf-linux ~]# vim /etc/init.d/memcached
#!/bin/bash  
#  
# Init file for memcached  
#  
# chkconfig: - 86 14  
# description: Distributed memory caching daemon  
#  
# processname: memcached  
# config: /etc/sysconfig/memcached
. /etc/rc.d/init.d/functions
## Default variables
PORT="11211"  
USER="memcached"  
MAXCONN="1024"  
CACHESIZE="64"  
OPTIONS=""
[ -f /etc/sysconfig/memcached ] && . /etc/sysconfig/memcached
RETVAL=0
prog="/usr/local/memcached/bin/memcached"  
desc="Distributed memory caching"  
lockfile="/var/lock/subsys/memcached"
start() {
        echo -n $"Starting $desc (memcached): "  
        daemon $prog -d -p $PORT -u $USER -c $MAXCONN -m $CACHESIZE  $OPTIONS  
        RETVAL=$?  
        echo  
        [ $RETVAL -eq 0 ] && touch $lockfile  
        return $RETVAL  
}
stop() {
        echo -n $"Shutting down $desc (memcached): "  
        killproc $prog  
        RETVAL=$?  
        echo  
        [ $RETVAL -eq 0 ] && rm -f $lockfile  
        return $RETVAL  
}
restart() {
        stop  
        start  
}
reload() {
        echo -n $"Reloading $desc ($prog): "  
        killproc $prog -HUP  
        RETVAL=$?  
        echo  
        return $RETVAL  
}
case "$1" in
  start)  
        start  
        ;;  
  stop)  
        stop  
        ;;  
  restart)  
        restart  
        ;;  
  condrestart)  
        [ -e $lockfile ] && restart  
        RETVAL=$?  
        ;;   
  reload)  
        reload  
        ;;  
  status)  
        status $prog  
        RETVAL=$?  
        ;;  
   *)  
        echo $"Usage: $0 {start|stop|restart|condrestart|status}"  
        RETVAL=1  
esac
[root@hpf-linux ~]# chmod +x /etc/init.d/memcached
[root@hpf-linux ~]# chkconfig --add memcached
[root@hpf-linux ~]# chkconfig memcached on  8、启动服务
[root@hpf-linux ~]# service memcached start
Starting Distributed memory caching (memcached):           [确定]  9、测试
[root@hpf-linux ~]# telnet 192.168.1.6 11211
Trying 192.168.1.6...
Connected to 192.168.1.6.
Escape character is '^]'.
stats
STAT pid 8279 #进程ID
STAT uptime 8000 #服务器运行秒数
STAT time 1378284623 #服务器当前unix时间戳
STAT version 1.4.15 #服务器版本
STAT libevent 2.0.21-stable #libevent版本号
STAT pointer_size 64 #操作系统指针大小(这台服务器是64位的)
STAT rusage_user 0.000999 #进程累计用户时间
STAT rusage_system 0.003999 #进程累计系统时间
STAT curr_connections 10 #当前打开连接数
STAT total_connections 11 #曾打开的连接总数
STAT connection_structures 11 #服务器分配的连接结构数
STAT reserved_fds 20 #内部使用的FD数
STAT cmd_get 0 #执行get命令总数
STAT cmd_set 0 #执行set命令总数
STAT cmd_flush 0 #执行flush命令总数
STAT cmd_touch 0 #执行touch命令总数
STAT get_hits 0 #get命中次数
STAT get_misses 0 #get未命中次数
STAT delete_misses 0 #delete未命中次数
STAT delete_hits 0 #delete命中次数
STAT incr_misses 0 #incr未命中次数
STAT incr_hits 0 #incr命中次数
STAT decr_misses 0 #decr未命中次数
STAT decr_hits 0 #decr命中次数
STAT cas_misses 0 #cas未命中次数
STAT cas_hits 0 #cas命中次数
STAT cas_badval 0 #使用擦拭次数
STAT touch_hits 0 #touch命中次数
STAT touch_misses 0 #touch未命中次数
STAT auth_cmds 0 #认证处理的次数  
STAT auth_errors 0 #认证失败次数
STAT bytes_read 7 #读取字节总数
STAT bytes_written 0 #写入字节总数
STAT limit_maxbytes 134217728 #现在的内存大小为128M  
STAT accepting_conns 1 #目前接受的新接数
STAT listen_disabled_num 0 #失效的监听数
STAT threads 4 #当前线程数
STAT conn_yields 0 #连接操作主支放弃数目
STAT hash_power_level 16 #hash等级
STAT hash_bytes 524288 #当前hash表等级
STAT hash_is_expanding 0 #hash表扩展大小
STAT bytes 0 #当前存储占用的字节数
STAT curr_items 0 #当前存储数据总数
STAT total_items 0 #启动以来存储的数据总数
STAT expired_unfetched 0 #已过期但未获取的对象数目
STAT evicted_unfetched 0 #已驱逐但未获取的对象数目
STAT evictions 0 #LRU释放的对象数目
STAT reclaimed 0 #用已过期的数据条目来存储新数据的数目
END  

  三、memcached 使用详解
  1、memcached 基本命令
  Memcached提供了为数不多的几个命令来完成与服务器端的交互,这些命令基于memcached的协议实现。

  •   存储类命令:set, add, replace, append, prepend
  •   获取数据类命令:get, delete, incr/decr
  •   统计类命令:stats, stats items, stats slabs, stats sizes
  •   清理命令: flush_all
  2、memcached 存储命令的格式
  格式:
     
  参数说明:

  •    操作命令:set/add/replace……
  •    缓存的键值
  •    客户机使用它存储关于键值对的额外信息
  •    缓存过期时间 单位为秒 0 表示永远存储
  •    缓存值的字节数
  •    数据块




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-655632-1-1.html 上篇帖子: Debian 8.1(amd64)下部署Memcached 下篇帖子: 与session_set_save_handler无关的memcached保存session的方法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表