'oracle10gRAC'에 해당되는 글 1건

  1. 2007.06.25 ORACLE RAC 100무정지를 향한 아름다운 도전
ORACLE/RAC2007. 6. 25. 03:59
반응형

[RAC] 100% 무정지를 향한 아름다운 도전

김형일

Real Application Cluster, 그 어렵다던 RAC을 정복하기 위해 여행을 떠나 보자. 사실 어렵지 않다. 단지 100% 무정지를 구현하기가 어려울 뿐이다. 연금술사들이 금을 만들기 위해 부단한 노력을 했던 것처럼 100% 무정지를 위해 필수불가결한 RAC에 대한 여행을 시작해 보겠다.

사실 ‘전문가와 떠나는 30일간의 여행’의 진행을 요청받았을 때 가볍게 생각한 것은 사실이다. 일반적인 Q&A를 하는 것처럼 글을 쓰면 되겠구나 했는데 그것이 아니었다. 처음 송정훈씨를 만나며 느낀 것은 걱정스러움이었다. 현재 송정훈씨는 OPS 및 RAC을 운영하고 있으니 최전방에서 전투를 벌이고 있는 예봉을 겸비한 군인처럼 늠름했다. 그래도 주변의 권고로 용기를 내어 그동안 경험을 바탕으로 여행을 함께 떠나기로 했다.
송정훈씨가 주로 알고 싶어하는 것은 운영시의 RAC에 대한 진단과 튜닝 그리고 구축 방법과 TAF, CTF 등이었다. 업무 자체가 OPS와 RAC을 운영하고 있으므로 시스템의 헬스 체크, 그리고 문제 발생시의 해결 방안에 대해 궁금해 했다. 이에 다음과 같은 코스로 여행을 했다.

1. RAC의 개념과 구축 방법, 업무 분산 설계
2. RAC 운영
3. RAC의 진단 및 개선 활동
4. TAF, CTF 그리고 로드밸런스

자! 그럼 여행을 떠나보도록 하자. 우선 본격적인 RAC 진단과 개선을 시작하기에 앞서 RAC의 개념, 구축 방법, 그리고 업무 분산 설계에 대해 알아보겠다.

RAC이란 무엇인가?

오라클에서는 100% 무정지를 구축하고자 하는 고객의 요구에 따라 오라클7부터 OPS (Oracle Parallel Server)를 지원했으며 오라클8, 오라클8i로 발전하여 오라클9i에서는 각 노드간 캐시의 일치성을 보장하기 위한 서버간의 통신 방식을 디스크를 이용한 방식에서 초고속 인터커넥트를 이용한 캐시 퓨전(Cache Fusion)으로 변경하면서 획기적인 발전을 가져왔다. 결국 현재 오라클10g에서 그리드 컴퓨팅을 지원하는 더욱 발전된 RAC이 출시되어 100% 가용성을 위한 도전에 좋은 솔루션이 되고 있다. 간단하게 RAC을 설명하면 물리적인 하나의 데이터베이스를 여러 대의 서버가 공유하여 사용하는 것으로, 모든 서버들은 같은 데이터를 사용하게 되어 논리적으로는 하나의 시스템을 이용하는 것이다.

<그림 1> 기본적인 RAC 구조




<그림 2> 4번째 노드를 추가하는 경우




<그림 3> RAC의 캐시 퓨젼

확장이 손쉬운 RAC

RAC의 주요한 특징으로는 확장성을 제공한다는 것이다. 많은 고객들이 용량을 고려하여 시스템을 구축하지만 시간의 흐름에 따라 데이터는 증가하고, 또한 사용자의 새로운 요구사항으로 신규 애플리케이션이 추가되어 시스템의 부하는 점점 커지게 된다. 따라서 하나의 하드웨어에서 최대의 용량으로 증설하더라도 용량 부족 문제가 해결되지 않는 경우가 종종 생긴다. 이렇게 되면 시스템 운영 중에 많은 돈을 투자하여 더욱 큰 시스템을 도입하고, 기존의 운영 중이던 시스템을 신규 시스템으로 이관하는 작업을 하게 된다. 실로 엄청난 비용이 추가된다.
과거 OPS를 사용하는 경우에는 노드간 데이터를 주고받는 핑에 의한 성능의 저하로, OPS의 설계를 잘못했을 경우 1+1=0.7로 되어버리는, 즉 2대의 서버로 구축한 OPS 시스템이 하나의 시스템으로 운영하는 시스템보다 성능이 떨어지는 경우가 있었다. 그래서 어떤 경우에는 한 쪽 노드만을 사용하고, 다른 쪽 노드는 장애 발생시에 Fail-over하기 위한 용도로 사용하는 Hot Standby 시스템으로 운영하기도 했다. 그러나 현재의 RAC(오라클9i, 10g)에서는 이러한 제약사항이 개선되어 일반적으로 하나의 노드로 운영하는 데이터베이스와 마찬가지로 구성해도 별다른 성능 문제가 발생하지 않는다. 과거의 OPS가 1+1=0.7이 되었다면 현재의 RAC은 1+1=1.8 정도의 확장성을 제공한다.

