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.getItem
은Column.apply
를 호출하지 않도록 수정되었습니다. 따라서Column
이getItem
에 대한 인수로 사용되는 경우 인덱싱 연산자를 사용해야 합니다. 예를 들어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.forceNullable
을false
로 설정합니다. - 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.ContinuousTrigger
가Trigger.Continuous
를 위해 제거되고org.apache.spark.sql.execution.streaming.OneTimeTrigger
가Trigger.Once
를 위해 숨겨졌습니다. SPARK-28199를 참조하세요.
SQL, 데이터 세트 및 DataFrame
- Spark 3.0에서 값을 데이터 형식이 다른 테이블 열에 삽입하는 경우 ANSI SQL 표준에 따라 형식 강제 변환이 수행됩니다.
string
을int
로 변환하고double
을boolean
로 변환하는 것과 같은 불합리한 특정 형식 변환은 허용되지 않습니다. 값이 열의 데이터 형식 범위를 벗어나면 런타임 예외가 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.createExternalTable
및SparkSession.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로 처리합니다.FloatType
및DoubleType
의 경우 빈 문자열에서 실패하고 예외를 throw합니다. Spark 3.0부터 빈 문자열을 허용하지 않으며StringType
및BinaryType
를 제외한 데이터 형식에 대해 예외를 throw합니다. - Spark 3.0부터
from_json
함수는PERMISSIVE
및FAILFAST
의 두 가지 모드를 지원합니다. 이러한 모드는mode
옵션을 통해 설정할 수 있습니다. 기본 모드는PERMISSIVE
입니다. 이전 버전에서는, 특히 형식이 잘못된 JSON 레코드를 처리할 때from_json
의 동작이PERMISSIVE
또는FAILFAST,
와 일치하지 않았습니다. 예를 들어 스키마가a INT
인{"a" 1}
JSON 문자열은 이전 버전에서null
로 변환되지만, Spark 3.0에서는Row(null)
로 변환됩니다.
DDL 문
- Spark 3.0에서 특정 공급자가 없는
CREATE TABLE
은spark.sql.sources.default
값을 공급자로 사용합니다. Spark 버전 2.4 이하에서는 Hive였습니다. Spark 3.0 이전의 동작을 복원하려면spark.sql.legacy.createHiveTableByDefault.enabled
을true
로 설정할 수 있습니다. - Spark 3.0에서 값을 데이터 형식이 다른 테이블 열에 삽입하는 경우 ANSI SQL 표준에 따라 형식 강제 변환이 수행됩니다.
string
을int
로 변환하고double
을boolean
로 변환하는 것과 같은 불합리한 특정 형식 변환은 허용되지 않습니다. 값이 열의 데이터 형식 범위를 벗어나면 런타임 예외가 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.allowUntypedScalaUDF
를true
로 설정합니다. 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.mapKeyDedupPolicy
를LAST_WIN
으로 설정하여 마지막 승리 정책을 사용하여 맵 키를 중복 제거할 수 있습니다. 사용자는 여전히 이를 적용하지 않는 데이터 원본(예: Parquet)에서 중복 키가 있는 맵 값을 읽을 수 있습니다. 동작은 정의되지 않습니다.
Data Sources
- Spark 버전 2.4 이하에서 파티션 열 값은 해당 사용자 제공 스키마로 캐스팅할 수 없는 경우 null로 변환됩니다. 3.0에서는 사용자가 제공한 스키마를 사용하여 파티션 열 값의 유효성이 검사됩니다. 유효성 검사가 실패하면 예외가 throw됩니다.
spark.sql.sources.validatePartitionColumns
를false
로 설정하여 이러한 유효성 검사를 사용하지 않도록 설정할 수 있습니다. - Spark 버전 2.4 이하에서 JSON 데이터 원본의 파서는
IntegerType
과 같은 일부 데이터 형식에 대해 빈 문자열을 null로 처리합니다.FloatType
,DoubleType
,DateType
및TimestampType
의 경우 빈 문자열에서 실패하고 예외를 throw합니다. Spark 3.0에서는 빈 문자열을 허용하지 않으며StringType
및BinaryType
를 제외한 데이터 형식에 대해 예외를 throw합니다. 빈 문자열을 허용하는 이전 동작은spark.sql.legacy.json.allowEmptyString.enabled
를true
로 설정하여 복원할 수 있습니다. - Spark 3.0에서 재귀 디렉터리를 나열하는 중에 파일 또는 하위 디렉터리가 사라지는 경우(즉, 중간 목록에 표시되지만 동시 파일 삭제 또는 개체 저장소 일관성 문제로 인해 재귀 디렉터리 나열의 이후 단계에서 읽거나 나열할 수 없음)
spark.sql.files.ignoreMissingFiles
가true
(기본값 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.outputTimestampType
을INT96
로 설정하여 이전 동작을 복원하고 상호 운용성을 유지할 수 있습니다. - 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.failAmbiguousSelfJoin
을false
로 설정할 수 있습니다. - Spark 3.0에서 과학적 표기법으로 작성된 숫자(예:
1E2
)는Double
로 구문 분석됩니다. Spark 버전 2.4 이하에서는Decimal
로 구문 분석됩니다. Spark 3.0 이전의 동작을 복원하려면spark.sql.legacy.exponentLiteralAsDecimal.enabled
를true
로 설정할 수 있습니다. - 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는 날짜/타임스탬프와의 이진 비교에서
String
을Date/Timestamp
로 캐스팅합니다.Date/Timestamp
를String
으로 캐스팅하는 이전 동작은spark.sql.legacy.typeCoercion.datetimeToString.enabled
를true
로 설정하여 복원할 수 있습니다. - 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.timeParserPolicy
를LEGACY
로 설정하여 복원할 수 있습니다. weekofyear
,weekday
,dayofweek
,date_trunc
,from_utc_timestamp
,to_utc_timestamp
및unix_timestamp
함수는java.time
API를 사용하여 변환을 위한 연도의 주 수, 주의 일 수를 계산하고 UTC 표준 시간대의TimestampType
값에서/으로 변환합니다.lowerBound
및upperBound
JDBC 옵션은 문자열을 TimestampType/DateType 값으로 캐스팅하는 것과 동일한 방식으로 TimestampType/DateType 값으로 변환됩니다. 변환은 Proleptic 그레고리력 및spark.sql.session.timeZone
SQL 구성에 의해 정의된 표준 시간대를 기반으로 합니다. Spark 버전 2.4 이하에서 변환은 하이브리드 달력(율리우스력 + 그레고리력) 및 기본 시스템 표준 시간대를 기반으로 합니다.TIMESTAMP
및DATE
리터럴 형식 지정- 문자열에서 형식화된
TIMESTAMP
및DATE
리터럴 만들기. 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 시스템 표준 시간대를 기반으로 합니다. 기본 표준 시간대의 다른 원본은 형식화된TIMESTAMP
및DATE
리터럴의 동작을 변경할 수 있습니다.
- 타임스탬프/날짜 문자열의 구문 분석/형식 지정. 이는 사용자가 지정한 패턴이 구문 분석 및 형식 지정에 사용되는 경우 CSV/JSON 데이터 원본 및
Apache Hive
- Spark 3.0에서는 다음과 같은 영향을 주는 기본 제공 Hive 버전을 1.2에서 2.3으로 업그레이드했습니다.
- 연결하려는 Hive 메타스토어의 버전에 따라
spark.sql.hive.metastore.version
및spark.sql.hive.metastore.jars
를 설정해야 할 수도 있습니다. 예를 들어 Hive 메타스토어 버전이 1.2.1인 경우spark.sql.hive.metastore.version
을1.2.1
로 설정하고spark.sql.hive.metastore.jars
를maven
으로 설정합니다. - 사용자 지정 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 네이티브 테이블 판독기 및 파일 판독기에 영향을 주지 않습니다.
- 연결하려는 Hive 메타스토어의 버전에 따라
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
을 사용합니다. 기본regParam
은RidgeRegressionWithSGD
의 경우 0.01이지만LinearRegression
의 경우 0.0입니다. - 2.0에서 더 이상 사용되지 않는
org.apache.spark.mllib.regression.LassoWithSGD
는 3.0에서 제거되었습니다.elasticNetParam = 1.0
이 있는org.apache.spark.ml.regression.LinearRegression
을 사용합니다. 기본regParam
은LassoWithSGD
의 경우 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.getRuns
및setRuns
는 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
를 확장합니다. 따라서MultilayerPerceptronClassificationModel
의layers
가Array[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.MulticlassMetrics
의fMeasure
멤버 변수는 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
추상 클래스로 바뀌었습니다. 사용자 지정 HiveSerDe
구현의 경우AbstractSerDe
로 마이그레이션해야 합니다. spark.sql.hive.metastore.jars
를builtin
으로 설정하면 Hive 2.3 메타스토어 클라이언트가 Databricks Runtime 7.x용 메타스토어에 액세스하는 데 사용됩니다. Hive 1.2 기반 외부 메타스토어에 액세스해야 하는 경우spark.sql.hive.metastore.jars
를 Hive 1.2 jar가 포함된 폴더로 설정합니다.
- Hive의
사용 중단 및 제거
- 데이터 건너뛰기 인덱스는 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)