博主 | 发布时间: 20. August 2010 10:28
很多phper不知道如何在Windows下如何搭建Memcache的开发调试环境,所以写篇 Memcache的文档分享给大家。
Windows下的Memcache安装:
1. 下载Memcached1.2.5的 windows稳定版,解压放某个盘下面,比如在c:\memcached
2. 在终端(也即cmd命令界面)下输入 ‘c:\memcached\memcached.exe -d install’ 安装
3. 再输入: ‘c:\memcached\memcached.exe -d start’ 启动。NOTE: 以后memcached将作为windows的一个服务每次开机时自动启动。这样服务器端已经安装完毕了。
4.下载php_memcache.dll, 请自己查找对应的php版本的文件
5. 在C:\winnt\php.ini 加入一行 ‘extension=php_memcache.dll’
6.重新启动Apache,然后查看一下phpinfo,如果有memcache,那么就说明安装成功!
memcached的基本设置:
-p 监听的端口
-l 连接的IP地址, 默认是本机
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
-u 以的身份运行 (仅在以root运行的时候有效)
-m 最大内存使用,单位MB。默认64MB
-M 内存耗尽时返回错误,而不是删除项
-c 最大同时连接数,默认是1024
-f 块大小增长因子,默认是1.25
-n 最小分配空间,key+value+flags默认是48
-h 显示帮助
Memcache环境测试:
运行下面的php文件,如果有输出This is a test!,就表示环境搭建成功。开始领略Memcache的魅力把!
< ?php
$mem = new Memcache;
$mem->connect(”127.0.0.1″, 11211);
$mem->set(’key’, ‘This is a test!’, 0, 60);
$val = $mem->get(’key’);
echo $val;
?>
dc41e598-79e3-40f8-aed7-cf6db0cb2083|0|.0
博主 | 发布时间: 15. July 2010 17:09
1. stats
统计
2.stats malloc
显示内存分配
3. stats reset
清空统计数据
4. stats cachedump slab_id limit
显示某个slab中的前limit个key列表: ITEM key [ value_length b; expire_time s] (1.2.2前是访问时间,不是过期时间)
说明:expire_time是unixtime时间戳。如果一个key是没有过期的,那这个时间就等于memcache启动的时间。可以通过stats命令中获得的time – uptime 算得。
5. stats slabs
显示slabs信息。从这个命令能获取每个slabs的chunksize长度,从而确定数据到底存哪个slab。
6. stats items
显示slab中的item数目
7. stats detail dump
打印详细操作信息,需要使用stats detail on|off 来启动|关闭
8. get |gets 键
两者的区别是gets多返回一个更新版本,即该key值被更新的版本号
返回:
VALUE key flag length (ver)
data
另外,flag是客户端给的,对memcached服务器来说无意义。举例PHP的memcache客户端有个压缩选项,即设的这个flag,压缩操作在客户端做的。
71e629b7-ea05-4d48-8666-bf1c065cde59|0|.0
博主 | 发布时间: 8. April 2010 15:56
一.基础篇
1.下载源代码并解压
cd /opt/software
wget -c http://www.squid-cache.org...
tar -zxvf squid-2.5.STABLE14.tar.gz
2.安装Squid Proxy Server
cd /opt/software/squid-2.5.STABLE14
./configure --prefix=/usr/local/squid
3. 设置squid.conf,内容如下
http_port 80
# squid 的端口
cache_dir aufs /usr/local/squid/var/cache 250 16 256
# 缓存目录:/cache 类型:ufs 大小:250mb 允许Squid在目录下建立一级(16)和二级目录(256)
cache_mem 64 MB
# cache内存大 小:64mb
cache_store_log /var/log/squid/store.log
#Squid的日志1:在 /var/log/squid下,注意此目录的权限
cache_access_log /var/log/squid/access.log
#Squid的日志2:在/var/log/squid下,注意此目录的权限
cache_log /var/log/squid/cache.log
#Squid的日志3:在/var/log/squid下,注意此目录的权限
### cache user
cache_effective_user nobody #缓存用户UID
cache_effective_group nobody #缓存用户组 GID
### cache admin
visible_hostname www.phpme.com
#发生错误时,生成提示所显示的缓存服务器名
cache_mgr caminero.yang@gmail.com
#发生错误时,生成提示所显示的缓存服务器管理员名
acl badurls dstdomain popme.163.com
http_access deny badurls
#以上2句不允许使用该缓存服务器 访问popme.163.com
acl badwords url_regex -i sex
http_access deny badwords
#以上2句不允许使用该缓存服务器访问URL正则表达式中含sex字样的URL
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
#httpd 透明代理配置
acl all src 0.0.0.0/0.0.0.0
http_access allow all
4.启动squid
/usr/local/squid/sbin/squid -z #初始化cache目录
/usr/local/squid/sbin/squid
以下信息可以参考判断问题
squid -k parse #检查配置是否有错误,没有任何输出,证明配置基本是正确的!!!
squid -zX #可以加一个X参数,看看初始化具体的项目.
如果因为DNS无法启动squid,可以用下面的命令启动squid
squid –D
如果发现启动了一下,squid的进程又在进程列表中消失了。可以用下面的命令
squid -NCd2
5.设置hosts将 需要cache的网址指向我们要指向的ip,再通过ie访问,就可以发现已经成功的配置squid了。
二.升级篇
1.限 制可以cache的域名
修改squid.conf文件,最后一行修改为:http_access deny all
前面加上以下内 容:
acl allowurls dstdomain blog.cnfol.com
http_access allow allowurls
#以上2句只允许使用该缓存服务器访问blog.cnfol.com
原理说明:需要理解一下squid的读取配置的 方式。Squid将使用allow-deny-allow-deny……这样的顺序套用规则。例如,当一个用户访问代理服务器时, Squid会顺序测试Squid中定义的所有规则列表,当所有规则都不匹配时,Squid会使用与最后一条相反的规则。当定义了允许的规则,再定义一条 deny的规则,则deny的规则不会生效。也就是说,在最后一条加上deny all可以保证只有在指定规则范围内才能使用。
2.限制 cache的时间
refresh_pattern ^http: 5 20% 50
#限制当网址是以http:开头的,那么 在5分钟后,cache内的数据会被更新
说到这个问题,不得不说一下我在学习过程中发现的一个情况,FF中查看header几乎全部的请求都是 miss,查看access.log发现状态是tcp_refresh_hit(关于状态说明此处不做详解),但是IE下吐出的头却是hit,状态时 tcp_ims_hit。猜想可能是两个浏览器送出的头不同。对比两个头
FF:
IE:
3. 限制可以cache的网址规则
设置带?号的网址不cache:在squid.conf中加入以下几行
acl badwords urlpath_regex -i ?
http_access deny badwords
#以上2句不允许使用该缓存服务器访问 URL正则表达式中含?字样的URL
注意:若发现未生效,请更换一下此语句的位置,当存在多个http_access的时候,位置不同也会造成问 题,具体我们以后再研究。
设置特殊规则的网址不cache
以博客为例,只想cache文章页(http://blog.cnfol.com/aa/1...,其他 页面都不cache
acl articleurl url_regex -i ^http://blog.cnfol.com/([0-9a-zA-Z_]+)/article/([0-9]+).html
http_access allow articleurl
acl badwords urlpath_regex -i .+
http_access deny badwords
#以上4句只允许使用该缓存服务器访问文章页
写了以上两个规则以后发现,当url不符合我们规则时时,访问结 果都变成403了,这显然不是我们需要的结果,我们再看要如何修改
Squid有一个no_cache的命令,可以指定规则不进行cache,如:
acl articleurl url_regex -i ^http://blog.cnfol.com/shtml/([0-9]+).shtml
no_cache deny articleurl
#这样就不会cache我们指定的页面了。
接下来,我们试试看,如果我们希望只cache其中的某个规则的页 面,而其他页面都不cache规则要如何来写
acl allowurl url_regex -i ^http://blog.cnfol.com/shtml/19.shtml
no_cache allow allowurl
acl denyurl urlpath_regex -i .+
no_cache deny denyurl
#以上四句的意思相信不用我再解 释了吧
4.根据不同的规则设置不同的cache时间
refresh_pattern .shtml$ 5 10% 5 ignore-reload
#限制当网址是以.shtml结尾的,那么在5分钟后,cache内的数据会被更新,但是我测试似乎结果并非如此
5. 防盗链设置
acl picurl url_regex -i .bmp$ .png$ .jpg$ .gif$ .jpeg$
acl mystie1 referer_regex -i ^http://blog.cnfol.com
http_access deny !mystie1 picurl
#以上是防盗链设置,这里拒绝了不是从blog.cnfol.com过来的请求
#这句必须放在下面的语句 之上,因为squid匹配条件的规则是按照自上而下的顺序,当匹配到允许或者拒绝的条件,就不会向下继续进行匹配,故限制条件应放在通配条件之上
acl articleurl url_regex -i ^http://blog.cnfol.com/shtml/([0-9]+).([a-zA-Z0-9]+)
http_access allow articleurl
上面的说明,可能有做过apache的rewrite的人会比较容易理解,我之前也被规则的顺 序困扰了很久,其实这个就是一个正常的程序员的思路,找到符合当前的规则就跳出, 否则继续向下。
6.根据头信息判断页面是否需要cache
上 面已经说了我们可以通过refresh_partern来配置特定网址的过期时间。在Squid的手册上有这样一段话:refresh_pattern规 则仅仅应用到没有明确过时期限的响应。原始服务器能使用Expires头部,或者Cache-Control:max-age指令来指定过时期限。也就是 说,我们可以通过服务器输出头信息来控制此cache的cache时间。如何控制呢?看下面的代码
$offset = 60;
$ExpStr = "Expires: " .gmdate("D, d M Y H:i:s", time()+$offset) ." GMT";
header($ExpStr);
header("Last-Modified:". gmdate( 'D, d M Y H:i:s' ) . " GMT" );
#header("Cache-Control: max-age=".$offset);
#header("Cache-Control: public");
# Basic认证的网页若需要缓冲须用public的头
echo '
';
print_r(getallheaders());
?>
这段代码里面指定了页面的过期时间和最后修改时间。这样squid会按照这里指定的过期时间来控制cache的时间,而不会按照refresh_pattern的设置。
我在测试过程中,一开始只是使用了Expires,而没有使用Last-Modified,结果发现每次的结果都是tcp_miss,加了Cache-Control也没用,那么,我们要如何理解这几个参数(包括squid会返回的一个Date参数)与对squid的判断作用呢?
Date:指squid从realserver中获得数据的时间
Last-Modified:一般指页面生成的时间
Expires:页面指定的过期时间
由于指定了过期时间,但未制定生成时间,我猜想squid会默认一个生成时间值,很可能是1970年1月1日,所以这个铁定是会被认为过期的,于是我们每次都会看到都miss了。而后来加了一个生成时间,判断无误。
说到这里,我想有必要再回过头去说要一下refresh_parttern这个配置。
refresh_pattern语法如下:
refresh_pattern [-i] regexp min percent max [options]
#-i 是用来控制是否区分大小写的,min和max的单位是分钟,percent是百分比
对于一个cache是否过期,squid会这样计算,
If ((CURRENT_DATE-DATE(就是LM里定义的时间)) < min),cache是新鲜的
else if ((CURRENT_DATE-DATE) < (min + (max-min)*percent),cache是新鲜的
else cache是过期的
有一点一定要记住::refresh_pattern规则仅仅应用到没有明确过时期限的响应。原始服务器能使用Expires头部,或者Cache-Control:max-age指令来指定过时期限。所以,上面说的公式并不适用于有输出Expire和Last-Modified头的页面。
说到这里,我们再回过头来看FF和IE的问题,为什么IE可以hit而FF不行呢?
对比squid发给realserver的头,我们发现,ff请求的时候,squid请求(对realserver)头Cache-Control:max-age=0;而IE则是Cache-Control:max-age=960。
实际情况是这样,当第一次请求的时候,request中不会有max-age,而此时若squid中有所请求的资源未过期的拷贝,则squid会将拷贝返回给浏览器,这个是没问题的。问题出在,当第二次请求,本地的FF中已经包含了一个cache,此时FF会向squid发起请求要求验证本地cache是否有效,于是squid再次在服务器寻找cache,squid找到了一个貌似过期的资源,出现TCP_REFRESH_MISS状态。这样前台便出现miss的情况。但是,这样的情况为什么只出现在FF,而IE不会呢?我想是不是与响应头有关,在查看hit的时候返回的响应头
FF
IE
7.如何清除cache
有时候,我们可能想根据一定的规则清除cache住的一些资源,可以通过下面的方法实现:
1.squid –z重建cache区
2. squid清空缓存
# /usr/local/squid/sbin/squid -k shutdown 关闭squid
# echo "" > /usr/local/squid/var/cache/swap.state 写入一些垃圾数据到这个文件
# echo "" > /usr/local/squid/var/cache/swap.state 如果有多个....
#/usr/local/squid/sbin/squid –z
#/usr/local/squid/sbin/squid
如果你有多个cache目录,请为每个cache目录下的swap.state文件执行上门的命令
不能直接删除swap.state命令,或者是把这个文件清为0,需要写一些垃圾数据到这个文件中
3.还有一种比较夸张的方法,清除 URL 以“.mp3”结尾的缓存文件
#./purge -p localhost:80 -P 1 -se '.mp3$'(未验证)
三.高级篇
1. 什么是squid的命中率,如何分析squid当前的运行状态
在实际测试当中,在日志中发现的最多种的状态(除了MISS以外的)是:
TCP_REFRESH_HIT:指squid发现cache中存在资源的拷贝,但不知是否新鲜的,向realserver发起了一次确认,realserver指出该拷贝是新鲜的
TCP_IMS_HIT:指浏览器向squid发起请求,squid指出浏览器本地cache是新鲜的
TCP_MEM_HIT:指squid在cache中发现存在资源的拷贝,并返回给浏览器
除了下面两种状态以外,其他都应该是未命中状态。下面介绍一款squid命中率监控软件squid-graph
下载包:http://sourceforge.net/pro...
解压后直接就可以使用。但是需要perl的gd的支持
GD的安装:http://stein.cshl.org/www/...,下载后解压
perl makefile.pl
make
make install
接下来,编辑apache的配置文件,加入访问路径
Alias /squid-graph /var/www/squid-graph
Order deny,allow
Allow from all
弄好上面的步骤以后,我们要利用工具开始分析日志
./squid-graph -o=/var/www/squid-graph/ < /var/log/squid/access.log
具体命令的意思就不多说了
分析完成以后就可通过http://ip/squid-graph来进行查看squid的命中率统计了。
2.squid的cache存储结构
3.如何查看squid当前的运行状态
四.技巧学习
1.注意观察日志文件,日志文件中有状态码,可以协助你判断此时cache的性能
f98c7511-39a3-4a8c-8fc3-a4bc6798c8ac|0|.0
博主 | 发布时间: 13. January 2010 23:13
1. 安装 memcached,还是那套 ./configure; make; make install,注意 memcached 用 libevent 来作事件驱动,所以要先安装有 libevent。
2. 安装 pecl::memcache,用 pecl 命令行工具安装:
pecl install memcache
或直接从源码安装:
phpize
./configure
make
make install
将 php.ini 中 extension=memcache.so 打开,重启一下 apache,查看 phpinfo 中的 "Registered save handlers" 会有 "files user memcache" 这3个可用。
3. 修改配置文件,在 php.ini 中全局设置:
session.save_handler = memcache
session.save_path = "tcp://127.0.0.1:11211"
或者某个目录下的 .htaccess :
php_value session.save_handler "memcache"
php_value session.save_path "tcp://127.0.0.1:11211"
再或者在某个一个应用中:
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "tcp://127.0.0.1:11211");
如果要做分布式的memcache,就要把127.0.0.1改成局域网内的IP地址。使用多个 memcached server 时用逗号","隔开,并且和 Memcache::addServer() 文档中说明的一样,可以带额外的参数"persistent"、"weight"、"timeout"、"retry_interval" 等等,类似这样的:"tcp://host1:port1?persistent=1&weight=2,tcp://host2:port2" 。
4. 启动 memcached:
#memcached -d -l 127.0.0.1 -p 11212 -m 128
/usr/local/bin/memcached -d -m 50 -u root -l 192.168.1.13 -p 11211 -P /tmp/memcached
-m memcache最大可用内存数(单位:M)
-u 用户
-l 链接地址,如果是多个机器共用memcache,一定要使用局域网IP
-p 端口号
-P ...
5. 在程序中使用 memcache 来作 session 存储,用例子测试一下:
<?php
session_start();
if (!isset($_SESSION['TEST'])) {
$_SESSION['TEST'] = time();
}
$_SESSION['TEST3'] = time();
print $_SESSION['TEST'];
print "<br><br>";
print $_SESSION['TEST3'];
print "<br><br>";
print session_id();
?>
6. 用 sessionid 去 memcached 里查询一下:
<?php
$memcache = memcache_connect('localhost', 11211);
var_dump($memcache->get('19216821213c65cedec65b0883238c278eeb573e077'));
?>
会有看到
string(37) "TEST|i:1177556731;TEST3|i:1177556881;"
这样的输出,证明 session 正常工作。
用 memcache 来存储 session 在读写速度上会比 files 时快很多,而且在多个服务器需要共用 session 时会比较方便,将这些服务器都配置成使用同一组 memcached 服务器就可以,减少了额外的工作量。缺点是 session 数据都保存在 memory 中,持久化方面有所欠缺,但对 session 数据来说也不是很大的问题。
命令行查看Memcached运行状态
很多时候需要监控服务器上的Memcached运行情况,比如缓存的查询次数,命中率之类的。但找到的
那个memcached-tool是linux下用perl写的,我也没试过windows能不能用。后来发现个简单的办法
可以做到,就是使用Telnet。
首先登录到服务器,然后在cmd命令行中键入
telnet 127.0.0.1 11211
其中127.0.0.1是服务器的地址(这里是本机) ,11211是memcached绑定的端口号。
之后命令行窗口全黑只有光标提示,摸黑输入stats,即可得到描述Memcached服务器运行情况的参
数。如下图:
其中,uptime 是memcached运行的秒数,cmd_get是查询缓存的次数。这两个数据相除一下就能得到
平均每秒请求缓存的次数——最近niupu的流量很低,所以平均也就一秒请求一次多,这么点大的压
力,用文件系统缓存一样没问题,根本不会体现出使用memcached的优越。
下面的cmd_set 就是设置key=>value的次数。整个memcached是个大hash,用cmd_get没有找到的内
容,就会调用一下cmd_set写进缓存里。紧跟着是get_hits,就是缓存命中的次数。缓存命中率 =
get_hits/cmd_get * 100%。
下面的get_misses的数字加上get_hits应该等于cmd_get。而total_itemscurr_items表示现在在缓
存中的键值对个数,在图上total_items == cmd_set == get_misses,不过当可用最大内存用光时
,memcached就会删掉一些内容,上面的等式就不成立了。
话说回来,memcached要是能有一套完整的监测工具就太好了。memcached的安装和php相应配置请看
这里。
Memcached的stats命令
telnet到memcached服务器后有很多的命令可以使用,除了大家熟知的add、get、set、incr、decr、replace、delete等赋值命令外,还有一系列的获取服务器信息的命令,这部分命令都是以stats开头的。
用PHP的Memcache::getStats($cmd)也可以访问这些命令
常用的命令
stats
显示服务器信息、统计数据等
stats reset
清空统计数据
stats malloc
显示内存分配数据
stats cachedump slab_id limit_num
显示某个slab中的前limit_num个key列表,显示格式如下
ITEM key_name [ value_length b; expire_time|access_time s]
其中,memcached 1.2.2及以前版本显示的是 访问时间(timestamp)
1.2.4以上版本,包括1.2.4显示 过期时间(timestamp)
如果是永不过期的key,expire_time会显示为服务器启动的时间
stats cachedump 7 2
ITEM copy_test1 [250 b; 1207795754 s]
ITEM copy_test [248 b; 1207793649 s]
stats slabs
显示各个slab的信息,包括chunk的大小、数目、使用情况等
stats items
显示各个slab中item的数目和最老item的年龄(最后一次访问距离现在的秒数)
stats detail [on|off|dump]
设置或者显示详细操作记录
参数为on,打开详细操作记录
参数为off,关闭详细操作记录
参数为dump,显示详细操作记录(每一个键值get、set、hit、del的次数)
stats detail dump
PREFIX copy_test2 get 1 hit 1 set 0 del 0
PREFIX copy_test1 get 1 hit 1 set 0 del 0
PREFIX cpy get 1 hit 0 set 0 del 0
d250db8f-f0fc-4990-aab7-a773a08689d2|0|.0
博主 | 发布时间: 13. January 2010 23:07
查询实时的状态,类似于“top”命令。
在命令行下执行任一命令(第二个办法需要通过php):
1. watch "echo stats | nc 127.0.0.1 11211"
结果如下:
STAT pid 13785
STAT uptime 1377436
STAT time 1227764242
STAT version 1.2.6
STAT pointer_size 32
STAT rusage_user 9.265591
STAT rusage_system 36.541444
STAT curr_items 6
STAT total_items 1093
STAT bytes 24628
STAT curr_connections 19
STAT total_connections 79352
STAT connection_structures 117
STAT cmd_get 609575
STAT cmd_set 1093
STAT get_hits 608483
STAT get_misses 1092
STAT evictions 0
STAT bytes_read 14703639
STAT bytes_written 2297950214
STAT limit_maxbytes 52428800
STAT threads 1
END
2. watch '/www/php/bin/php -r '"'"'$m=new Memcache;$m->connect("127.0.0.1", 11211);print_r($m->getstats());'"'"
结果如下:
Array
(
[pid] => 13785
[uptime] => 1377469
[time] => 1227764275
[version] => 1.2.6
[pointer_size] => 32
[rusage_user] => 9.266591
[rusage_system] => 36.541444
[curr_items] => 6
[total_items] => 1093
[bytes] => 24628
[curr_connections] => 16
[total_connections] => 79372
[connection_structures] => 117
[cmd_get] => 609593
[cmd_set] => 1093
[get_hits] => 608501
[get_misses] => 1092
[evictions] => 0
[bytes_read] => 14704073
[bytes_written] => 2298032330
[limit_maxbytes] => 52428800
[threads] => 1
)
上面命令假设memcached按默认情况运行,即服务器地址为127.0.0.1,端口为11211。请按实际情况修改
24d29b35-2f0c-418b-a158-14252c24892a|0|.0