前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >通过celery提高crontab配置效率

通过celery提高crontab配置效率

作者头像
jeanron100
发布2018-11-05 17:46:59
8570
发布2018-11-05 17:46:59
举报

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

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

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

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

大体的使用界面如下:

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

代码语言:javascript
复制
/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,通过装饰器,我们可以把它封装为一个异步任务。

代码语言:javascript
复制
@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

代码语言:javascript
复制
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})

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

代码语言:javascript
复制
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的方式把执行结果封装到队列里面,对于变更执行类的需求,通过这种方式是比较适合的,可以极大提高系统吞吐率。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-10-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 杨建荣的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档