redis+mysql 实现lamp缓存

fastcgi与cgi简单区别参考:https://www.jianshu.com/p/0cdaa89eeb7a

主从复制的特点:不实时 一定有延迟 网络因素 数据库sql性能 主 多线程 io上有复制延迟 从 默认为单线程

fastcgi与cgi的区别:
fastCGI有后台进程 9000端口在后台 一直运行 请求过来直接解析
cgi:fork一个新的进程进行处理

这个实验存在的问题是数据不同步 除非清除redis的缓存,让redis再去请求mysql取数据
或者在做update时,在redis中删除数据 ,但是所以最好的方式是在mysql中做触发(下一篇博客gearman会写到)
异步同步

数据流向,分为两种情况:

  • webserver ----> (r/w) redisserver ----> 内置钩子函数 ----> input ----> mysql
  • webserver ----> r (redisserver cache) <–> w mysql ----> update mysql ----> trigger(触发器) ----> redisserver
    传统的 redis只做缓存 用来降低mysql访问压力。当客户端有请求过来时,会判断客户端的请求是post还是get,如果为post—写 则写到mysql中,如果为get—读 则读redis的缓存数据 (cache 缓存,数据从mysql里来)
    此时如果客户端的请求是修改数据,即 mysql被update(数据被更新)的话, redis和mysql两者没同步就会导致数据不一致的问题,
    而redis只有在他的数据过期或没有缓存的时侯才会去找mysql拿数据,
    update后 会触发redisserver

实验环境

  • rhel7且firewalld和selinux为stop并且disabled。
主机名(IP)服务
server1(172.25.11.1)php lamp前端
server2(172.25.11.2)redis(中间的缓存)
server3(172.25.11.3)mysql(w)

实验步骤

server1(lamp)
  • 安装lamp架构需要的软件,开启httpd服务。
[root@server1 ~]# yum install httpd php php-mysql -y
[root@server1 ~]# systemctl start httpd
  • 写一个php文件用于载浏览器中测试(这里是别人写好的,我们修改两处,redis服务器的ip和mysql服务器的ip)。
[root@server1 ~]# mv test.php /var/www/html/

[root@server1 ~]# vim /var/www/html/test.php 
[root@server1 ~]# cat /var/www/html/test.php 
<?php
        $redis = new Redis();
        $redis->connect('172.25.11.2',6379) or die ("could net connect redis server");
  #      $query = "select * from test limit 9";
        $query = "select * from test";
        for ($key = 1; $key < 10; $key++)
        {
                if (!$redis->get($key))
                {
                        $connect = mysql_connect('172.25.11.3','redis','westos');
                        mysql_select_db(test);
                        $result = mysql_query($query);
                        //如果没有找到$key,就将该查询sql的结果缓存到redis
                        while ($row = mysql_fetch_assoc($result))
                        {
                                $redis->set($row['id'],$row['name']);
                        }
                        $myserver = 'mysql';
                        break;
                }
                else
                {
                        $myserver = "redis";
                        $data[$key] = $redis->get($key);
                }
        }
 
        echo $myserver;
        echo "<br>";
        for ($key = 1; $key < 10; $key++)
        {
                echo "number is <b><font color=#FF0000>$key</font></b>";
 
                echo "<br>";
 
                echo "name is <b><font color=#FF0000>$data[$key]</font></b>";
 
                echo "<br>";
        }
?>

在这里插入图片描述

  • 加载php的模块,此时有mysql模块了,但是还没有redis。
[root@server1 ~]# php -m   #查看所有
[root@server1 ~]# php -m | grep mysql    #与mysql相关的,有3个
mysql
mysqli
pdo_mysql
[root@server1 ~]# php -m | grep redis   #与redis相关的,不存在。
  • 所以我们下载php有关redis的压缩包,解压(安装php的redis扩展)。
lftp 172.25.11.250:/pub/redis> get phpredis-master.zip 
[root@server1 ~]# yum install unzip -y
[root@server1 ~]# unzip phpredis-master.zip

在这里插入图片描述

  • 进入解压后的目录下,加载php的模块,发现报错了,这是因为我们缺少php的依赖包,我们下载并安装。
    注意:phpize是一个运行脚本,主要作用是检测php的环境还有就是在特定的目录生成相应的configure文件,这样makeinstall之后,生成的.so文件才会自动加载到php扩展目录下面。
[root@server1 ~]# cd phpredis-master
[root@server1 phpredis-master]# ls
[root@server1 phpredis-master]# phpize 
lftp 172.25.11.250:/pub/redis> get php-devel-5.4.16-42.el7.x86_64.rpm 
[root@server1 phpredis-master]# yum install php-devel-5.4.16-42.el7.x86_64.rpm -y

在这里插入图片描述

  • 再次加载,发现加载成功。
[root@server1 phpredis-master]# phpize 

