博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Redis——基于lamp架构做mysql的缓存服务器和配置gearman实现数据同步
阅读量:2344 次
发布时间:2019-05-10

本文共 9025 字,大约阅读时间需要 30 分钟。

一.前言

对一个关系型数据库进行调优以获得高查询性能可能会比较困难。如果对数据模型优化和对查询调优不起作用,DBA就可以使用缓存系统,比如Redis,它是一个可以提供内存和永久数据存储的键值数据存储系统。

由于Redis能够将数据快速读写至数据存储系统,比起关系型数据库它更具性能优势。但是键值数据存储比较简单,它们没有类似SQL那样的查询语言或是结构化数据模型。取而代之的是,它们包含用键作为标识符并与值相关联的一个简单字典或是哈希模型。DBA可以通过这些键来存储和检索值。

键值存储简单而又快速,这使得它们可以很好地匹配关系型数据库丰富的数据模型和查询功能。有时使用键值和关系型数据库的组合是更好的选择。另外,还有大量支持商业化的键值数据库,包括Redis,Riak和Areospike。

要运行Redis缓存来优化常用查询的性能,首先要对你想要缓存的查询结果进行识别。将注意力集中在那些最频繁使用和耗时的查询上,然后从你要缓存的查询中识别数据。简言之,就是缓存一个查询返回的所有字段值。

流程图如下所示:

client——>app——>redis——>mysql——>redis——>client

二.基于lamp架构mysql的缓存服务器

实验环境:

主机 服务
server1 httpd,php等
server2 redis服务器
server3 mysql数据库

前提:

因为这之前是做过redis 高可用的。所以要将之前打开的redis-server的进程杀掉或者关闭

在这里插入图片描述

server2关闭主要是为了让它从slave变为master
在这里插入图片描述
server3也关闭
在这里插入图片描述

实验步骤如下所示:

第一步:配置server1和server2

  • server1:

server1上面安装相应的软件

在这里插入图片描述

编辑server1httpd的发布文件(我这里有已经写好的,上传到httpd的默认发布目录下,改改就好了)

在这里插入图片描述

test.php文件的内容如下

在这里插入图片描述在这里插入图片描述

