본문 바로가기
Oracle/운영

SCAN Listener?

by 취미툰 2025. 5. 22.

SCAN (Single Client Access Name) 은 Oracle RAC 환경에서 클라이언트가 접속할 때 단일 도메인 이름으로 접속할 수 있도록 제공하는 기능입니다. (직역하면 하나의 클라이언트로 접속하기 위한 이름..정도가 될듯함)
기존에는 RAC 클러스터의 각 노드에 대한 리스너 정보를 직접 클라이언트에 등록해야 했지만, SCAN을 사용하면 클라이언트는 하나의 이름(SCAN)만 알고 있으면, Oracle이 자동으로 적절한 노드로 연결해 줍니다.

 

사용목적?
1)클라이언트 접속의 단순화목적이 있습니다. 
각 IP를 접속해서 각 노드에 접속하던 방식과 달리 SCAN 이름 하나만 입력을 하면 알아서 노드로 붙어주고 하기 때문에 사용자입장에서는 신경쓸일이 없다고 보면 되겠습니다.
2)로드밸런싱(load_balance=ON)
scan 이름에 등록된 IP(기본 3개)로 알아서 로드밸런싱해주기 때문에 부하분산의 효과가 있습니다.
3)가용성향상(failover=ON)
만약 대상 인스턴스가 죽었거나 서비스가 내려간 경우, Oracle은 다른 정상 인스턴스를 찾아 자동 연결 전환(Failover) 수행합니다.

 

DB 노드 2개, 스캔리스너 3개의 구조

	  	클라이언트
                |
                v
      +----------------------+
      |      SCAN 이름       |  ← DNS에 등록 (예: rac-scan.localdomain)
      +----------------------+
           |    |    |
           |    |    |
     SCAN IP1  SCAN IP2  SCAN IP3
         |        |         |
   SCAN 리스너1  SCAN 리스너2  SCAN 리스너3
         |        |         |
        -----------------------
                 |
          ----------------
          |              |
      로컬 리스너1    로컬 리스너2  ← 각 노드에 존재
          |              |
         노드1          노드2        ← RAC 인스턴스들

 

클라이언트는 SCAN이름만 넣으면 등록된 SCAN IP > 스캔리스너 > 로컬리스너 > DB 접속까지의 순서대로 접속이 됩니다.

테스트를 통해서 실제로 분배가 잘되는지 접속할때 로그는 어떻게 보이는지 확인해보겠습니다.

 

테스트 시나리오.

1) nslookup으로 DNS등록이 잘 되어있는지 확인

2) 스캔리스너1,2,3번 로그를 tail로 추적한 상태에서

3) 하나의 세션을 추가로 열어 여러번 client(sqlplus)로 접속을 시도합니다.

4) 접속한 세션의 v$instance를 확인하여 1번노드,2번노드인지 확인합니다.

5) 스캔리스너 로그를 활용해서 몇번 스캔리스너를 사용했는지 확인합니다.

 

1) nslookup으로 DNS등록이 잘 되어있는지 확인

여러번 nslookup했을때 3개ip가 잘 나오는지 확인. 순서가 바뀌면서 나오는지 확인.

$ nslookup rac-scan.localdomain
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   rac-scan.localdomain
Address: 192.168.75.132
Name:   rac-scan.localdomain
Address: 192.168.75.130
Name:   rac-scan.localdomain
Address: 192.168.75.131
...

$ nslookup rac-scan.localdomain
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   rac-scan.localdomain
Address: 192.168.75.130
Name:   rac-scan.localdomain
Address: 192.168.75.131
Name:   rac-scan.localdomain
Address: 192.168.75.132

 

tnsnames.ora에 클라이언트 접속시 사용할 정보 추가

rac_scan_pdb =
  (DESCRIPTION = (LOAD_BALANCE=ON)(FAILOVER=ON)
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = rac-scan.localdomain)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = PDB)
    )
  )

 

2)스캔 리스너 확인 및 로그 확인

rac 기준 1,2번 모두 스캔리스너(3개 기준)로그 디렉토리와 로그파일이 있습니다. 하지만 스캔리스너가 떠있는 노드의 로그를 확인해야 로그가 접속시 잘 쌓이는 것을 확인할 수 있습니다.

 

$ srvctl config scan
SCAN name: rac-scan.localdomain, Network: 1
Subnet IPv4: 192.168.75.0/255.255.255.0/enp0s3, static
Subnet IPv6:
SCAN 1 IPv4 VIP: 192.168.75.130
SCAN VIP is enabled.
SCAN 2 IPv4 VIP: 192.168.75.131
SCAN VIP is enabled.
SCAN 3 IPv4 VIP: 192.168.75.132
SCAN VIP is enabled.

$ srvctl status scan_listener
SCAN Listener LISTENER_SCAN1 is enabled
SCAN listener LISTENER_SCAN1 is running on node rac2
SCAN Listener LISTENER_SCAN2 is enabled
SCAN listener LISTENER_SCAN2 is running on node rac1
SCAN Listener LISTENER_SCAN3 is enabled
SCAN listener LISTENER_SCAN3 is running on node rac1

