背景

前段时间我选用了 Airflow 对 wms 进行数据归档,在运行一段时间后,经常发现会报以下错误:

[-- ::,: WARNING/ForkPoolWorker-] Failed operation _store_result.  Retrying  more times.
Traceback (most recent call last):
File "/usr/local/python38/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line , in _execute_context
self.dialect.do_execute(
File "/usr/local/python38/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line , in do_execute
cursor.execute(statement, parameters)
File "/usr/local/python38/lib/python3.8/site-packages/MySQLdb/cursors.py", line , in execute
self.errorhandler(self, exc, value)
File "/usr/local/python38/lib/python3.8/site-packages/MySQLdb/connections.py", line , in defaulterrorhandler
raise errorvalue
File "/usr/local/python38/lib/python3.8/site-packages/MySQLdb/cursors.py", line , in execute
res = self._query(query)
File "/usr/local/python38/lib/python3.8/site-packages/MySQLdb/cursors.py", line , in _query
db.query(q)
File "/usr/local/python38/lib/python3.8/site-packages/MySQLdb/connections.py", line , in query
_mysql.connection.query(self, query)
_mysql_exceptions.OperationalError: (, 'MySQL server has gone away') The above exception was the direct cause of the following exception: Traceback (most recent call last):
File "/usr/local/python38/lib/python3.8/site-packages/celery/backends/database/__init__.py", line , in _inner
return fun(*args, **kwargs)
File "/usr/local/python38/lib/python3.8/site-packages/celery/backends/database/__init__.py", line , in _store_result
task = list(session.query(Task).filter(Task.task_id == task_id))
File "/usr/local/python38/lib/python3.8/site-packages/sqlalchemy/orm/query.py", line , in __iter__
return self._execute_and_instances(context)
File "/usr/local/python38/lib/python3.8/site-packages/sqlalchemy/orm/query.py", line , in _execute_and_instances
result = conn.execute(querycontext.statement, self._params)
File "/usr/local/python38/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line , in execute
return meth(self, multiparams, params)
File "/usr/local/python38/lib/python3.8/site-packages/sqlalchemy/sql/elements.py", line , in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "/usr/local/python38/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line , in _execute_clauseelement
ret = self._execute_context(
File "/usr/local/python38/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line , in _execute_context
self._handle_dbapi_exception(
File "/usr/local/python38/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line , in _handle_dbapi_exception
util.raise_from_cause(sqlalchemy_exception, exc_info)
File "/usr/local/python38/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line , in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/usr/local/python38/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line , in reraise
raise value.with_traceback(tb)
File "/usr/local/python38/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line , in _execute_context
self.dialect.do_execute(
File "/usr/local/python38/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line , in do_execute
cursor.execute(statement, parameters)
File "/usr/local/python38/lib/python3.8/site-packages/MySQLdb/cursors.py", line , in execute
self.errorhandler(self, exc, value)
File "/usr/local/python38/lib/python3.8/site-packages/MySQLdb/connections.py", line , in defaulterrorhandler
raise errorvalue
File "/usr/local/python38/lib/python3.8/site-packages/MySQLdb/cursors.py", line , in execute
res = self._query(query)
File "/usr/local/python38/lib/python3.8/site-packages/MySQLdb/cursors.py", line , in _query
db.query(q)
File "/usr/local/python38/lib/python3.8/site-packages/MySQLdb/connections.py", line , in query
_mysql.connection.query(self, query)
sqlalchemy.exc.OperationalError: (_mysql_exceptions.OperationalError) (, 'MySQL server has gone away')
[SQL: SELECT celery_taskmeta.id AS celery_taskmeta_id, celery_taskmeta.task_id AS celery_taskmeta_task_id, celery_taskmeta.status AS celery_taskmeta_status, celery_tas
kmeta.result AS celery_taskmeta_result, celery_taskmeta.date_done AS celery_taskmeta_date_done, celery_taskmeta.traceback AS celery_taskmeta_traceback
FROM celery_taskmeta
WHERE celery_taskmeta.task_id = %s]
[parameters: ('e909b916-4284-47c4-bc5b-321bc32eb9f9',)]
(Background on this error at: http://sqlalche.me/e/e3q8)

解决过程

查了下资料一般情况下数据库服务器断开连接后,被连接池未收回将会导致以下错误:

MySQL server has gone away

所以看了下 sqlalchemy 的配置:

sql_alchemy_pool_enabled = True

# The SqlAlchemy pool size is the maximum number of database connections
# in the pool. indicates no limit.
sql_alchemy_pool_size = # The maximum overflow size of the pool.
# When the number of checked-out connections reaches the size set in pool_size,
# additional connections will be returned up to this limit.
# When those additional connections are returned to the pool, they are disconnected and discarded.
# It follows then that the total number of simultaneous connections the pool will allow is pool_size + max_overflow,
# and the total number of "sleeping" connections the pool will allow is pool_size.
# max_overflow can be set to - to indicate no overflow limit;
# no limit will be placed on the total number of concurrent connections. Defaults to .
sql_alchemy_max_overflow = # The SqlAlchemy pool recycle is the number of seconds a connection
# can be idle in the pool before it is invalidated. This config does
# not apply to sqlite. If the number of DB connections is ever exceeded,
# a lower config value will allow the system to recover faster.
sql_alchemy_pool_recycle = # Check connection at the start of each connection pool checkout.
# Typically, this is a simple statement like “SELECT ”.
# More information here: https://docs.sqlalchemy.org/en/13/core/pooling.html#disconnect-handling-pessimistic
sql_alchemy_pool_pre_ping = True sql_alchemy_pool_size = # The maximum overflow size of the pool.
# When the number of checked-out connections reaches the size set in pool_size,
# additional connections will be returned up to this limit.
# When those additional connections are returned to the pool, they are disconnected and discarded.
# It follows then that the total number of simultaneous connections the pool will allow is pool_size + max_overflow,
# and the total number of "sleeping" connections the pool will allow is pool_size.
# max_overflow can be set to - to indicate no overflow limit;
# no limit will be placed on the total number of concurrent connections. Defaults to .
sql_alchemy_max_overflow = # The SqlAlchemy pool recycle is the number of seconds a connection
# can be idle in the pool before it is invalidated. This config does
# not apply to sqlite. If the number of DB connections is ever exceeded,
# a lower config value will allow the system to recover faster.
sql_alchemy_pool_recycle = # Check connection at the start of each connection pool checkout.
# Typically, this is a simple statement like “SELECT ”.
# More information here: https://docs.sqlalchemy.org/en/13/core/pooling.html#disconnect-handling-pessimistic
sql_alchemy_pool_pre_ping = True

该配的都配置上了,因为我们的任务是一天跑一次,查了下数据库变量 waits_timeout 是 28800 ,所以直接改成25个小时。

到了第二天发现还是报这个错,很奇怪该配的都配上了,到底是哪里的问题?

仔细翻下报错日志:

File "/usr/local/python38/lib/python3.8/site-packages/celery/backends/database/__init__.py", line , in _store_result
task = list(session.query(Task).filter(Task.task_id == task_id))

难道 Airflow 的 sqlalchemy 配置对 celery 不生效?

翻阅下源码发现果然 Airflow 配置的 sqlalchemy 只对 Airflow 生效

app = Celery(
conf.get('celery', 'CELERY_APP_NAME'),
config_source=celery_configuration)

在继续翻阅 Celery 文档看有没有办法配置

database_short_lived_sessions Default: Disabled by default.

Short lived sessions are disabled by default. If enabled they can drastically reduce performance, especially on systems processing lots of tasks. This option is useful on low-traffic workers that experience errors as a result of cached database connections going stale through inactivity. For example, intermittent errors like (OperationalError) (2006, ‘MySQL server has gone away’) can be fixed by enabling short lived sessions. This option only affects the database backend.

文档告知通过database_short_lived_sessions 参数就可以避免这个问题,但是新的问题又来了,如何在 Airflow 中配置额外的 Celery 配置呢?

解决方案

找到以下文件拷贝到 DAGS 目录下,重新命名为 my_celery_config 随便起

Python/Python37/site-packages/airflow/config_templates/default_celery.py
修改 Airflow.cfg 配置 找到 celery_config_options 将配置改为 刚才起的名字
celery_config_options = my_celery_config.DEFAULT_CELERY_CONFIG
在 my_celery_config 文件中的 DEFAULT_CELERY_CONFIG dict 中就可以随便加自己需要的 Celery 配置

Airflow 使用 Celery 时,如何添加 Celery 配置的更多相关文章

  1. Python3安装Celery模块后执行Celery命令报错

    1 Python3安装Celery模块后执行Celery命令报错 pip3 install celery # 安装正常,但是执行celery 命令的时候提示没有_ssl模块什么的 手动在Python解 ...

  2. celery 分布式异步任务框架(celery简单使用、celery多任务结构、celery定时任务、celery计划任务、celery在Django项目中使用Python脚本调用Django环境)

    一.celery简介: Celery 是一个强大的 分布式任务队列 的 异步处理框架,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行.我们通常使用它来实现异步任务(async tas ...

  3. [mark] 使用Sublime Text 2时如何将Tab配置为4个空格

    在Mac OS X系统下,Sublime Text是一款比较赞的编辑器. 作为空格党的自觉,今天mark一下使用Sublime Text 2时如何将Tab配置为4个空格: 方法来自以下两个链接: ht ...

  4. 问题.NET--win7 IIS唯一密钥属性“VALUE”设置为“DEFAULT.ASPX”时,无法添加类型为“add”的重复集合

    问题现象:.NET--win7 IIS唯一密钥属性“VALUE”设置为“DEFAULT.ASPX”时,无法添加类型为“add”的重复集合 问题处理: 内容摘要:    HTTP 错误 500.19 - ...

  5. mybatis JdbcTypeInterceptor - 运行时自动添加 jdbcType 属性

    上代码: package tk.mybatis.plugin; import org.apache.ibatis.executor.ErrorContext; import org.apache.ib ...

  6. SpringBoot运行时动态添加数据源

    此方案适用于解决springboot项目运行时动态添加数据源,非静态切换多数据源!!! 一.多数据源应用场景: 1.配置文件配置多数据源,如默认数据源:master,数据源1:salve1...,运行 ...

  7. IDEA 创建类是自动添加注释和创建方法时快速添加注释

    1.创建类是自动添加注释 /*** @Author: chiyl* @DateTime: ${DATE} ${TIME}* @Description: TODO*/2. 创建方法时快速添加注释2.1 ...

  8. eclipse启动时虚拟机初始内存配置

    eclipse启动时虚拟机初始内存配置: -Xms256M -Xmx512M -XX:PermSize=256m -XX:MaxPermSize=512m

  9. 如何设置SVN提交时强制添加注释

    windows版本: 1.新建一个名为pre-commit.bat的文件并将该文件放在创建的库文件的hooks文件夹中 2.pre-commit.bat文件的内容如下: @echo off set S ...

  10. iOS 10 (X8)上CoreData的使用(包含创建工程时未添加CoreData)

    1.在创建工程时未添加CoreData,后期想要使用CoreData则要在工程Appdelegate.h文件中添加CoreData库和CoreData中的通道类(用来管理类实例和CoreData之间的 ...

随机推荐

  1. SSH框架搭建 笔记 (含spring注解驱动)

    分类: web 开发2014-04-27 12:33 354人阅读 评论(0) 收藏 举报 框架springinterface注解 好久没有搭建框架了,今天整理下以前的知识,整合下SSH,没想到手生了 ...

  2. SqlServer查看锁表与解锁

    某些情况下,sqlserver的表会被锁住,比如某个会话窗口有数据一直没提交,窗口又没关闭,这时表就会被锁住 其他任何连接查询表数据时都不会返回 这时需要手工杀掉产生死锁的会话ID,才能恢复正常 查看 ...

  3. jsp中include的两种用法

    JSP中的include的两种用法 1.两种用法 <%@ include file=” ”%> <jsp:include page=” ” flush=”true”/> 2.用 ...

  4. 连接mysql报错java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized...解决方法

    报错内容: java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized or represents mo ...

  5. WAFの基本防护透明流模式v1.0

                      一.WAFの透明流模式     1)首先先配置WAF的网络,配置一个网桥接口,设置IP便于带内管理.             2)当然,如果需要不同网段之间都能够管 ...

  6. Python面试常问的10个问题

    很多人想找Python工作,面试往往在基础知识点采坑了 Python是个非常受欢迎的编程语言,随着近些年机器学习.云计算等技术的发展,Python的职位需求越来越高.下面我收集了10个Python面试 ...

  7. Educational Codeforces Round 63 选做

    D. Beautiful Array 题意 给你一个长度为 \(n\) 的序列.你可以选择至多一个子段,将该子段所有数乘上给定常数 \(x\) .求操作后最大的最大子段和. 题解 考虑最大子段和的子段 ...

  8. 构造方法与setter方法

    上一个随笔提到了constructor-arg子标签,此随笔将会介绍一些类型的赋值方法 ①String类型.基本数据类型或其包装类都可以使用value标签属性赋值 String类型和基本类型的操作如下 ...

  9. Java For 循环

    章节 Java 基础 Java 简介 Java 环境搭建 Java 基本语法 Java 注释 Java 变量 Java 数据类型 Java 字符串 Java 类型转换 Java 运算符 Java 字符 ...

  10. 一文详解scala泛型及类型限定

    今天知识星球球友,微信问浪尖了一个spark源码阅读中的类型限定问题.这个在spark源码很多处出现,所以今天浪尖就整理一下scala类型限定的内容.希望对大家有帮助. scala类型参数要点 1. ...