Redis Xcom部署到UAT环境

目前我们UAT环境的Airflow使用的原生的XCOM机制,使用默认的BaseXcom类。由于之前MWAA的Airflow发生过因为xcom问题导致任务卡死的事故,值得我们花时间研究Redis xcom作为替换方案。

首先看看Airflow官网关于custom xcom的说法

https://airflow.apache.org/docs/apache-airflow/2.7.1/core-concepts/xcoms.html#custom-xcom-backends

我们根据下面github代码作为基础,修改少量代码来作为我们的Redis Xcom方案。

https://gist.github.com/msumit/1bc995c4a21acb257a39c36f0279e3d6

上面github代码主要思想是覆盖BaseXcom类的serialize_value和deserialize_value两个方法,在这两个方法中嵌入redis操作,把xcom的value写到redis上,和从redis取回value,从而达到目的。

我们开发的代码如下:

redis_xcom.py

# This is an example to show how easy to extend the custom XCom backends in Apache Airflow. 
# File: airflow/providers/redis/xcom/redis_xcom.py
# Author: Sumit Maheshwari

import json
import logging
from typing import Any
import uuid

from airflow.configuration import conf
from airflow.models.xcom import BaseXCom
from airflow.providers.redis.hooks.redis import RedisHook

log = logging.getLogger(__name__)
redis_conn_id = conf.get('xcom', 'redis_conn_id', fallback=RedisHook.default_conn_name)
redis_hook = RedisHook(redis_conn_id=redis_conn_id)


class RedisXCom(BaseXCom):

    @classmethod
    def delete(cls, xcom):
        """Delete XCom value from Redis"""
        result = redis_hook.get_conn().delete(xcom.value)
        log.debug("Result of deleting key to Redis %s", result)

    @staticmethod
    def serialize_value(value: Any):
        """Serialize the data as JSON, store into Redis & return the key"""
        val = json.dumps(value).encode('UTF-8')
        key = uuid.uuid4().hex

        log.debug('Setting XCom key %s to Redis', key)
        result = redis_hook.get_conn().set(f"xcom-{key}", val, 60 * 60 * 24 * 30)
        log.debug('Result of publishing to Redis %s', result)
        return BaseXCom.serialize_value(f"xcom-{key}")

    @staticmethod
    def deserialize_value(result: "XCom") -> Any:
        result = redis_hook.get_conn().get(result.value.decode().strip('"'))
        return json.loads(result.decode('UTF-8')) if result is not None \
            else '** XCom not found in Redis **'

上面部署到UAT环境后,发现redis可以正常存储xcom的value

但是,依然会使用到airflow metadata mysql的xcom表,而xcom表的value字段存储的是redis的key。

xcom_push操作,BaseXcom类的处理流程

结合BaseXcom类的代码我们可以得出使用Redis Xcom的xcom_push处理流程如下:

1.在redis_xcom.py覆盖serialize_value方法里,使用了uuid生成了一个随机的redis key,这个key连同xcom的value作为键值对,保存到redis

2.把redis key作为serialize_value方法的返回值,然后把这个返回值作为value写到xcom表的value字段

对于xcom_pull操作刚好是反过来

1.先查xcom表,拿到value字段的值,作为redis的key

2.使用该key到redis去取回真正的用户value

结论:

仅仅覆盖BaseXcom类的serialize_value和deserialize_value两个方法,是绕不开airflow写xcom表,这样看来,跟原生xcom行为差别不大。

S3 xcom backend 实现方式

https://github.com/Pilotcore/airflow-xcom-s3/blob/main/xcom_s3_backend.py

https://docs.astronomer.io/learn/xcom-backend-tutorial?tab=aws#step-4-define-a-custom-xcom-class-using-json-serialization

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值