다음을 통해 공유


Databricks Runtime 7.x 마이그레이션 가이드(EoS)

참고 항목

이 Databricks Runtime 버전에 대한 지원이 종료되었습니다. 지원 종료 날짜는 지원 종료 기록을 참조하세요. 지원되는 모든 Databricks Runtime 버전은 Databricks Runtime 릴리스 정보 버전 및 호환성을 참조하세요.

이 가이드에서는 Azure Databricks 워크로드를 Apache Spark 2.4 에서 빌드된 Databricks Runtime 6.x에서 Spark 3.0을 기반으로 하는 Databricks Runtime 7.3 LTS(EoS)로 마이그레이션하는 데 도움이 되는 지침을 제공합니다.

이 가이드에는 Azure Databricks 워크로드를 업데이트해야 할 수 있는 Spark 3.0 동작 변경 내용이 나와 있습니다. 이러한 변경 내용 중 일부에는 완전한 Python 2 지원 제거, Scala 2.12로 업그레이드, JDK 11에 대한 완전한 지원, 날짜 및 타임스탬프에 대한 그레고리력에서 Proleptic 달력으로의 전환이 포함됩니다.

이 가이드는 Databricks Runtime 7.3 LTS(EoS) 마이그레이션 가이드의 도우미입니다.

Databricks Runtime 7.x에서 사용 가능한 새로운 기능 및 향상된 기능

Databricks Runtime 7.3 LTS에 포함된 새로운 기능, 개선 사항 및 라이브러리 업그레이드 목록은 마이그레이션하려는 버전보다 위에 있는 각 Databricks 런타임 버전에 대한 릴리스 정보를 참조하세요. 지원되는 Databricks Runtime 7.x 버전은 다음과 같습니다.

릴리스 후 유지 관리 업데이트는 Databricks 런타임(보관됨)에 대한 유지 관리 업데이트에 나열됩니다.

Databricks Runtime 7.3 LTS 시스템 환경

  • 운영 체제: Ubuntu 18.04.5 LTS
  • Java:
    • 7.3 LTS: Zulu 8.48.0.53-CA-linux64(빌드 1.8.0_265-b11)
  • Scala: 2.12.10
  • Python: 3.7.5
  • R: 3.6.3(2020-02-29)
  • Delta Lake 0.7.0

Apache Spark 3.0의 주요 동작 변경 내용

다음 동작이 Spark 2.4에서 Spark 3.0으로 변경되는 경우 Databricks Runtime 6.x에서 Databricks Runtime 7.x로 마이그레이션할 때 Azure Databricks 워크로드를 업데이트해야 할 수 있습니다.

참고 항목

이 문서에서는 Databricks Runtime 7.x로 마이그레이션하는 경우 고려해야 할 중요한 Spark 동작 변경 내용 목록을 제공합니다.

핵심

  • Spark 3.0에서는 더 이상 사용되지 않는 누적기 v1이 제거됩니다.
  • 이벤트 로그 파일은 UTF-8 인코딩으로 작성되고, Spark 기록 서버에서 이벤트 로그 파일을 UTF-8 인코딩으로 재생합니다. 이전에는 Spark에서 이벤트 로그 파일을 드라이버 JVM 프로세스의 기본 문자 집합으로 작성했으므로 인코딩이 호환되지 않는 경우 이전 이벤트 로그 파일을 읽으려면 Spark 2.x의 Spark 기록 서버가 필요합니다.
  • 순서 섞기 블록을 가져오기 위한 새 프로토콜이 사용됩니다. Spark 3.0 앱을 실행하는 경우 외부 순서 섞기 서비스를 업그레이드하는 것이 좋습니다. spark.shuffle.useOldFetchProtocol 구성을 true로 설정하면 이전 외부 순서 섞기 서비스를 계속 사용할 수 있습니다. 그렇지 않으면 Spark에서 IllegalArgumentException: Unexpected message type: <number>과 같은 메시지와 함께 오류가 발생할 수 있습니다.

PySpark

  • Spark 3.0에서 Column.getItemColumn.apply를 호출하지 않도록 수정되었습니다. 따라서 ColumngetItem에 대한 인수로 사용되는 경우 인덱싱 연산자를 사용해야 합니다. 예를 들어 map_col.getItem(col('id'))map_col[col('id')]로 바꿔야 합니다.
  • Spark 3.0부터 Row 필드 이름은 Python 버전 3.6 이상에 대해 명명된 인수를 사용하여 생성할 때 더 이상 사전순으로 정렬되지 않으며 필드 순서는 입력한 순서와 일치합니다. Spark 2.4에서와 같이 기본적으로 정렬된 필드를 사용하도록 설정하려면 실행기와 드라이버 모두에 대해 PYSPARK_ROW_FIELD_SORTING_ENABLED 환경 변수를 true로 설정합니다. 이 환경 변수는 모든 실행기와 드라이버에서 일관되어야 합니다. 그렇지 않으면 실패 또는 잘못된 답변이 발생할 수 있습니다. Python 버전 3.6보다 낮은 경우 필드 이름은 유일한 옵션으로 사전순으로 정렬됩니다.
  • Python 2 지원이 더 이상 사용되지 않습니다(SPARK-27884).

