먼저 Hello Wolrd 출력부터 해보려고 한다

 

마찬가지로 아래 2가지 방식으로 구현할 것이다.

1) 이미 만들어져있는 이미지 사용
2) Docker File을 통한 커스텀 이미지 생성

 

1) 기존 이미지 사용

 

https://hub.docker.com/ 에 가면 다양한 도커 이미지들을 볼 수 있다.

그중에서 도커 공식이미지인 Hello-world 이미지를 살펴보자

 

hello-world 이미지

아무런 태그를 달지않으면 latest 태그가 받아질 것이고,

어떤 태그들이 있는지도 확인할 수 있다.

 

Hello-world Tag

기본 이미지, 사용방법 등의 설명페이지가 있지만,

간단한 Hello-world 이미지이기때문에 바로 수행해볼 것이다.

 

sudo docker run hello-world

위의 간단한 명령어로, 사용 가능하다.

어떤 동작원리인지 모르는 블랙박스 형태여도, 사용할수 있다는게 장점이기도 하다.

 

run 명령어 수행시, Host PC에 이미지가 없어서 hub.docker 에서 이미지를 가져오는 모습이다.

Tag는 따로 지정해주지 않아, Default 인 latest 태그 이미지를 가져온다.

 

 

2) Docker File을 통한 커스텀 이미지 생성

 

먼저, Docker File 기본 구성에 대해 알아보자.

 

- From : base 이미지 지정
- ADD : 로컬,URL에서 파일이나 디렉토리를 컨테이너로 복사할때 사용
- COPY : ADD와 같은 기능이나 URL에서 가져올 수 없고, 압축파일도 해제없이 그대로 복사된다.
- LABEL : key=value의 기타 정보를 이미지에 심을 떄 사용
            메타정보라고 넘어갈 수 있지만, 후에 쿠버네티스 사용 시 필요한 항목이니 유의
- ENV : 컨테이너에 적용할 환경변수 사전 정의
- ARG : 컨테이너 빌드시 사용할 아큐먼트 정의
- EXPOSE : 호스트와 연결할 포트 번호를 설정
- VOLUME : 호스트 디렉토리 마운트. 
- RUN : 이미지 생성 시, 실행할 Command 지정
- CMD : 이미지 생성 이후, 처음으로 실행될 명령어. 여러개의 CMD 작성시, 마지막 CMD만 적용
- ENTRYPOINT : 이미지 생성 이후 실행될 명령어.
 
 ※ Command 문법

RUN/CMD/ENTRYPOINT ["command","parameter1","parameter2"]

※ CMD와 ENTRYPOINT 차이

 

ENTRYPOINT는 DockerFile에 지정된 그대로 명령을 수행하지만,

CMD는 인자값을 주게되면 해당 인자값으로 명령을 수행한다.

 

 

Hello World DOCKER FILE

 

- Dockerfile 생성

 

FROM alpine:3.14  # 우분투 말고, 도커 베이스이미지로 많이쓰이는 알파인을 사용하였다. ( 5MB 정도 )

CMD ["echo","Hello-World"] # 이미지 생성후 Hello World 출력

 

- 이미지 빌드

sudo docker build -t sk007001/hello-world:v0.1 /docker

-t <이미지명:tag명> <Dockerfile 위치> 명령어로, Dockerfile 기반의 이미지를 태깅하여 빌드하였다.

앞의 sk007001은 개인 hub 저장소 위치를 명시해주었다.

 

 

- 이미지 확인 및 컨테이너 생성

 

sudo docker images

 

sudo docker run sk007001/hello-world:v0.1

 

- 해당 Image 저장소에 Push

 

잘 동작하는것을 확인했으니, 저장소에 Push 하려한다.

sudo docker push sk007001/hello-world:v0.1

 

'IT > 도커도커' 카테고리의 다른 글

(6-1) 도커 內 Rest Api 서버 구성하기 ( Python )  (0) 2021.08.11
(5) 도커 Hello World - 웹페이지  (0) 2021.07.22
(3) 도커 명령어  (0) 2021.07.19
(2) 컨테이너 및 도커  (0) 2021.07.14
(1) Ubuntu에 도커 설치하기  (0) 2021.06.30

도커 아키텍처


Docker run

 

클라이언트 환경에서 Docker run 수행시, Host의 Docker daemon과 통신한다.

UNIX 소켓 또는, 네트워크로 연결되며 REST API를 사용해 리퀘스트를 보낸다.

 

Run 프로세스

 

- docker run <option> $Image:tag <command>

1) Docker_Host 내에서 해당 이미지:태그를 찾는다
2) 없으면 레지스트리에서 이미지:태그를 다운받아온다
3) 이미지를 사용하여 컨테이너 실행
4) 컨테이너에서 명령 수행

 

Run 옵션

 

주로 사용하는 옵션들을 정리해보았다.

 

