我想要upsert一个记录列表,所以我有两个选择,一个只使用一个会话,另一个复制每个记录的会话.所以,正如我的观点,第一种方法可能比第二种方法慢,但是第一种方法会导致会话创建太多吗?
1.使用一次
func (this *CvStoreServiceImpl) SetCvJobItemMeasureList(accessToken *base_datatype.ServiceAccessToken, versionPolicy string, jobItemList []*cv_common_type.CvJobItemMeasure) (err error) {
session := this.session.Clone()
defer session.Close()
for _, jobItem := range jobItemList {
objKey := &orm.ItemIdKey{
VersionName: versionPolicy, //XXX
ItemId: jobItem.ItemId,
}
obj := orm.ConvertToCvJobItemMeasureObj(versionPolicy, jobItem)
_, err2 := this.jobMeasureCollection.With(session).Upsert(objKey, obj)
if nil != err2 {
err = &common_error.NamedError{err2.Error()}
this.logger.Println(err2.Error())
}
}
return
}
Run Code Online (Sandbox Code Playgroud)
2.每个记录的复制会话
func (this *CvStoreServiceImpl) SetCvJobItemMeasure(accessToken *base_datatype.ServiceAccessToken, versionPolicy string, jobItem *cv_common_type.CvJobItemMeasure) (err error) {
session := this.session.Clone()
defer session.Close()
objKey := &orm.ItemIdKey{
VersionName: versionPolicy, //XXX
ItemId: jobItem.ItemId,
}
obj := orm.ConvertToCvJobItemMeasureObj(versionPolicy, jobItem)
_, err2 := this.jobMeasureCollection.With(session).Upsert(objKey, obj)
if nil != err2 {
err = &common_error.NamedError{err2.Error()}
return
}
return
}
Run Code Online (Sandbox Code Playgroud)
然后在forloop中调用此方法:
for _, item := range cvMeasure.GetJobList() {
err = this.SetCvJobItemMeasure(accessToken, versionPolicy, item)
if nil != err {
return
}
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*erg 14
首先,我们需要看到mgo.Session.Copy()和mgo.Session.Clone()之间的区别.虽然go.Session.Clone()返回一个新的会话,会话使用同一个套接字连接.这不一定是坏事,但请记住,在服务器端,每个连接分配一个堆栈.所以会话将共享相同的堆栈.根据您的使用情况,这可能会产生很大的不同.
这就是问题 - 如果你为每条记录打开一个新的套接字连接,这会导致三次握手,这很慢.重用相同的套接字可以减少这种开销,但是仍然有一些并且具有上述缺点.
我倾向于做的是为每个长(er)运行工作单元建立一个新连接.一个简单的例子就是这样说
package main
import (
"fmt"
mgo "gopkg.in/mgo.v2"
bson "gopkg.in/mgo.v2/bson"
"net/http"
)
var (
Database *mgo.Database
)
// The listEntries lists all posts
func listPosts(w http.ResponseWriter, r *http.Request) {
// We have a rather long running unit of work
// (reading and listing all posts)
// So it is worth copying the session
collection := Database.C("posts").With( Database.Session.Copy() )
post := bson.D{}
posts := collection.Find(bson.M{}).Iter()
for posts.Next(&post) {
// Process posts and send it to w
}
}
func main() {
session, _ := mgo.Dial("mongodb://localhost:27017")
Database := session.DB("myDb")
// Count is a rather fast operation
// No need to copy the session here
count, _ := Database.C( "posts" ).Count()
fmt.Printf("Currently %d posts in the database", count )
http.HandleFunc("/posts", listPosts)
http.ListenAndServe(":8080", nil)
}
Run Code Online (Sandbox Code Playgroud)
Jia*_* YD -1
是的,复制一个会话来执行一个或多个操作是有好处的,让mgo中的连接池提高性能。一台 mongo 服务器的默认限制是 4096,以防止连接过多。
func newSession(consistency Mode, cluster *mongoCluster, timeout time.Duration) (session *Session) {
cluster.Acquire()
session = &Session{
cluster_: cluster,
syncTimeout: timeout,
sockTimeout: timeout,
poolLimit: 4096,
}
debugf("New session %p on cluster %p", session, cluster)
session.SetMode(consistency, true)
session.SetSafe(&Safe{})
session.queryConfig.prefetch = defaultPrefetch
return session
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6652 次 |
| 最近记录: |