본문 바로가기

Distributed System/이론 공부

분산시스템) 코드 마이그레이션

Code migration

더 크게 보면 process migration으로 볼 수 있다. 실행 중인 프로그램을 한 컴퓨터에서 다른 컴퓨터로 이동시키는 것이 좋을 때가 있다. 그때 이동을 어떤식으로 하는 것이 좋을까.

1. Reasons for migrating code

Performance improvement

어떤 서버 프로세스가 어떤 머신에서 돌고 있었는데 해당 머신이 로드가 많이 걸린다고 가정해보자. 부하가 별로 없는 서버가 있다면 돌고 있는 프로세스를 해당 서버로 이동시키면 성능이 향상될 것이다. 분산 시스템에서 주로 성능 저하 문제가 발생하는 이유는 컴퓨팅 성능보다 통신 문제가 더 많다.
예를 들어 거대한 DB를 다루는 서버가 있다고 가정해보자. 디비 query를 요청하는 부분을 client에서 서버로 네트워크를 통해 하지 말고 query를 요청하는 client의 부분을 server로 옮겨서 서버에서 다 하고 최종 결과만 client가 받도록 하면 통신 횟수를 줄일 수 있다.

Dynamically configured distributed systems

마이그레이션을 통해 시스템을 한 코드에 종속되는 것이 아니라 상황에 따라 프로토콜이나 클라이언트가 돌리는 프로그램 자체를 바꿀 수 있다. 클라이언트쪽에서 돌아가는 코드를 필요할 때 다른 원격지인 code repository에서 다운로드하여서 실행시키는 것이다. 클라이언트가 옛날 코드를 통해 실행되고 있었을 때 더 나은 코드를 받아서 실행시키면 퍼포먼스가 더 좋아질 수 있다. 실행 중에 필요한 부분만 다운로드할 수 있으면 Dynamically configured 될 수 있다.

Dynamic Configured

이런 방식을 사용하면 client는 전체 코드를 다운받을 필요 없고 필요할 때 필요한 부분만 다운로드할 수 있다. 인터페이스만 표준화되어있다면 궁극적으로 클라이언트의 동작 자체를 완전히 바꿀 수 있다.
이렇게 했을 때 단점은 보안의 문제점이 생길 수 있다.

2. Models for code migration

Process components

(ㄱ) Code segment

프로그램을 실행하는데 필요한 instruction 집합을 포함하는 부분이다.

(ㄴ) Resource segment

프로그램이 사용하는 외부 자원을 포함하는 부분이다. 파일, 소켓, 프린터, 이외의 주변 장치 등이 있다. 한 머신에서 다른 머신으로 이동할 때 리소스 부분은 옮기기 어려워진다.

(ㄷ) Execution segment

실행중일 때 실행하는데 필요한 현재 실행 상태(execution state)에 대한 데이터를 옮겨야 한다. execution state는 레지스터 값, 스택 정보, 프로그램 카운터 등 주로 OS에서 관리되는 데이터이다.

Mobility models

– Weak vs. strong mobility
– Sender-initiated vs. receiver-initiated mobility

(ㄱ) Weak mobility

code segment만 이동시킨다. 예로 Java applets이 있다. 원래 돌아가는 자바 코드는 웹서버에 있고 웹 브라우저에서 자바 애플릿을 실행하면 해당 애플릿이 웹서버에서 브라우저로 코드가 이동한다. 다 다운되면 브라우저 상에서 애플릿이 실행된다. 따라서 코드가 크면 실행을 시작하기까지 오래 걸린다. 일단 다 다운이 되면 로컬에서 실행하는 것이기 때문에 빠르다. 애플릿은 무조건 처음부터 실행된다.
장점은 간단하다는 것이다.

코드가 이동해서 실행되어야 하는데 target process에서 전송된 코드가 실행되는지, 받는 쪽에서 코드를 실행시키기 위해 별도의 프로세스를 띄워서 실행시키는지에 따라 구분된다. 애플릿인 경우 별도의 프로세스를 새로 생성해서 하는 것이 아니고 웹브라우저 프로세스가 실행시킨다. 대신 보안 문제가 생길 수 있다.