가용성에서 으뜸인 RAC

RAC의 또 다른 특징은 고가용성이다. 하나의 서버로 구성된 데이터베이스인 경우 서버에 돌발 장애가 발생하게 되면 장애에 대한 복구가 완료될 때까지 모든 서비스는 정지해야만 한다. 그러나 RAC의 경우에는 하나의 서버에 장애가 발생하더라도 나머지 서버에서 지속적인 서비스를 제공할 수 있으므로 서비스의 중지는 없다. 또한 RAC의 경우에는 HW의 유지 보수, 패치 적용, 업그레이드를 하는 경우에도 정지 없이 서비스를 제공할 수 있다. 특히 오라클10g에서 개선된 Rolling patch, Rolling upgrade 기능은 서비스의 정지를 최소화시켜 준다.

RAC 구축 방법

다음 여행지는 실제 RAC으로 시스템을 구축할 경우 어떠한 부분에 중점을 두어야 하는지에 대한 것이다. RAC 구축 시에 기술적으로 고려해야 하는 점은 다음과 같다.

RAC 내 공유 오브젝트의 관리

RAC의 특성상 서로 다른 노드에서 동일한 데이터를 동시에 액세스하게 되면 핑이 발생하는데 핑이 과도하게 발생하면 RAC의 특수 구조인 노드간 인터커넥트 부분에 부하가 발생하여 전반적인 시스템의 성능의 저하를 발생한다. 이러한 핑의 발생이 최소화되도록 애플리케이션의 배치와 테이블의 물리적인 구조, 파티셔닝에 신경을 써야 한다. 과거 OPS에서는 이러한 핑 현상을 최소화시키는 것이 성능을 극대화시키는 첫 번째 방법이었다. 예를 들어 다음과 같은 것을 고려해 구축했다.

1. 인스턴스별로 사용하는 오브젝트에 대한 파티션을 나누기
- 공유 테이블 생성시 경합을 최소화하기 위해 extent를 인스턴스별로 할당한다.
- 시퀀스 같이 공유하는 오브젝트의 캐시 값을 증대시킨다.
2. 락의 배분을 조절(init.ora의 gc_files_to_lock, gc_rollback_segments 등)
- 공유 오브젝트를 중점 관리 테이블 스페이스에 집중화하고, 이 테이블 스페이스에 많은 락을 할당한다.
- 조회 위주의 데이터와 전혀 공유하지 않는 데이터(한 노드에서만 사용하는 데이터)에는 락을 최소로 할당한다.
3. 동시에 같은 데이터를 액세스하는 애플리케이션은 한 노드에서 수행하도록 하는 애플리케이션 파티셔닝
- 동일한 애플리케이션은 같은 노드에서 수행하도록 배치한다.
- 업무별로 그룹핑하여 노드간에 경합이 없도록 배치한다.

물론 오라클9i, 10g로 올수록 RAC의 기능이 개선되어 수작업 튜닝이 필요 없어지고 있지만, 만약 애플리케이션의 특성상 많은 핑이 발생하면 이와 같이 업무와 오브젝트를 분산해야 할 것이다.

인스턴스 장애시 복구 요구 시간

가용성을 지원하는 RAC은 돌발 장애시의 복구 요구 시간에 따라 인스턴스의 복구 시간을 만족할 수 있도록 해야 한다. 즉 하나의 노드에 장애가 발생했을 때 얼마나 빠른 시간 내에 서비스를 할 수 있는가에 대한 것이다. 이러한 요구사항을 기반으로 인스턴스 복구 시간을 고려해 구성하게 된다.

