首页 > 解决方案 > 在 Azure 数据工厂中运行数据流比在 Azure SSIS 数据流中运行慢 4 倍

问题描述

下面是这个性能测试的细节(很简单)。我试图了解为什么在云原生 Azure 数据工厂环境 (Spark) 中运行数据流比运行在 Azure SSIS IR 中托管的数据流慢得多。我的结果表明,在最新的 ADFv2 中运行比在 Azure SSIS 中运行完全相同的数据流慢 4 倍以上(即使暖 IR 集群已经从之前的运行中预热)。我喜欢 v2 数据流的所有新功能,但除非我完全遗漏了某些东西,否则性能上的损失似乎不值得。最终,我将添加更复杂的数据流,但想了解基本性能行为。

来源:存储在 blob 存储中的 1GB CSV

目标:Azure SQL Server 数据库(一个表并在每次运行前截断)

在使用简单 CopyActivity 的 ADFv2 中使用控制流时(无数据流)

91 秒

将本机 SSIS 包与数据流(从同一 blob 存储中提取的 Azure 功能包)一起使用时,运行具有 8 个内核的 Azure SSIS。

76 秒

Pure ADF Cloud Pipeline 使用 DataFlow 和温暖的 Azure IR(从以前的运行中缓存) 8 个(+ 8 个驱动程序核心)和默认分区(Spark)(包括 96 秒的集群启动,这是我不明白的另一件事,因为 TTL 是 30 分钟在 IR 上,它只是在 10 分钟前运行)

360 秒

管道(LandWithCopy)

