• 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来操作了。

  • 相关阅读:
    LeetCode 23. 合并K个排序链表
    LeetCode 199. 二叉树的右视图
    LeetCode 560. 和为K的子数组
    LeetCode 1248. 统计「优美子数组」
    LeetCode 200. 岛屿数量
    LeetCode 466. 统计重复个数
    LeetCode 11. 盛最多水的容器
    LeetCode 55. 跳跃游戏
    LeetCode 56. 合并区间
    Java生鲜电商平台-订单架构实战
  • 原文地址:https://www.cnblogs.com/gpfeisoft/p/5981777.html
Copyright © 2020-2023  润新知