애플리케이션 서비스의 자동 복구 요구

돌발 장애시에 만약 사용자가 모르는 사이 복구되기를 원한다면 TAF (Transportation Application Failover)와 CTF(Connection Time Failover) 기능을 사용해야 한다. 그러나 현재의 버전에서 조회를 하는 애플리케이션인 경우에만 TAF의 기능을 이용하여 애플리케이션의 수정 없이 Failover를 구현할 수 있다.
CTF는 장애 발생시 새로 접속하는 사용자가 가용한 노드로 자동으로 접속할 수 있도록 구성하는 것이다. 이와 같이 TAF와 CTF를 통해 돌발 장애시 서비스의 정지 없이 혹은 수초 내에 가용한 노드로 접속을 넘김으로써 시스템의 가용성을 극대화시킬 수 있다.

자원의 효율적인 사용 요구

많은 사용자가 시스템 사용시 모든 노드가 균일하게 사용하도록 하려면 SQL*NET의 로드밸런스 기능을 사용해서 구현해야 한다. 보통의 경우 로드밸런서라는 네트워크 장비를 사용하여 사용자의 부하를 분산시키게 되는데, RAC을 사용하는 경우에는 SQL*NET의 구성만으로 사용자의 접속 수나 CPU의 부하를 계산하여 균일하게 분산시켜 줄 수 있다.

RAC의 진단

질문 : 캐시 퓨전 환경이나 업무 분산이 적절한지를 진단하려면 어떤 것을 살펴보면 되나?

이 부분은 송정훈씨가 가장 알고 싶어하는 것이었다. RAC을 운영하면서 어떤 부분을 점검해야 하는지, 또한 각각의 진단 결과에 따라 조치 사항이 무엇인지에 대해 많은 궁금증을 가지고 있었다. 필자 역시 이번 여행 중에서 가장 중요하게 여긴 부분이 바로 RAC 진단 부분이다.
RAC의 진단은 RAC의 특수 구조에 대한 진단이다. 즉 노드간 연결을 해주는 인터커넥트와 관련된 진단이 주가 된다. 결국 이 인터커넥트의 사용량과 부하를 진단하여 문제점을 해결하는 것이 RAC 진단의 시작과 끝이 된다. 그럼 인터커넥트와 관련된 진단을 어떤 방식으로 해야 하는가를 설명하겠다. 보통의 경우(필자의 경우)에는 다음의 3가지 방식으로 접근한다.

1. 통계치를 이용한 분석
2. RAC에 관련된 대기 정보를 이용한 분석
3. 오브젝트의 핑 정보

우선 통계치를 이용한 분석 방법을 살펴보겠다. 통계치란 데이터베이스가 운영되는 동안에 여러 가지 중요한 값을 저장·기록한 것으로, 이중에는 인터커넥트에 대한 정보들도 포함되어 있다. 이러한 통계치를 이용하여 의미있는 메트릭(Metric)을 만들게 된다. 트랜잭션 수를 통계치라 하면 메트릭은 초당 트랜잭션 수처럼 의미와 기준이 되는 것이다. 이러한 여러 가지 메트릭에는 적절한 기준 값이 있어서 진단 중인 시스템의 메트릭 값에 따라 기준에 적합한지 확인하여 시스템의 안정성을 점검하게 된다.
RAC의 진단에 대표적으로 확인하는 것은 AVG CR BLOCK RECEIVE TIME이다. 이 메트릭의 의미는 한 노드에서 다른 노드로부터 무결성 읽기를 하기 위해 블럭을 받기까지의 응답 시간을 의미하는 것으로 보통의 경우 15ms 이하의 값이 나와야 한다.

select b1.inst_id,
b2.value “CR BLOCKS RECEIVED”, -- 통계치
b1.value “CR BLOCK RECEIVE TIME”, -- 통계치
((b1.value / b2.value) * 10) “AVG CR BLOCK RECEIVE TIME (ms)” -- 메트릭
from gv$sysstat b1, gv$sysstat b2
where b1.name = ‘global cache cr block receive time’
and b2.name = ‘global cache cr blocks received’
and b1.inst_id = b2.inst_id ;

INST_ID CR BLOCKS RECEIVED CR BLOCK RECEIVE TIME AVG CR BLOCK RECEIVE TIME (ms)
------- ------------------ --------------------- ------------------------------
    2        958091        67770        .707344083
    1        1116902        82760        .74097817