-d : 컨테이너를 백그라운드로 수행

-e : 컨테이너 내의 환경변수 지정

    --env-file : 환경변수 파일을 지정하여 컨테이너 수행

-i : 표준입력(stdin)을 컨테이너와 연결하여, 명령어를 작성할 수 있게한다.

    주로 -t 옵션과 같이써서, bash 명령어 수행가능하게 한다.

--name: 컨테이너에 이름을 지정하여, 관리가 쉽게한다.

-p : 호스트로 접근하는 특정 포트를, 컨테이너 포트와 매핑시켜준다 ( 프록시, 포워딩 )

     ex) -p 80:8080 / 80포트로 호스트에 접근하는 리퀘스트를, 컨테이너의 8080포트로 연결해준다.

--rm : 컨테이너 수행이 완료되면, 자동으로 삭제한다.

-v : 호스트의 파일시스템을 컨테이너에 마운트한다.

 


Docker ps

 

현재 수행중인 컨테이너 목록. -a 옵션을 통해 종료된 컨테이너까지 확인할 수 있다.

 

Docker Images

 

현재 Host PC에 저장된 이미지 목록 확인

 

Docker Stop/Start $Contianer_ID

 

컨테이너 종료 및 종료된 컨테이너 수행

 

 

Docker rm $Container_ID

 

Host PC 내에서 컨테이너 삭제

 

Docker rmi $Container_ID

 

Host PC 내에서 이미지 삭제

 

 

Docker search $Image_name

 

Docker Hub내에서 해당 이미지 검색

 

 

Docker pull $Image:$tag

 

해당 이미지 다운로드. Run 명령어에는 pull 및 수행 명령단계가 포함되어있다.

 


※ docker pull 이슈 발생




Pull 리퀘스트 횟수 제한에 걸림

- 도커의 경우, 구독 유저가 아니면 리퀘스트 제한이 있는데 ( 익명 100회 / 로그인 200회 . 6시간 기준 )
  프록시 IP를 쓰다보니, 다른 사용자들로 인해 리퀘스트 제한에 걸렸다.

- login 하여, 계정을 통한 리퀘스트로 문제 해결

 

 

'IT > 도커도커' 카테고리의 다른 글

(5) 도커 Hello World - 웹페이지  (0) 2021.07.22
(4) 도커 Hello World  (1) 2021.07.20
(2) 컨테이너 및 도커  (0) 2021.07.14
(1) Ubuntu에 도커 설치하기  (0) 2021.06.30
(0) Oracle VM 을 통한 Ubuntu 서버 설치  (1) 2021.06.29

Heap Memory

 

프로그램이 구동되기 위해서는, 먼저 메모리에 올라가야한다.

메모리는 크게 4가지 ( Code, Data, Heap, Stack ) 으로 나뉘어있다.

 

그중에서 동적으로 할당되고 해제되는 영역인, Heap Memory 관련해서 작성하려한다.

 

c에서는 malloc(), free() 등으로 할당과 해제를 반복하며,

java에서는 GC ( Garbage Collector ) 를 통해 자동으로 정리해준다.

 

2021.04.04 - [서버운영/자바 GC ( Garbage Collection )] - GC ( Garbage Collection )

 

GC ( Garbage Collection )

GC , 가비지 컬렉션 이란? 자바 프로세스가 동적으로 할당했던 메모리 영역중에, 필요없는 영역을 해제하는 기능 => GC가 없다면, 더이상 사용하지 않는 잉여객체들이 메모리를 모두 차지해  OOM (

st-it.tistory.com


Heap Dump

 

Heap Memory는 프로세스가 동작할때 최소/최대 메모리를 지정하며, 할당된 메모리 안에서 동적으로 운영된다.

 

그리고 할당된 메모리가 부족한 경우, OOM ( Out Of memory )가 발생하며 프로그램이 종료된다.

1) 메모리 누수로 인해 정리가 되지않아, 최대 메모리 사용량에 도달했을 때
2) 현재 남아있는 메모리보다 큰 리퀘스트가 들어왔을 때

 

OOM이 발생하면 그때의 Heap Memory 상태 스냅샷을 확보할수 있으며,

.hprof 확장자의 heap dump 파일로 저장된다.

-XX:-HeapDumpOnOutOfMemoryError : OOM 발생시 Heap dump 생성
-XX:HeapDumpPath                         : Heap dump 파일의 위치

 

OOM이 없더라도, 메모리 누수가 의심되거나 현재의 메모리 상태를 확인하고 싶을 때

jmap을 사용하여, 수동으로 Heap memory 상태를 dump 파일로 저장할 수도 있다.

jmap -dump:format=b,file=$PATH/$file.hprof $PID

Heap dump 분석

 

주로 Eclipse MAT ( Memory Analyzer Tool )을 사용한다.

 

