python+php+redis+shell实现几台redis的同步数据?

之所以使用python,是因为python多线程非常简单。

之所以使用shell,是因为写了个服务,可以方便的重启python写的那个脚本。

总体思路:利用redis的发布订阅,php作为生产者,python作为消息费,来实现多台redis-master数据同步。中间也用了redis的list。

当然多台redis-master可以做一个redis集群,然后再两两同步。这里不讨论这么情况的实现。

1、PHP代码(php作为消息生产者,也就是客户端)

$redis = new Redis();
$redis->connect('127.0.0.0', 6379);
$redis->set('test', '123');//设置一个key/value
$count = $redis->lpush('rsync_list', 'test'); // 把key放到rsync_list这个队列里,做为同步使用
$redis->publish('rsync_list', $count);//发布一个消息,channel为rsync_list,用于python代码订阅的channel

2、PYTHON代码(python做为消息接收者,也就是服务端)

/home/www/py/muti_thread_redis.py

#!/usr/bin/env python
#coding=utf-8

import threading
import redis

MAIN_HOST = '127.0.0.1'
MAIN_PORT = 6379
MAIN_PASS = ''

RSYNCLIST = 'rsync_list'


def infinite():
        global rc

        ps = rc.pubsub()
        ps.subscribe('rsync_list')

        threads = []

        while True:
                data = ps.parse_response()
                if data[2] > 0:
                        #第一台
                        t1 = threading.Thread(target=write1,args=(data[2],))
                        t1.start()
                        threads.append(t1)
                        #第二台
                        t2 = threading.Thread(target=write2,args=(data[2],))
                        t2.start()
                        threads.append(t2)
                        for t in threads:
                                t.join()
                        #子进程执行完之后,清空list

def write1(args):
        global rc
        global RSYNCLIST
        redis_one = redis.Redis(host='127.0.0.1',port=6380,password='')
        for i in rc.lrange(RSYNCLIST, 0, -1):
                redis_one.set(i, rc.get(i))


def write2(args):
        global rc
        global RSYNCLIST
        redis_two = redis.Redis(host='127.0.0.1',port=6381,password='')
        for i in rc.lrange(RSYNCLIST, 0, -1):
                redis_two.set(i, rc.get(i))



if __name__ == '__main__':
        rc =redis.Redis(host=MAIN_HOST,port=MAIN_PORT,password=MAIN_PASS)
        infinite()

  注意:这里python和python的redis扩展的安装,就不在这里赘述了。baidu里很多

3、shell(做为一个服务用来启动python的服务端脚本)

cd /etc/init.d

新建一个脚本:vim rsync-redis

#!/bin/bash
#chkconfig:2345 55 25    //运行级别、启动优先级、关闭优先级 
#processname:rsync-redis        //进程名 
#description:source rsync-redis server daemon  //服务描述 
prog=/usr/bin/python
lock=/home/www/py/rsync_redis.pid

start(){
        echo "[正在启动服务...]"
        $prog /home/www/py/muti_thread_redis.py &
        echo "[OK]"
        touch $lock
} 
stop(){
        echo "[正在停止服务...]"
        pkill -f muti_thread_redis.py
        rm -f $lock
        echo "[OK]" 
} 
status(){
        if [ -e $lock ];then
            echo "$0 服务正在运行"
        else
            echo "$0 服务已经停止"
        fi
} 
restart(){
        stop 
        start
} 
case "$1" in
"start") 
        start
        ;; 
"stop")
        stop 
        ;; 
"status")
        status 
        ;; 
"restart")
        restart 
        ;; 
*)
        echo "用法:$0 start|stop|status|restart"
        ;; 
esac

  然后就可以用/etc/init.d/rsync-redis start/stop/restart/status来操作了。