본문 바로가기
스터디/오라클 성능고도화 원리와 해법1

06.I/O 효율화 원리 - 06. RAC 캐시 퓨전

by 취미툰 2020. 2. 14.
반응형

오라클 RAC모델은 공유 디스크 방식에 기반을 두면서 인스턴스 간에 버퍼 캐시까지 공유하는 캐시 퓨전 기술로 발전하였습니다.
튜닝이 잘 되지 않아 많은 블록 I/O를 일으키는 애플리케이션에서 RAC를 도입한다면 부하 분산은 커녕 단일 인스턴스 환경에서보다 더욱 심각한 성능저하 현상을 일으킬 수 있습니다.

RAC는 글로벌 캐시라는 개념을 사용합니다. 즉 클러스터링 돼 있는 모든 인스턴스 노드의 버퍼 캐시를 하나의 버퍼 캐시로 간주하빈다. 따라서 필요한 데이터 블록이 로컬 캐시에 없더라도 다른 노드에 캐싱돼 있다면 디스크 I/O를 일으키지 않고 그것을 가져와 읽거나 쓸 수 있습니다.
모든 데이터 블록에 대해 마스터 노드가 각각 정해져 있고, 그 노드를 통해 글로벌 캐시에 캐싱돼 있는 블록의 상태와 Lock정보를 관리합니다. 마스터 노드는 각 블록 주소의 해시 값에 의해 인스턴스가 기동되는 시점에 동적으로 정해집니다.
캐시 퓨전 원리를 간단히 설명하면 읽고자 하는 블록이 로컬 캐시에 없을 때 마스터 노드에 전송 요청을 하고, 마스터 노드는 해당 블록을 캐싱하고 있는 노드에 메시지를 보내 그 블록을 요청했던 노드에 전송하도록 지시하는 방식입니다. 만약 어느 노드에도 캐싱돼있지 않다면 직접 디스크에서 읽도록 권한을 부여합니다.
RAC환경에서의 Current블록은 Shared 모드 Current(Scur)와 Exclusive Current(Xcur)로 나뉩니다. Scur상태의 블록은 동시에 여러 노드에 캐싱될 수 있지만 Xcur상태의 블록은 단 하나의 노드에만 존재할 수 있습니다.
자주 읽히는 데이터 블록을 각 노드가 Scur모드로 캐싱하고 있을 때 가장 효율적인 상태가 됩니다. 하지만 그 중 한 노드가 Xcur모드로 업그레이드를 요청하는 순간 다른 노드에 캐싱돼 있던 Scur블록들은 모두 Null모드로 다운그레이드 됩니다. 더는 쓸수 없는 PI(past image)블록이 되는 것입니다.

(1) 전송 없는 읽기 : Read with No Transfer


A노드에서 k블록을 읽으려고 하는데 현재 어떤 노드에도 캐싱돼 있지않은 상태입니다.
-A노드는 마스터인 B노드에게 전송 요청을 보냅니다. 이때 gc cr request 이벤트가 발생합니다.
-B노드는 현재 어떤 노드에도 k블록을 캐싱하고 있지 않음을 확인하고 A노드에게 데이터파일에서 직접 블록을 Scur모드로 읽도록 권한을 부여합니다.
-A노드는 디스크에서 블록을 읽어 로컬 캐시에 캐싱합니다.

(2) 읽기/읽기 전송 : Read to Read Transfer
A노드만 K블록을 Scur모드로 캐싱한 상태에서 C노드가 같은 K블록을 Scur모드로 읽으려 합니다.
- C노드는 리소스 마스터인 B노드에 블록에 대한 전송 요청을 보냅니다. gc cr request이벤트가 발생합니다.
- B노드는 현재 A노드가 캐싱하고 있음을 확인하고 C노드에 블록을 전송해 주도록 A노드에게 지시합니다.
- A노드는 C노드에게 블록을 전송합니다.
- C노드는 블록을 전송받아 Scur모드로 로컬캐시에 캐싱하고 B에게 성공적으로 캐싱되었다고 메시지를 보냅니다.

(3) 읽기/쓰기 전송 : Read to Write Transfer
A와 C가 Scur로 둘다 캐싱하고 있을 때 C가 Xcur모드로 업그레이드 하려고 합니다.
- 마스터 노드인 B에게 업그레이드 하겠다고 요청합니다.
- B노드는 현재 캐싱돼 있는 노드를 확인하고 A노드에게 Null 모드로 다운그레이드하도록 지시합니다.
- A노드는 다운그레이드 했다고 C에게 알립니다.
- C노드는 Xcur모드로 업그레이드 하고 결과를 마스터인 B에게 전송합니다.
이때 블록 SCN이 변경이 되어 154로 증가했습니다.

(4) 쓰기/쓰기 전송 : Write to Write Transfer

C노드가 가진 블록이 154로 증가되었고 데이터파일에 있는 블록 SCN은 아직 123이므로 Dirty버퍼 상태입니다. 이때 null 모드인 A노드가 블록 갱신을 위해 Xcur모드로 읽으려고 합니다,
-마스터 노드인 B에게 블록 Xcur모드로 요청합니다.
- B노드는 현재 상태를 확인하고 C에게 A로 보내라고 지시합니다.
- C노드는 A에게 전송하고 자신이 갖고 있던 블록은 Null 모드로 다운그리에드 합니다. C가 가진 Xcur블록은 아직 커밋되지 않아 로우 Lock이 걸린 상태 일 수 있습니다.
- A노드는 Xcur모드로 캐싱하게 됐음을 B에게 알립니다.

다른 인스턴스가 갱신 중인 블록을 읽고자 할 때 로우 lock이 해제될 때까지 기다리지 않고 로우 Lock이 설정된 채 블록을 주고받는다는 것은 중요한 사실입니다. RAC에서는 디스크 동기화 없이 로우 Lock이 설정된 채로 버퍼 캐시 간 블록 전송이 가능해진 것입니다.

A노드의 블록이 154에서 168로 증가했습니다.

(5)쓰기/읽기 전송 : Write to Read Transfer
C노드가 다시 블록을 Scur모드로 읽으려고 합니다.
-B에게 블록을 Scur모드로 요청합니다.
-B는 상태 확인후 A에게 C로 블록을 보내라고 지시합니다.
- A는 블록 전송 후 자신이 캐싱하고 있던 블록은 Scur모드로 다운그레이드 합니다.
- C는 블록을 Scur모드로 캐싱하게 됐음을 B에게 알립니다.

캐시 퓨전 과정에서 생기는 성능부하는 I/O관련 부하와 같은 시작에서 바라봐야 합니다. 블록에 대한 읽기 요청 횟수가 많으면 디스크 I/O관련 대기 이벤트가 증가하는 만큼 RAC관련 이벤트도 같이 증가하는것을 관찰할 수 있습니다. 이에 대한 해결은 블록 읽기 요청횟수를 줄여 ㅇ니터커넥트를 통한 데이터 전송량을 감소시키는 것입니다.

반응형

댓글