만약 15ms보다 높은 값이 나온다면 CPU의 용량이 부족하거나 Long-running SQL이 수행되고 있음을 알 수 있다. Long-running SQL은 많은 데이터 블럭들을 노드 간에 주고받게 되므로 인터커넥트에 부하를 가중하여 시간이 길어지게 된다. 또한 인터커넥트의 대역폭이나 네트워크 관련 파라미터가 정상적으로 구성되어 있는지 확인해 보아야 할 것이다.
다음으로 확인해 보는 것이 글로벌 캐시 락 퍼포먼스(global cache lock performance)이다. 이는 RAC의 캐시에 대한 락을 획득할 때의 응답 시간으로 20~30ms 이하의 값을 가져야 한다. 이 시간은 기존의 락을 획득하는 시간과 더불어 새로운 락을 생성하는 시간도 포함된다.

select b1.inst_id,
(b1.value + b2.value) “GLOBAL LOCK GETS”, -- 통계치
b3.value “GLOBAL LOCK GET TIME”, -- 통계치
(b3.value /(b1.value + b2.value)*10) “AVG GLOBAL LOCK GET TIME (ms)” - 메트릭
from gv$sysstat b1, gv$sysstat b2, gv$sysstat b3
where b1.name = ‘global lock sync gets’
and b2.name = ‘global lock async gets’
and b3.name = ‘global lock get time’
and b1.inst_id = b2.inst_id
and b2.inst_id = b3.inst_id;

INST_ID GLOBAL LOCK GETS GLOBAL LOCK GET TIME AVG GLOBAL LOCK GET TIME (ms)
------- ---------------- -------------------- -----------------------------
    1        185162646        1089892        .058861332
    2        2455830        323333        1.31659358

만약 이 값이 20~30ms보다 크다면 시스템 전체의 대기 이벤트 중 상위 10위에는 ‘WAITING SESSIONS’, ‘PCM LOCK BLOCKERS’, ‘PCM LOCK WAITERS’이 있을 것이다. 이러한 경우는 서로 다른 노드의 애플리케이션에서 동일한 오브젝트의 변경과 조회를 동시에 하게 되는 경우가 많이 발생한다. 물론 양 노드의 시스템에 부하가 많거나 인터커넥트의 네트워크 속도가 느린 경우도 발생하지만 Global Lock Get Time이 지나치게 큰 값이면 애플리케이션 락이 발생하는지 확인하여 해결해야 하며, 또한 노드간의 애플리케이션에서 동일한 오브젝트를 변경하는 애플리케이션끼리 그룹 핑하여 한쪽 노드에서 수행할 수 있도록 한다. 이를 애플리케이션 파티션닝이라고 하는데 각각의 애플리케이션의 크루드 메트릭스(CRUD: Create, Read, Update, Delete) 형태를 파악하여 동일 데이터를 접근하는 애플리케이션은 같은 노드에서 운영되도록 배치해야 한다. 과거의 OPS에서는 OPS 튜닝의 99%가 이러한 오브젝트의 배치와 업무 분산이 가장 중요한 포인트였다.
시스템의 상태와 Waiting을 이용한 분석으로는 v$session_wait이나 v$system_wait의 대기 이벤트를 이용하여 문제되는 부분을 중점적으로 찾아 진단하는 방법이다. 특히 RAC에 관련되는 대기 이벤트로는 ‘global cache cr requests’, ‘buffer busy global CR’, ‘ges inquiry response’ 등이 있다. 대부분 RAC에 관련된 대기 이벤트는 각각의 이벤트에 따른 조치 방법이 매우 다양하므로 오라클 Metalink에서 찾아보기 바란다. 찾는 방식은 http:://metalink. oracle.com의 검색 창에서 표를 붙여서 ‘global cache cr requests’로 찾으면 해결법을 쉽게 찾을 수 있다. 다음은 시스템 내에 현재 어떤 대기 이벤트가 있는가를 확인하는 방법이다.

