【PyTHON】redis資料遷移

風塵_NULL發表於2016-03-25
同事直接將redis2.8dump檔案移到redis3.0上,結果出現了問題,於是本人就編寫簡單的資料遷移指令碼,原理是透過遍歷不同型別的資料,然後在插入redis3.0中
#!/usr/local/bin/python
#name:redisDataTans.py
try :
        from redis.sentinel import Sentinel
        from redis.client import StrictRedis
        from redis.client import Redis
except ImportError :
        print 'redis module import failed,please check the packege is installed'
//對於string型別的處理
def trans_string(from_obj,to_obj,key) :
        string_value=from_obj.get(key)
        to_obj.set(key,string_value)
//對於hash型別的處理
def trans_hash(from_obj,to_obj,key) :
        hash_value=from_obj.hgetall(key)
        to_obj.hmset(key,hash_value)
//對於列表的處理
def trans_list(from_obj,to_obj,key) :
        list_values=from_obj.lrange(key,0,-1)
        for list_value in list_values :
                to_obj.rpush(key,list_value)
//對於set的處理
def trans_set(from_obj,to_obj,key) :
        set_values=from_obj.smembers(key)
        for set_value in set_values :
                to_obj.sadd(key,set_value)
//對於zset的處理
def trans_zset(from_obj,to_obj,key) :
        try :
                zset_values=from_obj.zrange(name=key,start=0,end=-1,desc=True,withscores=True)
        except :
                print "error ,zrange get none values"
        for (name,score) in zset_values:
                to_obj.zadd(key,name,score)
//判斷資料型別,選擇相應的處理方法
def switch(data_type,from_object,to_object,key) :
        try :
                {"string":lambda from_object,to_object,key:trans_string(from_object,to_object,key),
                "list":lambda from_object,to_object,key:trans_list(from_object,to_object,key),
                "hash":lambda from_object,to_object,key:trans_hash(from_object,to_object,key),
                "set":lambda from_object,to_object,key:trans_set(from_object,to_object,key),
                "zset":lambda from_object,to_object,key:trans_zset(from_object,to_object,key)
                }[data_type](from_object,to_object,key)
        except KeyError :
                print '%s not found,please check it is a redis data type!'%data_type

if __name__=="__main__":
        //以下是測試用例
        connect_type=1
        socket_pair=[('10.16.147.195',26579)]
        serviceName='cluster63791'
        passwd='abc'
        dbname=15
        sentinel=Sentinel(sentinels=socket_pair)
        from_object=sentinel.master_for(service_name=serviceName,password=passwd,db=dbname)
        to_object=Redis(host='10.16.147.193',port=6379,db=6,password='cba')
        keys=from_object.keys('*')
        for key in keys :
                data_type=from_object.type(key)
                switch(data_type=data_type,from_object=from_object,to_object=to_object,key=key)

當然,我們可以做成命令列的形式
具體看下面指令碼
#!/usr/local/bin/python
#name:redisTansfer.py
try :
        import argparse
        import redisDataTrans as transfer
except ImportError :
        print "argparse module import failed,please check the packege is installed"
if __name__=="__main__" :
        try :
                parse=argparse.ArgumentParser(prog="redisDataTrans",usage='%(prog)s [options]',description="this script transfer redis db from one to anthor,for example:ip1,db0=>ip2,db3")
                parse.add_argument('-sip','--source-ipaddress',required=True,help='the source server,which will transfer data to destination server')
                parse.add_argument('-dip','--destination-ipaddress',required=True,help='the destination server')
                parse.add_argument('-sport','--source-port',default=6379,help='the source redis port')
                parse.add_argument('-dport','--destination-port',default=6379,help='the destination redis port')
                parse.add_argument('-sdb','--source-database',default=0,type=int,choices=range(0,16),help='the redis dbname')
                parse.add_argument('-ddb','--destination-database',default=15,type=int,choices=range(0,16),help='the redis dbname')
                parse.add_argument('-sstnl','--issource-sentinel',action='store_true',default=False,help='the source redis use sentinel or not')
                parse.add_argument('-dstnl','--isdestination-sentinel',action='store_true',default=False,help='the desitination redis use sentinel or not')
                parse.add_argument('-spwd','--source-password',help='the source redis password')
                parse.add_argument('-dpwd','--destination-password',help='the source redis password')
                parse.add_argument('-scluster','--source-cluster',default='cluster63791',help='the sentinel cluster name')
                parse.add_argument('-dcluster','--destination-cluster',default='cluster63791',help='the sentinel cluster name')
                parse.add_argument('-keyvalue',default='*',help='the needed data to be transfer,for example:* or abc *')
        except :
                print 'paramter product error!'
                sys.exit()
        args=parse.parse_args()
        print args.issource_sentinel
        if args.issource_sentinel :
                print "create soure_sentinel object start ..."
                socket_pair=[(args.source_ipaddress,args.source_port)]
                serviceName=args.source_cluster
                passwd=args.source_password
                dbname=args.source_database
                sentinel=transfer.Sentinel(sentinels=socket_pair)
                try :
                        from_object=sentinel.master_for(service_name=serviceName,password=passwd,db=dbname)
                except :
                        print "create source_sentinel object failed!"
        else :
                try :
                        from_object=transfer.Redis(host=args.source_ipaddress,port=args.source_port,db=args.source_database,password=args.source_password)
                except :
                        print "create source_redis object failed!"
        if args.isdestination_sentinel :
                socket_pair=[(args.destination_ipaddress,args.destination_port)]
                serviceName=args.destination_cluster
                passwd=args.destination_password
                dbname=args.destination_database
                sentinel=transfer.Sentinel(sentinels=socket_pair)
                try :
                        to_object=sentinel.master_for(service_name=serviceName,password=passwd,db=dbname)
                except :
                        print "create destination_sentinel object failed!"
        else :
                try :
                        to_object=transfer.Redis(host=args.destination_ipaddress,port=args.destination_port,db=args.destination_database,password=args.destination_password)
                except :
                        print "create destination object failed!"

        keys=from_object.keys(args.keyvalue)
        for key in keys :
                data_type=from_object.type(key)
                transfer.switch(data_type=data_type,from_object=from_object,to_object=to_object,key=key)

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30221425/viewspace-2063525/,如需轉載,請註明出處,否則將追究法律責任。

相關文章