MemCached详解及服务的搭建

一、我们来了解一下MemCached与MemCache之间的区别:

1.1 Memcache是什么?

  • Memcache是一个自由和开放源代码、高性能、分配的内存对象缓存系统。用于加速动态web应用程序,减轻数据库负载。

  • 它可以应对任意多个连接,使用非阻塞的网络IO。由于它的工作机制是在内存中开辟一块空间,然后建立一个HashTable,Memcached自管理这 些HashTable。

1.2 Memcached又是什么?

  • Memcached是Memcache系统的主程序文件,以守护程序方式运行于一个或多个服务器中,随时接受客 户端的连接操作,使用共享内存存取数据。

  • 那PHP中的Memcache是什么?php中的所讲的memcache是用于连接Memecached的php支持扩展之一(可用phpinfo查看),类似mbstring,eAccelerator。

二 、概述

Memcache是总的缓存系统项目名称,容易和PHP中的Memcache混淆。
我们常提到Memcache其实是PHP中的Memcache,即PHP的Memcached扩展支持。

我们常提到Memcached是服务端主程序文件,服务端安装程序。

为了让你的程序飞起来,必须安装memcached服务端程序和PHP的Memcached扩展,所以如果您要使用Memcache来缓存系统,memcache和memcached两样我们都需要安装。

2.1 、接下来,我们来了解一下Memcached有关的知识点:

Memcached是danga.com(运营LiveJournal的技术团队)开发的一套分布式内存对象缓存系统,用于在动态系统中减少数据库 负载,提升性能。

2.2 、它所具有的特点有:

  • 协议简单

  • 基于libevent的事件处理

  • 内置内存存储方式

  • memcached不互相通信的分布式
    在这里插入图片描述

  • Memcached处理的原子是每一个(key,value)对(以下简称kv对),key会通过一个hash算法转化成hash-key,便于查找、对比以及做到尽可能的散列。同时,memcached用的是一个二级散列,通过一张大hash表来维护。

  • Memcached有两个核心组件组成:服务端(ms)和客户端(mc),在一个memcached的查询中,mc先通过计算key的hash值来 确定kv对所处在的ms位置。当ms确定后,客户端就会发送一个查询请求给对应的ms,让它来查找确切的数据。因为这之间没有交互以及多播协议,所以 memcached交互带给网络的影响是最小化的。

2.3 、内存分配

默认情况下,ms是用一个内置的叫“块分配器”的组件来分配内存的。舍弃c++标准的malloc/free的内存分配,而采用块分配器的主要目的 是为了避免内存碎片,否则操作系统要花费更多时间来查找这些逻辑上连续的内存块(实际上是断开的)。用了块分配器,ms会轮流的对内存进行大块的分配,并 不断重用。当然由于块的大小各不相同,当数据大小和块大小不太相符的情况下,还是有可能导致内存的浪费。

同时,ms对key和data都有相应的限制,key的长度不能超过250字节,data也不能超过块大小的限制 — 1MB。
因为mc所使用的hash算法,并不会考虑到每个ms的内存大小。理论上mc会分配概率上等量的kv对给每个ms,这样如果每个ms的内存都不太一样,那 可能会导致内存使用率的降低。所以一种替代的解决方案是,根据每个ms的内存大小,找出他们的最大公约数,然后在每个ms上开n个容量=最大公约数的 instance,这样就等于拥有了多个容量大小一样的子ms,从而提供整体的内存使用率。

2.4 、 缓存策略

当ms的hash表满了之后,新的插入数据会替代老的数据,更新的策略是LRU(最近最少使用),以及每个kv对的有效时限。Kv对存储有效时限是在mc端由app设置并作为参数传给ms的。

同时ms采用是偷懒替代法,ms不会开额外的进程来实时监测过时的kv对并删除,而是当且仅当,新来一个插入的数据,而此时又没有多余的空间放了,才会进行清除动作。

2.5 、缓存数据库查询

现在memcached最流行的一种使用方式是缓存数据库查询,下面举一个简单例子说明:

App需要得到userid=xxx的用户信息,对应的查询语句类似:

“SELECT * FROM users WHERE userid = xxx”

App先去问cache,有没有“user:userid”(key定义可预先定义约束好)的数据,如果有,返回数据;如果没有,App会从数据库中读取数据,并调用cache的add函数,把数据加入cache中。

