通过celery提高crontab配置效率

这是学习笔记的第 1777篇文章

今天在接入备份任务配置的时候也是一波三折,解决了业务元数据的问题,也逐步熟悉了业务,对于现有的备份情况会越来越有把握。

业务问题过去之后很快就碰到了性能问题,这个也是之前的处理中没有意识到的。比如现在我尝试逐步介入备份任务的时候,每次接入10个,添加了配置任务,会在系统的crontab中生成一条定时任务配置。

整个平台暂时只负责任务并行调度,即分成几组并行任务,任务时间调度,即任务什么时候开始,怎么去衔接任务的执行时间。

大体的使用界面如下:

在接入之后,确认元数据没有问题的时候,我们开启数据同步操作,会在元数据中同步配置,然后下推crontab的配置到系统任务中,但是这个时候原有的异步请求AJAX抛出了异常,大体的日志如下:

/usr/local/DBA_SCRIPTS/mysql/crontab_automanage.sh -h 1 -m 59 -o add -c mysqlfullbackup -H xxxx -P 4306
{u'mission_id': u'25089', u'failed': {}, u'success': {u'xxxxx': [u'20181018 17:54:43 Create crontab task...', u'20181018 17:54:43 Clear crontab tmp file', u'20181018 17:54:43 remove crontab xtraback
up_innodb_full_v6 on tmp file', u'20181018 17:54:43 Job complete']}, u'unreachable': {}}
{u'mission_id': u'25089', u'failed': {}, u'success': {u'xxxxx': [u'20181018 17:54:43 Create crontab task...', u'20181018 17:54:43 Clear crontab tmp file', u'20181018 17:54:43 remove crontab xtraback
up_innodb_full_v6 on tmp file', u'20181018 17:54:43 Job complete']}, u'unreachable': {}}
Thu Oct 18 17:54:43 2018 - uwsgi_response_writev_headers_and_body_do(): Broken pipe [core/writer.c
 line 306] during POST /backup/mysql_backupconf_batch_sync/ (192.168.xxxx)
IOError: write error

可以看到这个问题是在请求的过程中发生了异常,根据配置很可能是超时导致,使用ansible_adhoc触发每次执行大约需要2秒,30多个刚好触发了临界点。

这里恰好就是程序端实现的一个瓶颈,目前的任务执行是轮询,也即为串行执行模式,按照这种方式,如果任务的数量增加,那么系统的交互时长会直线上升,体验会很差,而且任务的执行很可能会中断。

整体的一个流程设计图如下:

注意这里是可以称为执行器,但是还离调度器有点距离。

这个部分怎么改进呢,可以参考下面的图:

我们下发的任务都可以先接受,然后慢慢执行,这样就好比对于前端马上有了反馈,整个任务的后端执行是真正的异步方式,这个时候是串行还是并行就没那么敏感了,如果想要提高执行效率,那么可以配置多个worker,否则就是串行的方式。

从代码的层面来简单说一下如何改进,代码中我们封装了ansible_adhoc,通过装饰器,我们可以把它封装为一个异步任务。

@shared_task
def ansible_adhoc(user, hosts, module, command, sudo=False):
    url = 'http://xxxxxx:8000/dba/ansible/adhoc'
    body = {"hosts": hosts, "module": module, "module_args": command, "sudo": sudo}
    return_dict = {}
    。。。。。

后端的业务逻辑如下,是会通过循环的方式调用ansible_adhoc

def mysql_backupconf_batch_sync(request):
    return_dict = {}
    mysql_xtrabackup_schedulers = mysql_xtrabackup_scheduler.objects.all()
    for temp in mysql_xtrabackup_schedulers:
        print temp.os_crontab
        mysql_backupconfig.objects.filter(backup_ip=temp.backup_ip,backup_instanceport=temp.backup_instanceport).update(
            os_crontab=temp.os_crontab
            )
        begin_hour = int(temp.os_crontab.split(":")[0])
        begin_minute = int(temp.os_crontab.split(":")[1])
        commend = "/usr/local/DBA_SCRIPTS/mysql/crontab_automanage.sh -h %s -m %s -o add -c mysqlfullbackup -H %s -P %s" % (
        begin_hour, begin_minute,temp.backup_ip,temp.backup_instanceport)
        print(commend)
        result = ansible_adhoc('dba_mysql', temp.backup_ip, "script", commend, True)
        print(result)
    return JsonResponse({'msg': '更新成功', "code": 200, 'data': return_dict})

在这个代码的基础上,只需要添加一个函数,即可变得高大上,切换为队列模式,间接实现了并发。

def mysql_backupconf_batch_sync(request):
    return_dict = {}
    mysql_xtrabackup_schedulers = mysql_xtrabackup_scheduler.objects.all()
    for temp in mysql_xtrabackup_schedulers:
        print temp.os_crontab
        mysql_backupconfig.objects.filter(backup_ip=temp.backup_ip,backup_instanceport=temp.backup_instanceport).update(
            os_crontab=temp.os_crontab
            )
        begin_hour = int(temp.os_crontab.split(":")[0])
        begin_minute = int(temp.os_crontab.split(":")[1])
        commend = "/usr/local/DBA_SCRIPTS/mysql/crontab_automanage.sh -h %s -m %s -o add -c mysqlfullbackup -H %s -P %s" % (
        begin_hour, begin_minute,temp.backup_ip,temp.backup_instanceport)
        print(commend)
        result = ansible_adhoc.delay('dba_mysql', temp.backup_ip, "script", commend, True)
        print(result)
    return JsonResponse({'msg': '更新成功', "code": 200, 'data': return_dict})

当然程序端的并发也是需要视情况而定,而不要一位为了技术酸爽而本末倒置。

按照这种方式,整个任务的串行,并行都可以做到基本可控。

后续在这个基础上,在celery方向上需要考虑五类任务的接入:

1)异步任务,这个是celrey原生支持的

2)定时任务,这个是celery原生支持的

3)crontab,这个是保留原本的crontab,但是执行时间可以根据配置灵活的调度产生,这样执行和时间就可以做到解耦合。

4)API,这个计划作为内部和外部使用两种模式,通过API的方式把执行结果封装到队列里面,对于变更执行类的需求,通过这种方式是比较适合的,可以极大提高系统吞吐率。

原文发布于微信公众号 - 杨建荣的学习笔记(jianrong-notes)

原文发表时间:2018-10-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏安斌的专栏

再说TCP神奇的40ms

本文结合具体的 tcpdump 包,分析触发 delay ack 的场景,相关的内核参数, 以及规避的方案。

11.4K70
来自专栏WeTest质量开放平台团队的专栏

HTTP/2之服务器推送(Server Push)最佳实践

商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处。

48300
来自专栏PHP在线

Apache与Nginx的优缺点比较

Apache与Nginx的优缺点比较 1、nginx相对于apache的优点: 轻量级,同样起web 服务,比apache 占用更少的内存及资源 抗并发,...

38660
来自专栏网络

负载均衡原理的解析

作者:源子姗 my.oschina.net/u/3341316/blog/877206 开头先理解一下所谓的“均衡” 不能狭义地理解为分配给所有实际服务器一样多...

33580
来自专栏腾讯大数据的专栏

zookeeper 运营经验分享

Zookeeper作为TDBank系统的一个重要模块,我们运营它已经两年多。在使用过程中,我们也遇到了一些问题及走过很多弯路,本文主要对zookeeper运营经...

30490
来自专栏技术点滴

git使用小结

git使用小结 很多人可能和我一样,起初对git是一无所知的。我也是因为一次偶然的机会接触到git,并被它强大的功能所蛰伏。git其实就是一种版本控制工具,就像...

21680
来自专栏大数据实战演练

Linux NTP时钟同步

时钟同步在大数据方向,用到的地方很多。举个例子来说吧,像Zookeeper、RegionServer服务都是需要实时和各节点进行通信的。假如各节点差超过30s,...

85120
来自专栏知晓程序

开发 | 效率提升 100%,小程序开发应该这样做

16930
来自专栏北京马哥教育

Linux 运维工程师必备的80个监控工具(第30-80个)

这是《Linux 运维工程师必备的80个监控工具》的下篇,上篇请点击:Linux运维工程师必备的80个监控工具全集(上) 与系统有关的监控 30 nmom[2...

69570
来自专栏腾讯移动品质中心TMQ的专栏

移动APP测试用例设计的关注点

在我们的测试工作中,对于某个APP的测试其实有很多东西都是类似的可以抽象出来的,这里june总结一下大部分APP测试的时候都要考虑到的方面。如果漏下了其他方面,...

293100

扫码关注云+社区

领取腾讯云代金券