구조적 스트리밍

  • 텍스트, json, csv, parquet 및 orc와 같은 파일 기반 데이터 원본이 spark.readStream(...)을 통해 사용되는 경우 Spark 3.0에서 구조적 스트리밍은 강제로 원본 스키마를 null 허용으로 적용합니다. ,이전에는 원본 스키마의 Null 허용 여부를 준수했지만 NPE를 사용하여 디버그하는 데 까다로운 문제가 발생했습니다. 이전 동작을 복원하려면 spark.sql.streaming.fileSource.schema.forceNullablefalse로 설정합니다.
  • Spark 3.0에서 상태 스키마를 변경하는 스트림-스트림 외부 조인의 정확성 문제가 해결되었습니다. 자세한 내용은 SPARK-26154를 참조하세요. 스트림-스트림 외부 조인을 사용하는 Spark 2.x에서 생성된 검사점에서 쿼리를 시작하면 Spark 3.0이 쿼리에 실패합니다. 출력을 다시 계산하려면 검사점을 버리고 이전 입력을 재생합니다.
  • Spark 3.0에서는 더 이상 사용되지 않는 클래스 org.apache.spark.sql.streaming.ProcessingTime이 제거되었습니다. 대신 org.apache.spark.sql.streaming.Trigger.ProcessingTime를 사용하세요. 마찬가지로 org.apache.spark.sql.execution.streaming.continuous.ContinuousTriggerTrigger.Continuous를 위해 제거되고 org.apache.spark.sql.execution.streaming.OneTimeTriggerTrigger.Once를 위해 숨겨졌습니다. SPARK-28199를 참조하세요.

