数据模型(Data Model)
1、mongodb支持内嵌document 即document中一个字段的值也是一个document
2、如果内嵌文档(即reference文档)尺寸是动态的,比如一个user可以有多个card,因为card数量无法预估,这就会导致document的尺寸可能不断增加以至于超过“Power of 2 Allocate”,从而触发空间重新分配,带来性能开销
3、这种情况下,我们需要将内嵌文档单独保存到一个额外的collection中,作为一个或者多个document存储,比如把card列表保存在card collection中
4、如果reference文档尺寸较小,可以内嵌,如果尺寸较大,建议单独存储。此外内嵌文档还有个优点就是write的原子性
索引
1、提高查询性能,默认情况下_id字段会被创建唯一索引; 2、因为索引不仅需要占用大量内存而且也会占用磁盘,所以我们需要建立有限个索引,而且最好不要建立重复索引; 3、每个索引需要8KB的空间,同时update、insert操作会导致索引的调整, 会稍微影响write的性能,索引只能使read操作收益, 所以读写比高的应用可以考虑建立索引
大集合拆分
比如一个用于存储log的collection, log分为有两种“dev”、“debug”,结果大致为 {"log":"dev","content":"...."},{"log":"debug","content":"....."}。 这两种日志的document个数比较接近, 对于查询时,即使给log字段建立索引,这个索引也不是高效的, 所以可以考虑将它们分别放在2个Collection中,比如:log_dev和log_debug。
数据生命周期管理
mongodb提供了expire机制, 即可以指定文档保存的时长,过期后自动删除,即TTL特性, 这个特性在很多场合将是非常有用的, 比如“验证码保留15分钟有效期”、“消息保存7天”等等, mongodb会启动一个后台线程来删除那些过期的document 需要对一个日期字段创建“TTL索引”, 比如插入一个文档:{"check_code":"101010",$currentDate:{"created":true}}}, 其中created字段默认值为系统时间Date;然后我们对created字段建立TTL索引: collection.createIndex(new Document("created",1),new IndexOptions().expireAfter(15L,TimeUnit.MILLISECONDS));//15分钟 向collection中insert文档时,created的时间为系统当前时间, 其中在creatd字段上建立了“TTL”索引,索引TTL为15分钟, mongodb后台线程将会扫描并检测每条document的(created时间 + 15分钟)与当前时间比较, 如果发现过期,则删除索引条目(连带删除document)。 某些情况下,可能需要实现“在某个指定的时刻过期”, 只需要将上述文档和索引变通改造即可, 即created指定为“目标时间”,expiredAfter指定为0。
架构模式
Replica set 复制集
通常是三个对等的节点构成一个“复制集”集群, 有“primary”和secondary等多种角色 其中primary负责读写请求,secondary可以负责读请求,这又配置决定, 其中secondary紧跟primary并应用write操作; 如果primay失效,则集群进行“多数派”选举,选举出新的primary,即failover机制,即HA架构。 复制集解决了单点故障问题,也是mongodb垂直扩展的最小部署单位, 当然sharding cluster中每个shard节点也可以使用Replica set提高数据可用性。
Sharding cluster 分片集群
数据水平扩展的手段之一; replica set这种架构的缺点就是“集群数据容量”受限于单个节点的磁盘大小, 如果数据量不断增加,对它进行扩容将时非常苦难的事情,所以我们需要采用Sharding模式来解决这个问题。 将整个collection的数据将根据sharding key被sharding到多个mongod节点上, 即每个节点持有collection的一部分数据,这个集群持有全部数据, 原则上sharding可以支撑数TB的数据。
系统配置
- 建议mongodb部署在linux系统上,较高版本,选择合适的底层文件系统(ext4),开启合适的swap空间
- 无论是MMAPV1或者wiredTiger引擎,较大的内存总能带来直接收益
- 对数据存储文件关闭“atime”(文件每次access都会更改这个时间值,表示文件最近被访问的时间),可以提升文件访问效率
- ulimit参数调整,这个在基于网络IO或者磁盘IO操作的应用中,通常都会调整,上调系统允许打开的文件个数(ulimit -n 65535)。
数据文件存储原理(Data Files storage,MMAPV1引擎)
mongodb的数据将会保存在底层文件系统中, 比如我们dbpath设定为“/data/db”目录, 我们创建一个database为“test”,collection为“sample”, 然后在此collection中插入数条documents。我们查看dbpath下生成的文件列表:
可以看到test这个数据库目前已经有6个数据文件(data files), 每个文件以“database”的名字 + 序列数字组成, 序列号从0开始,逐个递增,数据文件从16M开始,每次扩张一倍(16M、32M、64M、128M...), 在默认情况下单个data file的最大尺寸为2G, 如果设置了smallFiles属性(配置文件中)则最大限定为512M; mongodb中每个database最多支持16000个数据文件,即约32T, 如果设置了smallFiles则单个database的最大数据量为8T。 如果你的database中的数据文件很多, 可以使用directoryPerDB配置项将每个db的数据文件放置在各自的目录中。 当最后一个data file有数据写入后, mongodb将会立即预分配下一个data file, 可以通过“--nopreallocate”启动命令参数来关闭此选项
参考文档
https://blog.csdn.net/quanmaoluo5461/article/details/85164588