사용전에 설치폴더 MemoryAnalyzer.ini 설정파일을 열어, 분석툴의 메모리를 정해주어야한다.

기본 1GB로 되어있지만, Heap dump 파일이 그보다 큰 경우 프로그램이 종료되기 때문이다.

 

이후에 파일을 넣어주면 아래와 같은 화면이 나온다.

문제로 예상되는 17번 쓰레드가, 전체 1.5GB 중에 94.54%를 차지하고 있었다.

 

웹로직 기반의 쓰레드이며, MAT는 char[]를 로드하려다가 문제가 발생한것으로 예상했다.

 

 

오브젝트 리스트를 살펴보면, MAT 예상대로 char 배열이 1.5GB 대부분을 차지중이었다.

 

 

해당 Thread dump 를 분석해보았다.

[ACTIVE] ExecuteThread: '17' for queue: 'weblogic.kernel.Default (self-tuning)'
  at java.lang.OutOfMemoryError.<init>()V (OutOfMemoryError.java:48)
  at java.util.Arrays.copyOf([CI)[C (Arrays.java:3332)
  at java.lang.AbstractStringBuilder.ensureCapacityInternal(I)V (AbstractStringBuilder.java:124)
  at java.lang.AbstractStringBuilder.append(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder; (AbstractStringBuilder.java:448)
  at java.lang.StringBuffer.append(Ljava/lang/String;)Ljava/lang/StringBuffer; (StringBuffer.java:270)
  at com.cspi.cornerstone.container.TemplateParser.transferObjectTag(Ljava/lang/StringBuffer;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/StringBuffer; (TemplateParser.java:368)
  at com.cspi.cornerstone.j2ee.http.HttpResponse.out(Lcom/cspi/cornerstone/cmps/Composer;)V (HttpResponse.java:130)
  at jsp_servlet._contents._voc._global_voc._process._detailview.__voc_detailview.run(Lcom/cspi/cornerstone/j2ee/http/HttpRequest;Lcom/cspi/cornerstone/j2ee/http/HttpResponse;)V (__voc_detailview.java:2481)
  at jsp_servlet._contents._voc._global_voc._process._detailview.__voc_detailview._jspService(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V (__voc_detailview.java:2727)
.
.
.
.

 

대략 분석해보면

 

1) OOM이 발생했고

2) Array, String Builder 즉 위의 Char[] =1.5GB 짜리를 String 으로 변환하려다 발생한 OOM?

   혹은 추가로 Char 배열이 들어오려다, 메모리가 부족해서 OOM이 발생한것으로 보인다

3) voc 관련한 소스코드쪽에서 유발된 것 같다

 

 

실제 분석결과, VOC 본문 ( content ) 작성 시

사용자가 프로그램 예약어를 사용해서 무한루프가 돌면서 내용 생성되는 문제가 있었다.

 

물론 Dump 분석으로는 정확한 유발지 및 원인을 찾기는 어렵지만,

이처럼 대략적인 방향을 잡을수있다.

 

'서버운영 > 자바 프로세스 관리' 카테고리의 다른 글

Thread dump  (0) 2021.07.15

Thread란

프로세스 내에서 실행되는 흐름의 단위
※ 프로세스 : 특정 서비스를 위해, OS내에서 메모리를 할당받아 수행되는 프로그램

하나의 프로세스에 여러개의 쓰레드가 존재할 수 있으며, 각 쓰레드는 아래의 상태값을 가진다.

 

① NEW : 스레드가 생성되었지만 스레드가 아직 실행할 준비가 되지 않았음
② RUNNABLE : 스레드가 실행되고 있거나 실행준비되어 스케쥴링은 기달리는 상태
③ WAITING : 다른 스레드가 notify(), notifyAll()을 불러주기 기다리고 있는 상태(동기화)
④ TIMED_WAITING : 스레드가 주어진 시간동안, 대기하고 있는 상태
⑤ BLOCK : 사용하고자하는 객체의 Lock이 풀릴때까지 대기하는 상태
⑥ TERMINATED : 스레드가 종료한 상태

 

JVM에 의해 관리되며, 설명해놓은 그림이 있어 가져와봤다.

 

[출처] https://raccoonjy.tistory.com/15


Thread dump

프로세스에 수행중인 모든 쓰레드들의 상태를 스냅샷 수행

보통 아래 상황일때 Thread 분석을 한다.

 

1) 어플리케이션이 Hang 상태일 때

2) 서비스 처리가 늦어질 때

3) CPU 사용량이 높을 때

 

Thread Lock이 원인일수도, 여유 Thread가 없어서 일수도 있다.

SQL 지연일수도, 특정 코드 Stack 에서 막힌것일수도 있어 분석툴로 확인해야한다.

 

하지만 하나의 스냅샷만으로는 정확한 원인파악이 어렵다.

