背景

目前我在一家IM相关的公司上班,老的项目聊天数据没做相关的数据缓存直接存在的mysql数据库,经常链接数过多服务假死,所以现在我们在重构整个聊天项目

业务场景数据

  1. 由于要持久化redis中的用户消息数据,数据量比较大,写频繁。因为MongoDB的底层实现采用内存映射机制,因此非常适合大并发量的写。
  2. 由于用户的消息量非常大,因此要很方便的支持水平扩展。MongoDB的对水平扩展的支持非常好,并且支持自动分片  
  3. 因为redis和Mongodb都是Nosql其他方面的属性差不多,所以我选择了用Mongodb来储存聊天数据

业务分析

  1.  单聊只会缓存离线数据,拉去一条离线就会删除一条,整体数据量不大
  2.  群聊会缓存全部的聊天数据,对与聊天信息比较多的群会7天新建一个collection同样存30天的数据,聊天少的30天为一个collection,超过的数据会导出为文本放在minio搭建的对象存储服务器上面(eg:可以看看我其他文章,了解minio搭建已经介绍)
  3.  其他
mongodb 最大可以创建多少 collection ?
默认的情况下,MongoDB的每个数据库有24000左右命名空间的限制。
每个命名空间有628字节。.nsfile默认为16MB。
每个collection以及索引都算作namespace。因此如果每个collection有一个索引,
我们能创建12000个collection。
--nssize允许提升这个限制。
小心的是每个collection都会占用一些存储-很少的KB。更近一步说,任何的索引都需要至少8KB的数据空间,
也就意味着每个b-tree page大小为8KB.
如果有很多collection以及元数据经常要页输出,会导致核心的操作速度变慢。
--nssize
如果需要更多的collection,运行mongod --nssize参数。这个参数会让.ns文件更大,
支持更多的collection。注意的是 --nssize 用于最新创建数据库。如果你运行在一个存在的数据库,
希望重新定义大小,那么在运行--nssize之后,要运行db.repairDatabase()命令来调整大小。
.ns 文件最大为 2GB.

应用

collection单聊 名字我设置为single_用户id
collection群聊 名字我设置为group_群id_年月日  通过年月日就可以判断是否需要新建或者存档数据

MongoDb 集群(副本集)

mongod --nssize 500  --bind_ip 192.168.2.28  --port 27019 --dbpath /data/db_c   --replSet howie/192.168.2.28:27017
mongod  --nssize 500  --bind_ip 192.168.2.28  --port 27018 --dbpath /data/db_b   --replSet howie/192.168.2.28:27019
mongod  --nssize 500  --bind_ip 192.168.2.28  --port 27017 --dbpath /data/db_a   --replSet howie/192.168.2.28:27018

随便链接到一个节点执行

config = {_id: 'howie', members: [{
        "_id":1,
        "host":"192.168.2.28:27017"
    },{
        "_id":2,
        "host":"192.168.2.28:27018"
     },{
        "_id":3,
        "host":"192.168.2.28:27019"
     }]
}

rs.initiate(config)
//链接命令 mongodb://192.168.2.28:27017,192.168.2.28:27018,192.168.2.28:27019/?replicaSet=howie

简单介绍

package main
import (
	"gopkg.in/mgo.v2"
	"log"
	"gopkg.in/mgo.v2/bson"
)
type User struct {
	Id       bson.ObjectId `bson:"_id"`
	Name     string        `bson:"name"`
	PassWord string        `bson:"pass_word"`
	Age      int           `bson:"age"`
}
func main() {
	db, err := mgo.Dial("mongodb://192.168.2.28:27017,192.168.2.28:27018,192.168.2.28:27019/?replicaSet=howie")
	if err != nil {
		log.Fatalln(err)
	}
	defer db.Close()
	db.SetMode(mgo.Monotonic, true)
	c := db.DB("howie").C("person")
	//插入
	/*c.Insert(&User{
		Id:       bson.NewObjectId(),
		Name:     "JK_CHENG",
		PassWord: "123132",
		Age: 2,
	}, &User{
		Id:       bson.NewObjectId(),
		Name:     "JK_WEI",
		PassWord: "qwer",
		Age: 5,
	}, &User{
		Id:       bson.NewObjectId(),
		Name:     "JK_HE",
		PassWord: "6666",
		Age: 7,
	})*/
	var users []User
	c.Find(nil).All(&users) //查询全部数据
	log.Println(users)
	c.FindId(users[0].Id).All(&users) //通过ID查询
	log.Println(users)
	c.Find(bson.M{"name": "JK_WEI"}).All(&users) //单条件查询(=)
	log.Println(users)
	c.Find(bson.M{"name": bson.M{"$ne": "JK_WEI"}}).All(&users) //单条件查询(!=)
	log.Println(users)
	c.Find(bson.M{"age": bson.M{"$gt": 5}}).All(&users) //单条件查询(>)
	log.Println(users)
	c.Find(bson.M{"age": bson.M{"$gte": 5}}).All(&users) //单条件查询(>=)
	log.Println(users)
	c.Find(bson.M{"age": bson.M{"$lt": 5}}).All(&users) //单条件查询(<)
	log.Println(users)
	c.Find(bson.M{"age": bson.M{"$lte": 5}}).All(&users) //单条件查询(<=)
	log.Println(users)
	/*c.Find(bson.M{"name": bson.M{"$in": []string{"JK_WEI", "JK_HE"}}}).All(&users) //单条件查询(in)
	log.Println(users)
	c.Find(bson.M{"$or": []bson.M{bson.M{"name": "JK_WEI"}, bson.M{"age": 7}}}).All(&users) //多条件查询(or)
	log.Println(users)
	c.Update(bson.M{"_id": users[0].Id}, bson.M{"$set": bson.M{"name": "JK_HOWIE", "age": 61}}) //修改字段的值($set)
	c.FindId(users[0].Id).All(&users)
	log.Println(users)
	c.Find(bson.M{"name": "JK_CHENG", "age": 66}).All(&users) //多条件查询(and)
	log.Println(users)
	c.Update(bson.M{"_id": users[0].Id}, bson.M{"$inc": bson.M{"age": -6,}}) //字段增加值($inc)
	c.FindId(users[0].Id).All(&users)
	log.Println(users)*/
	//c.Update(bson.M{"_id": users[0].Id}, bson.M{"$push": bson.M{"interests": "PHP"}}) //从数组中增加一个元素($push)
	c.Update(bson.M{"_id": users[0].Id}, bson.M{"$pull": bson.M{"interests": "PHP"}}) //从数组中删除一个元素($pull)
	c.FindId(users[0].Id).All(&users)
	log.Println(users)
	c.Remove(bson.M{"name": "JK_CHENG"})//删除
}

联系 QQ: 3355168235