gearman实现redis与mysql的数据同步

udf:用户自定义函数缩写

任务(job)提交给gearman server,任务的提交者可以是mysql,因为他有触发器,可以进行 update,
用户自定义函数有两个,通过调用函数来触发 gearman 发给server1的4730端口(server-set的设置)
使用json 格式的原因是mysql与redis数据结构不同,而 json数据支持跨平台 ,所以用json格式

把任务发给gearman server
server交给(多个)worker处理, worker是一段程序 可以是java python php
在worker中,php-gearman模块作用是将数据传过来,php-redis模块的作用是存储数据

  • 前面的实验中,如果客户端的请求是修改数据,即 mysql被update(数据被更新)的话, redis和mysql两者没同步就会导致数据不一致的问题,所以为了解决这两者数据不同步的问题,我们这里利用Gearman这个工具,让mysql中数据有更新时,主动触发redis进行同步。
  • redis只有在他的数据过期或没有缓存的时侯才会去找mysql拿数据,所以我们希望在mysql有update操作后,会自动的触发redisserver。
    数据流向:job(mysql trigger) mysql-gearman ----> gearman server ----> worker(php-gearman、php-redis、 set)

Gearman

简介
  • Gearman是一个支持分布式的任务分发框架,是一套用来把程式需求委派给机器,提供通用的程序框架来将任务分发在机器运算。它同时具备并行工作的能力、负载均衡处理的能力,以及在不同程序语言之间沟通的能力。
  • Gearman提供了一个通用的应用程序框架,用于将工作转移到更适合于工作的其他机器或流程。它允许你并行工作,负载平衡处理,并在语言间调用函数。它可用于从高可用性网站到传输数据库复制事件的各种应用程序。换句话说,它是分布式处理交流的神经系统。
运行过程

一个Gearman请求的处理过程涉及三个角色:Client -> Job -> Worker

  • Gearman Job Server: Gearman 核心程序,需要编译安装并以守护进程形式运行在后台。
  • Gearman Client:可以理解为任务的请求者。
  • Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式
    运行,Gearman Worker 接收到 Gearman Client 传递的任务内容后,会按顺序处理。
    因为 Client,Worker 并不限制用一样的语言,所以有利于多语言多系统之间的集成。
    甚至我们通过增加更多的 Worker,可以很方便的实现应用程序的分布式负载均衡架构
    在这里插入图片描述
优点
  • 开源它是免费的!(在这个词的两个意思中)Gearman有一个活跃的开源社区,如果你需要帮助或者想贡献,很容易参与进来。担心授权?Gearman是BSD。
  • 多语言 - 有一些语言的接口,这个列表正在增长。您也可以选择使用一种语言提交工作的客户端编写异构应用程序,并在另一种语言中执行该工作的工作人员。
  • ==灵活 ==- 您不受限于任何特定的设计模式。您可以使用您选择的任何模型快速组合分布式应用程序,这些选项之一是Map / Reduce。
  • 快速 - Gearman有一个简单的协议和接口,用C / C ++编写的优化的,线程化的服务器可以最大限度地减少应用程序开销。
  • 嵌入式 - 由于Gearman速度快,重量轻,适用于各种尺寸的应用。以最小的开销引入现有的应用程序也很容易。
  • 没有单点故障- Gearman不仅可以帮助扩展系统,而且还可以通过容错方式实现。
  • 消息大小没有限制 - Gearman支持最多4gig的单个消息。需要做更大的事情?没问题Gearman可以大块消息。
Gearman如何工作?

在这里插入图片描述

  • 一个Gearman驱动的应用程序由三部分组成:一个客户端,一个工作者和一个作业服务器。客户端负责创建要运行的作业并将其发送到作业服务器。作业服务器将找到可以运行作业并转发作业的合适工作人员。工作人员执行客户端请求的工作,并通过作业服务器向客户端发送响应。Gearman提供您的应用程序调用的客户端和工作者API来与Gearman作业服务器(也称为gearmand)交谈,因此您不需要处理网络或作业的映射。在内部,gearman客户端和工作者API使用TCP套接字与作业服务器进行通信。

实验流程

  • 此实验基于上一篇博客的实验环境,需要提前在三个节点搭建好相应的服务。
  • 我们此实验要编写的 mysql 触发器,就相当于 Gearman 的客户端。修改表,插入表就相当于直接下发任务。然后通过 lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式,然后在通过 gearman-mysql-udf 插件将任务加入到 Gearman 的任务队列中,最后通过redis_worker.php,也就是 Gearman 的 worker 端来完成 redis 数据库的更新
server1(lnmp)
  • 下载gearman的软件包进行安装。
lftp 172.25.11.250:/pub/redis/rhel7> get gearmand-1.1.12-18.el7.x86_64.rpm 
lftp 172.25.11.250:/pub/redis/rhel7> mget libgearman-*
lftp 172.25.11.250:/pub/redis/rhel7> mget libevent-devel-2.0.21-4.el7.x86_64.rpm 
[root@server1 ~]# yum install gearmand-1.1.12-18.el7.x86_64.rpm  libevent-devel-2.0.21-4.el7.x86_64.rpm  libgearman-* -y

在这里插入图片描述

  • 开启gearmand服务,查看他所开启的端口为4730。
[root@server1 ~]# systemctl start gearmand
[root@server1 ~]# netstat -antlp

在这里插入图片描述

  • 编写gearman的worker端。修改worker.php文件,将redis的ip改为我们redis服务器的ip。
[root@server1 ~]# vim worker.php
<?php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction('syncToRedis', 'syncToRedis');

$redis = new Redis();
$redis->connect('172.25.11.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);    ##这条语句就是将 id 作 KEY 和name 作 VALUE 分开存储,需要和前面写的 php 测试代码的存取一致。
}
?>
[root@server1 ~]# php -m | grep gearman