여러개의 스냅샷을 비교하며, 쓰레드의 변화상태를 통해야만 특정 쓰레드를 원인지을수 있다.

 

빠른시간내에 여러개 덤프를 떠서, 순간의 변화사항 분석이 필요하다

( Ex: 5초내 여러개 Thread dump 획득 )

 

 

생성방법

 

1) kill -3 $PID

 

 

2) jstack 활용

 

jps-v 로 PID를 확인 가능하며, ps -ef | grep 을 통해서도 특정 PID를 알 수 있다.

jstack $PID > log.txt

분석

 

일반적으로 쓰레드 덤프 구조는 아래와 같다

"pool-1-thread-13" prio=6 tid=0x000000000729a000 nid=0x2fb4 runnable [0x0000000007f0f000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)at java.net.SocketInputStream.read(SocketInputStream.java:129)at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)- locked <0x0000000780b7e688> (a java.io.InputStreamReader)at java.io.InputStreamReader.read(InputStreamReader.java:167)at java.io.BufferedReader.fill(BufferedReader.java:136)at java.io.BufferedReader.readLine(BufferedReader.java:299)- locked <0x0000000780b7e688> (a java.io.InputStreamReader)at java.io.BufferedReader.readLine(BufferedReader.java:362) 

쓰레드 이름: Thread-(Number) 혹은 pool-(number)-thread-(number)로 지정된 고유이름

우선순위 : 쓰레드의 우선순위

쓰레드 ID

쓰레드 상태

쓰레드 콜스택

 

 

저런 로그들이 쓰레드마다 존재하기에, 육안으로 구별하기는 힘들다.

보통 분석툴을 사용하여 변화사항을 비교한다.

 

 

 

분석툴

 

1) Ibm thread and monitor dump analyzer for java

 

2) fastThread ( https://fastthread.io/ )

 

 

 

분석예시

 

※ 해당부분은 타 블로그에서 분석한 내용을 가져와 서술하였습니다. - CPU 사례

( https://d2.naver.com/helloworld/10963 )

먼저, CPU를 가장 많이 점유하는 스레드가 무엇인지 추출한다.

추출한 결과에서 CPU를 가장 많이 사용하는 LWP(light weight process)와 고유 번호를 확인한다.


[user@linux ~]$ ps -mo pid,lwp,stime,time,cpu -C java
 
PID LWP STIME TIME %CPU
10029 - Dec07 00:02:02 99.5
10039 Dec07 00:00:00 0.1
- 10040 Dec07 00:00:00 95.5


파악한 PID를 통해 thread dump를 획득한다.

"NioProcessor-2" prio=10 tid=0x0a8d2800 nid=0x2737 runnable [0x49aa5000]
java.lang.Thread.State: RUNNABLE
    at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
- locked <0x74c52678> (a sun.nio.ch.Util$1)
- locked <0x74c52668> (a java.util.Collections$UnmodifiableSet)
- locked <0x74c501b0> (a sun.nio.ch.EPollSelectorImpl)


수초내 지속적으로 dump를 획득하여, 해당 Stack 별 변화를 비교해보며 원인을 찾는다.

 

 

 

'서버운영 > 자바 프로세스 관리' 카테고리의 다른 글

Heap dump  (0) 2021.07.16

도커에 대해 설명하기전에 컨테이너 개념에 대해서 먼저 알아야한다.

컨테이너 : 리눅스 커널을 공유하여, 프로세스를 격리된 공간에서 띄우는 기술

 

비슷한 용어로 가상화가 있지만, 둘의 의미는 다르다.

 

먼저 가상화 같은경우

컴퓨터 리소스의 추상화라는, 좀더 넓은 의미를 가지고있다.

 

하지만 주로 Hypervisior를 구동하여 가상머신 ( Virtual Machine ) 을 생성하는 논리적 플랫폼 기술을 의미한다.


VM은 리소스의 추상화와 격리가 되어있지만, 크나큰 단점이 하나 있다.

 

바로 Geust OS의 중복이다.

VM 아키텍처

VM을 하나 생성해, 격리할때마다 Gesut OS 위에 Application을 올리므로

Guest OS 만큼의 리소스가 중복으로 낭비되고 있다.

 

이러한 특징은 MSA ( MicroService Architecture )가 떠오르면서, 큰 단점이 되었다.

2021.07.13 - [분류 전체보기] - MSA ( MicroService Architecture )

 


MSA에서 수백 수천개로 나뉘는 서비스를 위해, 효율적인 리소스 활용은 필수가 되었고

운영체제 수준의 가상화리눅스 커널을 공유하는 컨테이너 기술이 떠오르게 되었다.

 

컨테이너는 모든 컴포넌트마다 OS를 가상화하는것이 아니라

리눅스 커널을 공유하고, APP 단위로 가상화하여 구분하는 개념이다.

 

각 컨테이너는 Cgroup, namespace 개념을 적용해, 격리 및 관리가 진행된다.

 

Cgroup


프로세스들의 격리 및 자원관리 역할을 하는 리눅스 커널 기능
cpu, 디스크, 메모리 등을 다룬다.


Namespace

각 컨테이너는 namespace 단위로 리소스가 관리된다.

(1)  Mnt(파일 시스템 마운트) : 파일시스템 포인트 관리
(2)  Pid(프로세스) : 독립적인 프로세스 공간을 할당
(3)  Net(네트워크) : 네트워크 인터페이스. namespace 간에 network 충돌을 방지 (중복 포트 등)
(4)  Ipc(System IPC) : 독립적으로 프로세스 간의 통신 관리 ( Sahred memory, semaphore 등 )
(5)  Uts(hostname) : 독립적인 hostname 할당
(6)  User(UID) : 독립적인 사용자 할당

 

그중, 대표적인 오픈소스 프로젝트가 Docker 이다.

 

도커 아키텍처


도커 이미지

 

 

이미지란 컨테이너 실행에 필요한 파일과 설정 값등을 포함하고 있는 읽기전용 템플릿이다.

( ex: Ubuntu 이미지에는, Ubuntu 구성을 위한 파일과 환경변수값들이 저장되어있다 )

 

 

특징으로는,

 

1) 변하지 않는다.
2) 하나의 이미지로 여러개의 컨테이너를 구동할 수 있다.
3) Dockerfile을 bulid하면 Image가 생성되고, Image 를 run 하면 컨테이너가 생성된다.
4) Git 처럼 Docker Hub를 통해 쉽게 관리할 수 있다 ( Pull & Push )
5) 레이어 개념을 적용해, 이미지 다운로드시 불필요한 작업을 줄인다

 