1번노드
$ ps -ef |grep tns
root        37     2  0 May21 ?        00:00:00 [netns]
oracle    1335  1266  0 10:32 pts/3    00:00:00 grep --color=auto tns
oracle    4548     1  0 May21 ?        00:00:32 /ORA19/app/grid/19.3.0/bin/tnslsnr ASMNET1LSNR_ASM -no_crs_notify -inherit
oracle    4649     1  0 May21 ?        00:00:02 /ORA19/app/grid/19.3.0/bin/tnslsnr LISTENER -no_crs_notify -inherit
oracle    4663     1  0 May21 ?        00:00:02 /ORA19/app/grid/19.3.0/bin/tnslsnr LISTENER_SCAN2 -no_crs_notify -inherit
oracle    4671     1  0 May21 ?        00:00:02 /ORA19/app/grid/19.3.0/bin/tnslsnr LISTENER_SCAN3 -no_crs_notify -inherit

2번노드
$ ps -ef |grep tns
root        37     2  0 May21 ?        00:00:00 [netns]
oracle    9741     1  0 May21 ?        00:00:02 /ORA19/app/grid/19.3.0/bin/tnslsnr LISTENER -no_crs_notify -inherit
oracle    9770     1  0 May21 ?        00:00:02 /ORA19/app/grid/19.3.0/bin/tnslsnr LISTENER_SCAN1 -no_crs_notify -inherit
oracle    9836     1  0 May21 ?        00:00:33 /ORA19/app/grid/19.3.0/bin/tnslsnr ASMNET1LSNR_ASM -no_crs_notify -inherit

각 파일위치 /ORA19/app/oracle/diag/tnslsnr/rac*/listener_scan*/alert/log.xml

 

3) 하나의 세션을 추가로 열어 여러번 client(sqlplus)로 접속을 시도합니다.

30번 접속을 시도하는데 접속 후 v$instance를 조회하고 나가도록 하였고, 다음 접속전까지 random하게 sleep한 후 접속하도록 하였습니다.

for i in {1..30}; do
  echo "접속 $i"
  sqlplus -s ysbae/oracle@rac_scan_pdb <<EOF
    SELECT instance_name, host_name FROM v\$instance;
    EXIT;
EOF
  sleep $((RANDOM % 3 + 1))
done

 

4) 접속한 세션의 v$instance를 확인하여 1번노드,2번노드인지 확인합니다.

접속한 노드가 1번 2번 랜덤하게 붙는것을 확인 할 수 있었습니다.

접속 28
...
INSTANCE_NAME HOST_NAME
----------------
ORADB1	rac1

...
접속 30

INSTANCE_NAME HOST_NAME
------------------
ORADB2	rac2

 

5) 스캔리스너 로그를 활용해서 몇번 스캔리스너를 사용했는지 확인합니다.

각 스캔리스너의 로그파일에는 아래의 정보로 접속기록이 확인되었습니다. 다만 균일하게 10개씩 되지는 않았고 30개 테스트 해본 결과 1번 24개 2번 3개 3번 3개의 로그가 남은걸로보아 1번 스캔리스너가 대부분 사용되었다고 확인 할 수 있었습니다.

1번
<msg time='2025-05-22T10:34:27.387+09:00' org_id='oracle' comp_id='tnslsnr'
 type='UNKNOWN' level='16' host_id='rac2'
 host_addr='192.168.75.229' pid='9770'>
 <txt>22-5월 -2025 10:34:27 * (CONNECT_DATA=(SERVICE_NAME=PDB)(CID=(PROGRAM=sqlplus@rac2)(HOST=rac2)(USER=oracle))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.75.229)(PORT=60012)) * establish * PDB * 0
 </txt>
</msg>
<msg time='2025-05-22T10:34:29.503+09:00' org_id='oracle' comp_id='tnslsnr'
 type='UNKNOWN' level='16' host_id='rac2'
 host_addr='192.168.75.229' pid='9770'>
 <txt>22-5월 -2025 10:34:29 * (CONNECT_DATA=(SERVICE_NAME=PDB)(CID=(PROGRAM=sqlplus@rac2)(HOST=rac2)(USER=oracle))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.75.229)(PORT=60022)) * establish * PDB * 0
 </txt>
 
2번
<msg time='2025-05-22T10:34:51.380+09:00' org_id='oracle' comp_id='tnslsnr'
 type='UNKNOWN' level='16' host_id='rac1'
 host_addr='192.168.75.228' pid='4663'>
 <txt>22-5월 -2025 10:34:51 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=rac1)(USER=oracle))(COMMAND=status)(ARGUMENTS=64)(SERVICE=LISTENER_SCAN2)(VERSION=318767104)) * status * 0
 </txt>
</msg>

 3번
 <msg time='2025-05-22T10:34:50.118+09:00' org_id='oracle' comp_id='tnslsnr'
 type='UNKNOWN' level='16' host_id='rac1'
 host_addr='192.168.75.228' pid='4671'>
 <txt>22-5월 -2025 10:34:50 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=rac1)(USER=oracle))(COMMAND=status)(ARGUMENTS=64)(SERVICE=LISTENER_SCAN3)(VERSION=318767104)) * status * 0
 </txt>
</msg>

 

이상입니다.

반응형

댓글