select sw.inst_id, sw.sid,sw.state,sw.event,sw.seconds_in_wait seconds,sw.p1,
sw.p2,sw.p3,sa.sql_text last_sql
from gv$session_wait sw,gv$session s,gv$sqlarea sa
where sw.event not in (‘rdbms ipc message’, ‘smon timer’, ‘pmon timer’,
‘SQL*Net message from client’, ‘lock manager wait for remote message’,
‘ges remote message’, ‘gcs remote message’,
‘gcs for action’, ‘client message’,’pipe get’,’Null event’, ‘PX Idle Wait’,
‘single-task message’, ‘PX Deq: Execution Msg’,
‘KXFQ: kxfqdeq - normal deqeue’,’listen endpoint status’,
‘slave wait’, ‘wakeup time manager’)
and seconds_in_wait > 0 and (sw.inst_id = s.inst_id and sw.sid = s.sid)
and (s.inst_id = sa.inst_id and s.sql_address = sa.address)
order by seconds desc;

마지막으로 오브젝트의 핑 정보를 이용한 방법이 있다. RAC 환경에서는 핑 오퍼레이션이 많을수록 시스템의 부하는 가중되어 성능이 점차 느려질 수 있다. 그러므로 이러한 핑 현상이 많이 발생하는지 확인하는 진단이 필요하고 만약 많이 발생한다면 적절한 조치를 취해 이를 해소해서 RAC의 성능이 최적화될 수 있도록 해야 한다.
핑의 양이 얼마나 많이 발생하는지 확인하려면 v$lock_activity를 1분의 시간차를 두어 조회한 후 그 값들의 차이가 5000 이상이면 핑이 많이 발생한다고 볼 수 있다. 이러한 경우에 오브젝트에 대한 핑을 조사하여 애플리케이션 파티셔닝을 하면 효과가 있다.

select * from gv$lock_activity;

INST_ID    FROM TO_V ACTION_VAL    COUNTER
------- ---- ---- -------------------------------------------- -------------------
    1 NULL S    Lock buffers for read    27977258
    1 NULL X    Lock buffers for write    2330669
    1 S    NULL Make buffers CR (no write)    27724129
    1 S    X    Upgrade read lock to write    402467
    1 X    NULL Make buffers CR (write dirty buffers)    2448830
    1 X    S    Downgrade write lock to read (write dirty buffers)    249608
    2 NULL S    Lock buffers for read    10765390
    2 NULL X    Lock buffers for write    2259510
    2 S    NULL Make buffers CR (no write)    10684894
    2 S    X Upgrade read lock to write    272618
    2 X    NULL Make buffers CR (write dirty buffers)    2212990
    2 X    S Downgrade write lock to read (write dirty buffers)    275689

시스템 전체에 핑이 많이 발생한다면 어떤 오브젝트에서 많이 발생하는가를 확인한다. 다음은 핑이 발생하는 오브젝트들을 파악하기 위한 SQL이다.

select inst_id, name, kind, file#, status,BLOCKS, READ_PINGS, WRITE_PINGS
from ( select
/*+ rule use_merge(df) */
p.inst_id, p.name, p.kind, p.file#, p.status, count(p.block#) BLOCKS,
sum(p.forced_reads) READ_PINGS, sum(p.forced_writes) WRITE_PINGS
from gv$ping p, gv$datafile df
where p.file# = df.file# (+)
group by p.inst_id, p.name, p.kind, p.file#, p.status
order by sum(p.forced_writes) desc, sum(p.forced_reads) desc)
where rownum < 50
order by WRITE_PINGS desc, READ_PINGS desc;

INST_ID    NAME    KIND    FILE#    STATU    BLOCKS READ_PINGS WRITE_PINGS
--- ---------------------- ------------- ----------- ----- ----------- -----------
1 STATS$SQL_PLAN_USAGE_HV INDEX 73 cr 510 988 0
1 IX_PTTA_N1         INDEX PARTITION 29 xcur 344 880 0
1 STATS$SQL_PLAN_USAGE_HV INDEX 62 cr 460 832 0
2 TB_PTRT         TABLE 14 scur 60 394 0
1 _SYSSMU16$     UNDO 5 cr 8 332 0
1 TB_PTRT         TABLE 14 scur 80 316 0
......