※ 도커에서 이미지를 만드는 방식 ( 레이어 )

 

- 여러개의 레이어를 겹쳐서 하나의 F/S처럼 동작하는 이미지를 만든다.

 

예를들어, Hello World를 출력하는 웹페이지를 서비스하는 Image를 만든다고 가정하자.
Base Image를 기반으로, ubuntu OS 레이어와, Nginx 레이어를 올려 하나의 이미지를 만들 것이다.

이 이미지를 누군가 다운받아, Hello Wolrd2라는 image를 만들었을때
index.jsp 내용만 바뀌었을뿐인데 전체 레이어를 다시 받을필요가 없다.

변경된 index.jsp 에 해당하는 레이어만 다시 받음으로써,
Hello World2 이미지를 사용할 수 있다.

 

 

도커의 장점

 

어느곳에서든 동일한 환경을 유지할 수 있다.

  - 개발서버가 존재하여, 운영과 동일환경에서 개발하는 경우는 드물다고 생각된다.

    보통 로컬PC 에서 개발하고, 해당 소스를 시스템에 반영할텐데 몇 가지 문제가 예상된다.

     

   1) 가장 먼저, 로컬PC (윈도우) 에서 만든 서비스는, 시스템 (리눅스)에서 호환되지 않을 가능성이 높을 것이다.

   2) 로컬PC의 환경변수 세팅과 시스템의 환경변수가 다르기 때문에, 동일 아키텍처라도 디플로이가 안될수도 있다.

 

컨테이너 단위로 관리

  - 하나의 OS에 다양한 컨테이너를 띄울수 있으며, 각 컨테이너는 독립된 환경이기 때문에

    다양한 서버들을 운영할 수 있다. ( 자바, 파이썬, 오라클 등등 )

 

유연한 자원관리

  - 고정된 자원을 할당받는것이 아니기 때문에, 자유롭게 Scale up/out 이 가능하다.

 

'IT > 도커도커' 카테고리의 다른 글

(5) 도커 Hello World - 웹페이지  (0) 2021.07.22
(4) 도커 Hello World  (1) 2021.07.20
(3) 도커 명령어  (0) 2021.07.19
(1) Ubuntu에 도커 설치하기  (0) 2021.06.30
(0) Oracle VM 을 통한 Ubuntu 서버 설치  (1) 2021.06.29

MSA란?

 

MSA에 대한 공식적인 정의는 찾을 수 없었다.

그래서 나름대로 MSA의 특징이라고 생각되는 것을 적어보았다.

- 서비스가 작게 나뉘어져있어야하고, 개별 서비스는 독립적인 배포가 가능해야한다.
- API를 통해 각 서비스간 통신한다.
- 각 서비스간 영향도가 최소화 되어야한다.
  ※ DB조차도 중앙관리 될 필요가 없으며, 개별 서비스가 DB를 소유한채 API를 통해서만 데이터를 가져온다.

장점

앞서 작성했던 Monolithic의 단점이, MSA의 장점이 될 수 있다.

( 2021.07.03 - [IT/아키텍처] - Monolithic )

 