在这里插入图片描述

  • 编译并安装,编译时加上激活redis的参数选项。
[root@server1 phpredis-master]# ./configure --enable-redis
[root@server1 phpredis-master]# make && make install

在这里插入图片描述

  • 按照提示,安装完成后生成的模块都在此目录下。
    在这里插入图片描述
  • 修改php的初始化文件,修改时区为上海。
[root@server1 modules]# vim /etc/php.ini
 878 date.timezone = Asia/Shanghai
  • 拷贝mysql的初始化文件,修改内容为redis的模块名,加载redis模块。
[root@server1 modules]# cd /etc/php.d/
[root@server1 php.d]# cp mysql.ini redis.ini
[root@server1 php.d]# vim redis.ini 
[root@server1 php.d]# cat redis.ini 
extension=redis.so
  • 重启httpd,再次查看与redis有关的模块,发现成功加载。
[root@server1 php.d]# systemctl restart httpd
[root@server1 php.d]# ps ax
[root@server1 php.d]# php -m | grep redis
redis
server2(redis)
  • 部署redis服务。
    具体流程参考本人之前的博客,这里简写。
lftp 172.25.11.250:/pub/redis> get redis-5.0.3.tar.gz 
[root@server2 ~]# tar zxf redis-5.0.3.tar.gz 
[root@server2 ~]# cd redis-5.0.3
[root@server2 redis-5.0.3]# yum install gcc && make && make install
[root@server2 redis-5.0.3]# cd utils/
[root@server2 utils]# ./install_server.sh 
#修改配置文件
[root@server2 init.d]# vim /etc/redis/6379.conf
  70 bind 0.0.0.0
#开启服务
[root@server2 init.d]# /etc/init.d/redis_6379 status
server3(mysql)
  • 下载mariadb数据库的服务器端,开启服务,尝试登陆。
[root@server3 ~]# yum install mariadb-server -y
[root@server3 ~]# systemctl start mariadb
[root@server3 ~]# mysql

在这里插入图片描述

  • 下载并导入test.sql库。
lftp 172.25.11.250:/pub/redis> get test.sql 
[root@server3 ~]# mysql < test.sql 
  • test.sql文件的内容。
[root@server3 ~]# cat test.sql 
use test;
CREATE TABLE `test` (`id` int(7) NOT NULL AUTO_INCREMENT, `name` char(8) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `test` VALUES (1,'test1'),(2,'test2'),(3,'test3'),(4,'test4'),(5,'test5'),(6,'test6'),(7,'test7'),(8,'test8'),(9,'test9');

#DELIMITER $$
#CREATE TRIGGER datatoredis AFTER UPDATE ON test FOR EACH ROW BEGIN
#    SET @RECV=gman_do_background('syncToRedis', json_object(NEW.id as `id`, NEW.name as `name`)); 
#  END$$
#DELIMITER ;
  • 导入成功后我们查询一下导入的数据。
MariaDB [(none)]> use test;
MariaDB [test]> select * from test;

在这里插入图片描述

  • 给用户和数据库授权。
MariaDB [test]> grant all on test.* to redis@'%' identified by 'westos';

测试

  • 在浏览器中访问我们下载的测试页。
172.25.11.1/test.php
  • 第一次是从mysql中读取到的数据。(因为redis中还没有缓存)
    在这里插入图片描述
  • 第二次是在redis数据库中。(缓存)
    在这里插入图片描述
  • 在redis数据库端查询数据。
    在这里插入图片描述
  • 但是,主从复制存在数据不一致的问题,即当用户更新mysql数据库中的数据时,reids端并不能立即同步修改后的数据库(除非清除缓存或数据过期),用户此时查询到的依然是之前的缓存。
#更新数据
MariaDB [test]> update test set name='westos' where id=1;
MariaDB [test]> select * from test;

在这里插入图片描述

  • 浏览器中访问的结果依然没有改变。
    在这里插入图片描述
  • 但在如果在redis数据库清除更新的数据之后,用户再访问,数据就会刷新。
  • 第一次,从mysql中读。
    在这里插入图片描述
  • 第二次,从redis中读,可以看到数据已经同步,读的是redis的缓存。
    在这里插入图片描述
  • 这里让两者同步的办法是清除redis中的缓存。
    在这里插入图片描述
    总结:
    1.这种方式存在明显的问题:在mysql更新数据数据无法同步到redis上,虽然可以直接在redis中更新,但是在企业中更新的数据杂且多,而数据库的数据是比较稳定的,如果只在redis上更新,如果redis出现问题,则更新的数据会丢失,这是不可取的。
    2.我们已经实现了 redis 作为 mysql 的缓存服务器,但是如果更新了 mysql,redis
    中仍然会有对应的 KEY,数据就不会更新,此时就会出现 mysql 和 redis 数据不一致的情
    况。所以接下来就要通过 mysql 触发器将改变的数据同步到 redis 中。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值