分布式跑批数据方案

本文介绍了一种分布式跑批数据的解决方案,通过Redis有序集合进行任务分配,将大任务按序号分批处理。首先,将每个任务插入Redis有序集合,然后按序号查询数据库数据,确保数据平均分配到多个节点。关键代码实现包括负载均衡函数和获取本机IP的方法,以确保任务按顺序执行。
摘要由CSDN通过智能技术生成

1. 背景

分布式跑批数据,但是跑批数据很大的情况下,需要将数据库中的任务分批处理

2. 方案

(1)跑批时每个任务向redis 有序集合中插入记录

redis> zadd redis_zset 100 192.168.0.1

(integer) 1

redis> zadd redis_zset 100 192.168.0.2

(integer) 1

redis>  zadd redis_zset 100 192.168.0.3

(integer) 1

redis> ZRANGE redis_zset 0 -1

1) "192.168.0.1"

2) "192.168.0.2"

3) "192.168.0.3"

redis> zcard redis_zset

(integer) 3

redis> ZREVRANK redis_zset 192.168.0.1

(integer) 2

redis> ZREVRANK redis_zset 192.168.0.2

(integer) 0

redis> ZREVRANK redis_zset 192.168.0.3

(integer) 1

redis zset 命令见 https://www.runoob.com/redis/redis-sorted-sets.html  注意区分ZREVRANK和zrank命令

实际KEY:  redis_zset

  1. 然后等待2s ,有序集合中插入值

  2. 获取每个ip在有序集合中的序号
  3. 按序号分别查询数据库中的数据,分别处理,将数据平均分成三等分

    mysql> select status,count(*) from table1 where status='0';

    +--------+----------+

    | status | count(*) |

    +--------+----------+

    0      |   739119 |

    +--------+----------+

    mysql> select count(*) from table1 where status='0' and mod(id,3)=0;

    +----------+

    | count(*) |

    +----------+

    |   246357 |

    +----------+

    1 row in set (0.33 sec)

    mysql> select count(*) from table1 where status='0' and mod(id,3)=1;

    +----------+

    | count(*) |

    +----------+

    |   246356 |

    +----------+

    1 row in set (0.30 sec)

    mysql> select count(*) from table1 where status='0' and mod(id,3)=2;

    +----------+

    | count(*) |

    +----------+

    |   246357 |

    +----------+

    1 row in set (0.30 sec)

  4. 手动执行时需要注意执行顺序
    192.168.0.1
    192.168.0.2
    192.168.0.3
    

  5. 其他跑批任务也可参考该算法将数据分开执行
  6. 关键代码实现
def load_balancing(self, redis_zset_key, value):
        '''
        mysql负载
        :param redis_zset_key:
        :param value:
        :return:
        '''
        mod_len = self.redisCli.zcard(redis_zset_key)
        mod_index = self.redisCli.zrevrank(redis_zset_key, value)
        return mod_len, mod_index
@staticmethod
    def get_host_ip():
        '''
        获取本机内网ip
        :return:
        '''
        #获取本机电脑名
        myname = socket.getfqdn(socket.gethostname())
        #获取本机ip
        myaddr = socket.gethostbyname(myname)
        return myaddr
sql = self.query_no_check_dlp_file_sql
mod_len, mod_value = self.load_balance()
if mod_len and (mod_value or mod_value==0) and mod_len != 0:
     sql = "%s and %s" % (sql, "mod(id,%s)=%s" % (mod_len, mod_value))
return sql

记录一下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值