• 검색 결과가 없습니다.

Oracle9i Real Application Clusters의 Application Fail-Over와 Load balancing

문서에서 Oracle RAC9i(R2) for Sun Cluster Workshop (페이지 49-63)

Oracle9i Real Application Clusters 의 페일오버 기능 - CTF vs TAF

아마도 독자들이 Oracle9i Real Application Clusters 를 도입하는 가장 큰 이유는 Oracle9i Real Application Clusters 가 고가용성(HA)을 보장해 주기 때문일 것인데, 실제로 HA 를 구현하기 위해서 가장 중요한 부분이 애플리케이션 페일오버(application failover)이다. 애플리케이션 페일오버를 간단히 설명하면, Oracle9i Real Application Clusters 환경에서 하나의 노드에 장애가 발생했을 때 애플리케이션은 나머지 살아 있는 노드들 중의 하나로부터 서비스를 받게 되므로, 엔드유저들은 장애가 발생했는지조차 모르는 것이다.

이것이 바로 오라클에서 Oracle9i Real Application Clusters 를 '난공불락(Unbreakable)'이라고 내세우는 이유이다.

최근에는 HA 에 대한 관심이 높아지면서 플랫폼 벤더에서도 여러 가지 HA 솔루션 - 이를테면, IP

스위치오버 - 을 제공한다. Oracle9i Real Application Clusters 사용 고객이 이러한 플랫폼 솔루션을 훌륭하게 함께 사용하는 경우도 많이 있지만, 이번 호에서는 혼돈을 피하기 위해 100% 오라클이 제공하는

솔루션만을 다루도록 한다.

Oracle9i Real Application Clusters 에서 제공하는 페일오버 기능에는 CTF(Connection Time Failover)와 TAF(Transparent Application Failover)가 있다. 이 두 가지 기능 모두는 Oracle8i Parallel Server 에서부터 제공되던 기능이다. 그런데, 많은 고객들이 CTF 와 TAF 가 상호 배타적인 기능이라고 여기는 것 같은데, TAF 는 CTF 기능 위의 부가적인 기능이다. 따라서, CTF 를 사용할 것인지 TAF 를 사용할 것인지 고민할 필요 없이 TAF 를 사용할 것인지 아닌지의 여부만 선택하면 된다.

이 글의 기반이 되는 필자의 테스트 환경은 다음과 같다. 앞으로 이어지는 테스트에서는 항상 이전의 설정을 기본으로 변경사항만 추가하도록 하겠다.

데이타베이스 서버 ‥ 2 노드의 Oracle9i Real Application Clusters o 운영체제 : Sun Solaris 8

o 오라클 데이타베이스 버전 : Oracle9i Database Release 2(9.2.0.3) 64 비트 o 호스트명(공용 네트워크) : krrac1, krrac2

o ORACLE_SID : RAC1(krrac1), RAC2(krrac2) o init.ora 파라미터

o local_listener=(지정 안함) o remote_listener=(지정 안함) o service_names=(지정 안함) o db_name='rac'

o rac1.instance_name='rac1' o rac2.instance_name='rac2'

o listener.ora(krrac1. krrac2 는 HOST 와 SID_NAME 만 각각 krrac2, RAC2 이며 나머지는 동일) LISTENER =

(DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = krrac1) (PORT = 1521))

)

) )

SID_LIST_LISTENER = (SID_LIST =

(SID_DESC =

(ORACLE_HOME = /data/oracle) (SID_NAME = RAC1)

) )

• Oracle*Net 클라이언트(SQL*Plus)

o 운영체제 : Windows 2000 Professional

o 오라클 클라이언트 버전 : Oracle9i Database Release 2(9.2.0.3) o tnsnames.ora

o RAC1 = o (description=

o (address=(protocol=tcp)(host=krrac1)(port=1521)) o (connect_data=

o (service_name=RAC)) o )

자, 이제 클라이언트에서 rac1 이라는 TNS alias 로 RAC1 에 접속할 수 있다면 모든 준비가 되었다. RAC1 인스턴스에 접속되었는지 확인해 보도록 하자<리스트 1>.

