Mongodb 并发查询性能调优

【背景】没有并发的时候,Mongodb使用正常,当模拟多人并发访问(tps 100,不算高)所有功能接口的时候,4核cpu的mongo进程升到100%(理论上应该是接近400%),3分钟之后,查询接口开始变慢,响应时间高达20s

【思路】第一个想到了加索引,实际上数据库并不大,topic集合 和reply集合分别只有3万数据,在数据量大的情况下加索引才有优势

【解决】从数据库的链接入手,把mongdb的GlobalSession用一个实例改为每次拷贝副本操作,用完即关闭副本

【结果】再次用loadRunner做并发测试,所有接口响应时间都在1秒之内,快的几十毫秒,性能提示非常显著,cpu使用率升到340%

【代码】

*******************************通用部分 初始化*********************************

package db

import (
	"chpkg.in/qiniu/log.v1"
	"gopkg.in/mgo.v2"

	"../config"
)

var GlobalSession *mgo.Session

func init() {
	var err error
	GlobalSession, err = mgo.Dial(config.Cfg.MgoAddr)
	if err != nil {
		log.Fatalln(err)
		return
	}
	GlobalSession.SetMode(mgo.Monotonic, true)
	GlobalSession.SetPoolLimit(config.Cfg.MongoPoolLimit)

	Coll = GlobalSession.DB(config.Cfg.MgoDB).C(config.Cfg.MgoColl)
}

*******************************老代码*********************************
声明
// Coll is globle collection of binding
var Coll *mgo.Collection

func GetColl() *mgo.Collection {
	if GlobalSession.Ping() != nil {
		GlobalSession.Refresh()
		log.Debug("refreshed GlobalSession")

		Coll = GlobalSession.DB(config.Cfg.MgoDB).C(config.Cfg.MgoColl)
	}

	return Coll
}

调用
// 存在多用户绑定同一微信关系
	if err := db.GetColl().Find(bson.M{"openid": u.OpenId}).All(&docs); err != nil {
		log.Warn("FindBindByOpenId: ", err)
		return ErrNoBinding
}

*******************************新代码*********************************
声明

func GetColl2(session *mgo.Session) *mgo.Collection {
	return session.DB(config.Cfg.MgoDB).C(config.Cfg.MgoColl)
}

调用
func ReceiveGift(giftId bson.ObjectId) *Result {
	session := db.GlobalSession.Copy()
	defer session.Close()

	err := db.GetColl2(session).UpdateId(giftId, bson.M{"$set": bson.M{"status": "1", "receiveTime": time.Now().Format("2006-01-02 15:04:05")}})
	if err != nil {
		re := Result{Status: false, Code: "-9999"}.Handle()
		re.Msg += err.Error()
		return re
	}
	return nil
}


你可能感兴趣的:(mongodb)