# 분산 시스템에서의 시간 동기화 사례 분석

#### 1. 분산 시스템에서의 시간 동기화 개요

분산 시스템에서 시간 동기화는 매우 중요한 요소이다. 각 노드는 독립적인 클록을 가지고 있으며, 네트워크 지연, 클록 드리프트 등의 문제로 인해 시간이 일치하지 않을 수 있다. 이러한 시간 차이는 노드 간 데이터 통신, 명령 처리, 로깅 등에 영향을 미치며, 특히 실시간 시스템에서는 심각한 성능 저하나 오류를 발생시킬 수 있다.

시간 동기화를 해결하기 위해 여러 가지 방법이 사용되며, 그 중 대표적인 방법으로는 **NTP(Network Time Protocol)**, **PTP(Precision Time Protocol)**, **ROS2의 time API** 등이 있다.

#### 2. 시간 동기화 방식

**네트워크 시간 프로토콜 (NTP)**

NTP는 인터넷 상에서 시간이 다른 컴퓨터 시스템을 동기화하는 표준 프로토콜이다. 일반적으로 NTP 서버로부터 클라이언트가 주기적으로 시간을 받아와 각 시스템의 클록을 수정한다. NTP는 비교적 오랜 역사를 가지고 있으며, 일반적인 분산 시스템에서 널리 사용된다.

하지만, NTP는 **마이크로초** 또는 **밀리초** 수준의 시간 정밀도를 제공하기 때문에, 매우 높은 정밀도가 필요한 시스템에서는 한계가 있을 수 있다. 특히 **ROS2**와 같이 로봇, 산업용 시스템, 드론과 같은 실시간 성능이 중요한 환경에서는 더 높은 정밀도의 시간 동기화 방법이 요구된다.

**정밀 시간 프로토콜 (PTP)**

PTP는 IEEE 1588 표준에 기반한 시간 동기화 프로토콜로, **나노초** 수준의 시간 동기화를 가능하게 한다. PTP는 하드웨어 타임스탬프 기능을 사용하여 네트워크 지연에 영향을 덜 받으며, 분산 시스템에서의 정밀한 시간 동기화를 제공한다. 특히, PTP는 로봇 공학, 통신, 금융 등 정밀한 시간 동기화가 중요한 산업에서 많이 사용된다.

다음과 같은 PTP의 시간 동기화 과정이 있다:

1. 마스터 노드가 슬레이브 노드에 현재 시간을 전송한다.
2. 슬레이브 노드는 마스터로부터 받은 시간과 자신의 클록을 비교해 시간 오차를 계산한다.
3. 슬레이브 노드는 오차를 보정해 자신의 클록을 조정한다.

#### 3. 분산 시스템에서 시간 동기화의 문제

**클록 드리프트**

각 노드의 클록은 조금씩 다르게 흐를 수 있다. 이를 \*\*클록 드리프트(Clock Drift)\*\*라고 하며, 분산 시스템의 시간 동기화 정확도를 떨어뜨리는 주요 요인이다. 클록 드리프트는 시간이 지남에 따라 누적되어, 일정 주기마다 동기화를 수행해야 하는 이유가 된다.

클록 드리프트를 수식으로 표현하면 다음과 같다.

$$
\Delta t\_{\text{drift}} = \mathbf{t}\_A - \mathbf{t}\_B
$$

여기서, $\mathbf{t}\_A$는 노드 A의 시간, $\mathbf{t}*B$는 노드 B의 시간이다. 시간 $\Delta t*{\text{drift}}$는 시간이 지남에 따라 누적되며, 이를 보정하지 않으면 노드 간 데이터 처리 및 이벤트 발생 시간에 차이가 생깁니다.

**네트워크 지연**

시간 동기화에서 또 다른 중요한 문제는 **네트워크 지연**이다. 네트워크를 통해 노드 간 시간 정보를 교환할 때, 통신 경로 상에서 발생하는 지연으로 인해 실제 시간 동기화에 오차가 발생할 수 있다. 네트워크 지연은 고정된 값이 아니며, 네트워크 상황에 따라 달라지므로 이를 예측하고 보정하는 것이 필요하다.

네트워크 지연 $\Delta t\_{\text{network}}$을 고려한 클록 동기화 식은 다음과 같이 표현된다:

$$
\mathbf{t}*{\text{sync}} = \mathbf{t}*{A} + \frac{\Delta t\_{\text{network}}}{2}
$$

여기서, $\mathbf{t}\_{\text{sync}}$는 동기화된 시간, $\mathbf{t}*A$는 노드 A의 시간, $\Delta t*{\text{network}}$는 네트워크 지연 시간이다. 네트워크 지연의 절반을 더하여 동기화 시간을 계산하는 방식이다.

#### 4. ROS2에서의 시간 동기화 적용