{“名称”:“LandWithCopy”,“属性”:{“活动”:[{“名称”:“CopyData”,“类型”:“复制”,“dependsOn”:[],“策略”:{“超时": "7.00:00:00", "retry": 0, "retryIntervalInSeconds": 30, "secureOutput": false, "secureInput": false }, "userProperties": [], "typeProperties": { "source" : { "type": "DelimitedTextSource", "storeSettings": { "type": "AzureBlobStorageReadSettings", "recursive": true, "wildcardFileName": "data.csv", "enablePartitionDiscovery": false }, "formatSettings": { "type": "DelimitedTextReadSettings" } }, “汇”:{“类型”:“AzureSqlSink”,“preCopyScript”:“TRUNCATE TABLE PatientAR”,“disableMetricsCollection”:假},“enableStaging": false, "translator": { "type": "TabularTranslator", "mappings": [ { "source": { "name": "RecordAction", "type": "String" }, "sink": {“名称”:“RecordAction”,“类型”:“字符串”}},{“来源”:{“名称”:“UniqueId”,“类型”:“字符串”},“接收器”:{“名称”:“UniqueId”,“类型”:“字符串”}},{“来源”:{“名称” :“类型”,“类型”:“字符串”},“接收器”:{“名称”:“类型”,"type": "String" } }, { "source": { "name": "TypeDescription", "type": "String" }, "sink": { "name": "TypeDescription", "type": “字符串”}},{“来源”:{“名称”:“PatientId”,“type”:“String”},“sink”:{“name”:“PatientId”,“type”:“String”}},{“source”:{“name”:“PatientVisitId”,“type”: “字符串”},“接收器”:{“名称”:“PatientVisitId”,“类型”:“字符串”} },{“来源”:{“名称”:“访问日期服务”,“类型”:“字符串”},“接收器”:{“名称”:“访问日期服务”,“类型”:“字符串”}},{ “来源”:{“名称”:“VisitDateOfEntry”,“类型”:“字符串”}, "sink": { "name": "VisitDateOfEntry", "type": "String" } }, { "source": { "name": "DoctorId", "type": "String" }, "sink ": { "name": "DoctorId", "type": "String" } },{ "source": { "name": "DoctorName", "type": "String" }, "sink": { "name": "DoctorName", "type": "String" } }, { "source" : { "name": "FacilityId", "type": "String" }, "sink":{“名称”:“FacilityId”,“类型”:“字符串”}},{“来源”:{“名称”:“设施名称”,“类型”:“字符串”},“接收器”:{“名称” :“设施名称”,“类型”:“字符串”}},{“来源”:{“名称”:“公司名称”,“类型”:“字符串”},“接收器”:{“名称”:“公司名称”,“类型”:“字符串”}},{“来源”:{“名称” : "TicketNumber", "type": "String" }, "sink": { "name": "TicketNumber", "type": "String" } }, { "source": { "name": "TransactionDateOfEntry", "type": "String" }, "sink": { "name": "TransactionDateOfEntry", "类型”:“字符串”}},{“来源”:{“名称”:“内部代码”,“类型”:“字符串”},“接收器”:{“名称”:“内部代码”,“类型”:“字符串”}},{“源”:{“名称”:“外部代码”, “类型”:“字符串”},“接收器”:{“名称”:“外部代码”,“type": "String" } }, { "source": { "name": "Description", "type": "String" }, "sink": { "name": "Description", "type": "字符串“}},{“来源”:{“名称”:“费用”,“类型”:“String" }, "sink": { "name": "Fee", "type": "String" } }, { "source": { "name": "Units", "type": "String" }, “汇”:{“名称”:“单位”,“类型”:“字符串”}},{ "source": { "name": "AREffect", "type": "String" }, "sink": { "name": "AREffect", "type": "String" } }, { "source" : { "name": "Action", "type": "String" }, "sink":{ "name": "Action", "type": "String" } }, { "source": { "name": "InsuranceGroup", "type": "String" }, "sink": { "name" : "InsuranceGroup", "type": "String" } }, { "source":{“名称”:“付款人”,“类型”:“字符串”},“汇”:{“名称”:“付款人”,“类型”:“字符串”}},{“来源”:{“名称” : "PayerType", "type": "String" }, "sink": { "name": "PayerType",“类型”:“字符串”} },{“来源”:{“名称”:“PatBalance”,“类型”:“字符串”},“接收器”:{“名称”:“PatBalance”,“类型”: “字符串”}},{“来源”:{“名称”:“InsBalance”,“type”:“String”},“sink”:{“name”:“InsBalance”,“type”:“String”}},{“source”:{“name”:“Charges”,“type”: "String" }, "sink": { "name": "Charges", "type": "String"} },{“来源”:{“名称”:“付款”,“类型”:“字符串”},“接收器”:{“名称”:“付款”,“类型”:“字符串”}},{ “来源”:{“名称”:“调整”,“类型”:“字符串”}, "sink": { "name": "Adjustments", "type": "String" } }, { "source": { "name": "TransferAmount", "type": "String" }, "sink ": { "name": "TransferAmount", "type": "String" } },{“来源”:{“名称”:“归档数量”,“类型”:“字符串”},“接收器”:{“名称”:“归档数量”,“类型”:“字符串”}},{“来源” : { "name": "CheckNumber", "type": "String" }, "sink": { "name": "CheckNumber", "type": "String" } }, { "source": { "name": "CheckDate", "type": "String" }, "sink": { "name ": "CheckDate", "type": "String" } }, { "source":{“名称”:“创建”,“类型”:“字符串”},“接收器”:{“名称”:“创建”,“类型”:“字符串”}},{“源”:{“名称” : "ClientTag", "type": "String" }, "sink": { "name": "ClientTag",“类型”:“字符串”} } ] } },“输入”:[{“referenceName”:“PAR_Source_DS”,“类型”:“DatasetReference”}],“输出”:[{“referenceName”:“PAR_Sink_DS” , "类型": "数据集引用" } ] } ], "注释": [] } }} } ] } },“输入”:[{“referenceName”:“PAR_Source_DS”,“type”:“DatasetReference”}],“输出”:[{“referenceName”:“PAR_Sink_DS”,“type”:“DatasetReference " } ] } ], "注解": [] } }} } ] } },“输入”:[{“referenceName”:“PAR_Source_DS”,“type”:“DatasetReference”}],“输出”:[{“referenceName”:“PAR_Sink_DS”,“type”:“DatasetReference " } ] } ], "注解": [] } }[ {“referenceName”:“PAR_Source_DS”,“type”:“DatasetReference”}],“输出”:[{“referenceName”:“PAR_Sink_DS”,“type”:“DatasetReference”}]}],“注释”: [] } }[ {“referenceName”:“PAR_Source_DS”,“type”:“DatasetReference”}],“输出”:[{“referenceName”:“PAR_Sink_DS”,“type”:“DatasetReference”}]}],“注释”: [] } }“类型”:“数据集引用”}]}],“注释”:[]}}“类型”:“数据集引用”}]}],“注释”:[]}}