<리스트 1> RAC1 인스턴스의 접속 확인

$ sqlplus scott/tiger@rac1

SQL*Plus: Release 9.2.0.3.0 - Production on 화 Jul 8 12:20:46 2003 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

다음에 접속됨:

Oracle9i Enterprise Edition Release 9.2.0.3.0 - 64bit Production

With the Partitioning, Real Application Clusters, OLAP and Oracle Data Mining options JServer Release 9.2.0.3.0 - Production

세션이 변경되었습니다.

그러면, 이제 각각의 기능이 어떻게 작동하는지 자세히 알아보도록 하자.

51-67 CTF

CTF(Connection Time Failover)는 가장 기본적인 페일오버 설정 방법으로, 클라이언트의 TNS alias 만 아래와 같이 수정해주면 된다.

RAC_CTF = (description=

(load_balance=off) (failover=on)

(address=(protocol=tcp)(host=krrac1)(port=1521)) (address=(protocol=tcp)(host=krrac2)(port=1521)) (connect_data=

(service_name=RAC) )

)

로드 밸런싱(load balancing)은 이후에 별도로 자세히 설명하므로, 일단 여기서는 로드 밸런싱에 대한 언급은 하지 않기로 하자. 이와 같이 설정한다면, 일단 RAC_CTF 를 사용하여 접속하는 클라이언트들은

1. krrac1 의 1521 포트로 기동된 리스너를 컨택한다.

2. 그 리스너가 RAC 라는 서비스를 하고 있다면 RAC 라는 서비스에 등록되어 있는 인스턴스에 접속한다.

3. 만일 1 에서 리스너가 응답이 없거나, 2 에서 RAC 라는 서비스가 없다면, 다음에 지정된 어드레스인 krrac2 의 1521 포트로 기동된 리스너를 컨택한다. 여기서 리스너가 응답이 없다면 에러를 리턴하며 접속을 하지 못하게 된다.

4. 2 와 마찬가지 과정으로 RAC 서비스에 등록되어 있는 인스턴스를 접속한다. 여기서 RAC 서비스를 찾을 수 없다면, 마찬가지로 에러를 리턴하며 접속을 하지 못하게 된다.

따라서, 새로이 접속하는 클라이언트에 대하여는 krrac1 에서 어떤 장애가 일어나더라도 문제없이 krrac2 로 페일오버가 된다. 그렇다면, 기존에 이미 접속되어 있던 클라이언트들은 어떻게 될까? 리스너에만 장애가 있다면 당연히 영향이 없을 것이지만, 만일 인스턴스가 중단되었다면? 물론 클라이언트는 ORA-3113/3114 에러를 만나게 되며 기존의 접속 상태가 끊어지고, 새로 접속하면 위와 같은 과정을 거쳐 krrac2 로 접속하게 된다. 실행되고 있던 DML 은 살아 있는 RAC2 인스턴스에서 트랜잭션 복구를 수행하여 모두 롤백된다.

여기서 각 호스트의 리스너가 어떤 포트로 기동되어 있는지, 어떤 서비스에 어떤 인스턴스가 등록되어 있는지는 <리스트 2>와 같은 방법으로 알 수 있다.

<리스트 2> 각 호스트의 리스너 포트와 서비스별 인스턴스 등록 확인 krrac1|/data/oracle> lsnrctl services

LSNRCTL for Solaris: Version 9.2.0.3.0 - Production on 08-JUL-2003 14:09:47 Copyright (c) 1991, 2002, Oracle Corporation. All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=krrac1)(PORT=1521))) Services Summary...

Service "RAC" has 1 instance(s).

Instance "RAC1", status READY, has 1 handler(s) for this service...

Handler(s):

"DEDICATED" established:1 refused:0 state:ready LOCAL SERVER

Service "RAC1" has 1 instance(s).

Instance "RAC1", status UNKNOWN, has 1 handler(s) for this service...

Handler(s):

"DEDICATED" established:0 refused:0 LOCAL SERVER

The command completed successfully

