>  기사  >  백엔드 개발  >  팬아웃 패턴

팬아웃 패턴

PHPz
PHPz원래의
2024-07-28 11:10:22579검색

Fanout Pattern

Go의 팬아웃 패턴을 간단히 살펴보겠습니다. 일반적으로 팬아웃은 여러 작업을 동시에 수행하는 데 사용됩니다.

예를 들어 데이터 파이프라인이 있고 개별 항목을 처리하려고 한다고 가정해 보겠습니다. Go 루틴과 채널을 사용하여 항목을 수신할 때 분할한 다음 개별 항목을 처리할 수 있습니다(예: dB로 입력).

구현하기가 간단한 패턴입니다. 하지만 교착상태를 방지하려면 채널 관리가 필요합니다.

// produce is simulating our single input as a channel
func produce(id int) chan int {
    ch := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            ch <- rand.Intn(20)
        }
        fmt.Printf("producer %d done\n", id)
        close(ch) // this is important!!!
    }()
    return ch
}

func worker(id int, jobs chan int, wg *sync.WaitGroup) {
    for value := range jobs {
        odd := "even"
        if (value & 1) == 1 {
            odd = "odd"
        }
        fmt.Printf("worker: %d, got %d is %s\n", id, value, odd)
    }
    wg.Done()
}

func main() {
    inputCh := produce(1)

    numWorkers := 3
    jobs := make(chan int)

    // split input into individual jobs
    go func() {
        for value := range inputCh {
            jobs <- value
        }
        close(jobs) // this is important!!!
    }()

    // fan-out
    var wg sync.WaitGroup
    for i := 0; i < numWorkers; i++ {
        wg.Add(1)
        go worker(i, jobs, &wg)
    }
    wg.Wait()

    fmt.Println("done")
}

여기서 핵심 아이디어는 고정된 수의 작업자가 작업해야 하는 일련의 데이터가 있다는 것입니다.

입력을 위해 일련의 난수를 생성하여 채널에 배치합니다. 우리는 노동자들이 자신의 '일자리'를 가져올 다른 채널로 그들을 옮깁니다.

이 예에서는 입력을 작업 채널로 이동하는 것이 꼭 필요한 것은 아닙니다. 작업자가 입력 채널에서 쉽게 당기도록 할 수도 있습니다. 여기서는 명확성을 위해 이렇게 했습니다.

그런 다음 고정된 수의 작업자를 고루틴으로 실행합니다. 각 작업자는 처리할 데이터가 더 이상 없을 때까지 작업 채널에서 작업을 가져오고, 이때 WaitGroup에 완료되었음을 알립니다.

메인 스레드는 WaitGroup을 사용하여 모든 작업자가 완료될 때까지, 즉 모든 작업이 처리될 때까지 완료되지 않도록 합니다.

이 패턴은 입력 시퀀스 처리 순서를 보장하지 않는다는 점을 언급하는 핵심 사항입니다. 많은 상황에서는 괜찮을 수 있습니다. 예를 들어 입력 시퀀스는 자체 타임스탬프가 포함된 데이터 레코드이며 목표는 레코드를 dB로 저장하는 것입니다. 이 경우 팬아웃은 허용됩니다.

마지막으로, 시퀀스의 모든 데이터가 전송된 후 채널을 닫는 것에 대한 몇 가지 설명을 볼 수 있습니다. 이것은 매우 중요합니다. 채널에서 가져오는 범위 연산자는 더 이상 데이터가 없으면 절전 모드로 전환됩니다. 교착 상태를 발생시키는 close() 문을 한 번 주석 처리하여 이를 확인할 수 있습니다. 고루틴과 채널은 매우 강력하지만 현명하게 사용해야 합니다.

무엇을 다르게 하시겠습니까? 이 예를 어떻게 개선할 수 있나요? 아래에 의견을 남겨주세요.

감사합니다!

이 게시물과 이 시리즈의 모든 게시물에 대한 코드는 여기에서 확인할 수 있습니다.

위 내용은 팬아웃 패턴의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.