Skip to content

FEATURE: Add foundation for zk and cluster management#41

Merged
oliviarla merged 1 commit into
developfrom
f1v3/cli
May 8, 2026
Merged

FEATURE: Add foundation for zk and cluster management#41
oliviarla merged 1 commit into
developfrom
f1v3/cli

Conversation

@f1v3-dev
Copy link
Copy Markdown

🔗 Related Issue

⌨️ What I did

arcusctl의 zk/cluster 관리 기능 구현을 위한 기반 구조를 추가합니다.

추가된 패키지

  • internal/topology: ZK 및 Cluster topology.yml 파싱을 위한 구조체
  • internal/store: ~/.arcusctl/ 내부 메타데이터(meta.yml, topology.yml) 저장 및 읽기
  • internal/ssh: SSH 원격 명령 실행 및 SCP 파일 전송

추가된 커맨드

  • arcusctl zk: deploy / start / stop / delete / list / status
  • arcusctl cluster: deploy / start / stop / delete / list / status

전체적인 틀만 잡아놓은 상태이며, 구현은 되어있지 않습니다.

궁금한 점

현재 내부 메타데이터 저장 경로를 아래와 같이 고정해둔 상태입니다.

  • ZK: ~/.arcusctl/clusters/zk/<ensemble-name>/
  • Cluster: ~/.arcusctl/clusters/arcus/<servicecode>/

위와 같이 홈 디렉토리(~/.arcusctl)를 기준으로 고정해두는게 맞는지 의문이 있습니다. 어디서 실행해도 동일한 데이터를 보는 장점이 있지만, 실행 위치 기준으로 관리하게 된다면 환경 및 프로젝트 별로 분리가 가능할 것 같다고 보여집니다.

@f1v3-dev f1v3-dev requested review from namsic and oliviarla April 28, 2026 09:08
@f1v3-dev f1v3-dev self-assigned this Apr 28, 2026
@f1v3-dev f1v3-dev force-pushed the f1v3/cli branch 3 times, most recently from 71599e9 to 856cef0 Compare April 28, 2026 10:26
Copy link
Copy Markdown
Member

@oliviarla oliviarla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

개요 수준에서 리뷰 완료입니다.

Comment thread internal/store/store.go Outdated
@f1v3-dev
Copy link
Copy Markdown
Author

f1v3-dev commented May 6, 2026

#41 (comment) 내용을 아래와 같이 정리합니다.

ARCUSCTL_HOME 환경변수 설정

내부 메타데이터 저장 경로를 결정하는 arcusctl 의 홈 디렉토리의 주소는 환경변수 ARCUSCTL_HOME으로 관리되며, 기본 값은 $HOME/.arcusctl 입니다.

ARCUSCTL_HOME 환경변수는 아래와 같이 사용자가 정의할 수 있습니다.

export ARCUSCTL_HOME=/custom/path/.arcusctl

Copy link
Copy Markdown
Member

@namsic namsic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리뷰 의견 반영된 것처럼 설정 파일 위치를 ARCUSCTL_HOME으로 지정할 수 있도록 하는 것이 좋아 보입니다.

실행 위치에 따라 base path를 달리하는 것은 현재 시점에서 크게 필요하지는 않습니다.
이미 ARCUSCTL_HOME 경로 하위에서 ensemble, servicecode 마다 하위 디렉토리를 두어 관리하는 구조이므로,
한 장비에서 여러 개의 ARCUSCTL_HOME을 두고 스위칭하는 패턴에 대한 요구는 크지 않을 것으로 생각합니다.

Comment thread go.mod
Comment thread cmd/connect.go
Comment thread internal/store/store.go Outdated
Comment on lines +39 to +47
if err := os.WriteFile(filepath.Join(dir, "meta.yml"), metaData, 0644); err != nil {
return err
}

return os.WriteFile(filepath.Join(dir, "topology.yml"), topologyData, 0644)
}

