1 memcached应用场景
1.1 Web缓存
想象有这么一个场景,一个电子商务网站,在网站的左侧会是商品的分类,中间是商品搜索结果的列表,可以查看商品信息和商家的基本信息和相关商家的信誉度信息。
在这个场景下,因为一个商场的类别不会经常改变的。实时性不是很高,这样应该放到缓存中取的。
一般时候做法:
执行一次或者多次sql从数据库中查询全站的商品分类---->>递归形成你所需的分类tree------>>进入处理数据------->>显示到页面上。
使用 memcached做法:
第一次显示的时候
:判断memcached缓存中是否有该分类----没有----->执行一次或者多次sql从数据库中查询全站的商品分类----->放到memcached中------->>进入处理数据------->>显示到页面
第二次显示的时候
:的判断memcached缓存中是否有该分类----有—>>-从memcached中取出数据-------->>进入处理数据------->>显示到页面
当这个过程首次发生时,数据将正常地从数据库或其他数据源加载,然后再存储到 memcached 内。当下一次访问此信息时,它就会从 memcached 中取出,而不是从数据库加载,节省了时间和 CPU 循环。
但是要是数据中的数据改变怎么来更新memcached中的数据呢?
过程为
:更新数据库中分类的信息------->找到memcached中key值,删除------>重新插入到你的memcached中就可以了。emcached 内的存储操作是原子的,所以信息的更新不会让客户机只获得部分数据;
1.2 数据库缓存
实际应用中,尤其是在大规模访问的Web项目中,Memcache作为一种优秀的缓存解决方案,被广泛使用。其灵活性和可扩展性受到了广大开发者的青睐。为了提高响应速度,使用Memcache来减少数据查询运算是一种不错的选择。
需求背景
:网站有一个图片放映功能,页面加载时需从数据库中查询管理员所提交放映的图片信息,图片放映区共有9张图片,对应在数据库表中有9条记录。每次用户访问网站时,需查询数据库,并显示图片。当承受大规模用户同时访问时,数据库的压力可想而之。
为了降低数据库压力,提高查询速度,我采用了Memcache来将图片记录信息缓存到Memcache服务器上。这样就将数据库的查询压力分散到了各缓存服务器,提高了网站访问的整体效率。
2 应用实例配置
2.1 基础环境配置
环境规划
192.168.91.139 : mysql( 8.0.16版本)
192.168.91.140 : web
192.168.91.165 :memcache
同步时间:
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
rpm -e mariadb-libs postfix
2.2 web服务器配置
在192.168.91.140 安装软件,启动服务
wget https://downloads.mysql.com/archives/get/file/mysql-community-libs-compat-8.0.16-2.el7.x86_64.rpm
安装mysql客户端等:
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 http php php-gb php-mysql php-memcache -y
启动服务:
systemctl restart httpd
systemctl enable httpd
systemctl restart mysql
systemctl enable mysql
在mysql服务端创建用户:
mysql> create user 'memcache'@'%' identified by 'Admin@123';
mysql> ALTER USER 'memcache'@'%' IDENTIFIED WITH mysql_native_password BY 'Admin@123';
mysql> flush privileges;
测试http功能:
[root@localhost ~]# vim /var/www/html/index.html
[root@localhost ~]# cat /var/www/html/index.html
this is a test form 192.168.91.140...
测试PHP链接功能:
[root@localhost ~]# vim /var/www/html/index.php
[root@localhost ~]# cat /var/www/html/index.php
<?php
phpinfo();
?>
测试mysql:
[root@localhost ~]# vim /var/www/html/mysql.php
[root@localhost ~]# cat /var/www/html/mysql.php
<?php
$link=mysql_connect('192.168.42.181','superadmin','Cloudbu@123');
if($link) echo "<h1>Success!!</h1>";
else echo "Fail!!";
mysql_close();
?>
2.3 memcache 服务配置
2.3.1 安装部署 memcache
软件版本:
libevent 稳定版:wget http://monkey.org/~provos/libevent-1.4.14b-stable.tar.gz
memcached 稳定版:wget https://memcached.org/files/memcached-1.5.16.tar.gz
Libevent安装:
mkdir memdir
tar zxvf libevent-1.4.14b-stable.tar.gz -C memdir/
yum install make gcc gcc-c++ -y
cd memdir/libevent-1.4.14b-stable/
./configure --prefix=/usr/local/libevent/
make
make install
Memcached安装
tar -zxvf memcached-1.5.16.tar.gz -C memdir/
cd memdir/memcached-1.5.16/
./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 7257 1 0 13:09 ? 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 7286 1303 0 13:10 pts/0 00:00:00 grep --color=auto memcached
[root@localhost ~]#
链接测试:
[root@localhost ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
stats
STAT pid 7257
STAT uptime 128
STAT time 1564031521
STAT version 1.5.16
STAT libevent 1.4.14b-stable
STAT pointer_size 64
......(省略)
STAT lrutail_reflocked 0
STAT moves_to_cold 0
STAT moves_to_warm 0
STAT moves_within_lru 0
STAT direct_reclaims 0
STAT lru_bumps_dropped 0
END
代码测试
[root@localhost ~]# vim /var/www/html/memcache.php
[root@localhost ~]# cat /var/www/html/memcache.php
<?php
$memcache = new Memcache;
$memcache->connect('192.168.91.145', 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
session.save_handler = memcache
session.save_path = "tcp://192.168.91.165:11211?
persistent=1&weight=1&timeout=1&retry_interval=15"
extension= memcached.so
- 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:11211");
测试memcache的可用性:
[root@localhost ~]# vim /var/www/html/session.php
[root@localhost ~]# cat /var/www/html/session.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;
grant all privileges on *.* to memcache@'%' with grant option;
测试memcache是否缓存数据库成功
[root@localhost ~]# vim /var/www/html/memcache.php
[root@localhost ~]# cat /var/www/html/memcache.php
<?php
$memcachehost = '192.168.91.165';
$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.91.139","memcache","Admin@123");
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需要重新从数据库中取得数据