-
[Etcd] Watch 기능 알아보기 ( HTTP2, WatchCreateRequest )Etcd 2024. 6. 17. 05:59728x90반응형
- 목차
들어가며.
Etcd 는 Distributed Application 의 상태를 저장하는 저장소로써 동작합니다.
일반적인 분산 시스템은 네트워크적으로 떨어져 존재하는데요.
하지만 이들은 마치 한 몸처럼 동작해야만 합니다.
대표적인 분산 시스템의 예시로써 Kafka 가 존재합니다.
보통 3개 이상의 Kafka 서버는 네트워크적으로 떨어져있지만 Kafka Client 는 Kafka Broker 들이 마치 하나의 시스템인 것처럼 보여집니다.
즉, 분산 시스템은 멀리 떨어져 있지만 한 몸처럼 동작해야한 하는 것이죠.
Kafka 는 Etcd 가 아닌 Zookeeper 를 사용하긴 하지만 Etcd, Zookeepr, Consul 등 이들은 분산 시스템의 상태를 저장하기 위한 저장소로써 동일한 목적을 가집니다.
그리고 이러한 기능의 핵심이 Watch Mechanism 입니다.
Watch Mechanism 은 특정 데이터의 상태가 변화하게 되면, 클라이언트인 Watcher 에게 이 변화를 보고합니다.
예를 들어, 여러 개의 Kafka Broker 들은 서로의 상태 변화에 민감하게 대응해야합니다.
왜냐하면 Leader Broker 가 Down 되면, 다른 Follower Broker 가 새로운 Leader 가 되어야하기 때문이죠.
그래서 각 node 의 상태를 저장하는 Key-Value 데이터를 Zookeeper 에 등록하고, Broker 들을 서로가 서로의 상태를 체크합니다.
만약 한 Broker-1 가 Down 되게되면 Zookeeper 의 Broker-1 데이터의 값이 unhealthy 상태로 변경되며,
Zookeeper 는 모든 Watcher 들에게 이 변화를 보고하게 됩니다.
Etcd 의 Watch Mechanism 도 이와 동일하게 동작합니다.
Application-A 는 자신의 상태를 Etcd 에 저장합니다.
"etcdctl put Application-A Healthy" 와 같은 형식으로 데이터를 생성할 수 있습니다.
그리고 Application-B 는 "Application-A" Key-Value 데이터를 모니터링하는 Watcher 입니다.
만약 Application-A 가 비정상 종료가 되고, "Application-A" 의 Value 가 Unhealthy 로 변경된다면,
Watcher 인 Application-B 는 이에 대한 보고를 Etcd 로부터 받게 됩니다.
그리고 사전에 정의된 Failure Handling 프로세스가 진행될 겁니다.
이번 글에서는 Watch Mechanism 이 실제로 어떻게 동작하는지에 대해서 깊이있게 다루어보도록 하겠습니다.
etcdctl watch.
etcdctl watch 명령어를 통해서 특정 Key 의 데이터를 모니터링할 수 있습니다.
먼저 아래의 명령어를 통해서 1개의 Etcd Docker Container 를 실행합니다.
docker network create etcd docker run --platform linux/amd64 -d --network etcd \ --name etcd1 --hostname etcd1 \ -p 12380:2380 \ -p 12379:2379 \ quay.io/coreos/etcd:v3.5.17 \ /usr/local/bin/etcd \ --data-dir=/var/etcd \ --listen-client-urls=http://0.0.0.0:2379 \ --advertise-client-urls="http://host.docker.internal:12379" \ --listen-peer-urls=http://0.0.0.0:2380 \ --initial-advertise-peer-urls=http://etcd1:2380 \ --initial-cluster="node1=http://etcd1:2380" \ --initial-cluster-state=new \ --initial-cluster-token=etcd \ --name=node1
그리고 아래와 같은 etcdctl watch 명령어를 통해서 특정 Key 에 해당하는 데이터의 변경을 감지할 수 있습니다.
docker run --platform linux/amd64 --network etcd --rm quay.io/coreos/etcd:v3.5.17 \ etcdctl --endpoints=http://etcd1:2379 watch key1
아래의 명령어는 etcdctl put 명령어의 예시입니다.
docker run --platform linux/amd64 --network etcd --rm quay.io/coreos/etcd:v3.5.17 \ etcdctl --endpoints=http://etcd1:2379 put key1 value1
블로그의 특정상 생동감있게 Watcher Process 의 데이터 변경 감지를 보여드리지는 못하지만,
아래의 캡쳐 이미지와 같이 key1 에 해당하는 데이터가 변경된다면 Put KEY VALUE 의 결과를 모니터링할 수 있습니다.
Watch Mechanism 과 HTTP2.
이번에는 Etcd Watch 기능를 네트워크 관점에서 이야기해보려고 합니다.
Etcd 는 통신을 위해서 일반적으로 gRPC 를 사용합니다.
그리고 AppendEntries, RequestVote, WatchCreateRequest 등의 대표적인 RPC 함수들이 존재합니다.
gRPC 의 중요한 두가지 특징이 있는데요.
하나는 HTTP2 프로토콜을 사용한다는 점, 그리고 다른 하나는 ProtoBuf 직렬화 방식을 사용하는 점입니다.
특히 Watch Mechanism 과 HTTP2 프로토콜을 Persistent Connection 이라는 관점에서 중요한 역할을 수행하는데요.
이 부분에 대해서 이야기해보도록 하겠습니다.
Etcd 의 클라이언트가 Watcher 로써 동작하기 위해서는 Etcd 와 Watcher 가 지속적인 네트워크 연결이 되어야만 합니다.
왜냐하면 클라이언트는 일반적인 서버처럼 네트워크 소켓을 만들어 특정 Port 를 리스닝하는 구조가 아니기 때문입니다.
그래서 Etcd 에게 어떠한 데이터의 변화가 감지되면 Watcher 인 클라이언트에게 이를 보고해야하는데,
네트워크 트래픽을 리스닝하고 있지 않는 Etcd 클라이언트에게 이를 보고하기 위해서 지속적인 네트워크 연결이 되어 있어야만 합니다.
HTTP 1.1 의 구조는 근본적으로 일회성 연결을 지원합니다.
Keep-Alive 설정이 있긴 하지만 이는 지속적인 네트워크 연결과 맞지 않습니다.
하지만 Etcd 는 gRPC 를 사용하고, gRPC 가 HTTP2 프로토콜을 사용하기 때문에 HTTP2 의 지속적인 네트워크 연결 구조의 힘입어
Watcher 인 클라이언트와 Etcd 는 지속적인 네트워크 연결이 가능합니다.
( 추후에 HTTP2 에 대한 새로운 주제로 글을 하나 작성해보도록 하겠습니다. )
Watcher 와 TCP 커넥션 관계 살펴보기.
일반적으로 HTTP 연결은 TCP 레이어 위에서 동작하게 됩니다.
etcdctl watch 명령어를 통해서 Etcd 의 특정 Key 를 모니터링하게 될 때에 내부적으로 어떻게 동작하게 되는지 살펴보겠습니다.
먼저 저는 2개의 etcdctl watch 명령를 실행하여 2개의 Watcher 프로세스를 실행합니다.
그리고 아래의 이미지는 netstat 를 통해서 확인되는 2개의 TCP 연결의 상태입니다.
각 TCP 커넥션은 etcd1:2379 주소와 연결되며, 이는 Etcd Docker Container 에 해당합니다.
그리고 각각의 Watcher Process 는 46828 과 38054 port 를 사용하고 있습니다.
즉, Watcher Process 는 TCP Client 에 해당하게 됩니다.
아래의 결과는 ps 명령어로 확인되는 실행 중인 Process 목록입니다.
저의 개발 환경에 ARM 기반의 컴퓨터라서 Process Command 에 rosetta 가 보이긴하지만, etcdctl watch 로 실행된 Process 2개가 구동되고 있습니다.
# ps auxww USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND 1001 1 0.0 0.1 1967348 34576 ? Ssl 05:14 0:00 /run/rosetta/rosetta /opt/bitnami/etcd/bin/etcdctl etcdctl --endpoints=http://etcd1:2379 watch key1 1001 23 0.0 0.0 726004 6744 pts/0 Ss 05:14 0:00 /run/rosetta/rosetta /usr/bin/bash bash 1001 29 0.0 0.1 1967360 35944 pts/0 Sl+ 05:15 0:00 /run/rosetta/rosetta /opt/bitnami/etcd/bin/etcdctl etcdctl --endpoints=http://etcd1:2379 watch key1 root 517 0.0 0.0 726040 6752 pts/1 Ss 05:24 0:00 /run/rosetta/rosetta /usr/bin/bash bash
반응형'Etcd' 카테고리의 다른 글
[Etcd] WAL Log (Write Ahead Log) 알아보기 (0) 2024.06.17 [Etcd] --listen-peer-urls 설정 알아보기 (--initial-advertise-peer-urls) (0) 2024.06.17 [Etcd] --initial-cluster 설정 알아보기 (0) 2024.06.16