(ㄴ) Strong mobility

code segment와 execution segment를 이동시킨다. 이게 가능하려면 OS단에서 프로세스 간에 context switch가 일어나는 것을 머신 간에 가능해야 한다. 돌고 있는 프로세스가 실행 중인 것을 잠시 멈추고 다른 머신에서 멈췄던 지점부터 다시 시작이 가능해야 한다.
더 일반적인 접근이지만 구현하기 더 어렵다.

지금 돌고 있는 프로세스 자체를 옮기는 것과 복제하는 것으로 나눌 수 있다. cloning 하는 것은 cloning에 필요한 데이터만 복제하여 그쪽에서 새로운 프로세스를 만드는 것이고 프로세스 자체는 전부 다 옮긴는 것이다.

(ㄷ) Sender-initiated mobility

마이그레이션을 보내는 쪽에서 시작하는 것이다. 프로그램을 서버 쪽에 업로드하는 것, 검색 엔진에서 서치 agent를 여러 웹서버로 보내는 것 등이 있다.

(ㄹ) Receiver-initiated mobility

마이그레이션을 받는 쪽에서 시작하는 것이다. 대표적인 예로 java applets이 있다. 두 가지를 비교하면 receiver가 sender보다 간단할 수 있다. 받는 쪽에서는 스스로가 누구인지 인증하지 않고 익명으로 코드를 받을 수 있는 경우가 있지만 보내는 쪽에서는 인증 절차를 거치고 보내야 하는 경우가 대부분이다.

Model for Code Migration

Migration and local resources

resources는 쉽게 이동시킬 수 없다. OS에 종속된 자원인 TCP 소켓의 경우 이동시켰을 때 의미가 없게 된다. 다른 예로 메모리 주소의 값을 이동시켜도 의미 없어진다. 이럴 경우 글로벌 링크를 만들어서 리소스는 이전 것에서 계속 사용하는 방법이 있다. 특정 파일에 대해 absolute URL을 만드는 것이 이런 경우이다. 또 다른 방법은 리소스 종류 중에 이전에 쓰던 리소스와 동일한 리소스가 새로 옮겨가는 것에 있다면 그쪽에 있는 리소스를 새로 쓰는 방법이 있다.

process-to-resource binding

리소스와 그것을 사용하는 프로세스와의 관계를 말한다. 프로세스가 해당 리소스를 어떻게 사용할 수 있을지이다.

(ㄱ) id

여기서 id는 unique 한 id이다. 프로세스가 id를 통해 리소스를 access 한다는 것은 해당 리소스가 단 하나라는 의미이다. 이럴 경우 가장 강하게 binding 되어있다고 한다.

(ㄴ) value

리소스의 값을 가지고 access 하는 경우이다. id는 다르지만 value가 같으면 사용할 수 있는 리소스가 된다. binding이 더 느슨하다고 볼 수 있다. 예를 들면 프로그램에서 standard library를 사용하는데 이동한다면 같은 value를 가진 library가 있다면 그대로 사용할 수 있다.

(ㄷ) type

리소스의 종류를 가지고 access하는 경우이다. value보다 더 느슨하게 binding 된 것이다. 어떤 프로세스가 파일 type의 리소스를 사용 중이었는데 다른 곳으로 옮겨졌을 때 꼭 그 파일이 아니더라도 그냥 파일 type의 리소스면 사용할 수 있다.

resource-to-machine binding

(ㄱ) Unattached resources

머신에 종속적이지 않은 자원이다. 하드웨어에 의존적이지 않기 때문에 이동하기 자유롭다. 예를 들어 일반적인 데이터 파일은 이동이 용이하다.

(ㄴ) Fastened resources

하드웨어에 완전히 종속적인 것은 아니라 이동은 가능하나 실질적으로 이동하기 위해선 비용이 큰 리소스이다 예를 들어 local databese나 complete Web sites가 있다. 가능은 하지만 시간이 매우 오래 걸린다.

(ㄷ) Fixed resources

하드웨어에 완전히 종속적이고 이동하기 힘들다. 예를 들어 local devices나 소켓 같은 local communication end points가 있다.