SQL, 데이터 세트 및 DataFrame

  • Spark 3.0에서 값을 데이터 형식이 다른 테이블 열에 삽입하는 경우 ANSI SQL 표준에 따라 형식 강제 변환이 수행됩니다. stringint로 변환하고 doubleboolean로 변환하는 것과 같은 불합리한 특정 형식 변환은 허용되지 않습니다. 값이 열의 데이터 형식 범위를 벗어나면 런타임 예외가 throw됩니다. Spark 버전 2.4 이하에서는 테이블 삽입 중 형식 변환이 유효한 Cast이면 허용됩니다. 범위를 벗어난 값을 정수 필드에 삽입하면 값의 하위 비트가 삽입됩니다(Java/Scala 숫자 형식 캐스팅과 동일). 예를 들어 257을 바이트 형식의 필드에 삽입하면 결과는 1입니다. 동작은 spark.sql.storeAssignmentPolicy 옵션으로 제어되며 기본값은 "ANSI"입니다. 옵션을 "Legacy"로 설정하면 이전 동작이 복원됩니다.
  • Spark 3.0에서 문자열 값을 정수 형식(tinyint, smallint, int 및 bigint), 날짜/시간 형식(날짜, 타임스탬프 및 간격) 및 부울 형식으로 캐스팅하는 경우 이러한 형식 값으로 변환되기 전에 선행 및 후행 공백(<= ACSII 32)이 잘립니다. 예를 들어 cast(' 1\t' as int)1을 반환하고, cast(' 1\t' as boolean)true를 반환하고, cast('2019-10-10\t as date)2019-10-10 날짜 값을 반환합니다. Spark 버전 2.4 및 이전 버전에서는 문자열을 정수 및 부울로 캐스팅하는 동안 양쪽 끝에서 공백을 자르지 않으며, 앞의 결과는 null이지만 날짜/시간까지 후행 공백(= ASCII 32)만 제거됩니다. https://databricks.com/blog/2020/07/22/a-comprehensive-look-at-dates-and-timestamps-in-apache-spark-3-0.html을 참조하세요.
  • Spark 3.0에서 더 이상 사용되지 않는 SQLContext.createExternalTableSparkSession.createExternalTable 메서드가 createTable로 대체하기 위해 제거되었습니다.
  • Spark 3.0에서 spark.sql.crossJoin.enabled 구성은 내부 구성이 되고 기본적으로 true이므로 Spark는 기본적으로 암시적 크로스 조인을 사용하는 SQL에 대한 예외를 발생시키지 않습니다.
  • Spark 3.0에서 trim 함수의 인수 순서가 다른 데이터베이스와 호환되도록 TRIM(trimStr, str)에서 TRIM(str, trimStr)으로 반전되었습니다.
  • Spark 버전 2.4 이하에서는 FROM <table> 또는 FROM <table> UNION ALL FROM <table>과 같은 SQL 쿼리가 실수로 지원됩니다. FROM <table> SELECT <expr> hive 스타일에서 SELECT 절은 무시할 수 없습니다. 이 구문은 Hive와 Presto 모두에서 지원하지 않습니다. 따라서 Spark 3.0부터 이러한 쿼리를 유효하지 않은 것으로 처리합니다.
  • Spark 3.0부터 unionAll Dataset 및 DataFrame API는 더 이상 사용되지 않습니다. 이는 union에 대한 별칭입니다.
  • Spark 버전 2.4 이하에서는 JSON 데이터 원본의 파서에서 IntegerType과 같은 일부 데이터 형식에 대해 빈 문자열을 null로 처리합니다. FloatTypeDoubleType의 경우 빈 문자열에서 실패하고 예외를 throw합니다. Spark 3.0부터 빈 문자열을 허용하지 않으며 StringTypeBinaryType를 제외한 데이터 형식에 대해 예외를 throw합니다.
  • Spark 3.0부터 from_json 함수는 PERMISSIVEFAILFAST의 두 가지 모드를 지원합니다. 이러한 모드는 mode 옵션을 통해 설정할 수 있습니다. 기본 모드는 PERMISSIVE입니다. 이전 버전에서는, 특히 형식이 잘못된 JSON 레코드를 처리할 때 from_json의 동작이 PERMISSIVE 또는 FAILFAST,와 일치하지 않았습니다. 예를 들어 스키마가 a INT{"a" 1} JSON 문자열은 이전 버전에서 null로 변환되지만, Spark 3.0에서는 Row(null)로 변환됩니다.

DDL 문

  • Spark 3.0에서 특정 공급자가 없는 CREATE TABLEspark.sql.sources.default 값을 공급자로 사용합니다. Spark 버전 2.4 이하에서는 Hive였습니다. Spark 3.0 이전의 동작을 복원하려면 spark.sql.legacy.createHiveTableByDefault.enabledtrue로 설정할 수 있습니다.
  • Spark 3.0에서 값을 데이터 형식이 다른 테이블 열에 삽입하는 경우 ANSI SQL 표준에 따라 형식 강제 변환이 수행됩니다. stringint로 변환하고 doubleboolean로 변환하는 것과 같은 불합리한 특정 형식 변환은 허용되지 않습니다. 값이 열의 데이터 형식 범위를 벗어나면 런타임 예외가 throw됩니다. Spark 버전 2.4 이하에서는 테이블 삽입 중 형식 변환이 유효한 Cast이면 허용됩니다. 범위를 벗어난 값을 정수 필드에 삽입하면 값의 하위 비트가 삽입됩니다(Java/Scala 숫자 형식 캐스팅과 동일). 예를 들어 257을 바이트 형식의 필드에 삽입하면 결과는 1입니다. 동작은 spark.sql.storeAssignmentPolicy 옵션으로 제어되며 기본값은 "ANSI"입니다. 옵션을 "Legacy"로 설정하면 이전 동작이 복원됩니다.
  • Spark 3.0에서 지정된 테이블이 Hive SerDe 테이블인 경우에도 SHOW CREATE TABLE은 항상 Spark DDL을 반환합니다. Hive DDL을 생성하려면 SHOW CREATE TABLE AS SERDE 명령을 대신 사용합니다.
  • Spark 3.0에서 CHAR 형식의 열은 Hive-Serde가 아닌 테이블에서 허용되지 않으며, CHAR 형식이 검색되면 CREATE/ALTER TABLE 명령이 실패합니다. 대신 STRING 형식을 사용하세요. Spark 버전 2.4 이하에서는 CHAR 형식이 STRING 형식으로 처리되고 length 매개 변수만 무시됩니다.

UDF 및 기본 제공 함수

  • Spark 3.0에서 org.apache.spark.sql.functions.udf(AnyRef, DataType)는 기본적으로 사용할 수 없습니다. 계속 사용하려면 spark.sql.legacy.allowUntypedScalaUDFtrue로 설정합니다. Spark 버전 2.4 이하에서는 org.apache.spark.sql.functions.udf(AnyRef, DataType)에서 기본 형식 인수가 있는 Scala 클로저를 가져오는 경우 입력 값이 null이면 반환되는 UDF에서 null을 반환합니다. 그러나 Spark 3.0에서 입력 값이 null이면 UDF에서 Java 형식의 기본값을 반환합니다. 예를 들어 x 열이 null인 경우 val f = udf((x: Int) => x, IntegerType), f($"x")는 Spark 2.4 이하에서 null을 반환하고 Spark 3.0에서는 0을 반환합니다. Spark 3.0이 기본적으로 Scala 2.12를 사용하여 빌드되므로 이 동작 변경이 도입되었습니다.
  • Spark 버전 2.4 이하에서는 CreateMap, StringToMap 등과 같은 기본 제공 함수를 통해 중복 키가 있는 맵을 만들 수 있습니다. 중복 키가 있는 맵의 동작은 정의되지 않습니다. 예를 들어 맵 조회는 중복 키가 먼저 표시되도록 고려하고, Dataset.collect는 중복 키만 마지막에 표시되도록 유지하고, MapKeys는 중복 키를 반환합니다. Spark 3.0에서 중복 키가 검색되면 Spark에서 RuntimeException를 throw합니다. spark.sql.mapKeyDedupPolicyLAST_WIN으로 설정하여 마지막 승리 정책을 사용하여 맵 키를 중복 제거할 수 있습니다. 사용자는 여전히 이를 적용하지 않는 데이터 원본(예: Parquet)에서 중복 키가 있는 맵 값을 읽을 수 있습니다. 동작은 정의되지 않습니다.

Data Sources

  • Spark 버전 2.4 이하에서 파티션 열 값은 해당 사용자 제공 스키마로 캐스팅할 수 없는 경우 null로 변환됩니다. 3.0에서는 사용자가 제공한 스키마를 사용하여 파티션 열 값의 유효성이 검사됩니다. 유효성 검사가 실패하면 예외가 throw됩니다. spark.sql.sources.validatePartitionColumnsfalse로 설정하여 이러한 유효성 검사를 사용하지 않도록 설정할 수 있습니다.
  • Spark 버전 2.4 이하에서 JSON 데이터 원본의 파서는 IntegerType과 같은 일부 데이터 형식에 대해 빈 문자열을 null로 처리합니다. FloatType, DoubleType, DateTypeTimestampType의 경우 빈 문자열에서 실패하고 예외를 throw합니다. Spark 3.0에서는 빈 문자열을 허용하지 않으며 StringTypeBinaryType를 제외한 데이터 형식에 대해 예외를 throw합니다. 빈 문자열을 허용하는 이전 동작은 spark.sql.legacy.json.allowEmptyString.enabledtrue로 설정하여 복원할 수 있습니다.
  • Spark 3.0에서 재귀 디렉터리를 나열하는 중에 파일 또는 하위 디렉터리가 사라지는 경우(즉, 중간 목록에 표시되지만 동시 파일 삭제 또는 개체 저장소 일관성 문제로 인해 재귀 디렉터리 나열의 이후 단계에서 읽거나 나열할 수 없음) spark.sql.files.ignoreMissingFilestrue(기본값 false)가 아니면 예외와 함께 목록이 실패합니다. 이전 버전에서는 이러한 누락된 파일 또는 하위 디렉터리가 무시되었습니다. 이 동작 변경은 쿼리 실행이 아니라 초기 테이블 파일 나열 동안(또는 REFRESH TABLE 동안)에만 적용됩니다. 최종적으로 이제는 쿼리 실행 시간뿐만 아니라 테이블 파일 나열 및 쿼리 계획 중에도 spark.sql.files.ignoreMissingFiles가 적용되도록 변경되었습니다.
  • Spark 버전 2.4 이하에서 CSV 데이터 원본은 잘못된 형식의 CSV 문자열을 PERMISSIVE 모드의 모든 null이 포함된 행으로 변환합니다. Spark 3.0에서는 일부 CSV 열 값이 성공적으로 구문 분석되고 원하는 형식으로 변환된 경우 반환되는 행에 null이 아닌 필드가 포함될 수 있습니다.
  • Spark 3.0에서 TIMESTAMP 열을 저장하는 동안 TIMESTAMP_MICROS parquet 논리 형식이 기본적으로 사용됩니다. Spark 버전 2.4 이하에서는 TIMESTAMP 열이 INT96으로 parquet 파일에 저장됩니다. Hive 1.x 및 Impala 2.x와 같은 일부 SQL 시스템에서 INT96 타임스탬프만 읽을 수 있습니다. spark.sql.parquet.outputTimestampTypeINT96로 설정하여 이전 동작을 복원하고 상호 운용성을 유지할 수 있습니다.
  • Spark 3.0에서 Avro 파일이 사용자 제공 스키마를 사용하여 작성되는 경우 필드는 위치 대신 촉매 스키마와 Avro 스키마 간의 필드 이름과 일치합니다.

쿼리 엔진

  • Spark 3.0에서 자체 조인으로 인해 발생하는 모호한 열 참조가 포함되면 Dataset 쿼리가 실패합니다. 일반적인 예제(val df1 = ...; val df2 = df1.filter(...);, then df1.join(df2, df1("a") > df2("a")))에서 매우 혼란스러운 빈 결과를 반환합니다. 이는 Spark에서 자체 조인되는 테이블을 가리키는 Dataset 열 참조를 확인할 수 없고 df1("a")이 Spark의 df2("a")와 정확히 동일하기 때문입니다. Spark 3.0 이전의 동작을 복원하려면 spark.sql.analyzer.failAmbiguousSelfJoinfalse로 설정할 수 있습니다.
  • Spark 3.0에서 과학적 표기법으로 작성된 숫자(예: 1E2)는 Double로 구문 분석됩니다. Spark 버전 2.4 이하에서는 Decimal로 구문 분석됩니다. Spark 3.0 이전의 동작을 복원하려면 spark.sql.legacy.exponentLiteralAsDecimal.enabledtrue로 설정할 수 있습니다.
  • Spark 3.0에서 spark.sql.crossJoin.enabled 구성은 내부 구성이 되며 기본적으로 true입니다. 기본적으로 Spark는 암시적 크로스 조인이 있는 SQL에서 예외를 발생시키지 않습니다.
  • Spark 버전 2.4 이하에서 float/double -0.0은 의미상 0.0과 같지만, -0.0과 0.0은 집계 그룹화 키, 창 파티션 키 및 조인 키에서 사용하는 경우 다른 값으로 간주됩니다. Spark 3.0에서 이 버그가 수정되었습니다. 예를 들어 Seq(-0.0, 0.0).toDF("d").groupBy("d").count()는 Spark 3.0에서 [(0.0, 2)]를 반환하고, Spark 2.4 이하에서는 [(0.0, 1), (-0.0, 1)]을 반환합니다.
  • Spark 3.0에서 TIMESTAMP 리터럴은 spark.sql.session.timeZone SQL 구성을 사용하여 문자열로 변환됩니다. Spark 버전 2.4 이하에서 변환은 Java 가상 머신의 기본 표준 시간대를 사용합니다.
  • Spark 3.0에서 Spark는 날짜/타임스탬프와의 이진 비교에서 StringDate/Timestamp로 캐스팅합니다. Date/TimestampString으로 캐스팅하는 이전 동작은 spark.sql.legacy.typeCoercion.datetimeToString.enabledtrue로 설정하여 복원할 수 있습니다.
  • Spark 버전 2.4 이하에서 잘못된 표준 시간대 ID는 자동으로 무시되고, 예를 들어 from_utc_timestamp 함수에서 GMT 표준 시간대로 대체됩니다. Spark 3.0에서 이러한 표준 시간대 ID는 거부되고 Spark에서 java.time.DateTimeException을 throw합니다.
  • Spark 3.0에서 Proleptic 그레고리력은 날짜 및 타임스탬프를 구문 분석, 형식 지정 및 변환하고 연도, 일 등과 같은 하위 구성 요소를 추출하는 데 사용됩니다. Spark 3.0은 ISO 연대기를 기반으로 하는 java.time 패키지의 Java 8 API 클래스를 사용합니다. Spark 버전 2.4 이하에서 이러한 작업은 하이브리드 달력(율리우스력 + 그레고리력)을 사용하여 수행됩니다. 변경 내용은 1582년 10월 15일(그레고리오리언) 이전 날짜의 결과에 영향을 미치며 다음 Spark 3.0 API에 영향을 줍니다.
    • 타임스탬프/날짜 문자열의 구문 분석/형식 지정. 이는 사용자가 지정한 패턴이 구문 분석 및 형식 지정에 사용되는 경우 CSV/JSON 데이터 원본 및unix_timestamp, date_format, to_unix_timestamp, from_unixtime, to_date, to_timestamp 함수에 영향을 줍니다. Spark 3.0에서 내부적으로 java.time.format.DateTimeFormatter를 통해 구현되는 자체 패턴 문자열은 sql-ref-datetime-pattern.md에 정의되어 있습니다. 새 구현은 입력을 엄격하게 검사합니다. 예를 들어 파서에서 전체 입력을 사용하지 않으므로 패턴이 yyyy-MM-dd이면 2015-07-22 10:00:00 타임스탬프를 구문 분석할 수 없습니다. 또 다른 예로 hh에서 1~12 범위의 시간을 미리 추정하므로 31/01/2015 00:00 입력을 dd/MM/yyyy hh:mm 패턴으로 구문 분석할 수 없습니다. Spark 버전 2.4 이하에서는 java.text.SimpleDateFormat이 타임스탬프/날짜 문자열 변환에 사용되며, 지원되는 패턴은 simpleDateFormat에 설명되어 있습니다. 이전 동작은 spark.sql.legacy.timeParserPolicyLEGACY로 설정하여 복원할 수 있습니다.
    • weekofyear, weekday, dayofweek, date_trunc, from_utc_timestamp, to_utc_timestampunix_timestamp 함수는 java.time API를 사용하여 변환을 위한 연도의 주 수, 주의 일 수를 계산하고 UTC 표준 시간대의 TimestampType 값에서/으로 변환합니다.
    • lowerBoundupperBound JDBC 옵션은 문자열을 TimestampType/DateType 값으로 캐스팅하는 것과 동일한 방식으로 TimestampType/DateType 값으로 변환됩니다. 변환은 Proleptic 그레고리력 및 spark.sql.session.timeZone SQL 구성에 의해 정의된 표준 시간대를 기반으로 합니다. Spark 버전 2.4 이하에서 변환은 하이브리드 달력(율리우스력 + 그레고리력) 및 기본 시스템 표준 시간대를 기반으로 합니다.
    • TIMESTAMPDATE 리터럴 형식 지정
    • 문자열에서 형식화된 TIMESTAMPDATE 리터럴 만들기. Spark 3.0에서 형식화된 TIMESTAMP/DATE 리터럴로의 문자열 변환은 TIMESTAMP/DATE 값으로의 캐스팅을 통해 수행됩니다. 예를 들어 TIMESTAMP '2019-12-23 12:59:30'은 의미상 CAST('2019-12-23 12:59:30' AS TIMESTAMP)와 같습니다. 입력 문자열에 표준 시간대에 대한 정보가 포함되지 않은 경우 spark.sql.session.timeZone SQL 구성의 표준 시간대가 사용됩니다. Spark 버전 2.4 이하에서 변환은 JVM 시스템 표준 시간대를 기반으로 합니다. 기본 표준 시간대의 다른 원본은 형식화된 TIMESTAMPDATE 리터럴의 동작을 변경할 수 있습니다.

Apache Hive

  • Spark 3.0에서는 다음과 같은 영향을 주는 기본 제공 Hive 버전을 1.2에서 2.3으로 업그레이드했습니다.
    • 연결하려는 Hive 메타스토어의 버전에 따라 spark.sql.hive.metastore.versionspark.sql.hive.metastore.jars를 설정해야 할 수도 있습니다. 예를 들어 Hive 메타스토어 버전이 1.2.1인 경우 spark.sql.hive.metastore.version1.2.1로 설정하고 spark.sql.hive.metastore.jarsmaven으로 설정합니다.
    • 사용자 지정 SerDe를 Hive 2.3으로 마이그레이션하거나 hive-1.2 프로필을 사용하여 사용자 고유의 Spark를 빌드해야 합니다. 자세한 내용은 HIVE-15167을 참조하세요.
    • hive의 동작에 따라 달라지는 스크립트 변환에 SQL의 TRANSFORM 연산자를 사용하는 경우 10진수 문자열 표현은 Hive 1.2와 Hive 2.3 간에 다를 수 있습니다. Hive 1.2에서 문자열 표현은 후행 0을 생략합니다. 그러나 Hive 2.3에서는 필요한 경우 후행 0을 사용하여 항상 18자리까지 채워집니다.
    • Databricks Runtime 7.x에서 Hive SerDe 테이블을 읽는 경우 기본적으로 Spark는 테이블 파티션이 아닌 하위 디렉터리에 있는 파일의 읽기를 허용하지 않습니다. 사용하도록 설정하려면 spark.databricks.io.hive.scanNonpartitionedDirectory.enabled 구성을 true로 설정합니다. 이렇게 하면 Spark 네이티브 테이블 판독기 및 파일 판독기에 영향을 주지 않습니다.

MLlib

  • 2.3에서 더 이상 사용되지 않는 OneHotEncoder는 3.0에서 제거되었으며, OneHotEncoderEstimator의 이름이 이제 OneHotEncoder로 변경되었습니다.
  • 2.3에서 더 이상 사용되지 않는 org.apache.spark.ml.image.ImageSchema.readImages는 3.0에서 제거되었습니다. 대신 spark.read.format('image')를 사용하세요.
  • 2.1에서 더 이상 사용되지 않고 param Int runs이 있는 org.apache.spark.mllib.clustering.KMeans.train은 3.0에서 제거되었습니다. 대신 실행이 없는 학습 메서드를 사용합니다.
  • 2.0에서 더 이상 사용되지 않는 org.apache.spark.mllib.classification.LogisticRegressionWithSGD는 3.0에서 제거되었습니다. 대신 org.apache.spark.ml.classification.LogisticRegression 또는 spark.mllib.classification.LogisticRegressionWithLBFGS를 사용합니다.
  • 2.1에서 더 이상 사용되지 않는 org.apache.spark.mllib.feature.ChiSqSelectorModel.isSorted는 3.0에서 제거되었으며 하위 클래스에서 사용할 수 없습니다.
  • 2.0에서 더 이상 사용되지 않는 org.apache.spark.mllib.regression.RidgeRegressionWithSGD는 3.0에서 제거되었습니다. elasticNetParam = 0.0이 있는 org.apache.spark.ml.regression.LinearRegression을 사용합니다. 기본 regParamRidgeRegressionWithSGD의 경우 0.01이지만 LinearRegression의 경우 0.0입니다.
  • 2.0에서 더 이상 사용되지 않는 org.apache.spark.mllib.regression.LassoWithSGD는 3.0에서 제거되었습니다. elasticNetParam = 1.0이 있는 org.apache.spark.ml.regression.LinearRegression을 사용합니다. 기본 regParamLassoWithSGD의 경우 0.01이지만 LinearRegression의 경우 0.0입니다.
  • 2.0에서 더 이상 사용되지 않는 org.apache.spark.mllib.regression.LinearRegressionWithSGD는 3.0에서 제거되었습니다. 대신 org.apache.spark.ml.regression.LinearRegression 또는 LBFGS를 사용하십시오.
  • 2.1에서 더 이상 사용되지 않는 org.apache.spark.mllib.clustering.KMeans.getRunssetRuns는 3.0에서 제거되었으며 Spark 2.0.0부터 아무런 효과가 없습니다.
  • 2.4에서 더 이상 사용되지 않는 org.apache.spark.ml.LinearSVCModel.setWeightCol은 3.0에서 제거되었으며 사용자를 위한 것이 아닙니다.
  • 3.0에서 org.apache.spark.ml.classification.MultilayerPerceptronClassificationModel은 학습 매개 변수를 공개하도록 MultilayerPerceptronParams를 확장합니다. 따라서 MultilayerPerceptronClassificationModellayersArray[Int]에서 IntArrayParam으로 변경되었습니다. 레이어 크기를 검색하려면 MultilayerPerceptronClassificationModel.layers 대신 MultilayerPerceptronClassificationModel.getLayers를 사용해야 합니다.
  • 2.4.5에서 더 이상 사용되지 않는 org.apache.spark.ml.classification.GBTClassifier.numTrees는 3.0에서 제거되었습니다. 대신 getNumTrees를 사용하세요.
  • 2.4에서 더 이상 사용되지 않는 org.apache.spark.ml.clustering.KMeansModel.computeCost는 3.0에서 제거되었습니다. 대신 ClusteringEvaluator를 사용합니다.
  • 2.0에서 더 이상 사용되지 않는 org.apache.spark.mllib.evaluation.MulticlassMetrics의 멤버 변수 정밀도는 3.0에서 제거되었습니다. 대신 정확도를 사용합니다.
  • 2.0에서 더 이상 사용되지 않는 org.apache.spark.mllib.evaluation.MulticlassMetrics의 멤버 변수 재호출은 3.0에서 제거되었습니다. 대신 accuracy를 사용하세요.
  • 2.0에서 더 이상 사용되지 않는 org.apache.spark.mllib.evaluation.MulticlassMetricsfMeasure 멤버 변수는 3.0에서 제거되었습니다. 대신 accuracy를 사용하세요.
  • 2.0에서 더 이상 사용되지 않는 org.apache.spark.ml.util.GeneralMLWriter.context는 3.0에서 제거되었습니다. 대신 session를 사용하세요.
  • 2.0에서 더 이상 사용되지 않는 org.apache.spark.ml.util.MLWriter.context는 3.0에서 제거되었습니다. 대신 session를 사용하세요.
  • 2.0에서 더 이상 사용되지 않는 org.apache.spark.ml.util.MLReader.context는 3.0에서 제거되었습니다. 대신 session를 사용하세요.
  • abstract class UnaryTransformer[IN, OUT, T <: UnaryTransformer[IN, OUT, T]]는 3.0에서 abstract class UnaryTransformer[IN: TypeTag, OUT: TypeTag, T <: UnaryTransformer[IN, OUT, T]]로 변경되었습니다.
  • Spark 3.0에서 Pyspark의 다중 클래스 로지스틱 회귀는 이제(정확하게) BinaryLogisticRegressionSummary 하위 클래스가 아니라 LogisticRegressionSummary를 반환합니다. 어쨌든 이 경우에는 BinaryLogisticRegressionSummary에서 공개한 추가 메서드가 작동하지 않습니다. (SPARK-31681)
  • Spark 3.0에서 pyspark.ml.param.shared.Has* mixin은 더 이상 set*(self, value) setter 메서드를 제공하지 않으며 대신 해당 self.set(self.*, value)을 사용합니다. 자세한 내용은 SPARK-29093을 참조하세요. (SPARK-29093)

기타 동작 변경

  • Scala 2.12로의 업그레이드에 포함된 변경 내용은 다음과 같습니다.

    • 패키지 셀 직렬화가 다르게 처리됩니다. 다음 예제에서는 동작 변경과 이를 처리하는 방법을 보여 줍니다.

      다음 패키지 셀에서 정의한 대로 foo.bar.MyObjectInPackageCell.run()을 실행하면 java.lang.NoClassDefFoundError: Could not initialize class foo.bar.MyObjectInPackageCell$ 오류가 트리거됩니다.

      package foo.bar
      
      case class MyIntStruct(int: Int)
      
      import org.apache.spark.sql.SparkSession
      import org.apache.spark.sql.functions._
      import org.apache.spark.sql.Column
      
      object MyObjectInPackageCell extends Serializable {
      
        // Because SparkSession cannot be created in Spark executors,
        // the following line triggers the error
        // Could not initialize class foo.bar.MyObjectInPackageCell$
        val spark = SparkSession.builder.getOrCreate()
      
        def foo: Int => Option[MyIntStruct] = (x: Int) => Some(MyIntStruct(100))
      
        val theUDF = udf(foo)
      
        val df = {
          val myUDFInstance = theUDF(col("id"))
          spark.range(0, 1, 1, 1).withColumn("u", myUDFInstance)
        }
      
        def run(): Unit = {
          df.collect().foreach(println)
        }
      }
      

      이 오류를 해결하기 위해 MyObjectInPackageCell을 직렬화 가능한 클래스 내에서 래핑할 수 있습니다.

    • DataStreamWriter.foreachBatch를 사용하는 특정 경우에는 소스 코드 업데이트가 필요합니다. 이 변경은 Scala 2.12에 람다 식에서 SAM 형식으로의 자동 변환이 있고 모호성을 유발할 수 있기 때문입니다.

      예를 들어 다음 Scala 코드는 컴파일할 수 없습니다.

      streams
        .writeStream
        .foreachBatch { (df, id) => myFunc(df, id) }
      

      컴파일 오류를 수정하려면 foreachBatch { (df, id) => myFunc(df, id) }foreachBatch(myFunc _)로 변경하거나 Java API를 명시적으로 사용합니다(foreachBatch(new VoidFunction2 ...)).

  • Hive 사용자 정의 함수 및 Hive SerDe를 처리하는 데 사용되는 Apache Hive 버전이 2.3으로 업그레이드되었으므로 두 가지 변경이 필요합니다.

    • Hive의 SerDe 인터페이스가 AbstractSerDe 추상 클래스로 바뀌었습니다. 사용자 지정 Hive SerDe 구현의 경우 AbstractSerDe로 마이그레이션해야 합니다.
    • spark.sql.hive.metastore.jarsbuiltin으로 설정하면 Hive 2.3 메타스토어 클라이언트가 Databricks Runtime 7.x용 메타스토어에 액세스하는 데 사용됩니다. Hive 1.2 기반 외부 메타스토어에 액세스해야 하는 경우 spark.sql.hive.metastore.jars를 Hive 1.2 jar가 포함된 폴더로 설정합니다.

사용 중단 및 제거

  • 데이터 건너뛰기 인덱스는 Databricks Runtime 4.3에서 더 이상 사용되지 않으며 Databricks Runtime 7.x에서 제거되었습니다. 대신 향상된 데이터 건너뛰기 기능을 제공하는 델타 테이블을 사용하는 것이 좋습니다.
  • Databricks Runtime 7.x에서 Apache Spark의 기본 버전은 Scala 2.12를 사용합니다. Scala 2.11에 대해 컴파일된 라이브러리는 Databricks Runtime 7.x 클러스터를 사용하지 않도록 예기치 않은 방식으로 설정할 수 있으므로 Databricks Runtime 7.x를 실행하는 클러스터는 모든 클러스터에 설치되도록 구성된 라이브러리를 설치하지 않습니다. 클러스터 라이브러리 탭에는 상태 Skipped와 라이브러리 처리 변경 내용을 설명하는 사용 중단 메시지가 표시됩니다. 그러나 Azure Databricks 플랫폼 버전 3.20이 작업 영역에 릴리스되기 전에 이전 버전의 Databricks Runtime에서 만든 클러스터가 있고 이제 Databricks Runtime 7.x를 사용하도록 해당 클러스터를 편집하는 경우 모든 클러스터에 설치되도록 구성된 라이브러리가 해당 클러스터에 설치됩니다. 이 경우 설치된 라이브러리의 호환되지 않는 JAR로 인해 클러스터가 사용하지 않도록 설정될 수 있습니다. 해결 방법은 클러스터를 복제하거나 새 클러스터를 만드는 것입니다.

알려진 문제

  • 연도 필드가 누락된 경우 'D' 패턴 문자를 사용하여 연도의 일을 구문 분석하면 잘못된 결과가 반환됩니다. 이는 패턴 문자열을 사용하여 날짜/시간 문자열을 날짜/시간 값으로 구문 분석하는 to_timestamp와 같은 SQL 함수에서 발생할 수 있습니다. (SPARK-31939)
  • 키의 값이 -0.0 및 0.0인 경우 하위 쿼리 내의 조인/window/집계에서 잘못된 결과가 발생할 수 있습니다. (SPARK-31958)
  • window 쿼리가 모호한 자체 조인 오류와 함께 예기치 않게 실패할 수 있습니다. (SPARK-31956)
  • dropDuplicates 연산자를 사용하는 스트리밍 쿼리는 Spark 2.x에서 작성한 검사점에서 다시 시작하지 못할 수 있습니다. (SPARK-31990)