이 결과를 보면 IX_PTTA_N1 인덱스와 TB_PTRT 테이블에 Read 핑이 많이 발생하는 것을 알 수 있다. 그러므로 이 IX_PTTA_N1 인덱스와 TB_PTRT 테이블이 모든 노드에서 동시에 변경과 조회를 하므로 이 오브젝트를 사용하는 애플리케이션을 확인하여 가능하면 한쪽 노드에서 수행할 수 있도록 조정하면 효과를 볼 수 있다. 하지만 만약 인터커넥트에 별다른 부하가 없고 핑의 발생이 앞과 같이 그다지 많이 발생하지 않을 경우에는 특별한 조치를 하지 않아도 된다.
참고로 다음은 False 핑을 조회하는 방법이다. False 핑은 반드시 핑이 발생하지 않아도 되는데, RAC의 락 분배 방식에 따라 하나의 락에서 여러 개의 블럭을 관할하게 되어 실제로 필요한 블럭은 변경이 없는데도 불구하고 다른 블럭의 변경에 의해 락의 오너십을 넘겨주는 것을 False 핑이라 한다.

select inst_id, name, kind, file#, status, BLOCKS, READ_PINGS, WRITE_PINGS
from (
select /*+ rule use_merge(df) */
p.inst_id, p.name, p.kind, p.file#, p.status, count(p.block#) BLOCKS,
sum(p.forced_reads) READ_PINGS, sum(p.forced_writes) WRITE_PINGS
from gv$false_ping p, gv$datafile df
where p.file# = df.file# (+)
group by p.inst_id, p.name, p.kind, p.file#, p.status
order by sum(p.forced_writes) desc, sum(p.forced_reads) desc)
where rownum < 51
order by WRITE_PINGS desc, READ_PINGS desc;

INST_ID NAME KIND FILE# STATU BLOCKS READ_PINGS WRITE_PINGS
---- -------------------- ---------- -------- ----- -------- ---------- -----------
1 _SYSSMU16$ UNDO 5 cr 8 332 0
1 _SYSSMU20$ UNDO 5 cr 6 264 0
1 _SYSSMU13$ UNDO 5 cr 4 114 0
2 TB_PTRT TABLE 14 pi 4 102 0
......

만약 False 핑이 과도하게 발생하는 경우, 오라클9i 이전의 OPS에서 해결한 방식과 동일하게 읽기전용 테이블 스페이스에는 락의 할당을 적게 주고, 모든 노드에서 빈번하게 변경/수정이 발생하는 테이블 스페이스에는 락을 아주 많이 지정하여 해결할 수 있다. 그러나 이를 지정하는 것은 아주 조심해서 사용해야 하며 오라클9i 이상에서는 기본 값(Default)으로 사용해도 잘 운영된다.
추가적으로 statspack을 이용하여 RAC을 진단할 수 있다. 원하는 시간대의 statspack의 스냅샷을 이용하여 Statspack의 리포트를 생성해 보면 ‘Global Cache Service - Workload Characteristics’ 부분에 여러 가지 다양한 RAC 관련 메트릭를 보여준다. 다음은 statspack 리포트의 샘플이다. Statspack report 생성은 $ORACLE_HOME/rdbms/admin/ 디렉토리의 spreport.sql을 수행하면 만들 수 있다.

Global Cache Service - Workload Characteristics
-----------------------------------------------
Ave global cache get time (ms): 0.3
Ave global cache convert time (ms): 0.9
Ave build time for CR block (ms): 0.0
Ave flush time for CR block (ms): 0.2
Ave send time for CR block (ms): 0.1
Ave time to process CR block request (ms): 0.3
Ave receive time for CR block (ms): 0.6
Ave pin time for current block (ms): 0.1#
Ave flush time for current block (ms): 0.1
Ave send time for current block (ms): 0.1
Ave time to process current block request (ms): 0.2
Ave receive time for current block (ms): 0.7

다음은 RAC의 진단 중에 중요한 응답 속도에 대한 일반적인 기준 값이다. 이 statspack의 결과를 이용해 점검해 보면 RAC 관련된 메트릭을 검증할 수 있다.

간략하게나마 RAC 진단에 대해 알아보았다. 오라클9i, 10g의 RAC은 과거 OPS와는 달리 캐시 퓨전으로 기능과 성능이 아주 많이 개선되어 파라미터 튜닝이나 애플리케이션 파티셔닝의 부담이 현격히 줄어 데이터베이스 관리자가 쉽게 구축하여 사용할 수 있게 되었다. 심지어 오라클 RAC 매뉴얼에는 싱글 데이터베이스를 RAC으로 이관할 때 고려할 사항이 전혀 없다고 할 정도이다.

