본문 바로가기
프로그래밍

👨‍💻 [Go] Go 에서 sync.Map 은 무엇이며, 어떻게 활용할 수 있나요?

by 밝음의기둥 2025. 1. 8.
반응형

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."


👨‍💻 안녕하세요, 윌리 프로젝트의 윌리 입니다.

Go 에서 sync.Map 은 무엇이며, 어떻게 활용할 수 있는지 간략히 알아보았습니다.


질문 >

Go 에서 sync.Map 은 무엇이며, 어떻게 활용할 수 있나요?

답변 >

Go의 sync.Map

sync.Map은 Go 표준 라이브러리의 동시성 안전한 맵 구조체로, 여러 고루틴이 동시에 데이터를 읽고 쓸 수 있도록 설계되었습니다. 일반적인 맵(map)은 동시성 안전하지 않기 때문에, 동시 접근이 필요한 경우 뮤텍스(Mutex)나 기타 동기화 메커니즘이 필요합니다. 그러나 sync.Map은 이러한 동기화를 내장하여 개발자가 직접 처리하지 않아도 동시성을 보장합니다.


특징

  1. 동시성 안전:
    • 다수의 고루틴이 동시에 데이터를 읽고 쓰더라도 안전하게 동작합니다.
  2. 성능 최적화:
    • 빈번한 읽기 작업을 위해 데이터 구조와 내부 캐싱을 최적화.
  3. 일반 맵과의 차이점:
    • sync.Map은 타입 지정이 되지 않으므로 모든 키와 값은 interface{} 타입으로 저장됩니다.
    • 일반 맵처럼 인덱싱(map[key])으로 접근하지 않고, 전용 메서드를 사용합니다.

sync.Map 주요 메서드

 

메서드  설명
Load(key) 특정 키의 값을 읽습니다. 키가 존재하지 않으면 두 번째 반환 값으로 false를 반환합니다.
Store(key, value) 키-값 쌍을 저장합니다. 기존 키가 있으면 값을 업데이트합니다.
LoadOrStore(key, value) 키가 이미 있으면 기존 값을 반환하고, 없으면 새 값을 저장하고 반환합니다.
Delete(key) 특정 키-값 쌍을 삭제합니다.
Range(func) 모든 키-값 쌍을 순회하며 지정된 함수(func(key, value))를 호출합니다.

사용 예제

1. 기본 사용

package main

import (
	"fmt"
	"sync"
)

func main() {
	var m sync.Map

	// Store: 값 저장
	m.Store("name", "Alice")
	m.Store("age", 25)

	// Load: 값 읽기
	name, ok := m.Load("name")
	if ok {
		fmt.Println("Name:", name)
	}

	// LoadOrStore: 값 읽기 또는 저장
	value, loaded := m.LoadOrStore("name", "Bob")
	fmt.Println("Existing Value:", value, "Was Loaded:", loaded)

	// Delete: 값 삭제
	m.Delete("age")
	if _, ok := m.Load("age"); !ok {
		fmt.Println("Age key deleted")
	}
}

출력:

Name: Alice
Existing Value: Alice Was Loaded: true
Age key deleted


2. 동시성 활용

package main

import (
	"fmt"
	"sync"
)

func main() {
	var m sync.Map
	var wg sync.WaitGroup

	// 여러 고루틴에서 동시 작업
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(id int) {
			defer wg.Done()
			m.Store(id, fmt.Sprintf("Value-%d", id))
		}(i)
	}

	wg.Wait()

	// 결과 출력
	m.Range(func(key, value interface{}) bool {
		fmt.Printf("Key: %v, Value: %v\\n", key, value)
		return true
	})
}


활용 사례

  1. 캐싱 시스템:
    • sync.Map은 읽기 및 쓰기가 빈번하게 발생하는 캐싱에 적합합니다.
    • 예: HTTP 요청을 처리하는 캐시.
  2. 고루틴 간 데이터 공유:
    • 고루틴 간 데이터를 안전하게 공유하며 뮤텍스를 직접 사용할 필요가 없습니다.
  3. 동적 설정 관리:
    • 실시간으로 설정 값을 저장하고 업데이트하며 여러 고루틴에서 읽습니다.
  4. 통계 데이터 저장:
    • 동시적으로 발생하는 이벤트를 기반으로 통계를 수집하고 관리.

장단점

장점

  • 동시성 안전 보장: 고루틴 간의 데이터 경쟁을 걱정할 필요 없음.
  • 간단한 API: 복잡한 동기화 메커니즘 없이 간단하게 사용 가능.
  • 높은 성능: 읽기 작업을 위한 최적화.

단점

  • 타입 안정성 부족: 모든 데이터가 interface{}로 저장되므로 타입 변환이 필요.
  • 작은 데이터셋에서는 일반 맵과 뮤텍스를 사용하는 것이 더 효율적일 수 있음.
  • 읽기와 쓰기가 매우 빈번히 교차하면 성능 저하 가능.

주의 사항

  • sync.Map은 읽기가 빈번하고 쓰기가 적은 경우에 성능이 뛰어납니다.
  • 읽기와 쓰기가 비슷한 빈도로 발생하는 경우에는 sync.RWMutex와 일반 맵을 조합해 사용하는 것이 더 적합할 수 있습니다.

결론

sync.Map은 동시성을 안전하게 처리해야 하는 상황에서 유용한 데이터 구조입니다. 특히 고루틴이 많은 환경에서 간단하고 효율적으로 데이터를 공유하는 데 적합합니다. 하지만 성능 및 타입 안전성이 중요하다면, 다른 동기화 메커니즘과 비교하여 적합성을 평가해야 합니다.



🎬 유튜브 채널 🎬

 

위로그@WiLog

📢 안녕하세요, 위로그@WiLog 시청자 여러분, 저는 윌리(Willee) 입니다. 📢 위로그@WiLog 는 자기계발을 목적으로 하는 채널 입니다. 📢 오늘도 즐겁게~ 자신을 위한 계발을 함께 해보아요~ d^_^b 📌

www.youtube.com

🎬 치지직 채널 🎬

 

위로그 채널 - CHZZK

지금, 스트리밍이 시작됩니다. 치지직-

chzzk.naver.com


반응형