func LoadZKMeta(ensembleName string) (*ZKMeta, error) {
data, err := os.ReadFile(filepath.Join(arcusDir(), "clusters", "zk", ensembleName, "meta.yml"))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

경로, 파일명 등 변동이 없는 문자열들을 상수로 분리하는 것은 어떤가요?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

실수를 줄이는 방향이라서 더 적합할 것 같습니다.

아래와 같은 예시를 기반으로 반영하고자 합니다.

as-is

func SaveZK(ensembleName string, version string, topologyData []byte) error {
	dir := filepath.Join(arcusDir(), "clusters", "zk", ensembleName)

to-be

const (
	clusters    = "clusters"
	zk          = "zk"
	arcus       = "arcus"
	metaYML     = "meta.yml"
	topologyYML = "topology.yml"
)

... 

func SaveZK(ensembleName string, version string, topologyData []byte) error {
	dir := filepath.Join(arcusDir(), dirClusters, dirZK, ensembleName)

혹시 변수명에 관한 네이밍 컨벤션같은게 있을까요?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 변수명에 관한 네이밍 컨벤션같은게 있을까요?

개인적으로 Effective Go를 참고하는 것을 제외하면 프로젝트 수준의 네이밍 컨벤션은 없습니다.

Comment thread internal/store/store.go Outdated
Comment thread internal/ssh/ssh.go
Comment thread internal/topology/loader.go Outdated
@namsic
Copy link
Copy Markdown
Member

namsic commented May 6, 2026

논의 결과, go 버전 업그레이드 및 lint 관련 수정은 개발하는 환경에 따라 의존성 차이가 발생하는 것으로 보입니다.

  • go 1.26.2 버전에서 go mod tidy 수행 시 go.mod 파일의 버전이 자동 수정됨
    • yaml 또는 crypto 의존성이 추가되면서 이에 대한 영향을 받는 것으로 추측
  • golangci-lint 최신 버전 사용 시 errcheck 이슈 발생
    • linux 환경에서 go install …@latest 수행하면 최신 버전(v2.12.1) 대신 v1.64.8 설치됨
    • github에서 가이드하는대로 install.sh 수행하면 최신 버전도 설치 가능한 것으로 보임

따라서 현재 PR의 변경사항을 유지(go 버전 업그레이드 및 conn.Close() 수정을 포함)하고,
CI 및 의존성 버전 관련 문제는 별도 이슈로 다루는 것으로 하겠습니다.

@oliviarla oliviarla requested a review from jhpark816 May 6, 2026 08:41
Copy link
Copy Markdown
Contributor

@jhpark816 jhpark816 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

일부 리뷰

대부분 용어 등의 리팩토링에 관한 내용입니다.

Comment thread internal/topology/cluster.go Outdated
GlobalConfig ClusterConfig `yaml:"global_config"`
}

type ClusterServer struct {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oliviarla @namsic
용어가 괜찮은가요?
MCServer, MemcServer, CacheServer 등이 대안입니다.

아래에 있는 코드를 보니, ZKServer, ZKConfig가 사용되고 있고
따라서 MCServer, MCConfig가 나을 거라고 생각됩니다.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ArcusServer, ArcusConfig 용어가 좋을 것 같습니다.

Memcached라는 용어는 사용하지 않는게 좋겠습니다.

Copy link
Copy Markdown
Member

@namsic namsic May 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

구현 상의 네이밍 자체는 notion의 설계를 그대로 따른 것입니다.

  • zk resource 하위의 server: ZKServer
  • zk resource 하위의 config: ZKConfig
  • cluster resource 하위의 server: ClusterServer
  • cluster resource 하위의 config: ClusterConfig
arcusctl cluster deploy <version> <topology.yml>
arcusctl zk deploy <version> <topology.yml>

cluster topology.yml 예시

servicecode: kr-product-prod
path: /home/arcus/arcus-memcached

zookeeper: zk1:2181,zk2:2181,zk3:2181

servers:
  - address: cache1:11211
  - address: cache2:11211
  - address: cache3:11211
    config:
      listen: 192.168.1.3

global_config:
  threads: 4
  max_connections: 1024
  engine:
    memory_limit: 64
    eviction: true

다른 리뷰 코멘트들도 보면 구현 수준에서의 용어 문제라기보다,
기존 설계를 그대로 따라 구현한 부분에 대한 질문으로 보입니다.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

용어는 두 사람이 판단해 주세요.

cluster는 cache cluster 의미를 줄여서 cluster로 지칭하고,
zk는 zk ensemble 의미를 줄여서 zk로 지칭한 것입니다. 여기까지는 ok입니다.

cache cluster를 의미할 때 cache라고 지칭했으면,
cacheserver, zkserver가 일관적이다고 보았을 것이지만,
clusterserver, zkserver로 지칭하는 것은 어색한 감이 있다고 느껴집니다. 참고 바랍니다.

Comment thread internal/topology/cluster.go Outdated
Role string `yaml:"role"`
}

type ClusterConfig struct {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 개별 캐시 노드에 대한 설정이어서, 용어 검토가 필요합니다.

Comment thread internal/topology/cluster.go Outdated
type ClusterTopology struct {
ServiceCode string `yaml:"servicecode"`
Path string `yaml:"path"`
ZooKeeper string `yaml:"zookeeper"`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ServiceCode 다음에 ZooKeeper가 나오는 순서이면 좋겠습니다.

Path는 어떤 path인가요?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ServiceCode 다음에 ZooKeeper가 나오는 순서이면 좋겠습니다.

현재 순서는 설계 문서 상의 topology.yml 순서에 맞게 구성해둔 상태입니다.

Path는 어떤 path인가요?

원격 서버에 Arcus를 설치할 경로를 의미합니다.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 순서는 설계 문서 상의 topology.yml 순서에 맞게 구성해둔 상태입니다.

topology.yml 도 순서를 변경하는 것이 나을 것 같습니다.

Comment thread internal/store/store.go Outdated
const (
clusters = "clusters"
zk = "zk"
arcus = "arcus"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"arcus" 라는 문자열 대신에 arcus 상수로 정의하여 사용하는 형태가 보편적인가요?

Comment thread internal/store/store.go Outdated
}

func SaveZK(ensembleName string, version string, topologyData []byte) error {
dir := filepath.Join(arcusDir(), clusters, zk, ensembleName)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"clusters", "zk" 라는 문자열을 그대로 사용하는 것이 직관적이지 않는 지 ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위의 리뷰(#41 (comment)) 와 같이 답변을 드리자면

변동이 없는 문자열을 상수로 분리하여 오타를 방지하고, 변경이 필요한 경우 상수 한 곳만 수정하면 되는 장점이 있어서 상수를 사용하였습니다.

조금 더 생각해보니 헬퍼 함수로 경로를 묶는 방식으로 아래와 같은 메서드를 생성해서 사용해도 괜찮을 것 같습니다.

func zkDir(ensembleName string) string {
    return filepath.Join(internal.Config.Home, "clusters", "zk", ensembleName)
}

func clusterDir(serviceCode string) string {
    return filepath.Join(internal.Config.Home, "clusters", "arcus", serviceCode)
}

다만, meta.yml, topology.yml은 여러 곳에서 반복 사용되는 파일명이므로 상수로 유지하는게 좋아보입니다.

Comment thread internal/store/store.go
}

return &meta, nil
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ZKTopology loading 하는 함수를 여기에 두어도 되지 않는 지?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loader.go 의 메서드(LoadZK, LoadCluster)를 store.go로 옮기고 loader.go를 지우는 방향을 말씀하시는게 맞을까요?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loader.go 의 메서드(LoadZK, LoadCluster)를 store.go로 옮기고 loader.go를 지우는 방향을 말씀하시는게 맞을까요?

맞습니다.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

변경하도록 하겠습니다.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조금 더 생각해보니 아래와 같이 역할/책임을 나누는 것이 적절할 것 같습니다.

  • topology 패키지(loader.go): YAML 구조 정의 + 파싱
  • store 패키지(store.go): 저장 경로 기반 파일 관리 (메타데이터, topology 저장 및 조회)

Comment thread internal/store/store.go
}

return names, nil
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아래 용어는 어떤지?

  • ZK => ZKEnsemble
  • Cluster => MCCluster

Comment thread cmd/connect.go
@jhpark816
Copy link
Copy Markdown
Contributor

@oliviarla
Approve 해 두었습니다. 용어 등의 선택은 자체적으로 판단해 주세요.

@f1v3-dev
Copy link
Copy Markdown
Author

f1v3-dev commented May 8, 2026

@oliviarla @namsic

현재 변경한 사항은 아래와 같습니다. 참고해주시면 될 것 같습니다.

변경 사항

cluster.go 용어 번경 (#41 (comment))

  • ClusterServer → CacheServer
  • ClusterConfig → CacheConfig

store.go 상수 (#41 (comment))

func zkBaseDir() string {
	return filepath.Join(internal.Config.Home, "clusters", "zk")
}

func zkDir(ensembleName string) string {
	return filepath.Join(zkBaseDir(), ensembleName)
}

func clusterBaseDir() string {
	return filepath.Join(internal.Config.Home, "clusters", "arcus")
}

func clusterDir(serviceCode string) string {
	return filepath.Join(clusterBaseDir(), serviceCode)
}

@oliviarla oliviarla merged commit 4eaae93 into develop May 8, 2026
1 check passed
@f1v3-dev f1v3-dev deleted the f1v3/cli branch May 12, 2026 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants