想象有这么一个场景,一个电子商务网站,在网站的左侧会是商品的分类,中间是商品搜索结果的列 表,可以查看商品信息和商家的基本信息和相关商家的信誉度信息。 在这个场景下,因为一个商场的类别不会经常改变的。实时性不是很高,这样应该放到缓存中取的。 一般时候做法: 在使用 memcached做法: 当这个过程首次发生时,数据将正常地从数据库或其他数据源加载,然后再存储到 memcached 内。当 下一次访问此信息时,它就会从 memcached 中取出,而不是从数据库加载,节省了时间和 CPU 循 环。
需求背景:网站有一个图片放映功能,页面加载时需从数据库中查询管理员所提交放映的图片信息,图片放映 区共有9张图片,对应在数据库表中有9条记录。每次用户访问网站时,需查询数据库,并显示图片。当承受大 规模用户同时访问时,数据库的压力可想而之。
为了降低数据库压力,提高查询速度,我采用了Memcache来将图片记录信息缓存到Memcache服务器 上。这样就将数据库的查询压力分散到了各缓存服务器,提高了网站访问的整体效率。
环境规划:
IP地址环境192.168.79.170memcache192.168.79.156web192.168.79.161mysql同步时间:
yum -y install ntp ntpdate ntpdate cn.pool.ntp.org hwclock --systohc关闭防火墙:
systemctl stop firewalld systemctl disable firewalld sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config setenforce 0在192.168.79.156上 安装软件,启动服务
rpm -e mariadb-libs postfix wget https://downloads.mysql.com/archives/get/file/mysql-community-libs-compat- 8.0.16-2.el7.x86_64.rpm yum localinstall mysql-community-client-8.0.16-2.el7.x86_64.rpm mysql-community- server-8.0.16-2.el7.x86_64.rpm mysql-community-libs-8.0.16-2.el7.x86_64.rpm mysql-community-common-8.0.16-2.el7.x86_64.rpm mysql-community-libs-compat- 8.0.16-2.el7.x86_64.rpm yum install httpd php php-gb php-mysql php-memcache systemctl restart httpd systemctl enable httpd在mysql服务端创建用户(192.168.79.161) mysql8.0中默认的身份认证插件是caching_sha2_password,替代了之前的mysql_navtive_password
mysql> create user 'memcache'@'%' identified by 'ABC123.com'; mysql> ALTER USER 'memcache'@'%' IDENTIFIED WITH mysql_native_password BY 'ABC123.com'; mysql> flush privileges;(web上)测试http功能
[root@localhost ~]# vim /var/www/html/index.html [root@localhost ~]# cat /var/www/html/index.html this is a test form 156..测试PHP测试功能
vim /var/www/html/index.php cat /var/www/html/index.php <?php phpinfo(); ?>在这里可以发现php链接是正常的 接下来,我们来测试mysql
链接mysql使用MySQL服务端的IP地址,之前创建好的memcache用户名和对相应的密码,若连接正常,返回success,失败则返回fail!!
[root@localhost ~]# cat /var/www/html/mysql.php <?php $link=mysql_connect('192.168.42.161','memcache','ABC123.com'); if($link) echo "<h1>Success!!</h1>"; else echo "Fail!!"; mysql_close(); ?>通过测试,可见MySQL数据库是可以正常链接的。
Libevent安装
tar zxvf libevent-1.4.14b-stable.tar.gz yum install make gcc gcc-c++ cd libevent-1.4.14b-stable ./configure --prefix=/usr/local/libevent/ make make installMemcached安装
tar -zxvf memcached-1.4.5.tar.gz cd memcached-1.4.5 ./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent/ make make install启动
[root@localhost ~]# /usr/local/memcached/bin/memcached -d -l 127.0.0.1 -p 11211 -u root -m 64 -c 1024 -P /var/run/memcached.pid [root@localhost ~]# ps -ef |grep memcached root 16227 1 0 00:56 ? 00:00:00 /usr/local/memcached/bin/memcached -d -l 127.0.0.1 -p 11211 -u root -m 64 -c 1024 -P /var/run/memcached.pid root 16238 1201 0 00:57 pts/0 00:00:00 grep --color=auto memcached启动参数说明: -d 选项是启动一个守护进程, -l 是监听的服务器IP地址,默认为所有网卡。 -p 是设置Memcache的TCP监听的端口,最好是1024以上的端口 -u 是运行Memcache的用户,如果当前为root 的话,需要使用此参数指定用户。 -m 是分配给Memcache使用的内存数量,单位是MB,默认64MB -c 选项是最大运行的并发连接数,默认是1024 -P 是设置保存Memcache的pid文件,我这里是保存在 /var/run/memcached.pid -M return error on memory exhausted (rather than removing items) -f chunk size growth factor (default: 1.25) -I Override the size of each slab page. Adjusts max item size(1.4.2版本新增) 也可以启动多个守护进程,但是端口不能重复
链接测试
[root@localhost init.d]# telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. stats ... STAT pid 17143 进程id STAT uptime 6177628 总的运行时间,秒数 STAT time 1508869811 当前时间 STAT version 1.2.0 版本号 STAT pointer_size 64 当前操作系统的指针大小(32位系统一般是32bit STAT rusage_user 556.351421 该进程累计用户时间 STAT rusage_system 1672.021814 该进程累计的系统时间 STAT curr_items 330722 当前缓存中的KeyValue数量######################## STAT total_items 1129411 曾经总共经过缓存的KeyValue数量 STAT bytes 132252377 所有的缓存使用的内存量 STAT curr_connections 121 当前连接数########################### STAT total_connections 58008 服务器运行以来接受的连接总数 STAT connection_structures 479 服务器分配的连接结构数 STAT cmd_get 92466399 总获取次数 STAT cmd_set 1129412 总的写入次数 STAT get_hits 90022544 总的命中次数 STAT get_misses 2443855 获取失败次数 STAT bytes_read 3822351834 总共读取的流量字节数 STAT bytes_written 63018557515 总的写入流量字节 STAT limit_maxbytes 4294967296 最大允许使用的内存量,字节 stats reset 清空统计数据 stats malloc 显示内存分配数据 stats maps stats sizes stats slabs 显示各个slab的信息,包括chunk的大小、数目、使用情况等 stats items 显示各个slab中item的数目和最老item的年龄(最后一次访问距离现在的秒数) 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测试web和memcache的连通性 修改客户端监听所有地址 注意:先杀死之前创建的memcached进程
[root@localhost ~]# /usr/local/memcached/bin/memcached -d -l 0.0.0.0 -p 11211 -u root -m 64 -c 1024 -P /var/run/memcached.pid [root@localhost ~]# ps -ef |grep memcached root 16629 1 0 02:38 ? 00:00:00 /usr/local/memcached/bin/memcached -d -l 0.0.0.0 -p 11211 -u root -m 64 -c 1024 -P /var/run/memcached.pid root 16640 16561 0 02:38 pts/1 00:00:00 grep --color=auto memcached代码测试 这里的IP地址为memcached端,和他的端口号
[root@localhost ~]# cat /var/www/html/memcached.php <?php $memcache = new Memcache; $memcache->connect('192.168.79.170', 11211) or die ("Could not connect"); $version = $memcache->getVersion(); echo "Server's version: ".$version."<br/>"; $tmp_object = new stdClass; $tmp_object->str_attr = 'test'; $tmp_object->int_attr = 123; $memcache->set('key', $tmp_object, false, 10) or die ("Failed to save data at the server"); echo "Store data in the cache (data will expire in 10 seconds)<br/>"; $get_result = $memcache->get('key'); echo "Data from the cache:<br/>"; var_dump($get_result); ?>测试通过; 配置session:
vim /etc/php.ini // 把这段放在最下面即可,IP地址为web端地址 session.save_handler = memcache session.save_path = "tcp://192.168.79.156:11211?persistent=1&weight=1&timeout=1&retry_interval=15"扩展: session.save_handler:设置session的储存方式为memcache。默认以文件方式存取session数据,如 果想要使用自定义的处理来存取session数据,比如 memcache方式则修为session.save_handler = memcache session.save_path:设置session储存的位置,多台memcache用逗号隔开 memcache实现session共享也可以在某个一个应用中设置:
ini_set("session.save_handler", "memcache"); ini_set("session.save_path", "[tcp://192.168.0.9](http://192.168.0.9/):11211");测试memcached的可用性:
[root@localhost ~]# cat /var/www/html/memcached1.php <?php session_start(); if (!isset($_SESSION['session_time'])) { $_SESSION['session_time'] = time(); } echo "session_time:".$_SESSION['session_time']."<br />"; echo "now_time:".time()."<br />"; echo "session_id:".session_id()."<br />"; ?>测试通过; 在数据库节点上创建测试数据库
create database testab1; use testab1; create table test1(id int not null auto_increment,name varchar(20) default null,primary key(id)) engine=innodb auto_increment=1 default charset=utf8; insert into test1(name) values ('tom1'),('tom2'),('tom3'),('tom4'),('tom5'); select * from test1; mysql> grant select on testab1.* to memcache@'%'; Query OK, 0 rows affected (0.00 sec) [root@localhost ~]# cat /var/www/html/memcached2.php <?php $memcachehost = '192.168.79.170'; //memcached端地址 $memcacheport = 11211; $memcachelife = 60; $memcache = new Memcache; $memcache->connect($memcachehost,$memcacheport) or die ("Could not connect"); $query="select * from test1 limit 10"; $key=md5($query); if(!$memcache->get($key)) { $conn=mysql_connect("192.168.79.161","memcache","ABC123.com"); //数据库节点,地址,用户,密码 mysql_select_db(testab1); $result=mysql_query($query); while ($row=mysql_fetch_assoc($result)) { $arr[]=$row; } $f = 'mysql'; $memcache->add($key,serialize($arr),0,30); $data = $arr ; } else{ $f = 'memcache'; $data_mem=$memcache->get($key); $data = unserialize($data_mem); } echo $f; echo "<br>"; echo "$key"; echo "<br>"; //print_r($data); foreach($data as $a) { echo "number is <b><font color=#FF0000>$a[id]</font></b>"; echo "<br>"; echo "name is <b><font color=#FF0000>$a[name]</font></b>"; echo "<br>"; } ?>如果出现mysql表示memcached中没有内容,需要memcached从数据库中取得: 再刷新页面,如果有memcache标志表示这次的数据是从memcached中取得的。 memcached有个缓存时间默认是1分钟,过了一分钟后,memcached需要重新从数据库中取得数据