当取的数据需要更新,app会调用cache的update函数,来保持数据库与cache的数据同步。

从上面的例子我们也可以发现,一旦数据库的数据发现变化,我们一定要及时更新cache中的数据,来保证app读到的是同步的正确数据。当然我们可 以通过定时器方式记录下cache中数据的失效时间,时间一过就会激发事件对cache进行更新,但这之间总会有时间上的延迟,导致app可能从 cache读到脏数据,这也被称为狗洞问题。(以后我会专门描述研究这个问题)

2.6 、数据冗余与故障预防

从设计角度上,memcached是没有数据冗余环节的,它本身就是一个大规模的高性能cache层,加入数据冗余所能带来的只有设计的复杂性和提高系统的开支。

当一个ms上丢失了数据之后,app还是可以从数据库中取得数据。不过更谨慎的做法是在某些ms不能正常工作时,提供额外的ms来支持cache,这样就不会因为app从cache中取不到数据而一下子给数据库带来过大的负载。

同时为了减少某台ms故障所带来的影响,可以使用“热备份”方案,就是用一台新的ms来取代有问题的ms,当然新的ms还是要用原来ms的IP地址,大不了数据重新装载一遍。

另外一种方式,就是提高你ms的节点数,然后mc会实时侦查每个节点的状态,如果发现某个节点长时间没有响应,就会从mc的可用server列表里 删除,并对server节点进行重新hash定位。当然这样也会造成的问题是,原本key存储在B上,变成存储在C上了。所以此方案本身也有其弱点,最好 能和“热备份”方案结合使用,就可以使故障造成的影响最小化。

2.7 、Memcached客户端(mc)

Memcached客户端有各种语言的版本供大家使用,包括java,c,php,.net等等,具体可参见memcached api page [2]。
大家可以根据自己项目的需要,选择合适的客户端来集成。

缓存式的WEB应用程序架构

有了缓存的支持,我们可以在传统的app层和db层之间加入cache层,每个app服务器都可以绑定一个mc,每次数据的读取都可以从ms中取得,如果 没有,再从db层读取。而当数据要进行更新时,除了要发送update的sql给db层,同时也要将更新的数据发给mc,让mc去更新ms中的数据。

性能测试

Memcached 写速度
平均速度: 16222 次/秒
最大速度 18799 次/秒

Memcached 读速度
平均速度: 20971 次/秒
最大速度 22497 次/秒

Memcachedb 写速度
平均速度: 8958 次/秒
最大速度 10480 次/秒

Memcachedb 读速度
平均速度: 6871 次/秒
最大速度 12542 次/秒

三 、服务搭建

3.1 、 实验环境:首先准备俩台服务器,一台是客户端,一台是服务端

  • 服务端ip地址是:20.0.0.32
  • 客户端的ip地址是:20.0.0.33

3.2 、首先我们搭建服务端

[root@node abc]# tar zxvf libevent-2.1.8-stable.tar.gz -C /opt
[root@node abc]# tar zxvf memcached-1.5.6.tar.gz -C /opt
[root@node abc]# cd /opt
root@node opt]# yum install gcc gcc-c++ make 安装底层环境和编译工具
[root@node opt]# cd /opt/libevent-2.1.8-stable/
[root@node libevent-2.1.8-stable]# ./configure --prefix=/usr/local/libevent 一定要先安装通知事件库,因为内存数据库是依赖于事件库
[root@node libevent-2.1.8-stable]# make && make install
[root@node libevent-2.1.8-stable]# cd /opt/memcached-1.5.6/ 切到该扩展目录下
[root@node memcached-1.5.6]# ./configure
–prefix=/usr/local/memcached \ 指定安装路径
–with-libevent=/usr/local/libevent/

3.3 、安装好之后我们要让memcached的一些命令能让系统识别

[root@node1 memcached-1.5.6]# ln -s /usr/local/memcached/bin/* /usr/local/bin

3.4 、用memcached去指定守护进程、缓存数据的大小,指定端口及指定哪个用户对其进行管理

[root@node1 memcached-1.5.6]#memcached -d -m 32m -p 11211 -u root

[root@node1 memcached-1.5.6]# netstat -anpt |grep 11211

tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 14664/memcached
tcp6 0 0 :::11211 ::😗 LISTEN 14664/memcached

[root@node1 memcached-1.5.6]# telnet 127.0.0.1 11211 远程连接数据库,显示没有该命令

bash: telnet: 未找到命令…

[root@node1 memcached-1.5.6]# yum -y install telnet
[root@node1 memcached-1.5.6]# telnet 127.0.0.1 11211 再去连接就进去了

Trying 127.0.0.1…
Connected to 127.0.0.1.
Escape character is '^]

[root@node1 memcached-1.5.6]#add username 0 0 7

1234567
gets yang 或者 get yang 都可以查询之前输入的字节长度
VALUE yang 0 7 4
1234567
END

注释:username键值名称,第一个0,代笔不设置她的序列号,第二个0表示无时间要求,也就是说不设置的失效时间,后面的7代表你即将要输入的字节长度

set yang 0 0 8

用set可以更新已有的键值,同时还有另一层意思,如果没有该键值,它还有添加的意思;同时replace也是更新的意思,但是针对以存在的键值,这是二者的区别

set clour 0 0 3 这边创建一个没有的键值对
123
STORED
gets clour 获取里面的数据也是查询到的
VALUE clour 0 3 7
123
END

gets yang
VALUE yang 0 7 4 这后面的4是更新因子,每操作过一次更新,后面的更新因子会自增加1
1234567
END

cas 检查更新,更新因子必须与之前的更新因子一致,才能操作

gets yang 现在看到更新因子是7
VALUE yang 0 3 7
123
END

cas yang 0 0 5 7
login
STORED
gets yang
VALUE yang 0 5 8
login
END

append 在键值后追加

例如:gets yang
VALUE yang 0 5 8
login
END
append yang 0 0 4 设置一个四位的字符
book 输入一个值
STORED
get yang 获取里面的数据
VALUE yang 0 9
loginbook 会发现输入的数据已经添加到数值之后了
END

prepend 在键值前追加数据

append yang 0 0 7
example
STORED

delete yang 删除数据
flush yang 清除所有缓存数据
squit 是推出数据库
stats 显示状态信息

然后登录客户端安装lamp架构:可以点这个网址超级详细的流程和解释

搭建好之后解压文件包

[root@node2 opt]# tar xf memcache-2.2.7.tgz
[root@node2 opt]# cd memcache-2.2.7/
[root@node2 memcache-2.2.7]# ls 我们查看该扩展目录下没有configure的脚本文件

在这里插入图片描述
[root@node2 memcache-2.2.7]# /usr/local/php5/bin/phpiz 增加为PHP的模块后在对memcache进行配置
[root@node2 memcache-2.2.7]#ls 这时再去查看就有configure的启动脚本文件了
在这里插入图片描述

[root@node2 memcache-2.2.7]# ./configure \ 
--enable-memcache \   启动memcache
--with-php-config=/usr/local/php5/bin/php-config 使用php5中bin目录下的一个php-config文件开启它的客户端

[root@node2 memcache-2.2.7]# make && make install
[root@node2 memcache-2.2.7]# /usr/local/php5/lib/php/extensions/no-debug-zts-20131226/ 然后我们看下有没有这条路径,如果有记录下来

[root@node2 memcache-2.2.7]# vim /usr/local/php5/php.ini

添加
extension_dir="/usr/local/php5/lib/php/extensions/no-debug-zts-20131226/" 指定目录的位置
extension=memcache.so 指定memcache的模块

注释:这边memcache就是提供了一个客户端的API服务接口,然后是由PHP去负责连接的数据库的,所有我们是需要php上生成一个API,去连接我们的缓存对象站点,然后再去连接数据库

[root@node2 memcache-2.2.7]# cd /usr/local/httpd/htdocs/
[root@node2 htdocs]# vim index.php 在这里写一个脚本,用客户端去连接服务器,如果里连接成功返回Successfull

"index.php"                                                                  0,0-1      
<?php
$mencache = new Memcache();
$mencaceh->connect('20.0.0.32',11211);
$mencaceh->set('key','Memcache test Successfull !'0,60);
$result = $memcache->get('key');
unset($memcache);
echo $result;
?

然后用客户端主机访问测试
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值