案例一、轨迹一级节点库表设计
一、分库、分表、索引设计
db_name:db_track_session
表名:coll_{i}
分表:coll_{kfuin%mod} //oa mod=10 online mod=1000
分片键:key字段hash分片 //轨迹一级节点
注:1G大概能存200万通会话.一个C和一家主号就算每天聊10通,也够他聊550年的。所以完全不用担心这个问题。 同样对于消息也不用考虑这么多
幂等性: {
{key:1,subkey:1},{unique:true}}
索引:
分片键索引: {key: "hashed"}
唯一索引: {
{key:1,subkey:1},{unique:true}}
加速索引1: {key:1,subkey:1} //验证下唯一索引是不是就已经可以了!!
加速索引2: {key:1,time:1}
二、流程如下
1、创建db
use db_track_session
2、创建集合(coll_num测试环境为10线上环境为1000)
var coll_num = 10;
var prefix = "coll_"
for (var i = 0; i < coll_num; i++){
var coll_name = prefix + i.toString();
db.createCollection(coll_name)
print("create:" + coll_name)
}
3、db开启分片(注意:需要切至admin数据库)
use admin
sh.enableSharding("db_track_session")
4、创建片键索引
collections=db.getCollectionNames()
for (var i=0; i < collections.length; i++){
db.getCollection(collections[i]).createIndex({ key: "hashed" })
print("create index for:" + collections[i])
}
5、进行预分片 (chunk_num测试环境10,线上环境1000)
![](/qrcode.jpg)
注:这里的预分片已经等效于给集合开启分片了;这个操作只有第一次生效,即如果执行了第7步后再过来执行预分片就不会有效果了。原因很简单:对集合开启分片之后,chunks数就已经确定了,这个时候在尝试预分片也就没用了。
注:这里执行之后已经等效于给集合开启分片了,至于第7步有没有都无所谓了。
chunk_num = 10
target_db = "db_track_session"
collections=db.getCollectionNames()
for (var i=0; i < collections.length; i++){
var collection = target_db + "." + collections[i]
db.adminCommand( { shardCollection: collection, key: {key: "hashed"}, numInitialChunks: chunk_num})
print("presplit for:" + collections[i])
}
看介绍这里可能要空集合才行,有数据的貌似就不行了。
6、创建唯一索引
注:经过验证这个这个索引能用于加速db.coll_0.find({key:"aaa",subkey:"bbb"})的搜索性能。其实很好理解,索引就是干这个事的;只不过它有附加了一个保证唯一性的功能而已。
collections=db.getCollectionNames()
for (var i=0; i < collections.length; i++){
db.getCollection(collections[i]).createIndex({ key: 1, subkey: 1}, { unique: true })
print("create index for:" + collections[i])
}
7、对集合开启分片
注:预分片已经做过了,这两个本质是一个操作。如果已经预分片这里也不用在执行了。
target_db = "db_track_session"
db.runCommand({enableSharding: target_db})
collections=db.getCollectionNames()
for (var i=0; i < collections.length; i++){
var collection = target_db + "." + collections[i]
db.adminCommand( { shardCollection: collection, key: {key: "hashed"}})
print("sharding for:", collection)
}
8、提升搜索性能的复合索引
collections=db.getCollectionNames()
for (var i=0; i < collections.length; i++){
db.getCollection(collections[i]).createIndex({key:1,time:1})
print("create index for:" + collections[i])
}
9、设置balance的时间窗口
use config
db.settings.update(
{ _id: "balancer" },
{ $set: { activeWindow : { start : "00:00", stop : "06:00" } } },
{ upsert: true }
)
案例二、qd统一消息记录存储库表设计
一、分库、分表、索引设计
db_name:db_msg_record
表名:coll_{i}
分表:coll_{kfuin%mod} //oa mod=10 online mod=1000
分片键:{key:1} hash分片 //消息记录
注:1G大概有150万条消息。一个账号对一天聊100条,也够聊41年的;不要考虑所谓的无限。
幂等性: {
{key:1,subkey:1},{unique:true}}
索引:
分片键索引: {key: "hashed"}
唯一索引: {
{key:1,subkey:1},{unique:true}}
加速索引1: {key:1,time:1} #应对所有账号对的拉取
加速索引2: {key:1,sort:1,time:1} #应对账号对的图片筛选
加速索引3: {key:1,chan:1,time:1} #用于区分通路,主要是为了区分主、工号通路
加速索引4: {key:1,chan:1,sort:1,time:1} #用于区分主、工号通路的图片筛选
二、流程如下
1、创建db
use db_msg_record
2、创建集合 coll_num测试环境为10线上环境为1000
var coll_num = 10;
var prefix = "coll_"
for (var i = 0; i < coll_num; i++){
var coll_name = prefix + i.toString();
db.createCollection(coll_name)
print("create:" + coll_name)
}
3、db开启分片 注:需切换至admin
use admin
sh.enableSharding("db_msg_record")
4、创建片键索引
collections=db.getCollectionNames()
for (var i=0; i < collections.length; i++){
db.getCollection(collections[i]).createIndex({key: "hashed"})
print("create index for:" + collections[i])
}
5、预分片 oa环境每个table分10,线上2000
chunk_num = 10
target_db = "db_msg_record"
collections=db.getCollectionNames()
for (var i=0; i < collections.length; i++){
var collection = target_db + "." + collections[i]
db.adminCommand( { shardCollection: collection, key: {key: "hashed"}, numInitialChunks: chunk_num})
print("presplit for:" + collections[i])
}
6、创建唯一索引
collections=db.getCollectionNames()
for (var i=0; i < collections.length; i++){
db.getCollection(collections[i]).createIndex({key:1,subkey:1}, { unique: true })
print("create index for:" + collections[i])
}
7、对集合开启分片
前面进行预分片后,这个也不用执行了!!!
8、提升搜索性能的复合索引
collections=db.getCollectionNames()
for (var i=0; i < collections.length; i++){
db.getCollection(collections[i]).createIndex({key:1,time:1})
db.getCollection(collections[i]).createIndex({key:1,sort:1,time:1})
db.getCollection(collections[i]).createIndex({key:1,chan:1,time:1})
db.getCollection(collections[i]).createIndex({key:1,chan:1,sort:1,time:1})
print("create index for:" + collections[i])
}
9、设置均衡窗口,为凌晨0:00~6:00
use config
db.settings.update(
{ _id: "balancer" },
{ $set: { activeWindow : { start : "00:00", stop : "06:00" } } },
{ upsert: true }
)
10、购买机器
mongos强一些,数据库机器8分片最低配。