2016-12-06 6 views
4

В моем слое данных используется Mongo aggregation приличное количество, и в среднем запросы возвращаются 500-650 мс. Я использую mgo.mgo - производительность запросов кажется медленно медленной (500-650 мс)

Ниже показана примерная функция запроса, которая представляет собой то, что представляет собой большинство моих запросов.

func (r userRepo) GetUserByID(id string) (User, error) { 
    info, err := db.Info() 
    if err != nil { 
     log.Fatal(err) 
    } 

    session, err := mgo.Dial(info.ConnectionString()) 
    if err != nil { 
     log.Fatal(err) 
    } 
    defer session.Close() 

    var user User 
    c := session.DB(info.Db()).C("users") 
    o1 := bson.M{"$match": bson.M{"_id": id}} 
    o2 := bson.M{"$project": bson.M{ 
     "first":   "$first", 
     "last":   "$last", 
     "email":   "$email", 
     "fb_id":   "$fb_id", 
     "groups":   "$groups", 
     "fulfillments": "$fulfillments", 
     "denied_requests": "$denied_requests", 
     "invites":   "$invites", 
     "requests": bson.M{ 
      "$filter": bson.M{ 
       "input": "$requests", 
       "as": "item", 
       "cond": bson.M{ 
        "$eq": []interface{}{"$$item.active", true}, 
       }, 
      }, 
     }, 
    }} 
    pipeline := []bson.M{o1, o2} 
    err = c.Pipe(pipeline).One(&user) 
    if err != nil { 
     return user, err 
    } 
    return user, nil 
} 

user структура у меня выглядит следующим образом ..

type User struct { 
    ID    string  `json:"id" bson:"_id,omitempty"` 
    First   string  `json:"first" bson:"first"` 
    Last   string  `json:"last" bson:"last"` 
    Email   string  `json:"email" bson:"email"` 
    FacebookID  string  `json:"facebook_id" bson:"fb_id,omitempty"` 
    Groups   []UserGroup `json:"groups" bson:"groups"` 
    Requests  []Request  `json:"requests" bson:"requests"` 
    Fulfillments []Fulfillment `json:"fulfillments" bson:"fulfillments"` 
    Invites  []GroupInvite `json:"invites" bson:"invites"` 
    DeniedRequests []string  `json:"denied_requests" bson:"denied_requests"` 
} 

Основываясь на том, что я представил, что-нибудь очевидно, что хотел бы предложить, почему мои запросы в среднем 500-650ms?

Я знаю, что я, вероятно, проглотил немного удара по производительности, используя конвейер агрегации, но я не ожидал, что это будет так плохо.

+0

У вас есть какой-либо указатель на 'request.active'? – RickyA

+0

Как выглядит план запроса? ('db.collection.find ({$ query: {}, $ explain: 1})') – RickyA

ответ

10

.. есть ли что-либо очевидное, что бы предположить, почему мои запросы задают 500-650 мс?

Да, есть. Вы вызываете mgo.Dial() перед выполнением каждого запроса. mgo.Dial() должен подключаться к серверу MongoDB каждый раз, который вы закрываете сразу после запроса. Соединение, возможно, потребует сотни миллисекунд, чтобы установить, включая проверку подлинности, распределение ресурсов (как на стороне сервера, так и на стороне клиента) и т. Д. Это очень расточительно.

Этот метод обычно называют только один раз для данного кластера. Затем новые сеансы в том же кластере устанавливаются с использованием методов New или Copy на полученном сеансе. Это позволит им совместно использовать базовый кластер и управлять пулом подключений соответствующим образом.

Создать глобальную переменную сеанса, соединение при запуске раз (с использованием, например, функции пакета init()) и использовать эту сессию (или копировать/клонировать его, полученный Session.Copy() или Session.Clone()). Например:

var session *mgo.Session 
var info *db.Inf // Use your type here 

func init() { 
    var err error 
    if info, err = db.Info(); err != nil { 
     log.Fatal(err) 
    } 
    if session, err = mgo.Dial(info.ConnectionString()); err != nil { 
     log.Fatal(err) 
    } 
} 

func (r userRepo) GetUserByID(id string) (User, error) { 
    sess := session.Clone() 
    defer sess.Close() 

    // Now we use sess to execute the query: 
    var user User 
    c := sess.DB(info.Db()).C("users") 
    // Rest of the method is unchanged... 
} 
+0

Это сократило среднее время до ~ 75 мс :) Спасибо, что, указав это, у меня появилось чувство, что я делаю что-то серьезное неправильно. – TheJediCowboy

+0

Это даже не работает в стрессовых приложениях: https://github.com/go-mgo/mgo/issues/473 –

 Смежные вопросы

  • Нет связанных вопросов^_^