2014-01-25 2 views
1

mongodb에 빠르게 쓰는 응용 프로그램을 작성 중입니다. mongodb와 mgo가 처리하기에는 너무 빠릅니다. 제 질문은, 몽고가 계속 따라 잡고 막기 시작할 수 없다는 것을 결정하는 방법이 있습니까? 그러나 불필요하게 차단하고 싶지도 않습니다.Golang Mgo 페이싱

package main 

import (
    "labix.org/v2/mgo" 
    "time" 
    "fmt" 
) 

// in database name is a string and age is an int 

type Dog struct{ 
    Breed string "breed" 
} 

type Person struct{ 
    Name string "name" 
    Pet Dog `bson:",inline"` 
    Ts  time.Time 
} 

func insert(session *mgo.Session, bob Person){ 
    err := session.DB("db_log").C("people").Insert(&bob) 
    if err != nil { 
    panic("Could not insert into database") 
    } 
} 

func main() { 
    session, _ := mgo.Dial("localhost:27017") 
    bob := Person{Name : "Robert", Pet : Dog{}} 
    i := 0 
    for { 
    time.Sleep(time.Duration(1) * time.Microsecond) 
    i++ 
    go insert(session, bob) 
    } 
} 

나는 종종 같은 오류를 얻을 : 여기에 문제를 에뮬레이트 코드의 샘플입니다

panic: Could not insert into database 

또는

나는 당신이 경우 더 나은 성능을 얻을 것이다 의심
panic: write tcp 127.0.0.1:27017: i/o timeout 
+0

@EvanShaw 대신에 무엇을 권장하나요? – thwd

+1

문제의 애플리케이션에 대해 알지 못해서는 추천하기가 어렵지만, PostgreSQL은 종종 좋은 선택입니다. –

+2

의견을 쓰는 것이 멋지다면, @ EnvanShaw에게 반대 의견을 제시 할 것입니다. 우리는 몽고를 생산에 사용하고 그것을 좋아합니다. 우리는 훌륭한 성과를 거둘 수 있습니다. 싫어하는 사람이 너를 혼란스럽게하지 마라. 나는 아직 대처할 수없는 몽고에 대한 논쟁을 듣지 않았다. Server Density의 David Mytton은 1 년 반 전에 [읽기에 좋은 대명사] (https://blog.serverdensity.com/does-everyone-hate-mongodb/)를 썼습니다. – Tyson

답변

6

allow Go to use multiple threadsCopy() then Close()입니다.

질문에 대답하려면 채널에 대한 완벽한 사용 사례 일 수 있습니다. 하나의 고 루틴에있는 채널에 항목을 공급하고 다른 곳에서 몽고로 보내거나 쓸 수 있습니다. 필요에 맞게 채널 크기를 조정할 수 있습니다. 생성자 스레드는 일단 채널이 전송하려고하면 채널이 가득 차면 차단합니다.

Safe() 방법 설정으로 재생할 수도 있습니다. W : 0으로 설정하면 Mongo를 "화재 및 잊어 버리기"모드로 전환 할 수 있습니다. 이렇게하면 일부 데이터가 손실 될 위험이 있으므로 성능이 크게 향상됩니다. 시간 종료 시간을 변경할 수도 있습니다.

+0

감사합니다. 나는 그것을 시도하고 내일 다시 당신에게 돌아갑니다 – Gary

+0

나는 Copy()와 Close()를 사용하려고했습니다. 다음과 같은 몇 가지 오류가 나타납니다. 2014/01/27 18:28:36 http : Accept error : accept tcp [::] : 9090 : 열린 파일이 너무 많습니다. 다시 시도 1시 – Gary

+0

또한 안전() 매개 변수를보고 아주 안전하지 않은 모드에서 오전, 매우 빨리해야합니다. – Gary

0

아직 테스트하지 않았지만이 코드가 작동해야한다고 생각합니다. 오랜 시간 동안 세션을 유지 한 후에이 문제가 발생하여 특정 시간마다 세션을 갱신하는 타이머가 있습니다.

package main 

import (
    "gopkg.in/mgo.v2" 
    "time" 
    "fmt" 
) 

// in database name is a string and age is an int 

type Dog struct{ 
    Breed string "breed" 
} 

type Person struct{ 
    Name string "name" 
    Pet Dog `bson:",inline"` 
    Ts  time.Time 
} 

func insert(session *mgo.Session, bob Person){ 
    err := session.DB("db_log").C("people").Insert(&bob) 
    if err != nil { 
    panic("Could not insert into database") 
    } 
} 

func main() { 
    current_session, _ := mgo.Dial("localhost:27017") 
    using_session := current_session 
    bob := Person{Name : "Robert", Pet : Dog{}} 

    /* 
    * this technical to prevent connect timeout after long time connection on mongodb from golang session 
    * Idea is simple: the session will be renew after certain time such as 1 hour 
    */ 
    //ticker := time.NewTicker(time.Hour * 1) 

    //Set 10 seconds for test 
    ticker := time.NewTicker(time.Second * 10) 

    go func() { 

    for t := range ticker.C { 
     fmt.Println("Tick at", t) 
     new_session := current_session.Copy() 
     fmt.Printf("Current session here %p\n", current_session) 
     fmt.Printf("New session here %p\n", new_session) 
     using_session = new_session 
     //setTimeout 30 second before close old sesion, to make sure current instance use current connection isn't affect 
     //time.AfterFunc(time.Second * 30, func() { 

     //Set 2 seconds for test 
     time.AfterFunc(time.Second * 2, func() { 

     //close previous session 

     current_session.Close() 
     current_session = new_session 

     //assign to new session 

     }) 

    } 
    }() 

    i := 0 
    for { 
    time.Sleep(time.Duration(1) * time.Microsecond) 
    i++ 
    go insert(using_session, bob) 
    } 

}