在上一个实验中的数据并没有同步,在mysql端更新完数据后还有需要在redis端修改数据才可以同步,这显然是不科学的。所以引入 gearmand + udf 函数来实现数据同步。
MySQL到Redis数据复制方案
- 无论MySQL还是Redis,自身都带有数据同步的机制,像比较常用的MySQL的Master/Slave模式,就是由Slave端分析Master的binlog来实现的,这样的数据复制其实还是一个异步过程,只不过当服务器都在同一内网时,异步的延迟几乎可以忽略。
- 那么理论上我们也可以用同样方式,分析MySQL的binlog文件并将数据插入Redis。但是这需要对binlog文件以及MySQL有非常深入的理解,同时由于binlog存在多种形式,分析binlog实现同步的工作量是非常大的。
- 因此这里选择了一种开发成本更加低廉的方式,借用已经比较成熟的MySQL UDF函数,将MySQL数据首先放入Gearman中,然后通过一个自己编写的PHP、Gearman、Worker,将数据同步到Redis。比分析binlog的方式增加了不少流程,但是实现成本更低,更容易操作。
Gearman的安装与使用
- Gearman是一个支持分布式的任务分发框架。设计简洁,获得了非常广泛的支持。一个典型的Gearman应用包括以下这些部分:
- Gearman Job Server:Gearman核心程序,需要编译安装并以守护进程形式运行在后台。
- Gearman Client:可以理解为任务的收件员,比如我要在后台执行一个发送邮件的任务,可以在程序中调用一个Gearman Client并传入邮件的信息,然后就可以将执行结果立即展示给用户,而任务本身会慢慢在后台运行。
- Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式运行,Gearman Worker接收到Gearman Client传递的任务内容后,会按顺序处理。
- 以前曾经介绍过类似的后台任务处理项目Resque。两者的设计其实非常接近,简单可以类比为:
- Gearman Job Server:对应Resque的Redis部分
- Gearman Client:对应Resque的Queue操作
- Gearman Worker:对应Resque的Worker和Job
这里之所以选择Gearman而不是Resque是因为Gearman提供了比较好用的MySQL UDF,工作量更小。
实验
继续上一个实验的实验环境
机制: mysql 端更改数据后通过触发器 (插件) 提交, 最后提交给geramand(server端) 提交给worker端口(php-gearman/php-redis) 最后提交给redsi 同步成功
该实验分为:work端和client (mysql)端
- client(mysql)端:
- 安装解压工具:
yum install unzip -y
- 下载udf-json函数并解压:
unzip lib_mysqludf_json-master.zip
- 查看系统中是否安装mariadb-devel:
rpm -qa | grep mariadb-devel
- 如果没有则需要安装:
yum install mariadb-devel -y
- 安装编译软件gcc:
yum install gcc -y
- 进入解压后的 lib_mysqludf_json-master目录进行编译
gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
- 将lib_mysqludf_json.so复制到/usr/lib64/mysql/plugin/下:
cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/
- 此时进入数据库后查看能否获取到:
mysql -p --> show global variables like 'plugin_dir'
- 下载并安装相关软件:
yum install -y libevent-devel-2.0.21-4.el7.x86_64.rpm libgearman-*
- 下载并解压gearman-mysql-udf-0.6.tar.gz:
tar zxf gearman-mysql-udf-0.6.tar.gz
- 进入到解压后的目录 gearman-mysql-udf-0.6:
cd gearman-mysql-udf-0.6
- 编译 :
./configure --libdir=/usr/lib64/mysql/plugin/ --with-mysql
make && make install
- 进入数据库mysql -p
- 注册udf函数:
create function json_object returns string soname 'lib_mysqludf_json.so';
- 创建函数:
create function gman_do_background returns string soname 'libgearman_mysql_udf.so';
create function gman_servers_set returns string soname 'libgearman_mysql_udf.so';
-
查看是否创建成功:
select * from mysql.func;
-
指定gearmand的服务信息:select gman_servers_set(‘172.25.60.1:4370’);
-
修改数据库:
vim test.sql
-
将数据库导入:
mysql -p < test.sql
-
进入数据库后查看触发器:
show triggers from test;
-
work端:
-
安装gearman并开启:
systemctl start gearmand
-
查看端口是否开启
netstat -tnlp (4370)
-
编辑测试页面:
vim worker.php
将redis的ip修改
-
将测试页面放到local下:
cp worker.php /usr/local/
-
后台运行:
nohup php /usr/local/worker.php &> /dev/null &
-
测试:
-
在client端口更新mysql:
mysql -p-->update test set name='westos' where id=2;
-
在网页上刷新后就会看到数据更改
-
在redis端:
redis-cli --get 2
(get查看是否同步)