Gearman + Nodejs + MySQL UDF异步实现 MySQL 到 Redis 的数据同步
1, 环境
CentOS, MySQL, Redis, Nodejs
2, Redis简介
Redis是一个开源的K-V内存数据库,它的key可以是string/set/hash/list/...,因为是基于内存的,所在访问速度相当快。
3, Gearman简介
Gearman是一个开源的Map/Reduce分布式计算框架,具有丰富的client sdk,而且它支持MySQL UDF。
Gearman工作图

Gearman调用流程

Gearman集群
从图中可以看出貌似Gearman的集群功能比较弱,Job Server之间没啥关系好像。

4, MySQL - Redis配合使用方案

首先我们以MySQL数据为主,将insert/update/delete交给MySQL,而select交给redis;
当有数据发生变化时,通过MySQL Trigger实时异步调用Gearman的UDF提交一个job给Job Server,当job执行的时候会去更新redis;从而保证redis与MySQL中的数据是同步的。
4, 软件安装
安装gearman
//安装依赖
$ yum install -y boost-devel gperf libevent-devel libuuid-devel
//下载gearman
$ wget https://launchpad.net/gearmand/1.2/1.1.12/+download/gearmand-1.1.12.tar.gz
$ tar zxvf gearmand-1.1.12.tar.gz
//编译安装,指定mysqlclient的链接路径
$ ./configure LDFLAGS=-L/usr/lib64/mysql/
$ make
$ make install
//启动gearmand服务端
$ /usr/local/sbin/gearmand -l /var/log/gearmand.log -d
//查看是否安装成功,查看gearman版本
$ /usr/local/sbin/gearmand -V
gearman client
gearman client有很多种:PHP, Perl, Python, Ruby, Nodejs, Go, Java, C#...,我们选择GearmaNode(Nodejs库)作为实验用的gearman client
Nodejs的安装省略
GearmaNode的安装及测试
安装GearmaNode
//安装GearmaNode
$ npm install gearmanode
启动Gearman Job Server
//确保gearman的job server已经启动, job server默认监听4730端口
$ netstat -nplt | grep 4730
//如果没有,则启动job server(-d表示启动, -l指定log的位置)
$ /usr/local/sbin/gearmand -l /var/log/gearmand.log -d
worker.js (Gearman Job Worker)
var gearmanode = require('gearmanode');
var worker = gearmanode.worker();
//对job client传递过来的字符串执行reverse倒序操作
worker.addFunction('reverse', function (job) {
job.sendWorkData(job.payload); // mirror input as partial result
job.workComplete(job.payload.toString().split("").reverse().join(""));
});
//启动job worker
$ node worker.js
client.js (Gearman Job Client)
var gearmanode = require('gearmanode');
var client = gearmanode.client();
//提交job
var job = client.submitJob('reverse', 'hello world!');
job.on('workData', function(data) {
console.log('WORK_DATA >>> ' + data);
});
//结果回调函数
job.on('complete', function() {
console.log('RESULT >>> ' + job.response);
client.close();
});
//执行client.js
$ node client.js
//查看控制台打印输出
WORK_DATA >>> hello world!
RESULT >>> !dlrow olleh
可以看到gearman安装成功,运行正常。
5, MySQL UDF + Trigger同步数据到Gearman
安装lib_mysqludf_json
lib_mysqludf_json可以把MySQL表的数据以json数据格式输出
//下载lib_mysqludf_json
$ git clone https://github.com/mysqludf/lib_mysqludf_json.git
$ cd lib_mysqludf_json
//编译
$ gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
//拷贝lib_mysqludf_json.so到MySQL的plugin目录
//可以登陆MySQL,输入命令"show variables like '%plugin%'"查看plugin位置
$ cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/
//演示lib_mysqludf_json功能
$ mysql -uname -hhost -ppwd
//首先注册UDF函数
mysql> CREATE FUNCTION json_object RETURNS STRING
SONAME "lib_mysqludf_json.so";
//json_array|json_members|json_values函数注册方式与json_object一样.
mysql> use test;
mysql> select * from user_list;
+------+----------+
| NAME | PASSWORD |
+------+----------+
| troy | pwd |
+------+----------+
mysql> select json_object(name,password) as user from user_list;
+----------------------------------+
| user |
+----------------------------------+
| {"name":"troy","password":"pwd"} |
+----------------------------------+
安装gearman-mysql-udf
//下载
$ wget https://launchpad.net/gearman-mysql-udf/trunk/0.6/+download/gearman-mysql-udf-0.6.tar.gz
$ tar zxvf gearman-mysql-udf-0.6.tar.gz
$ cd gearman-mysql-udf-0.6
//安装libgearman-devel
$ yum install libgearman-devel
//编译安装
$ ./configure --with-mysql=/usr/bin/mysql_config --libdir=/usr/lib64/mysql/plugin/
$ make && make install
//登录MySQL注册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";
//函数gman_do|gman_do_high|gman_do_low|gman_do_high_background|gman_do_low_background|gman_sum注册方式类似,请参考gearman-mysql-udf-0.6/README
//指定gearman job server地址
mysql> SELECT gman_servers_set('127.0.0.1:4730');
如果出现异常信息:
ERROR 1126 (HY000): Can't open shared library 'libgearman_mysql_udf.so' (errno: 11 libgearman.so.8: cannot open shared object file: No such file or directory)
表示系统找不到 libgearman.so 文件,一般so都在/usr/local/lib目录下,修改配置文件/etc/ld.so.conf,将/usr/local/lib目录加入进去即可:
$ cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
/usr/local/lib
$ /sbin/ldconfig -v | grep gearman*
MySQL Trigger调用Gearman UDF实现同步
DELIMITER $$
CREATE TRIGGER user_list_data_to_redis AFTER UPDATE ON user_list
FOR EACH ROW BEGIN
SET @ret=gman_do_background('syncToRedis', json_object(NEW.name as 'name', NEW.password as 'password'));
END$$
DELIMITER ;
Gearman Nodejs Worker将数据异步复制到redis
redis的安装步骤省略
启动redis-server
$ redis-server
安装redis的Nodejs client:
npm install hiredis redis
redis-worker.js (Gearman Nodejs worker)
var redis = require("redis");
var gearmanode = require('gearmanode');
var worker = gearmanode.worker();
//添加gearman函数syncToRedis
//当MySQL表记录更改时,此函数会被调用
worker.addFunction('syncToRedis', function (job) {
job.sendWorkData(job.payload);
console.log("-------job.payload: " + job.payload.toString());
//将字符串转换成json object, 然后调用更新redis
updateRedis(eval('(' + job.payload.toString() + ')'));
job.workComplete("Successed!");
});
//些函数只是简单的将MySQL表中的一行的记录按单个字段更新到redis中。可根据实际情况自行扩展
function updateRedis(json)
{
var client = redis.createClient();
client.on("error", function (err) {
console.log("Error " + err);
});
for(var key in json)
{
client.set(key, json[key], redis.print);
}
client.quit();
}
启动worder:
node redis-worker.js
更新MySQL
mysql> select * from user_list;
+------+----------+
| NAME | PASSWORD |
+------+----------+
| troy | jane |
+------+----------+
mysql> update user_list set name='hello', password='world';
redis-worker控制台输出:
-------job.payload: {"name":"hello","password":"world"}
查看redis数据
$ redis-cli
127.0.0.1:6379> keys *
1) "password"
2) "name"
127.0.0.1:6379> get name
"hello"
127.0.0.1:6379> get password
"world"
可以看到只要MySQL中user_list表的数据被update了,redis中的数据也会被更新。
6, 参考资料
Gearman+PHP+MySQL UDF的组合异步实现MySQL到Redis的数据复制
Gearman + Nodejs + MySQL UDF异步实现 MySQL 到 Redis 的数据同步的更多相关文章
- JAVA通过Gearman实现MySQL到Redis的数据同步(异步复制)
MySQL到Redis数据复制方案 无论MySQL还是Redis,自身都带有数据同步的机制,像比较常用的 MySQL的Master/Slave模式 ,就是由Slave端分析Master的binlog来 ...
- 通过Gearman实现MySQL到Redis的数据同步
对于变化频率非常快的数据来说,如果还选择传统的静态缓存方式(Memocached.File System等)展示数据,可能在缓存的存取上会有很大的开销,并不能很好的满足需要,而Redis这样基于内存的 ...
- SQLite与MySQL、SQLServer等异构数据库之间的数据同步
SQLite DBSync是开源嵌入式数据库SQLite的数据同步引擎,实现了SQLite与SQLite数据库之间以及SQLite与异构数据库(Oracle.MySQL.SQLServer)之间的增量 ...
- mysql 集群 数据同步
mysql集群配置在网站负载均衡中是必不可少的: 首先说下我个人准备的负载均衡方式: 1.通过nginx方向代理来将服务器压力分散到各个服务器上: 2.每个服务器中代码逻辑一样: 3.通过使用redi ...
- 基于 MySQL Binlog 的 Elasticsearch 数据同步实践 原
一.背景 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品.订单等数据的多维度检索. 使用 Elasticsearch 存储业务数据可以 ...
- nginx集群+mysql数据同步
mysql集群配置在网站负载均衡中是必不可少的: 首先说下我个人准备的负载均衡方式: 1.通过nginx方向代理来将服务器压力分散到各个服务器上: 2.每个服务器中代码逻辑一样: 3.通过使用redi ...
- 基于MySQL Binlog的Elasticsearch数据同步实践
一.为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品.订单等数据的多维度检索. 使用 Elasticsearch 存储业务数 ...
- MySql UDF 调用外部程序和系统命令
1.mysql利用mysqludf的一个mysql插件可以实现调用外部程序和系统命令 下载lib_mysqludf_sys程序:https://github.com/mysqludf/lib_mysq ...
- 【API】Mysql UDF BackDoor
1.MySQL UDF是什么 UDF是Mysql提供给用户实现自己功能的一个接口,为了使UDF机制起作用,函数必须用C或C ++编写,并且操作系统必须支持动态加载.这篇文章主要介绍UDF开发和利用的方 ...
随机推荐
- 函数 buf_block_init
/********************************************************************//** Initializes a buffer contr ...
- 【App FrameWork】框架的页面布局
之前主要用JqueryMobile+PhoneGap的模式开发移动应用,但JQueryMobile自身存在的硬伤太多,如加载速度缓慢,页面转场白屏.闪烁,头尾部导航浮动问题,页面滚动等等,用户体验效果 ...
- 4月数据库流行度排行榜 MySQL能否追上Oracle
4月的数据库流行度排行榜可谓看点十足.闲言少叙,先上图: 前十名中,名次上升的都是NoSQL数据库,NoSQL凭借其对大数据处理的优势,发展越来越快.NoSQL是对众多非传统关系型数据库的总称,按存储 ...
- 也用 Log4Net 之将日志记录到数据库的配置 (一)
也用 Log4Net 之将日志记录到数据库的配置 (一) 前段时间我一直想做一个通用一点的日志记录系统,可以便于不同的业务组调用进行日志记录及分析.本来打算着自己下手写一个,后面发现各业务组可能会需 ...
- (转载)HTTP URL
HTTP URL的格式如下: http://host[“:”post][abs_path] 其中http表示要通过HTTP协议来定位网络资源.host表示合法的Internet主机域名或IP地址(以点 ...
- Asp.Net 高性能框架 SqlSugar.ORM 2.3
一.前言 SqlSugar从去年到现在已经一年了,版本从1.0升到了现在的2.3 ,这是一个稳定版本 ,有数家公司已经项目上线,在这里我将SqlSugar的功能重新整理成一篇新的贴子,希望大家喜欢. ...
- oracle 有关大数据
一. oracle大数据量分区后查询效率低下的一些建议: 1 对于当前表tm_bus_realtime_log.查看它的索引,只有一个(索引名:INDEX_BUS_REALTIME 字段名:UPLOA ...
- HTML DOM 教程Part1
2015-05-08 摘自W3C School HTML DOM HTML DOM 定义了访问和操作HTML文档的标准方法.HTML DOM 把 HTML 文档呈现为带有元素.属性和文本的树结构(节点 ...
- [转] python程序的调试方法
qi09 原文 python程序的调试方法 本文讨论在没有方便的IDE工具可用的情况下,使用pdb调试python程序 源码例子 例如,有模拟税收计算的程序: #!/usr/bin/python de ...
- FZU 2216 The Longest Straight 二分
0可以表示任何1到m的数,求一个最长的连续上升序列长度 因为m的范围在10w,所以以每个节点为起点 进行二分,复杂度mlogm 思路:b[i]表示到 1 到 i 有几个数没有出现,二分的时候注意加等号 ...