管道数据流 (LandWithFlow) { "name": "WriteData", "properties": { "type": "MappingDataFlow", "typeProperties": { "sources": [ { "dataset": { "referenceName": "PAR_Source_DS ", "type": "DatasetReference" }, "name": "GetData" } ], "sinks": [ { "dataset": { "referenceName": "PAR_Sink_DS", "type": "DatasetReference" }, "name": "WriteData" } ], "transformations": [], "script": "source(output(\n\t\tRecordAction as string,\n\t\tUniqueId as string,\n\t\tType as字符串,\n\t\tTypeDescription 作为字符串,\n\t\tPatientId 作为字符串,\n\t\tPatientVisitId 作为字符串,\n\t\tVisitDateOfService 作为字符串,\n\t\tVisitDateOfEntry 作为字符串,\n\ t\tDoctorId 作为字符串,\n\t\tDoctorName 作为字符串,\n\t\tFacilityId 作为字符串,\n\t\tFacilityName 作为字符串,\n\t\tCompanyName 作为字符串,\n\t\tTicketNumber 作为字符串,\n\t\tTransactionDateOfEntry 作为字符串,\n\t\tInternalCode 作为字符串,\n\t\tExternalCode 作为字符串,\n\t\tDescription 作为字符串,\n\t\tFee 作为字符串,\n\t \tUnits 作为字符串,\n\t\tAREffect 作为字符串,\n\t\tAction 作为字符串,\n\t\tInsuranceGroup 作为字符串,\n\t\tPayer 作为字符串,\n\t\tPayerType 作为字符串,\n\t\tPatBalance 作为字符串,\n\t\tInsBalance 作为字符串,\n\t\tCharges 作为字符串,\n\t\tPayments 作为字符串,\n\t\tAdjustments 作为字符串,\n\t\ tTransferAmount 作为字符串,\n\t\tFiledAmount 作为字符串,\n\t\tCheckNumber 作为字符串,\n\t\tCheckDate 作为字符串,\n\t\tCreated 作为字符串,\n\t\tClientTag 作为字符串\n \t),\n\tallowSchemaDrift: true,\n\tvalidateSchema: false,\n\twildcardPaths:['data.csv']) ~> GetData\nGetData sink(input(\n\t\tRecordAction as string,\ n\t\tUniqueId 作为字符串,\n\t\tType 作为字符串,\n\t\tTypeDescription 作为字符串,\n\t\tPatientId 作为字符串,\n\t\tPatientVisitId 作为字符串,\n\t\tVisitDateOfService作为字符串,\n\t\tVisitDateOfEntry 作为字符串,\n\t\tDoctorId 作为字符串,\n\t\tDoctorName 作为字符串,\n\t\tFacilityId 作为字符串,\n\t\tFacilityName 作为字符串,\n \t\tCompanyName 作为字符串,\n\t\tTicketNumber 作为字符串,\n\t\tTransactionDateOfEntry 作为字符串,\n\t\tInternalCode 作为字符串,\n\t\tExternalCode 作为字符串,\n\t\tDescription 作为字符串,\n\t\tFee 作为字符串,\n\t\ tUnits 作为字符串,\n\t\tAREffect 作为字符串,\n\t\tAction 作为字符串,\n\t\tInsuranceGroup 作为字符串,\n\t\tPayer 作为字符串,\n\t\tPayerType 作为字符串,\ n\t\tPatBalance 作为字符串,\n\t\tInsBalance 作为字符串,\n\t\tCharges 作为字符串,\n\t\tPayments 作为字符串,\n\t\tAdjustments 作为字符串,\n\t\tTransferAmount作为字符串,\n\t\tFiledAmount 作为字符串,\n\t\tCheckNumber 作为字符串,\n\t\tCheckDate 作为字符串,\n\t\t创建为字符串,\n\t\tClientTag 作为字符串,\n \t\tFileName 作为字符串,\n\t\tPractice 作为字符串\n\t),\n\tallowSchemaDrift: true,\n\tvalidateSchema: false,\n\tdeletable:false,\n\tinsertable:true,\ n\tupdateable:false,\n\tupsertable:false,\n\tformat: 'table',\n\tpreSQLs:['TRUNCATE TABLE PatientAR'],\n\tmapColumn(\n\t\tRecordAction,\n\t\tUniqueId,\n\t\tType,\n\t\tTypeDescription,\n\t\tPatientId,\n\t\tPatientVisitId,\n\ t\tVisitDateOfService,\n\t\tVisitDateOfEntry,\n\t\tDoctorId,\n\t\tDoctorName,\n\t\tFacilityId,\n\t\tFacilityName,\n\t\tCompanyName,\n\t \tTicketNumber,\n\t\tTransactionDateOfEntry,\n\t\tInternalCode,\n\t\tExternalCode,\n\t\tDescription,\n\t\tFee,\n\t\tUnits,\n\t\ tAREffect,\n\t\tAction,\n\t\tInsuranceGroup,\n\t\tPayer,\n\t\tPayerType,\n\t\tPatBalance,\n\t\tInsBalance,\n\t\tCharges ,\n\t\tPayments,\n\t\tAdjustments,\n\t\tTransferAmount,\n\t\tFiledAmount,\n\t\tCheckNumber,\n\t\tCheckDate,\n\t\tCreated, \n\t\tClientTag\n\t),\n\tskipDuplicateMapInputs: true,\n\tskipDuplicateMapOutputs: true) ~> WriteData" } } }\n\t\tPatientVisitId,\n\t\tVisitDateOfService,\n\t\tVisitDateOfEntry,\n\t\tDoctorId,\n\t\tDoctorName,\n\t\tFacilityId,\n\t\tFacilityName,\ n\t\tCompanyName,\n\t\tTicketNumber,\n\t\tTransactionDateOfEntry,\n\t\tInternalCode,\n\t\tExternalCode,\n\t\tDescription,\n\t\tFee,\n \t\tUnits,\n\t\tAREffect,\n\t\tAction,\n\t\tInsuranceGroup,\n\t\tPayer,\n\t\tPayerType,\n\t\tPatBalance,\n\ t\tInsBalance,\n\t\tCharges,\n\t\tPayments,\n\t\tAdjustments,\n\t\tTransferAmount,\n\t\tFiledAmount,\n\t\tCheckNumber,\n\t \tCheckDate,\n\t\tCreated,\n\t\tClientTag\n\t),\n\tskipDuplicateMapInputs: true,\n\tskipDuplicateMapOutputs: true) ~> WriteData" } } }\n\t\tPatientVisitId,\n\t\tVisitDateOfService,\n\t\tVisitDateOfEntry,\n\t\tDoctorId,\n\t\tDoctorName,\n\t\tFacilityId,\n\t\tFacilityName,\ n\t\tCompanyName,\n\t\tTicketNumber,\n\t\tTransactionDateOfEntry,\n\t\tInternalCode,\n\t\tExternalCode,\n\t\tDescription,\n\t\tFee,\n \t\tUnits,\n\t\tAREffect,\n\t\tAction,\n\t\tInsuranceGroup,\n\t\tPayer,\n\t\tPayerType,\n\t\tPatBalance,\n\ t\tInsBalance,\n\t\tCharges,\n\t\tPayments,\n\t\tAdjustments,\n\t\tTransferAmount,\n\t\tFiledAmount,\n\t\tCheckNumber,\n\t \tCheckDate,\n\t\tCreated,\n\t\tClientTag\n\t),\n\tskipDuplicateMapInputs: true,\n\tskipDuplicateMapOutputs: true) ~> WriteData" } } }\n\t\tExternalCode,\n\t\tDescription,\n\t\tFee,\n\t\tUnits,\n\t\tAREffect,\n\t\tAction,\n\t\tInsuranceGroup,\ n\t\tPayer,\n\t\tPayerType,\n\t\tPatBalance,\n\t\tInsBalance,\n\t\tCharges,\n\t\tPayments,\n\t\tAdjustments,\n \t\tTransferAmount,\n\t\tFiledAmount,\n\t\tCheckNumber,\n\t\tCheckDate,\n\t\tCreated,\n\t\tClientTag\n\t),\n\tskipDuplicateMapInputs:真,\n\tskipDuplicateMapOutputs: 真) ~> WriteData" } } }\n\t\tExternalCode,\n\t\tDescription,\n\t\tFee,\n\t\tUnits,\n\t\tAREffect,\n\t\tAction,\n\t\tInsuranceGroup,\ n\t\tPayer,\n\t\tPayerType,\n\t\tPatBalance,\n\t\tInsBalance,\n\t\tCharges,\n\t\tPayments,\n\t\tAdjustments,\n \t\tTransferAmount,\n\t\tFiledAmount,\n\t\tCheckNumber,\n\t\tCheckDate,\n\t\tCreated,\n\t\tClientTag\n\t),\n\tskipDuplicateMapInputs:真,\n\tskipDuplicateMapOutputs: 真) ~> WriteData" } } }} } }} } }

标签: azure-data-factory-2

解决方案


我们有同样的问题。没有数据流的复制活动比数据流快得多。我们的案例是复制活动与数据流。不确定我是否做错了什么。

我们的场景只是根据 where 子句从 Source 复制到 Destination 13 表。我们现在有两个复制活动,需要 1.5 分钟。所以我在想可能是创建数据流并做一个源两个接收器。但它的运行时间为 5 分钟到 8 分钟,具体取决于集群启动时间。希望我们能得到答案。


推荐阅读