目录node
CentOS, MySQL, Redis, Nodejsmysql
Redis是一个开源的K-V内存数据库,它的key能够是string/set/hash/list/...,由于是基于内存的,所在访问速度至关快。git
Gearman是一个开源的Map/Reduce分布式计算框架,具备丰富的client sdk,并且它支持MySQL UDF。github
从图中能够看出貌似Gearman的集群功能比较弱,Job Server之间没啥关系好像。
redis
首先咱们以MySQL数据为主,将insert/update/delete交给MySQL,而select交给redis;
当有数据发生变化时,经过MySQL Trigger实时异步调用Gearman的UDF提交一个job给Job Server,当job执行的时候会去更新redis;从而保证redis与MySQL中的数据是同步的。sql
//安装依赖 $ 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有不少种:PHP, Perl, Python, Ruby, Nodejs, Go, Java, C#...,咱们选择GearmaNode(Nodejs库)做为实验用的gearman client数据库
Nodejs的安装省略npm
GearmaNode的安装及测试json
安装GearmaNodeapi
//安装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安装成功,运行正常。
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"} | +----------------------------------+
//下载 $ 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*
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 ;
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中的数据也会被更新。