여기서 독자들은 뭔가 좀 특이한 점을 볼 수 있을 것이다. 현재 리스너에는 RAC 와 RAC1 두 가지 서비스가 등록되어 있으며, 각각의 서비스에는 RAC1 인스턴스가 등록되어 있다. 그렇다면, 왜 두 가지 서비스가 등록되어 있을까? 이것을 이해하기 위해서는 Oracle8i Database 에서 도입된 동적 등록(dynamic registration) 방식에 대하여 우선 알아야 한다. 위에서 status 항목을 자세히 살펴보면, RAC 서비스에 대하여는 READY 인 반면 RAC1 서비스에 대하여는 UNKNOWN 으로 나와 있는 것을 볼 수 있다. 즉, 리스너는 현재 RAC 서비스를 통해서는 RAC1 인스턴스가 살아 있다(READY)는 사실을 알 수 있지만, RAC1 서비스를 통해서는 RAC1 인스턴스의 상태를 알 수 없다(UNKNOWN). 여기서 한 번 RAC1 인스턴스를 셧다운한 후 똑 같은 테스트를 해 보자<리스트 3>.

<리스트 3> RAC1 인스턴스의 셧다운 후 테스트 실행 krrac1|/data/oracle> lsnrctl services listener_rac1

LSNRCTL for Solaris: Version 9.2.0.3.0 - Production on 08-JUL-2003 14:25:51 Copyright (c) 1991, 2002, Oracle Corporation. All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=krrac1)(PORT=1521))) Services Summary...

Service "RAC1" has 1 instance(s).

Instance "RAC1", status UNKNOWN, has 1 handler(s) for this service...

Handler(s):

"DEDICATED" established:0 refused:0 LOCAL SERVER

The command completed successfully

그러면, RAC 서비스가 사라진 것을 볼 수 있다. 반면에, RAC1 서비스는 여전히 RAC1 인스턴스의 상태를 모르고 있다. 즉, RAC 서비스는 동적으로 등록된 서비스이며, 이러한 서비스에 등록된 인스턴스는

지속적으로 자신의 상태를 리스너에 업데이트시켜 준다.

동적 등록을 구성하는 방법은 다음과 같다.

1. SERVICE_NAMES 파라미터 값을 설정해 준다. 이것이 바로 리스너에 등록하는 서비스의 이름으로, 디폴트 값은 db_name.db_domain 이 된다. 즉, 예제에서는 db_domain 값이 설정되어 있지 않으므로 그냥 rac 가 된다. 주의할 점은 service_names 를 임의로 설정하는 경우 Oracle9i Real Application Clusters 데이타베이스 내의 페일오버 설정에 참여하는 모든 인스턴스들은 같은 값으로 설정해야

53-67

한다는 것이다. 앞서 설명한 RAC_CTF TNS alias 를 보면 service_name 값을 RAC 로 사용하여 서로 다른 리스너 어드레스를 등록한 것을 확인할 수 있다.

2. LOCAL_LISTENER 파라미터 값을 설정해 준다. 즉 어느 리스너에 자신의 상태를 업데이트시켜 줄 것인지를 정해주는 부분으로, 디폴트 값은 (ADDRESS =

(PROTOCOL=TCP)(HOST=)(PORT=1521))이 된다. 즉, 로컬 호스트의 1521 포트로 기동되는 리스너에 대하여는 LOCAL_LISTENER 값을 설정하지 않더라도 자동으로 동적 등록이 설정된다.

이 예제에서는 SERVICE_NAMES, LOCAL_LISTENER 값을 둘 다 설정하지 않았지만 lsnrctl services 에서 동적 등록이 되어 있는 것을 확인할 수 있다. 모두 디폴트 값을 취했기 때문이다. 즉, db_name 을

SERVICE_NAMES 로 사용하고, 1521 포트의 리스너를 사용하고자 한다면 이 예제와 같이 아무것도 설정할 필요가 없다.

LOCAL_LISTENER 를 설정할 때는 디폴트 값처럼 TNS alias 구문으로 설정해 줄 수도 있지만 다른 방법도 있다. 서버의(클라이언트가 아니라 서버임에 유의하자) tnsnames.ora 파일에 다음과 같은 항목을 추가해 보자.