다른 서비스들에 영향을 끼치지 않음

  - 독립적인 서비스 구성으로, 배포 실패나 장애 발생시에 시스템 전체에 영향을 끼치지 않는다.

 

요구사항의 빠른 반영이 가능하다

 - 다른팀의 개발을 기다릴 필요없이, 빠르게 개발 및 테스트를 진행할 수 있고, CI/CD가 가능하다.

  ※ CI ( Continuous Integration ) : 지속적 통합으로, 코드의 변경사항이 형상관리 시스템에 계속 반영되어 품질을 유지
                                             개발 / 테스트 / 병합 단계를 의미


     CD ( Continuous Deploy 혹은 Delivery ) : 지속적 서비스 제공 또는 배포. 테스트 및 운영서버로 자동 배포를 의미.

 

배포시간의 감소

  - 기존 Monolithic에서는 몇십, 몇백GB 짜리 소스코드를 디플로이 하느라 시간이 오래걸린다.

    해당시간동안 서비스가 불가능하다는 의미이기도 하며, Time out 으로 디플로이가 실패할 수도 있다.

    

    하지만 MSA에서 소스코드 용량은 KB,MB 단위이기때문에 배포에 오랜시간이 걸리지 않는다.

 

다양한 형태의 아키텍처

  - 각 서비스간에 프로그래밍 언어나 프레임워크에 엮여있지 않아, 다양한 아키텍처 구성이 가능하다

   

 


단점

 

시스템 복잡도 상승

  - 위의 다양한 컴포넌트들에서 보이듯,  각 서비스별 관리에 있어 어느정도 컴포넌트에 대한 지식이 필요하다.

 

성능 하락

  - 서비스간 통신을 모두 API를 통해 진행하기 때문에, latency 및 네트워크 비용 발생

 

데이터 정합성

  - 데이터가 단일 DB가 아닌, 개별 서비스에 종속되어 있기때문에
    관리가 어렵고 정합성 문제가 발생할 수 있다.

'IT > 아키텍처' 카테고리의 다른 글

Rest  (0) 2021.07.29
Monolithic  (0) 2021.07.03

이번에는 DB Link로 데이터베이스에 직접 붙어서, 마이그레이션 하는 방법을 알아보자

 

그 전에, (1) data pump를 통한 데이터 이관과의 차이를 알아보려한다.

2021.07.06 - [DB/Oracle] - 마이그레이션 (1) expdp/impdp

 

1) F/S  VS  Network

 

먼저, data pump 방식은 File System을 통해 이관하기떄문에

 

데이터 크기에 준하는 F/S 용량이 필요하다. ( .dmp 파일만큼 크기 필요 )

 

export 하는 시스템은, 원본데이터 + .dmp 만큼의 F/S 크기가 필요한 셈이다.

 

이는 import 쪽에도 해당되는 얘기로, 데이터의 크기가 크다면 임시 스토리지 할당등의 추가적인 작업이 필요하며,

 

큰 용량의 .dmp 파일을 import 하는쪽으로 옮기기도 쉽지가 않다.

 

 

반면에 DB Link를 통한 마이그레이션은 네트워크를 통하기 떄문에

 

연결만 가능하다면, export 하는 시스템에 추가로 필요한 사항이 없다.

 

또한 import 하는쪽도 데이터 크기의 용량만큼만 필요하다.

 

2) 속도

 

DB Link를 사용하는 쪽이 훨씬 빠르다.

 

로그를 남기지 않고, 직접적으로 데이트를 쓰기 때문이다.

 

Data pump와 DB Link 속도 비교를 한 블로그가 있는데

 

data pump로 90분이 걸리던 것을, DB Link로는 20분만에 끝낼만큼 성능차이가 심하다

 

데이터 환경
서비스 DBMS 버전 : Oracle 9i
전체 데이터 파일 사이즈 : 120G (인덱스 포함)
타겟 테이블 데이터 사이즈 : 26G (인덱스 제외)
네트워크 속도 : 100Mbps (max: 12.5MB/s)

 

https://gywn.net/2012/04/migration_with_dblink_exp_imp/

 

DB Link와 Export/Import를 활용한 데이터 이관 성능 리포트 | gywndi's database

안녕하세요. 한동안 MySQL에 빠져 있다가, 최근 Oracle 데이터 이관 작업 도중 재미난 사례 공유 합니다. DB Link를 통한 CTAS(Create Table As Select)와 Export/Import를 통한 데이터 이관 비교입니다. 서비스 요

gywn.net

 


※ DB Link 란?

네트워크를 통해 다른 데이터베이스 접속 설정을 정의하는 오라클 객체

 

 

조건

 

1) Host Name이나 Oracle SID 가 다를것

 -> 동일 Host에서 Oracle SID마저 같으면 TNS Error 발생

 