Local Resource Migration

케이스를 따지면 9가지가 나온다. 각 경우에 대해 이동이 가능한지 구분이 되면 좋은데 특정 타입의 리소스다 하더라도 상황에 따라 이동이 가능할 수도 있고 가능하지 않을 수도 있다.

  • MV: 이동 가능하다.(기존에 사용하던 리소스를 그대로 사용하고 싶을 때)
  • GR: 글로벌 레퍼런스를 둔다.(기존에 사용하던 리소스를 그대로 사용하고싶을 때)
  • RB: 이동한 곳에서 다시 바인딩한다.
  • CP: value가 같은 리소스로 복사한다.
(i) by identifier

 

1. Unattached resource
id에 의해 구분되고 unattached 하면 대부분 MV 이동이 가능하지만 안될 경우 GR 글로벌 레퍼런스를 사용하면 된다는 의미이다. 해당 리소스를 다른 것에서도 사용하는 shared resource라면 이동할 수 없다.

 

2. Fastened or fixed resource
이동 자체가 안되므로 글로벌 레퍼런스를 만드는 것이 최선이다. 글로벌 레퍼런스를 둔다는 것은 리소스를 옮기지 않고 그 위치에 그대로 두고 사용한다는 것이다. 예를 들어 대용량 데이터라면 이동하기 힘들다. 또 다른 예로 소켓의 경우 새로 만든 곳으로 이전 소켓에서 forwarding 시켜줄 수 있다. 이런 식으로 하기 싫으면 이전 프로세스와 기존에 통신하던 외부 프로세스에게 바뀐 곳을 알려줄 수 있다.

 
(ii) by value

 

1. Unattached resource
옮길 수 있다면 프로세스와 같이 옮긴다. 공유 리소스의 경우 글로벌 레퍼런스를 둔다.

 

2. Fastened or fixed resource
id와 마찬가지로 이동 자체가 안되므로 글로벌 레퍼런스를 만드는 것이 최선이다. fixed resource의 예로 memory가 있다. 원격지에 있는 메모리로 접근하는 기술을 쓰면 된다. fastened resource의 예로 runtime libraries이 있다. 이동한 새 머신에 같은 값을 가지는 리소스가 있으면 그대로 사용하거나 글로벌 레퍼런스를 사용할 수 있다.

 
(iii) by type

 

타입만 같으면 되는 경우 리 바인딩해서 사용한다. RB가 불가능한 경우 CP나 GR를 통해 사용한다.

3. Migration in heterogeneous systems

이동하려는 플랫폼이 하드웨어나 OS가 다른 heterogeneous systems이라면 이동하기 어렵다.

migrate entire environments

가상 머신 기술을 통해 OS를 포함한 메모리 스냅샷을 다른 머신으로 이동시킨다. 이렇게 하는 이유는 migration 중에도 서비스가 멈추지 않고 계속 지원하기 위해서이다.

migration of entire memory

메모리 전체 이미지를 어떻게 이동시킬지이다. 우선 간단한 방법은 다 멈추고 이동시키는 것이다. 이러면 마이그레이션 하는 동안에는 이용하지 못하는 단점이 있다. 멈추지 않고 보내기 위해서는 일단 계속해서 메모리 페이지 부분을 보내고 다 보낸 이후에 보내면서 변경된 메모리 부분에 대해 다시 보낸다. 다른 방법은 새 머신 쪽에서 그때그때 필요한 부분의 메모리 페이지만 가져오는 것이다. 필요한 부분만 가져와서 바로 시작하고 on-demand로 필요한 부분만 계속 가져온다. 세 방법 중 가장 migration 시간이 긴 것은 마지막 방법이다. 이전 머신이 다 migration 될 때까지 계속 켜놔야 한다.

'Distributed System > 이론 공부' 카테고리의 다른 글

Middleware Protocol  (0) 2020.12.21
분산시스템) 커뮤니케이션  (0) 2020.08.26
분산시스템) 서버 클러스터  (0) 2020.08.19
분산시스템) 서버  (0) 2020.08.16
분산시스템) 클라이언트  (0) 2020.08.16