LISTENER_RAC1 = (description=

(address=(protocol=tcp)(host=krrac1)(port=1521)) )

그리고 init.ora 파일에는 LOCAL_LISTENER=LISTENER_RAC1 라고 지정해 보자. lsnrctl services 에서와 마찬가지로 동적 등록이 이루어진 것을 확인할 수 있다. 즉, 클라이언트에서 tnsnames.ora 파일에 TNS alias 를 설정하여 사용하듯이, 서버에서도 LOCAL_LISTENER 에 대하여 TNS alias 를 설정하여 사용할 수 있다. 물론 여기서 설정하는 값은 listener.ora 파일에 지정하는 리스너 이름과는 아무런 상관이 없다.

Oracle9i Database Release 2(V9.2)부터는 LOCAL_LISTENER 값을 인스턴스가 기동중인 상태에서도 아래와 같이 동적으로 바꿀 수 있다.

SQL>alter system set local_listener='LISTENER_RAC1';

System altered.

이 때 물론 서버의 tnsnames.ora 에는 LISTENER_RAC1 이라는 항목이 미리 지정되어 있어야 하며, 만일 이것이 없을 때에는 오라클 에러가 나타나며 실패하게 된다. 또한 SPFile(Server Parameter File)이 아닌 텍스트 방식의 init.ora 를 사용하는 경우 인스턴스를 내렸다 올리면 위 설정은 없어지고 원래대로 돌아가므로, 설정을 지속시키려면 init.ora 파일에 값을 명시적으로 설정해야 한다.

자, 그럼 여기서 한 가지 의문이 생길 수 있다. '그렇다면, 정적으로 등록된 서비스(즉 위 예제에서 status UNKNOWN 으로 등록된 RAC1 서비스)는?' 결론적으로 말하면, 동적 등록 방식이 정적 등록 방식을

오버라이드(override)하게 되므로 정적 등록 방식은 다음과 같이 listener.ora 파일을 수정하여 제거하는 것이 좋다.

LISTENER =

(DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS_LIST =

(ADDRESS = (PROTOCOL = TCP)(HOST = krrac1) (PORT = 1521)) )

) )

여기서 또 한 가지. 바로 위에 설정한 내용이 listener.ora 의 디폴트 값이다. 결국 listener.ora 파일에 아무런 내용이 없어도 된다는 이야기가 된다. 사실 1521 포트를 사용하면서 LISTENER 라는 이름의 리스너를 사용한다면 실제로 listener.ora 파일 자체가 필요가 없다. lsnrctl 명령어는 디폴트로 LISTENER 라는 이름의 리스너에 대하여 수행되므로, 시동/중단하는 데에도 아무런 지장이 없다. 한 번 listener.ora 파일을 제거하고 테스트해 보도록 하자. 여태까지와 마찬가지 결과를 얻을 것이다.

물론, LISTENER 라는 이름이 아닌 다른 이름의 리스너를 사용하고자 한다면 1521 포트를 사용하더라도 이름을 지정하기 위해서 listener.ora 파일이 필요하다. 이미 눈치 빠른 독자들은 알아챘겠지만, 동적 등록 방식이 우수하므로 앞으로는 항상 동적 등록 방식을 쓰도록 하자는 것이다. 동적 등록 방식은 세 가지 측면에서 과거의 정적 등록 방식보다 우수하다.

• 주기적으로 인스턴스가 리스너에 자신의 상태를 알려주므로, CTF 설정에서 인스턴스에 장애가 있을 경우 앞서 설정한 페일오버 과정에서 장애가 발생한 인스턴스에 접속을 시도하는 오버헤드가 없다.

즉, 리스너까지만 가면 인스턴스의 상태를 알 수 있다.

• Oracle9i Database 의 새로운 기능인 리스너(커넥션) 로드 밸런싱을 사용할 수 있다.

• TAF 를 사용할 수 있다.

그렇다면 TAF란 무엇인가? 이것에 대해 자세히 알아보도록 하자.

문서에서 Oracle RAC9i(R2) for Sun Cluster Workshop (페이지 49-63)

관련 문서