TAF와 CTF 그리고 로드밸런스

질문 : SQL*Net 및 관련 init.ora의 설정이 잘 되었는지 알고 싶다. 관련해서 예전에 설명해 주기로 한 부분(Failover & Load balancing)도 궁금하다. 그리고 순수하게 JDBC 연결을 사용할 경우 TAF를 지원할 수 없다고 알고 있는데 맞는지.

마지막 여행지로 다녀온 것은 TAF와 CTF 그리고 로드밸런스이다. 사실 이 부분은 RAC 데이터베이스와 클라이언트나 미들티어 애플리케이션과의 통신 구조에 대한 것이다. 결국 RAC의 아키텍처에서 빠질 수 없는 부분이다. 게다가 TAF, CTF, 로드밸런스의 사용 여부는 사용자의 가용성 요구사항과 응용 애플리케이션의 성격 등에 따라 그 구성이 달라지게 된다.

TAF와 CTF의 정의

◆ CTF : Connection Time Failover의 기능은 클라이언트가 데이터베이스로 접속을 시도할 때 접속하고자 하는 서버에 장애가 발생하여 접속하지 못할 경우 다른 서버로 접속할 수 있도록 하는 기능.
◆ TAF : Transparent Application Failover의 기능은 클라이언트가 RAC의 한쪽 노드에 접속하여 사용하는 중에 접속한 노드에 장애가 발생한 경우 가용한 다른 노드로 접속하여 작업을 계속할 수 있도록 하는 기능.

CTF는 접속할 수 있는 노드들을 tnsnames.ora에 명시해 놓고, 그 중에 접속할 수 있는 노드로 접속하는 것을 말한다. 결국 CTF는 접속시의 정지된 서버가 있을 경우 이 서버를 피해 가용한 서버로 접속하는 Failover 기능을 말한다.
TAF의 경우 오라클에서 조회(select)를 하고 있는 경우에만 자동 Failover를 지원한다. 만약 입력(insert), 삭제(delete)의 경우에는 해당 처리에 대한 롤백 처리를 반드시 구현해 주어야 Failover가 가능하다. 이러한 제약사항으로 DML이 있는 응용 프로그램에 대한 TAF는 현실적으로 구현이 어렵다. 사실 이러한 점이 송정훈씨의 고민 중 하나였는데, 다만 향후의 버전에서 조회뿐만이 아닌 모든 DML에 대한 TAR가 구현되어 진정한 Failover를 구현할 수 있기를 바란다.
결국 대부분의 경우에는 CTF나 조회만 하는 응용 프로그램에 TAF를 구현한다. 게다가 만약 응용 프로그램이 웹으로 구현되어 있을 경우에는 CTF만을 사용하더라도 어느 정도의 가용성은 보장할 수 있다. 예를 들어 CTF만 구현했다고 가정할 때, 페이지 이동 중 장애가 발생했다면 사용자 화면에 에러가 표시된다. 이때 사용자가 다시 시도하는 경우에 장애나 노드가 아닌 정상적인 노드로 다시 접속하게 되므로 사용자는 장애를 느끼지 않을 것이다.

TAF의 구현 구조

<그림 4> TAF의 구현 구조


다음은 TAF를 구현하는 모드와 방식을 나타낸 표이다. 방식에는 BASIC, PRECONNECT 방식이 있고, 접속 모드에는 SESSION, SELECT가 있다. 이러한 TAF 기능은 이미 언급한 바와 같이 OCI를 사용하는 프로그램 언어를 사용했을 때만 가능하다. <리스트 1>은 TAF 예제 프로그램으로 JDBC Thick 드라이버를 사용하여 Callback을 구현한 예제로써 TAF와 CTF를 동시에 사용한 것이다.

로드밸런스 알기

