让 ZeroMQ 为 MySQL 提供远程分布式任务处理

昨天写了一篇博文

身份证校验,检查身份证号码输入是否正确
http://netkiller-github-com.iteye.com/blog/1997402

很多人担心性能问题,我后来想用C写一个扩展,还会有人说影响性能,一不做二不休,干脆mq到远程,通过负载均衡解决。

这里只是提供了一个 mysql 与 ZeroMQ 通信的插件,我并没有将身份证校验程序写出来。不过MQ的服务端可以使用很多语言实现,c,java, php,python,perl,ruby ..... 你自己选择一个熟悉的语言写吧。

下载地址 : https://github.com/netkiller/mysql-zmq-plugin


数据库进程间通信解决方案之MQ
http://netkiller.github.io/journal/mysql.plugin.mq.html
Mr. Neo Chen (netkiller), 陈景峰(BG7NYT)

中国广东省深圳市龙华新区民治街道溪山美地
518131
+86 13113668890
+86 755 29812080
<netkiller@msn.com>
$Id: mysql-plugin.xml 587 2013-12-16 14:00:00Z netkiller $
版权 © 2011, 2012, 2013, 2014 http://netkiller.github.io
$Date: 2013-12-16 13:34:20 +0800 (Thu, 16 May 2013) $
摘要
你是否想过当数据库中的数据发生变化的时候出发某种操作?但因数据无法与其他进程通信(传递信号)让你放弃,而改用每隔一段时间查询一次数据变化的方法?下面的插件可以解决你的问题。
原文出处:http://netkiller.github.io/journal/mysql.plugin.fifo.html
我的系列文档

Netkiller Architect 手札 Netkiller Developer 手札 Netkiller PHP 手札 Netkiller Python 手札 Netkiller Testing 手札 Netkiller Cryptography 手札
Netkiller Linux 手札 Netkiller CentOS 手札 Netkiller FreeBSD 手札 Netkiller Security 手札 Netkiller Version 手札 Netkiller Web 手札
Netkiller Monitoring 手札 Netkiller Storage 手札 Netkiller Mail 手札 Netkiller Shell 手札 Netkiller Network 手札 Netkiller Database 手札
Netkiller PostgreSQL 手札 Netkiller MySQL 手札 Netkiller NoSQL 手札 Netkiller LDAP 手札 Netkiller Cisco IOS 手札 Netkiller H3C 手札
Netkiller Multimedia 手札 Netkiller Docbook 手札 Netkiller 开源软件 手札

目录
1. 背景
2. 应用场景
3. Mysql plugin
4. plugin 的开发与使用
5. 插件如何使用
1. 背景
之前我发表过一篇文章 http://netkiller.github.io/journal/mysql.plugin.fifo.html
该文章中提出了通过fifo 管道,实现数据库与其他进程的通信。属于 IPC 机制(同一个OS/服务器内),后我有采用ZeroMQ重新实现了一个 RPC 机制的方案,同时兼容IPC(跨越OS/服务器)
各种缩写的全称 IPC(IPC :Inter-Process Communication 进程间通信),ITC(ITC : Inter Thread Communication 线程间通信)与RPC(RPC: Remote Procedure Calls远程过程调用)。
支持协议
inproc://my_publisher
tcp://server001:5555
ipc:///tmp/feeds/0

2. 应用场景
如果你像处理数据,由于各种原因你不能在程序中实现,你可以使用这个插件。当数据库中的数据发生变化的时候出发某种操作,你可以使用这个插件。
有时候你的项目可能是外包的,项目结束后外包方不会在管你,你有无法改动现有代码,或者根本不敢改。你可以使用这个插件
采用MQ技术对数据库无任何压力,与采用程序处理并无不同,省却了写代码
处理方法,可以采用同步或者异步方式
例 1. 发送短信
发送短信、邮件,只需要查询出相应手机号码,发送到MQ的服务端,服务端接收到手机号码后,放入队列中,多线程程序从队列中领取任务,发送短信。
select zmq_client('tcp://localhost:5555',mobile) from demo where subscribed='Y' ...;

传递多个参数,可以使用符号分隔
select zmq_client('tcp://localhost:5555',concat(name,',',mobile,', news')) from demo;
select zmq_client('tcp://localhost:5555',concat(name,'|',mobile,'|news')) from demo;

json格式
select zmq_client('tcp://localhost:5555',concat('{name:',name,', tel:',mobile,', template:news}')) from demo;

建议采用异步方式,MQ端接收到任务立即反馈 “成功”信息,因为我们不太关心是否能发送成功,本身就是盲目性的发送,手机号码是否可用我们无从得知,短信或者邮件的发送到达率不是100%,所以当进入队列后,让程序自行处理,将成功或者失败信息记录到日志中即可。

例 2. 处理图片
首先查询出需要处理图片,然后将路径与分辨率传递给MQ另一端的处理程序
select zmq_client('tcp://localhost:5555',concat(image,',800x600}')) from demo;

建议采用异步方式,MQ端接收到任务立即反馈 “成功”信息

例 3. 身份证号码校验
select zmq_client('tcp://localhost:5555',id_number) from demo;