2) NLS_CHARACTER_SET 통일

 -> 데이터 이관 시 Character Set 이 다르면 깨질 가능성이 있다.

 

3) 연결 하려는 데이터베이스의 리스너가 켜져있을 것

 

 

문법

 

CREATE (Public) DATABASE LINK [Link 명] CONNECT TO [접속유저] IDENTIFIED BY [유저 패스워드]
USING [네트워크 서비스명-tnsname.ora 內];

 

- Public 옵션을 통해 모든 유저가 링크 사용가능

- tnsname.ora 파일에는 연결하려는 DB 정보가 하기와 같이 있어야한다.

 

====== tnsnames.ora =====
testdb =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = oracle)
    )
  )
=========================

 

 

사용

 

생성

SQL>CREATE DATABASE LINK testlink CONNECT TO scott IDENTIFIED BY tiger
USING testdb

 

조회

SQL>SELECT ename FROM table1@testlink;

 

SYNONYM 생성 및 조회

SQL> CREATE SYNONYM synolink FOR table1@testlink;

SQL> SELECT ename FROM synolink;

 

DB 링크 삭제

SQL> DROP DATABASE LINK test_server;

 

as select를 사용한 마이그레이션 ( 테이블구조까지 복사 )

SQL> DROP TABLE new_table ( 기존 테이블 삭제 )

SQL> CREATE TABLE new_table AS SELECT * FROM table1@testlink;

 

※ Large Object인 LOB타입 데이터가 있는경우는 dblink로 불가능.

   원격 DB간의 LOB 조회,삽입이 안되기 떄문.

-> 중간에 임시 DB를 하나 거쳐서 수행할수는 있음 ( https://ooz.co.kr/280 )

 

출처 : [구루비] http://www.gurubee.net/lecture/1560

'DB > Oracle' 카테고리의 다른 글

데이터 Reorg  (2) 2021.08.03
마이그레이션 (1) expdp/impdp  (0) 2021.07.06

Oracle DB 데이터 마이그레이션이 필요할때, 크게 두가지 방법으로 나뉜다.

 

1) expdp/impdp 명령어를 통해, 파일 기반으로 마이그레이션 수행
2) dblink로 다른 데이터베이스에 직접 붙어, 데이터를 가져오는 방식

 

그중에 먼저, exp/imp 방식을 알아보자


먼저, 오라클 10g 이전에 exp/imp 방식과 expdp/impdp ( data pump ) 방식으로 나뉜다.

 

두 방식은 서로 호환되지 않으며,

 

차이점으로는 1. 속도 및 작업방식  2. 병렬수행  3. Job Control  4. 소요시간 예측 등이 있다.

 

 

- 속도

 

가장 큰 차이는 속도로, 기존 exp/imp의 single stream data unload 방식보다

direct path method 방식을 사용하여, 15~45배 정도 빠르다.

 

direct path method 
- direct I/O를 통하여 OS 메모리를 쓰지않고, 데이터파일에 직접 작성하는 방식

※ [ Direct-path 가 되지 않는 경우 ]
- 클러스터 테이블인 경우
- 테이블에 활성화된 트리거가 존재할 경우
- 글로벌 인덱스를 가진 테이블이 하나의 파티션에 존재 할 경우
- LOB컬럼에 있는 도메인 인덱스
- insert 모드에서 fine_grained access control 이 enable인 경우
- BFILE을 가진 테이블인 경우

 

- 작업방식 ( 병렬수행 가능 )

 

또한, data pump는 Oracle Directory를 통해 OS 물리경로로 접근하기 때문에

Oracle Directory를 매핑해주어야한다.

 

exprot ( 기존 ) : exp 계정/패스워드 file=덤프파일위치

export ( datapump ) 
 - OS 물리경로 확인 : mkdir /data/pump
 - Oracle 디렉토리 지정 : reate directory pump_dir  AS '/data/pump';
 - DBMS 계정에 디렉토리 권한 부여 : grant read,write on directory pump_dir to scott;
 - export 명령 수행 : expdp 계정/PWD direcotry=pump_dir dumpfile={데이터파일명} logfile={로그파일명}
                           full/schema/table/tablespace 중에 모드 선택하여 대상 데이터 선택
   추가옵션 : filesize : 한 파일당 최대크기 / exclude: 특정 오브젝트 제외 /  query : 조건에 맞는 오브젝트만 포함
                 job_name : job name 설정 / parallel : 병렬수행 프로세스 개수 ( 동일한 데이터파일 개수 필요 )

 

- Job Control

 

하기 명령어들을 통해 수행중인 Job의 중단, 재수행, 모니터링등의 Control 가능

 add_file: 덤프파일 추가
 exit: job 작업에서 빠져나감
 parallel: 현재 작업중인 프로세스 개수 조정
 status: 현재 작업 상태를 모니터링 하는 갱신 시간 지정
 kill_job: 해당 작업 완전히 삭제, 이게 작동 안하면 job_name의 테이블을 drop 해야함
 start_job: 중단된 작업 다시 시작
 stop_job: 현재 작업 일시 중단

 

 

