1. 쿼리 패턴과 메모리 사용량
1.1 SELECT 쿼리로 데이터 조회
1.2 대량의 데이터 전송
-
결과 데이터의 크기
- Spark는 쿼리 결과를 JDBC 커넥터를 통해 데이터 전송받으므로, 전송하는 데이터가 많아질수록 Aurora DB의 I/O와 네트워크 부하가 증가
- 대량의 데이터를 처리하려면 Aurora DB는 더 많은 메모리와 디스크 I/O를 사용
1.3 데이터 페이지 캐싱
- Aurora DB는 데이터를 쿼리할 때 버퍼 캐시(Buffer Cache)에 데이터를 저장하여 I/O를 최적화
- 동일한 데이터를 반복적으로 쿼리하면 캐시를 활용하므로 메모리 사용량이 효율적으로 관리한다.
2. Aurora DB 메모리 사용량에 영향을 미치는 Spark JDBC 옵션
2.1 fetchsize 설정
- fetchsize는 JDBC 커넥션에서 한 번에 가져올 데이터의 크기를 설정하는 옵션
- 기본적으로, 많은 데이터가 한꺼번에 Aurora에서 읽혀질 경우 메모리 사용량이 높아질 수 있다.
- 적절한 fetchsize 설정
- 적당한 fetchsize를 설정하면 데이터가 작은 청크로 나뉘어 전송되며, Aurora의 메모리 부담을 줄일 수 있다.
val jdbcOptions = Map(
"url" -> "jdbc:mysql://aurora-endpoint:3306/dbname",
"user" -> "username",
"password" -> "password",
"fetchsize" -> "1000"
)
2.2 쿼리 분할 (partitionColumn, numPartitions)
- Spark JDBC는 쿼리 분할을 통해 대량 데이터를 병렬로 읽을 수 있다.
- 분할 작업은 Aurora의 부하를 줄이기보다는, Spark 클러스터의 성능을 향상시키는 데 초점이 있다.
- 그러나 분할된 쿼리가 많아질수록 Aurora가 동시에 처리해야 할 쿼리 수도 늘어나므로, Aurora 메모리 사용량과 CPU 부하가 증가한다.
val jdbcOptions = Map(
"url" -> "jdbc:mysql://aurora-endpoint:3306/dbname",
"user" -> "username",
"password" -> "password",
"dbtable" -> "table_name",
"partitionColumn" -> "id",
"lowerBound" -> "1",
"upperBound" -> "10000",
"numPartitions" -> "4"
)
3. Aurora DB에서의 메모리 사용량을 줄이는 방법
1. 필요한 데이터만 읽기
- Spark에서 읽어오는 데이터를 제한하기 위해 쿼리에 WHERE 절을 추가한다.
val jdbcDF = spark.read
.format("jdbc")
.option("url", "jdbc:mysql://aurora-endpoint:3306/dbname")
.option("dbtable", "(SELECT * FROM table_name WHERE column > 1000) as subquery")
.load()
2. fetchsize 설정 최적화
- fetchsize 값을 조정하여 한 번에 전송되는 데이터량을 줄인다.
3. 쿼리 최적화
- 인덱스를 활용하여 쿼리 성능을 높이고, Aurora의 메모리 사용을 줄인다.
- 불필요한 정렬, 집계, 서브쿼리 사용을 피한다.
4. 쿼리 분할 전략 최적화
- partitionColumn과 numPartitions를 적절히 조정하여 Aurora DB가 동시에 처리해야 하는 요청 수를 줄인다.
5. Aurora 읽기 레플리카 활용