在这里插入图片描述

  • 下载php的gearman扩展,解压,并进行phpize。
lftp 172.25.11.250:/pub/redis> get gearman-1.1.2.tgz 
[root@server1 ~]# tar zxf gearman-1.1.2.tgz
[root@server1 /]# cd ~/gearman-1.1.2
[root@server1 gearman-1.1.2]# phpize

在这里插入图片描述

  • 编译并安装,加上我们所需要的编译参数。
[root@server1 gearman-1.1.2]# ./configure  --help
[root@server1 gearman-1.1.2]# ./configure --with-gearman
[root@server1 gearman-1.1.2]# make && make install
  • 按照redis.ini的模版创建gearman.ini文件,编辑为我们gearman的模块,编辑完后重启apache,并过滤查看php中有没有gearman的模块。
[root@server1 gearman-1.1.2]# cd /usr/lib64/php/modules/
[root@server1 modules]# cd /etc/php.d/
[root@server1 php.d]# cp redis.ini gearman.ini
[root@server1 php.d]# vim gearman.ini 
[root@server1 php.d]# cat gearman.ini 
extension=gearman.so
[root@server1 php.d]# systemctl restart httpd
[root@server1 php.d]# php -m | grep gearman
gearman

在这里插入图片描述

  • 将修改后的php文件移至/usr/local下,用php以静默的模式运行。
[root@server1 ~]# mv worker.php /usr/local/
[root@server1 ~]# nohup php /usr/local/worker.php &    #后台运行worker
[1] 17361
[root@server1 ~]# ps ax

在这里插入图片描述
注意:我们这里把gearman server和处理job的gearman worker放在同一台主机了,实际生产环境中是分离的。

server3(mysql)
  • 修改之前的test.sql文件,此时将数据库直接导入是会报错的。
[root@server3 ~]# vim test.sql

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

  • 安装lib_mysqludf_json。lib_mysqludf_json UDF库函数将关系数据映射成json格式,通常,数据库中的数据映射成json格式是通过程序来转换的。(因为mysql与redis的数据类型不同所以必须转换为json标准数据类型。)
lftp 172.25.11.250:/pub/redis> get lib_mysqludf_json-master.zip

在这里插入图片描述

[root@server3 ~]# yum install unzip -y
[root@server3 lib_mysqludf_json-master]# yum install gcc -y
[root@server3 lib_mysqludf_json-master]# yum install mysql-devel -y   #安装所需依赖

在这里插入图片描述

[root@server3 lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c

在这里插入图片描述

  • 此时,查看mysql的模块目录。
[root@server3 plugin]# pwd
/usr/lib64/mysql/plugin
[root@server3 plugin]# ls

在这里插入图片描述

  • 在数据库中查询mysql的模块目录。
MariaDB [(none)]> show global variables like 'plugin_dir';

在这里插入图片描述

  • 拷贝lib_mysqludf_json.so模块到mysql模块目录下。
[root@server3 plugin]# cp ~/lib_mysqludf_json-master/lib_mysqludf_json.so .
[root@server3 plugin]# pwd
/usr/lib64/mysql/plugin
[root@server3 plugin]# ll lib_mysqludf_json.so 

在这里插入图片描述

  • 注册UDF函数,并查看函数。
MariaDB [(none)]> CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so';
MariaDB [(none)]> select * from mysql.func;

在这里插入图片描述

  • 安装gearman-mysql-udf,这个插件用来管理调用gearman的分布式的队列。
lftp 172.25.11.250:/pub/redis> get 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 --with-mysql --libdir=/usr/lib64/mysql/plugin

在这里插入图片描述

  • 发现编译失败,因为缺少所需要的依赖,我们安装依赖后继续编译。
[root@server1 ~]# scp gearmand-1.1.12-18.el7.x86_64.rpm libgearman-1.1.12-18.el7.x86_64.rpm  libgearman-devel-1.1.12-18.el7.x86_64.rpm libevent-devel-2.0.21-4.el7.x86_64.rpm  server3:
[root@server3 ~]# yum install * -y
[root@server3 ~]# cd -
/root/gearman-mysql-udf-0.6
[root@server3 gearman-mysql-udf-0.6]# ./configure --with-mysql --libdir=/usr/lib64/mysql/plugin
[root@server3 gearman-mysql-udf-0.6]# make && make install

在这里插入图片描述

  • 此时模块目录下出现了我们安装的gearman_mysql_udf的模块。
[root@server3 gearman-mysql-udf-0.6]# cd /usr/lib64/mysql/plugin
[root@server3 plugin]# ls

在这里插入图片描述

  • 注册并查看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服务的信息,这里gearman服务器为server1,端口为4730。
MariaDB [(none)]> SELECT gman_servers_set('172.25.11.1:4730');

在这里插入图片描述

  • 再次导入数据库。(这里是根据实际情况编写的mysql触发器)
[root@server3 ~]# mysql < test.sql
MariaDB [(none)]> SHOW TRIGGERS FROM test;    #查看触发器

在这里插入图片描述

测试

server3
  • 测试,更新mysql中的数据。
MariaDB [(none)]> use test;
MariaDB [test]> update test set name='zhangyiwen' where id=1;

在这里插入图片描述

server2
  • 查看redis,发现数据已同步。
[root@server2 init.d]# redis-cli get 1

在这里插入图片描述

  • 刷新测试页,测试数据同步。
    在这里插入图片描述
  • 继续修改mysql中的数据测试。
MariaDB [test]> update test set name='westos' where id=2;

在这里插入图片描述

总结:如上,我们实现了当mysql中数据有修改时,mysql主动的去触发redis服务器,进行数据的同步。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值