- 데이터 예상시간 조회

 

SELECT sid, serial#, sofar, totalwork 
FROM v$session_longops
WHERE opname='job_name대문자'
AND sofar != totalwork ;

 

 

※ Import 시 주의점

 

1) 버전이 다를경우 import 하는 DB의 버전으로 expdp 시에 version 옵션 넣어줄 것2) 스키마, Table space, table에 대하여 exp/imp 환경이 다르다면 remap_스키마/TBS/table 옵션을 사용하여 명시

 

 

 

 

출처 :

 

https://artdap.tistory.com/entry/datapump란 [이제 나의 인생에는 Ctrl+Z 란 없다.]

https://hayleyfish.tistory.com/99 [DB네 생선가게]

'DB > Oracle' 카테고리의 다른 글

데이터 Reorg  (2) 2021.08.03
마이그레이션 (2) DB Link  (1) 2021.07.06

Monolithic ?

 

MSA에 대해 정리하기 전에, 반대되는 개념인 Monolithic을 살펴봤다.

 

흔히 우리가 개발할때 하나의 war나 directory로 묶어서 배포하는 방식을 의미한다.

 

쇼핑몰 홈페이지를 구축한다고 가정하여, Monolithic의 단점과 왜 MSA가 떠오르게 되었는지 서술하려한다.

 

 


 

조그마한 변경도, 시스템 전체에 영향을 줄 수 있다.

프로젝트로 회원가입, 로그인, 장바구니, 구매등의 기능이 있는 홈페이지를 하나 만들었다고 가정하자.

 

고객으로부터 포인트 서비스를 개발해달라는 요청을 받아, 아래와 같이 프로세스를 진행하는 중이다.

 

요구사항 분석 - 설계 - 개발 - 빌드 - 테스트

 

오랜시간에 걸쳐 테스트까지 완료되었고, 운영서버에 배포하고 서비스를 확인하려 했으나...

 

 

다른쪽 코드는 건들지도 않았는데, 메인페이지부터 모든 서비스가 안되기 시작한다.

 


강력한 결합으로, 컴포넌트의 변경이 다른 컴포넌트에 영향을 미침

 

고객 요청사항을 위해, 로그인 방식을 바꾸려고 한다.

 

이 기능은 시스템의 자바버전으로 구현이 어려워서, 버전을 올리고 코드를 반영했다.

 

배포 후, 기능이 잘 동작하는것에 미소짓고 있었는데...?

 

회원가입이 안된다는 VOC가 마구들어오고 있었다.

 

회원가입 중 일부기능이 신규 자바버전과 호환되지 않는 탓이었다.

 


 

고객의 요구사항 반영이 늦어짐

 

크게 데인 우리는, 기준을 높여 배포를 진행하기로 하였다.

 

1) 코드 변경 시, 엄격한 영향도 조사

2) 특정 서비스를 개발도중에, 관련 서비스까지 모두 타팀에서 건들지 말 것

3) 최소한의 서비스 중단을 위해, 고객들이 이용하지 않는 저녁시간 이후에 배포할 것

 

이후에, 하나의 요구사항 반영에는

개발 및 테스트시간보다 기타 절차들에서 시간이 더 걸리게되었고, 우리는 고객들의 불만에 시달렸다...

 

 


배포시간의 증가

 

시간이 지나 우여곡절끝에,  시스템은 안정화되었고 평화로운 나날을 보내고 있었다.

 

어느날 간단한 소프트웨어 패치로, 배포를 하게되었는데

 

반영버튼을 누른뒤로, Admin 페이지는 모래시계만 돌고 서비스도 계속 작동을 하지 않았다

 

특별한 에러로그는 없이, 계속 서비스는 내려가있었고 결국 프로세스를 재시작하기로 하였다.

 

가동하면서 로그를 봤는데 웬걸. 너무나 시스템이 커져버린탓에 몇 십분씩 걸리는 거였다.

 

(1)번째 서비스가 가동되었습니다. ( 19:33 )
(2)번째 서비스가 가동되었습니다.
                     ·
                     ·
                     ·
(153)번째 서비스가 가동되었습니다. ( 19:45 )

개별 프레임워크 구성이 어려움

 

고객 요청으로 154번째 서비스를 추가하려고 한다.

 

마침 쉽고 효과적으로 적용할 수 있는 오픈소르를 찾았고, 기쁘게 관련 문서를 뒤져봤는데.....

 

호환 언어 : Python

 

'IT > 아키텍처' 카테고리의 다른 글

Rest  (0) 2021.07.29
MSA ( MicroService Architecture )  (0) 2021.07.13

+ Recent posts