ROS2에서는 시간 동기화를 위해 **ROS Time**을 사용한다. ROS Time은 두 가지 모드를 제공하는데, 하나는 실제 시스템 시간을 사용하는 **System Time**이고, 다른 하나는 시뮬레이션이나 소프트웨어에서 시간을 제어할 수 있는 **Simulation Time**이다. 이를 통해 노드 간의 시간 동기화가 이루어진다.

**시스템 시간과 시뮬레이션 시간**

* **System Time**: 실제 물리적 클록에 기반하여 노드 간의 시간을 동기화한다. 이 방식은 하드웨어 클록을 사용하여 동작하며, 물리적 세계에서 실시간 데이터를 처리할 때 사용된다.
* **Simulation Time**: 시뮬레이션 환경에서 특정 시간 간격을 기준으로 동기화되며, 실제 시간이 아닌 가상 시간이다. 시뮬레이션에서 데이터 재생, 테스트 등을 할 때 유용하다.

**타이머와 주기적 작업 관리**

ROS2에서 주기적 작업은 **타이머**를 사용하여 처리된다. 타이머는 일정한 간격으로 콜백을 호출하여, 반복 작업을 수행하게 한다. 타이머를 통해 주기적인 노드 간 통신, 센서 데이터 처리, 상태 업데이트 등이 이루어지며, 이때 시간 동기화가 매우 중요한 역할을 한다.

타이머의 동작은 다음과 같이 설정할 수 있다:

```cpp
auto timer = this->create_wall_timer(
  std::chrono::milliseconds(100),
  std::bind(&NodeClass::callback, this)
);
```

위 코드는 100ms 주기로 콜백을 호출하여 주기적인 작업을 처리하는 예이다.

**실시간 노드 구현에서의 타이머 활용 전략**

실시간 시스템에서는 타이머의 지연을 최소화하고, 각 노드 간의 시간 동기화를 정확하게 유지하는 것이 중요하다. 특히, 타이머 간격이 짧을수록 클록 드리프트 및 네트워크 지연이 성능에 큰 영향을 미칠 수 있다. 따라서, 실시간 시스템에서는 정밀한 타이머 설정 및 네트워크 지연을 고려한 동기화 알고리즘이 필요하다.

**ROS2에서 시간 동기화를 위한 API**

ROS2에서는 시간 동기화를 위한 몇 가지 API를 제공한다. 대표적으로 **rclcpp::Clock** 클래스는 시스템 시간이나 시뮬레이션 시간을 사용할 수 있도록 설정할 수 있다. 다음과 같은 방식으로 사용할 수 있다:

```cpp
rclcpp::Clock::SharedPtr clock = std::make_shared<rclcpp::Clock>(RCL_ROS_TIME);
rclcpp::Time now = clock->now();
```

위 코드는 ROS 시간을 기반으로 현재 시간을 가져오는 예이다. 이렇게 얻은 시간은 각 노드 간에 동기화된 형태로 사용할 수 있다.

**노드 간 시간 동기화 문제 해결 방안**

ROS2에서 시간 동기화의 핵심은 각 노드가 동일한 시간을 기준으로 작업을 수행하도록 하는 것이다. 이를 위해서는 아래와 같은 방법들을 사용할 수 있다:

1. **네트워크 지연 보정**: 네트워크 통신에서 발생하는 지연을 보정하여 클록 동기화를 수행한다. 이를 위해 PTP와 같은 고정밀 시간 동기화 프로토콜을 사용하는 것이 유용하다.
2. **주기적 클록 동기화**: 각 노드는 주기적으로 마스터 노드와 클록을 동기화하여 클록 드리프트를 최소화한다.
3. **시뮬레이션 환경에서는 Simulation Time을 사용**: 시뮬레이션에서 주기적 작업을 동기화하고 테스트하는 데 유용하다.

**시간 지연(Latency) 문제 해결 방안**

시간 지연은 네트워크 성능에 큰 영향을 미치며, 노드 간의 통신이 실시간으로 이루어지지 않을 경우 동기화 문제가 발생할 수 있다. 이를 해결하기 위해서는 다음과 같은 방법들이 있다.

* **네트워크 최적화**: 네트워크 설정을 최적화하여 지연 시간을 줄이다.
* **고정밀 시간 프로토콜 사용**: NTP보다 정밀한 PTP를 사용하여 시간 동기화 정확도를 높인다.
* **QoS 정책**: ROS2의 QoS(품질 서비스) 정책을 통해 네트워크 지연을 최소화하고 메시지 손실을 줄일 수 있다.

**시간 동기화에 mermaid를 적용한 시각화**

{% @mermaid/diagram content="sequenceDiagram
participant Node\_A
participant Node\_B
Node\_A->>Node\_B: 현재 시간 요청
Node\_B->>Node\_A: 시간 전달 (t\_B)
Node\_A->>Node\_A: t\_A와 t\_B 비교 및 동기화" %}

위 시퀀스 다이어그램은 두 노드 간 시간 동기화 과정의 간단한 흐름을 나타낸다. Node A가 Node B에 현재 시간을 요청한 후, Node A는 받은 시간을 기준으로 자신을 동기화한다.