connect('127.0.0.1',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('127.0.0.1','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 "
"; for ($key = 1; $key < 10; $key++) { echo "number is $key"; echo "
"; echo "name is $data[$key]"; echo "
"; }?>

修改test.php文件

在这里插入图片描述

在这里插入图片描述

开启httpd服务

[root@server1 ~]# systemctl start httpd

在这里插入图片描述

  • server2

因为server2之前是slave,所以我们需要将以下内容恢复,让其恢复为master

[root@server2 ~]# vim /etc/redis/6379.conf   bind 0.0.0.0           #第70行的监听所有端口的内容不用动#replicaof 172.25.27.1 6379#min-replicas-to-write 1    #注释458和459行#min-replicas-max-lag 10[root@server2 ~]# /etc/init.d/redis_6379 start[root@server2 ~]# redis-cli  info

在这里插入图片描述

在这里插入图片描述

第二步:配置server3

[root@server3 ~]# yum install mariadb-server -y[root@server3 ~]# systemctl start mariadb [root@server3 ~]# mysql   #查看是否有test这个库,没有的话,创建

在这里插入图片描述

在这里插入图片描述

编写test数据库的测试文件(test.sql),并将其导入到test数据库中

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 ;

在这里插入图片描述

[root@server3 ~]# mysql  < test.sql[root@server3 ~]# mysql     #进去查看是否导入成功

在这里插入图片描述

在这里插入图片描述

添加授权用户:

[root@server3 ~]# mysql MariaDB [(none)]> grant all on test.* to 'redis'@'%' identified by 'westos';

在这里插入图片描述

第三步:server1添加redis模块

  • server1

此时的php只有mysql的模块,没有redis的模块,这样就无法将其联系起来 ,如下图所示:

在这里插入图片描述

此时去浏览器访问,是空白的

在这里插入图片描述

所以我们需要编译php的redis模块,首先将所需的安装包发送给server1

在这里插入图片描述

解压:

在这里插入图片描述

安装devel库

在这里插入图片描述

预编译:我们可以用./configure --help查看帮助

在这里插入图片描述

我们进行以下操作来将redis模板加入进去:

./configure --enable-redismakemake installcd /usr/lib64/php/modulesvim /etc/php.ini   #修改时区

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

cp mysql.ini  redis.inivim redis.iniextension=redis.so    #加载 redis 模块(这个也可以在/etc/php.ini里面添加)systemctl restart httpdphp -m | grep redis       #此时有了redis模板

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

第四步:测试

在浏览器输入172.25.27.1/test.php

在这里插入图片描述

也可以使用redis进行测试(要客户端先去访问,redis拿到数据之后在测试):

在这里插入图片描述

结论:看到了test数据库中的内容,宣告实验成功

但是此时有一个问题,我们修改了数据库里面的内容,redis已经缓存,所以客户端取到的还是原本旧的内容,redis并没有同步更新,只有将redis的缓存删掉,让其重新去数据库取数据,客户端才能得到更新的数据。

如下图所示:

修改数据库内容

在这里插入图片描述

在这里插入图片描述

此时客户端去访问,还是原本的数据

在这里插入图片描述

因为redis的数据没更新:

在这里插入图片描述

将redis缓存删除,在让客户端访问,此时数据就更新了

在这里插入图片描述

此时是redis去取数据:
在这里插入图片描述
在这里插入图片描述
因为此时redis重新去取了数据:
在这里插入图片描述

总结:到这里,我们已经实现了 redis 作为 mysql 的缓存服务器,但是如果更新了 mysql,redis中仍然会有对应的 KEY,数据就不会更新,此时就会出现 mysql 和 redis 数据不一致的情况。所以接下来就要通过 mysql 触发器将改变的数据同步到 redis 中。

因为我们总不能每次更新数据就手动删除redis里面的数据,那也忒麻烦了,为了解决这个问题,我们配置gearman实现数据同步(也就是mysql的触发器)

三.配置gearman实现数据同步

前言:

Gearman+PHP+MySQL UDF的组合异步实现MySQL到Redis的数据复制。

用redis作为Mysql数据库的缓存,在查找的时候,首先查找redis缓存,如果找到则返回结果;如果在redis中没有找到,那么查找Mysql数据库,找到的花则返回结果并且更新redis;如果没有找到则返回空。对于写入的情况,直接写入mysql数据库,mysql数据库通过触发器及UDF机制自动把变更的内容更新到redis中。采用MySQL作为数据存储引擎,Redis则作为Cache。

mysql读写数据都需要从磁盘读取。磁盘的容量,带宽的大小就影响了网站的访问速度,读取的方式,也就是sql语句,次数和效率也会影响读取效率。

redis和mc都是缓存,并且都是驻留在内存中运行的,这大大提升了高数据量web访问的访问速度。然而mc只是提供了简单的数据结构,比如

string存储;redis却提供了大量的数据结构,比如string、list、set、hashset、sorted set这些,这使得用户方便了好多,毕竟封装了一层实用的功能,同时实现了同样的效果,当然用redis而慢慢舍弃mc。

这个实验的实现需要使用新的工具gearmand

Gearman是一套用来把程式需求委派给机器,提供通用的程序框架来将任务分发在机器运算。它同时具备并行工作的能力、负载均衡处理的能力,以及在不同程序语言之间沟通的能力。

运行过程:

一个Gearman请求的处理过程涉及三个角色:Client -> Job -> Worker。Client:请求的发起者,可以是 C,PHP,Perl,MySQL UDF 等等。Job:请求的调度者,用来负责协调把 Client 发出的请求转发给合适的 Worker。Worker:请求的处理者,可以是 C,PHP,Perl 等等。因为 Client,Worker 并不限制用一样的语言,所以有利于多语言多系统之间的集成。甚至我们通过增加更多的 Worker,可以很方便的实现应用程序的分布式负载均衡架构。

大致流程:

下面要编写的 mysql 触发器,就相当于 Gearman 的客户端。修改表,插入表就相当于直接下发任务。然后通过 lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式,然后再通过 gearman-mysql-udf

插件将任务加入到 Gearman 的任务队列中,最后通过redis_worker.php,也就是 Gearman 的 worker 端来完成 redis 数据库的更新。

实际的工作流程:

mysql(client)——>gearmand:4730(job server)——>worker(php/python/java)

实验过程如下所示:

第一步:server3安装插件

将test.mysql文件不用的部分注释,将触发器部分的注释取消(这一步也可以放到后面做):

在这里插入图片描述

此时导入数据库是失败的,因为缺少模块,如下图:

在这里插入图片描述

我们需要编译数据库添加插件,使用lib_mysqludf_json的原因是因为Gearman只接受字符串作为入口参数,可以通过lib_mysqludf_jsonUDF 库函数将关系数据映射为 JSON 格式(MySQL中的数据编码为JSON字符串,起到统一标准的作用)。编译数据库需要mariadb-devel和gcc。

[root@server3 ~]# yum install unzip -y[root@server3 ~]# unzip lib_mysqludf_json-master.zip [root@server3 ~]# cd lib_mysqludf_json-master[root@server3 ~]# yum install gcc -y[root@server3 ~]# yum install mariadb-devel -y    [root@server3 lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

查看 :

[root@server3 lib_mysqludf_json-master]# mysql -uroot -proot MariaDB [(none)]> show global variables like 'plugin_dir';

在这里插入图片描述

拷贝 lib_mysqludf_json.so 模块到mysql的插件目录

[root@server3 lib_mysqludf_json-master]# cd /usr/lib64/mysql/plugin/ [root@server  plugin]# cp  ~/lib_mysqludf_json-master/lib_mysqludf_json.so  .

在这里插入图片描述

数据库里注册 UDF 函数并查看

[root@server3 lib_mysqludf_json-master]# mysql -uroot -prootMariaDB [(none)]> CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so;MariaDB [(none)]> select * from mysql.func;

在这里插入图片描述

第二步:安装与配置 gearman

安装gearmand-1.1.12-18并且其对应的依赖包:

  • libgearman-1.1.12-18.el7.x86_64.rpm
  • libgearman-devel-1.1.12-18.el7.x86_64.rpm
  • ibevent-devel-2.0.21-4.el7.x86_64.rpm

将这下载好的这几个包上传给虚拟机:

在这里插入图片描述

[root@server3 ~]# yum install  gearmand-*  libevent-devel-2.0.21-4.el7.x86_64.rpm libgearman-*   -y   [root@server3 ~]#systemctl start gearmand[root@server3 ~]#netstat -antlp |grep gearmand

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

编译 gearman-mysql-udf

这个插件是用来管理调用 Gearman 的分布式的队列。

下载gearman-mysql-udf对应的软件包:

  • gearman-mysql-udf-0.6.tar.gz

步骤如下:

[root@server3 ~]# tar zxf gearman-mysql-udf-0.6.tar.gz [root@server3 ~]# cd gearman-mysql-udf-0.6[root@server3 gearman-mysql-udf-0.6]# ls[root@server3 gearman-mysql-udf-0.6]# ./configure --libdir=/usr/lib64/mysql/plugin/ --with-mysql     #预编译

[root@server3 gearman-mysql-udf-0.6]# make && make install #编译与安装

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

注册 UDF 函数并查看

[root@server3 ~]# mysql -uroot -proot#注册 UDF 函数:MariaDB [(none)]> CREATE FUNCTION gman_do_background RETURNS STRING SONAME 'libgearman_mysql_udf.so';MariaDB [(none)]> CREATE FUNCTION gman_servers_set RETURNS STRING SONAME 'libgearman_mysql_udf.so';#查看函数:MariaDB [(none)]> select * from mysql.func;

在这里插入图片描述

指定 gearman 的服务信息(这一步可以在上一步数据库里一起做)

在这里插入图片描述

root@server3 ~]# mysqlMariaDB [(none)]> SELECT gman_servers_set('172.25.27.1:4730');

在这里插入图片描述编写 mysql 触发器test.mysql(我们前面已经做过),将其导入数据库:

[root@server3 ~]# mysql  < test.sql  [root@server3 ~]# mysqlMariaDB [(none)]> SHOW TRIGGERS FROM test;

在这里插入图片描述

在这里插入图片描述

第三步:配置server1

安装 gearman(与server3过程一样,这里就粗略展示)

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

安装php的gearman 扩展

此时php没有gearman模块

在这里插入图片描述
进行以下操作添加:

tar zxf gearman-1.1.2.tgzcd gearman-1.1.2phpize./configure make && make install

在这里插入图片描述

在这里插入图片描述

编译完成界面:

在这里插入图片描述

cd /usr/lib64/php/modules    #查看是否有gearman模块cd /etc/php.dcp redis.ini  gearman.inivim gearman.ini在里面写入:extension=gearman.sosystemctl restart httpdphp -m | grep gearman

在这里插入图片描述

编写 gearman 的 worker 端——worker.php文件

worker.php文件内容如下:

addServer();$worker->addFunction('syncToRedis', 'syncToRedis'); $redis = new Redis();$redis->connect('172.25.27.2', 6379); while($worker->work());function syncToRedis($job){ global $redis; $workString = $job->workload(); $work = json_decode($workString); if(!isset($work->id)){ return false; } $redis->set($work->id, $work->name);}?>

在这里插入图片描述

在这里插入图片描述

将修改好的worker.php放到/usr/local下,并后台运行

mv worker.php  /usr/localnohup php /usr/local/worker.php &

在这里插入图片描述

查看服务进程:
在这里插入图片描述

查看服务端口:

在这里插入图片描述

第四步:测试

更新数据库里面的数据

[root@server3 ~]# mysql -uroot -proot MariaDB [(none)]> use test;MariaDB [test]> update test set name='redhat' where id=2;

在这里插入图片描述

在这里插入图片描述

MariaDB [test]> update test set name='hanghang' where id=3;

在这里插入图片描述

在这里插入图片描述

再次更新:

在这里插入图片描述在这里插入图片描述

大量更新:

在这里插入图片描述在这里插入图片描述

redis里面的数据也改变了

在这里插入图片描述

转载地址:http://lljvb.baihongyu.com/

你可能感兴趣的文章
浅入深出 MySQL 中事务的实现
查看>>
UML总结(对九种图的认识和如何使用Rational Rose 画图)
查看>>
Java中使用HttpRequest获取用户真实IP地址端口
查看>>
easyUI下拉列表点击事件的使用
查看>>
js遍历map
查看>>
单例模式
查看>>
JDBC连接数据库核心代码
查看>>
java生成随机汉字
查看>>
Java反射的基本应用
查看>>
HTML5常用标签
查看>>
where 1=1影响效率以及having和where的区别
查看>>
资源链接
查看>>
注册中心Eureka页面添加用户认证
查看>>
spring源码
查看>>
上传jar包到nexus私服
查看>>
lambda和抽象类
查看>>
idea自定义文档注释模板
查看>>
Enterprise Architect 生成项目类图
查看>>
idea导出配置
查看>>
JVM学习资料收集
查看>>