可以采用同步方案,因为MQ款处理几乎不会延迟,直接将处理结构反馈

例 4. 静态化案例
情景模拟,你的项目是你个电商项目,采用外包模式开发,项目已经开发完成。外包放不再负责维护,你现在要做静态化。增加该功能,你要检查多处与商品表相关的造作。
于其改代码,不如程序从外部处理,这样更保险。我们只要写一个程序将动态 URL 下载保存成静态即可,当数据发生变化的时候重新下载覆盖即可
CREATE DEFINER=`dba`@`%` TRIGGER `demo_after_insert` AFTER INSERT ON `demo` FOR EACH ROW BEGIN
select zmq_client('tcp://localhost:5555', NEW.id);
END
CREATE DEFINER=`dba`@`%` TRIGGER `demo_after_update` AFTER UPDATE ON `demo` FOR EACH ROW BEGIN
select zmq_client('tcp://localhost:5555', NEW.id);
END
CREATE DEFINER=`dba`@`%` TRIGGER `demo_after_delete` AFTER DELETE ON `demo` FOR EACH ROW BEGIN
select zmq_client('tcp://localhost:5555', NEW.id);
END

MQ 另一端的服务会下载http://www.example.com/goods.php?cid=111&id=100, 然后生成html页面,http://www.example.com/111/100.html
插入会新建页面,更新会覆盖页面,删除会删除页面
这样无论商品的价格,属性改变,静态化程序都会做出相应的处理。

例 5. 数据同步案例
我们有多个数据库,A 库里面的数据发生变化后,要同步书库到B库,或者处理结果,或者数据转换后写入其他数据库中
方法也是采用触发器或者EVENT处理
3. Mysql plugin
我开发了几个 UDF, 共4个 function
UDF
zmq_client(sockt,message)
sockt .成功返回true,失败返回flase.
有了上面的function后你就可以在begin,commit,rollback 直接穿插使用,实现在事物处理期间做你爱做的事。也可以用在触发器与EVENT定时任务中。
4. plugin 的开发与使用
编译UDF你需要安装下面的软件包
sudo apt-get install pkg-config
sudo apt-get install libmysqlclient-dev

sudo apt-get install gcc gcc-c++ make cmake

https://github.com/netkiller/mysql-zmq-plugin
编译udf,最后将so文件复制到 /usr/lib/mysql/plugin/

git clone https://github.com/netkiller/mysql-zmq-plugin.git
cd mysql-zmq-plugin

cmake .
make && make install


装载
create function zmq_client returns string soname 'libzeromq.so';
create function zmq_publish returns string soname 'libzeromq.so';

卸载
drop function zmq_client;
drop function zmq_publish;

确认安装成功

mysql> SELECT * FROM `mysql`.`func` where name like 'zmq%';
+-------------+-----+--------------+----------+
| name | ret | dl | type |
+-------------+-----+--------------+----------+
| zmq_client | 0 | libzeromq.so | function |
| zmq_publish | 0 | libzeromq.so | function |
+-------------+-----+--------------+----------+
2 rows in set (0.00 sec)


5. 插件如何使用
插件有很多种用法,这里仅仅一个例
编译zeromq server 测试程序
cd test
cmake .
make

启动服务进程
./server

发送Hello world!

mysql> select zmq_client('tcp://localhost:5555','Hello world!');
+---------------------------------------------------+
| zmq_client('tcp://localhost:5555','Hello world!') |
+---------------------------------------------------+
| Hello world! OK |
+---------------------------------------------------+
1 row in set (0.01 sec)


查看服务器端是否接收到信息。
$ ./server
Received: Hello world!

我们再将上面的例子使用触发器进一步优化

mysql> select zmq_client('tcp://localhost:5555',mobile) from demo;
+-------------------------------------------+
| zmq_client('tcp://localhost:5555',mobile) |
+-------------------------------------------+
| 13113668891 OK |
| 13113668892 OK |
| 13113668893 OK |
| 13322993040 OK |
| 13588997745 OK |
+-------------------------------------------+
5 rows in set (0.03 sec)


服务器端已经接收到数据库发过来的信息
$ ./server
Received: Hello world!
Received: 13113668891
Received: 13113668892
Received: 13113668893
Received: 13322993040
Received: 13588997745

我们可以拼装json或者序列化数据,发送给远端

mysql> select zmq_client('tcp://localhost:5555',concat('{name:',name,', tel:',mobile,'}')) from demo;
+------------------------------------------------------------------------------+
| zmq_client('tcp://localhost:5555',concat('{name:',name,', tel:',mobile,'}')) |
+------------------------------------------------------------------------------+
| {name:neo, tel:13113668891} OK |
| {name:jam, tel:13113668892} OK |
| {name:leo, tel:13113668893} OK |
| {name:jerry, tel:13322993040} OK |
| {name:tom, tel:13588997745} OK |
+------------------------------------------------------------------------------+
5 rows in set (0.03 sec)


返回数据取决于你服务端怎么编写处理程序,你可以返回true/false等等。
触发器以及事务处理,这里就不演示了
3
顶2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值