Azure Function处理Debezium删除消息时报bodies与metadata不匹配错误
问题根因
你遇到的AssertionError: Number of bodies and metadata mismatched错误是Azure Functions Python层Event Hub绑定的已知缺陷,该错误发生在业务代码执行之前,无法通过现有代码里的逻辑拦截:
- Debezium处理PostgreSQL删除操作时,会生成两条消息:一条带完整删除数据的事件,一条为了支持Kafka日志压缩的空值Tombstone消息。当批量拉取的事件列表中同时包含正常消息和空Tombstone消息时,Python绑定层解析时会出现消息体计数和元数据计数不匹配,触发断言报错。
可用解决方案
方案1:临时快速规避,切换为单事件触发
将批量接收逻辑改为单条事件接收,避免绑定层批量解析的缺陷:
- 修改函数签名,去掉
List包裹:
from typing import BinaryIO, List import logging import json import psycopg2 import azure.functions as func def main(event: func.EventHubEvent): # 先判断消息体是否为空,直接跳过Tombstone消息 body = event.get_body() if not body: logging.info("检测到空Tombstone消息,已跳过") return logging.debug('New event detected') logging.debug('Event message: %s', body.decode('utf-8')) row = json.loads(body.decode('utf-8')) # 后续业务逻辑
- 修改触发器配置文件
function.json,将cardinality参数设置为one:
{ "type": "eventHubTrigger", "name": "event", "direction": "in", "eventHubName": "你的Event Hub名称", "connection": "你的连接字符串配置项名称", "cardinality": "one", "consumerGroup": "$Default" }
方案2:从数据源侧关闭Tombstone消息生成
如果你的业务不需要Kafka日志压缩特性,可以直接在Debezium PostgreSQL连接器的配置中添加参数tombstones.on.delete=false,删除操作只会生成一条带有效负载的删除事件,不会产生后续的空Tombstone消息,从根源上避免空消息流入Event Hub。
方案3:升级运行时修复缺陷
该绑定层bug在新版Azure Functions运行时中已经修复,你可以将函数运行时升级到4.x版本,同时更新Python Worker扩展到最新版,即可继续使用批量接收逻辑,只需要在循环中增加空消息判断即可:
def main(events: List[func.EventHubEvent]): for event in events: body = event.get_body() # 跳过空的Tombstone消息 if not body: continue # 后续正常处理逻辑 logging.debug('Event message: %s', body.decode('utf-8')) row = json.loads(body.decode('utf-8'))
内容的提问来源于stack exchange,提问作者Tcheslav Tcheslav
相关产品推荐
相关产品推荐

