etcd

  • 분산 Key-Value 저장소
  • Go로 작성됨
  • Kubernetes의 설정 저장소로 사용하면서 유명해짐

etcd 실행

./etcd

REST API

# etcd는 REST API 제공함
curl -L http://localhost:2379/version

# v2
# 추가
curl -L http://localhost:2379/v2/keys/foo -XPUT -d value="bar"
# 조회
curl http://localhost:2379/v2/keys/foo
# 삭제
curl http://localhost:2379/v2/keys/foo-XDELET

# v3
# 추가
curl -L http://localhost:2379/v3/kv/put \
  -X POST -d '{"key": "Zm9v", "value": "YmFy"}'
# 조회
curl -L http://localhost:2379/v3/kv/range \
  -X POST -d '{"key": "Zm9v"}'
# 삭제
curl -L http://localhost:2379/v3/kv/deleterange \
  -X POST -d '{"key": "Zm9v"}'

etcdctl

  • A command line client for etcd
  • CRUD

      # 추가
      ./etcdctl --endpoints=localhost:2379 put foo bar
    
      # 조회
      ./etcdctl --endpoints=localhost:2379 get foo
    
      # 삭제
      ./etcdctl --endpoints=localhost:2379 del foo
    
  • Prefix

    
      ./etcdctl --endpoints=localhost:2379 put web1 value1
      ./etcdctl --endpoints=localhost:2379 put web2 value2
      ./etcdctl --endpoints=localhost:2379 put web3 value3
    
      # prefix 조회
      ./etcdctl --endpoints=localhost:2379 get web --prefix
    
      # prefix 삭제
      ./etcdctl --endpoints=localhost:2379 del web --prefix
    
  • Clustering

      TOKEN=token-01
      NAME_1=machine-1
      NAME_2=machine-2
      NAME_3=machine-3
      HOST_1=host1
      HOST_2=host2
      HOST_3=host3
      CLUSTER=${NAME_1}=http://${HOST_1}:12380,${NAME_2}=http://${HOST_2}:12381,${NAME_3}=http://${HOST_3}:12384
    
      THIS_NAME=${NAME_1}
      THIS_IP=${HOST_1}
      ./etcd --data-dir=data.etcd --name ${THIS_NAME} \
              --initial-advertise-peer-urls http://${THIS_IP}:12380 --listen-peer-urls http://${THIS_IP}:12380 \
              --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://${THIS_IP}:2379 \
              --initial-cluster ${CLUSTER} \
              --initial-cluster-token ${TOKEN} 
    
      ...
      ...
    
      ENDPOINTS=$HOST_1:2379,$HOST_2:2479,$HOST_3:2579
    
      # 클러스터링 멤버 조회
      ./etcdctl --endpoints=$ENDPOINTS member list
    
    • –name : 이 멤버의 이름. 기본값 ‘default’
    • –initial-advertise-peer-urls : List of this member’s peer URLs to advertise to the rest of the cluster.
    • –listen-peer-urls : List of URLs to listen on for peer traffic.
    • –advertise-client-urls : List of this member’s client URLs to advertise to the public. 지정된 URL을 다른 노드, 클라이언트, 프록시에게 알린다.
    • –listen-client-urls : List of URLs to listen on for client traffic. 클라이언트가 연결할 URL
    • –initial-cluster : 기동할 때 클러스터링 할 멤버의 URL
    • –initial-cluster-token : 각 클러스터를 구분하기 위한 key

jetcd

  • etcd v3의 공식 자바 기반의 클라이언트
  • 다른 라이브러리들은 v2만 지원
<dependency>
			<groupId>io.etcd</groupId>
			<artifactId>jetcd-core</artifactId>
			<version>0.5.4</version>
</dependency>
// create client
Client client = Client.builder().endpoints("http://localhost:2379").build();
KV kvClient = client.getKVClient();

ByteSequence key = ByteSequence.from("test_key".getBytes());
ByteSequence value = ByteSequence.from("test_value".getBytes());

// put the key-value
kvClient.put(key, value).get();

// get the CompletableFuture
CompletableFuture<GetResponse> getFuture = kvClient.get(key);

// get the value from CompletableFuture
GetResponse response = getFuture.get();
response.getKvs().get(0).getValue();

// delete the key
kvClient.delete(key).get();

// prefix
ByteSequence preifx = ByteSequence.from("/bxg/".getBytes());
GetOption getOption = GetOption.newBuilder().withPrefix(preifx).build();

List<KeyValue> keyValues = kvClient.get(preifx, getOption).get().getKvs();
keyValues.get(0).getValue().getBytes()

기타

  • etcd는 계층적인 키-값 방식을 제공한다고는 함..

  • v2에서는 계층적으로 key를 구별할 수 있었으며, REST API로도 쉽게 조작할 수 있음

      # feature-flags를 디렉토리로 가지는 하위 키 값
      curl http://localhost:2379/v2/keys/feature-flags/verbose-logging -XPUT -d value="true"
      curl http://localhost:2379/v2/keys/feature-flags/redesign -XPUT -d value="false"
    
      # 하위 키값을 모두 조회
      curl http://localhost:2379/v2/keys/feature-flags
    
      # 하위 키값을 모두 삭제 및 자신의 디렉토리도 삭제
      curl http://localhost:2379/v2/keys/feature-flags?dir=true -XDELETE
    
  • v3에서는 계층적이라고는 말하지만, 계층적이라고 볼 수 없는 형태로 제공함. range 방식

      # feature-flags를 디렉토리로 가지는 하위 키 값
      ./etcdctl --endpoints=localhost:2379 put /feature-flags/verbose-logging true 
      ./etcdctl --endpoints=localhost:2379 put /feature-flags/redesign  false
    
      # 하위 키값을 모두 조회
      ./etcdctl --endpoints=localhost:2379 get /feature-flags/ --prefix
    
      # 하위 키값을 모두 삭제
      ./etcdctl --endpoints=localhost:2379 del /feature-flags/ --prefix
    
  • e3ch : v3에서 계층적으로 제공을 하지 않아 따로 만든 오픈소스

    • There are directory and key-value in etcd v2, which is convenient to manage the key-value store. But etcd v3 only supports flat key-value space (see #633).Though you could use prefix to adjust the new API, it is not easy to manage key-value store or make the structure clearly. e3ch is built for making etcd v3 ‘look like’ a key-value store supporting hierarchy.

참조

https://www.joinc.co.kr/w/man/12/etcd

https://etcd.io/docs/current/dev-guide/api_grpc_gateway/

https://github.com/etcd-io/jetcd

https://github.com/soyking/e3ch