在上一篇文章当中,实现了简单的读写分离
客户端读的时候去找redis缓存;客户端写的时候去找mysql
但是存在一个问题:当mysql数据库中的数据有所变化的时候,redis缓存并不能实时同步
接下来我将实现一旦mysql有所变化,就触发redis更新所缓存的数据
原理如下:
通过gearman实现同步原理
Gearman 是一个支持分布式的任务分发框架:
Gearman Job Server: Gearman 核心程序,需要编译安装并以守护进程形式运行在后台。
Gearman Client:可以理解为任务的请求者。
Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式运行.
Gearman Worker 接收到 Gearman Client 传递的任务内容后,会按顺序处理。
sever1 前端页面,Gearman Worker
server2 redis服务器
server3 ,mysql数据库,Gearman Client
大致流程:
1)下面要编写的 mysql 触发器,就相当于 Gearman 的客户端。
2)修改表,插入表就相当于直接下发任务。
3)再通过 lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式
4)再通过 gearman-mysql-udf 插件将任务加入到 Gearman 的任务队列中
5)最后通过redis_worker.php,也就是 Gearman 的 worker 端来完成 redis 数据库的更新
实验环境搭建
在server3上
真机上
server3
yum install -y unzip
lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式。通常,数据库中的数据映射为 JSON 格式,是通过程序来转换的。
gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
查看 mysql 的模块目录:
拷贝 lib_mysqludf_json.so 模块:
注册 UDF 函数
开启gearman服务4730端口
server3:安装 gearman-mysql-udf
这个插件是用来管理调用 Gearman 的分布式的队列
./configure --with-mysql --libdir=/usr/lib64/mysql/plugin/ 报错
重新编译
注册 UDF 函数
mysql> CREATE FUNCTION gman_do_background RETURNS STRING SONAME ‘libgearman_mysql_udf.so’;
mysql> CREATE FUNCTION gman_servers_set RETURNS STRING SONAME ‘libgearman_mysql_udf.so’;
查看函数
mysql> select * from mysql.func;
指定 gearman 的服务信息
编写 mysql 触发器
查看触发器
mysql> SHOW TRIGGERS FROM test;
server1上编辑
?php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction(‘syncToRedis’, ‘syncToRedis’);
$redis = new Redis();
r e d i s − > c o n n e c t ( ′ 172.25.4. 2 ′ , 6379 ) ; w h i l e ( redis->connect('172.25.4.2', 6379); while( redis−>connect(′172.25.4.2′,6379);while(worker->work());
function syncToRedis($job)
{
global $redis;
$workString = $job->workload();
w o r k = j s o n d e c o d e ( work = json_decode( work=jsondecode(workString);
if(!isset($work->id)){
return false;
}
r e d i s − > s e t ( redis->set( redis−>set(work->id, $work->name); #这条语句就是将 id 作 KEY 和
name 作 VALUE 分开存储,需要和前面写的 php 测试代码的存取一致。
}
?>
server1php中没有gearman模块,要加入
安装 php 的 gearman 扩展
后台运行 worker
nohup php worker.php &
至此,gearman的client和worker端都已经部署完毕,开始测试:在server3中更新数据库的数据,查看redis数据库的数据能否实现实时同步
在server3 mysql中写
server2读