로드밸런스란 클라이언트의 요청들을 여러 개의 서버로 분산시켜서 다중 서버들의 자원을 골고루 사용할 수 있도록 하는 것이다. 오라클에서 지원하는 로드밸런스의 기능에는 클라이언트 사이드 로드밸런스와 서버 사이드 로드밸런스 2가지가 있다. 클라이언트 사이드 로드밸런스인 경우에는 tnsnames.ora에 LOAD_BALANCE=ON을 지정하고 ADDRESS_LIST에 여러 개의 노드로 접속하는 주소를 지정하면 임의적(random) 방식을 이용하여 접속하게 된다. 이와 같은 방식은 접속의 수를 1:1로 나뉘는 방식으로 고정 방식(static)이라 할 수 있다.
서버 사이드 로드밸런스인 경우에는 init.ora의 remote_listener들을 지정하여 로드밸런스를 할 모든 리스너를 지정한다. 이렇게 지정하면 오라클 프로세스 중의 하나인 PMON이 30초마다 서버의 부하를 측정하여 변화가 많이 있는 경우에 모든 리스너에 정보를 배포한다. 변화가 없을 경우에는 10분마다 다시 부하 정보가 갱신된다. 여기서 측정되는 부하는 접속 수와 서버 CPU의 부하를 계산한다. 이렇게 계산된 부하를 바탕으로 각각의 리스너가 클라이언트의 접속 요청에 대해 최소의 부하를 가진 서버로 보내주게 된다. 이와 같은 방식은 접속요청에 대해 부하에 따라 접속하는 서버를 결정하게 되므로 동적(dynamic) 방식이라 할 수 있다. 다음은 클라이언트 로드밸런스를 사용하는 방식이다.

TEST =
(DESCRIPTION =
(ADDRESS_LIST =
(LOAD_BALANCE = ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = hikim1)(PORT = 1526))
(ADDRESS = (PROTOCOL = TCP)(HOST = hikim2)(PORT = 1526))
)
(CONNECT_DATA =
(SERVICE_NAME = 10g2)
)
)

다음은 서버 사이드 로드밸런스를 사용하는 방식이다.

Init.ora(node1)
remote_listener=ERP02

Init.ora(node2)
Remote_listener=ERP01

로드밸런스의 기능은 RAC 환경에서 추가적인 로드밸런스 장비의 도입없이도 전체 자원을 균등하게 사용할 수 있도록 해주며 대용량 처리를 요하는 시스템이나 많은 사용자가 있는 시스템에서는 자원을 효과적으로 사용할 수 있게 해주는 것이다.
그럼 로드밸런스에 대해 좀 더 깊이 고민해 보자. 일반적으로 정상 운영 중에 로드밸런스를 많이 고민하게 된다. 이는 앞에서 설명한 기능으로 어느 정도 해결이 가능하다. 그런데 장애 후의 로드밸런스에 문제점이 있다. 만약 한 개의 노드에 장애가 발생했다고 가정하면 모든 접속은 정상적인 노드로 새로 접속하여 서비스를 받게 된다. 이후 장애가 발생한 노드가 정상 복귀되어 서비스를 재개하면 어떻게 될까? 이미 모든 클라이언트가 정상 노드에 접속하여 서비스를 받고 있으므로 계속적으로 정상 노드에서만 운영하게 되어 있다.
이렇듯 장애 후의 부하 분산에 대한 적당한 답은 아직까지 없었다. 보통의 경우는 어쩔 수 없이 응용 애플리케이션이나 WAS를 재가동하여 접속을 새로 하는 방법 밖에 없었다. 그러나 오라클10g에서는 이러한 장애 후 재부하 분산을 위해 dbms_service라는 PL/SQL 패키지를 이용하여 인액티브한 세션을 정리하여 다시 접속을 시키는 방식으로 장애 후 부하 분산 기능을 제공한다. 조금은 미약한 방식인 듯하지만 WAS의 커넥션 풀(connection pool)을 사용하는 경우라면 잘 활용할 수 있다.

캐시 퓨전의 발전

이번 여행을 마치면서 오라클 RAC에 대해 개념, 진단 방법, 구축 방법, 그리고 TAF, CTF, 로드밸런스에 대해 이야기했다. 9i RAC부터는 캐시 퓨전의 발전으로 과거의 OPS에서 항상 치러왔던 핑과의 전쟁에서 벗어날 수 있었으며, 애플리케이션의 파티셔닝이 없더라도 큰 문제 없이 시스템을 구축할 수 있다. 이러한 것들이 100% 무정지 시스템을 위해 어디선가 노력하는 분들에게 1%라도 도움이 되었으면 하는 마음으로 마무리한다. 100%의 무정지를 향한 아름다운 도전에 성공의 외침을 바라며 글을 마친다.

출처 : 마이크로소프트웨어[2004년도 7월호]

반응형
Posted by [PineTree]