如何选择MongoDB片键
选择MongoDB片键是分布式数据库设计中的一个重要环节,合理的片键选择能够提高数据库的性能和可扩展性。以下是根据搜索结果总结的选择MongoDB片键的一些关键要素和原则。
1.片键的选择原则
片键的选择主要有两个原则,一个是片键基数(片键的范围),一个是片键的分布情况。
1.1
片键基数
片键基数指的是划分数据块的能力。例如,如果要记录一个省所有考生的高考成绩,如果以成绩作为片键进行范围分片,那存储较高成绩记录的分片的数据量必然要远远小于存储平均成绩左右记录的分片的数据量,存储数据最多的这个分片就会成为瓶颈。这时以考生的考号作为片键就更有利于数据的均匀分布。
1.2
片键的分布情况
片键的分布情况会影响数据在集群中的分布情况。理想的情况是,片键能够将插入数据均匀分布到各个分片上,保证CRUD操作能够利用局部性,有足够的粒度进行块拆分。
2.片键的选择要素
2.1
读和写的分布
读和写的分布是选择片键时需要考虑的重要因素。如果总是朝一台机器写,那么这台机器将会成为写瓶颈,从而降低集群的写性能。通过副本集将读请求划分开能够使你的工作数据集大小随着分片数线性扩展,这样可以将负载压力均分到各台机器的内存和磁盘之上。
2.2
数据块的大小
数据块的大小也是一个关键因素。如果文档都使用了同样的片键,那么相应的会得到巨大的数据块。出现巨大块是非常不好的,不仅仅因为它会导致数据的不平均分布,还因为一旦这个数据块的大小超过某个值,那么你就不能够在分片之间移动它了。
2.3
每个查询命中的分片数目
最后一个需要考虑的因素是,如果能够保证大部分的查询请求都能够命中尽可能少的分片那就最好了。这是因为数据块在分片上的分布仅仅是近似的遵循片键的顺序,而并不是严格的强制指定。
3.片键的设计策略
3.1
升序片键
升序片键例如:日期时间字段、自增字段。这种片键能够保证数据的有序性,但是在面对大量数据时,可能会导致数据块的大小过大。
3.2
随机分发片键
随机分发片键例如:用户名、邮件名、UUID、MD5值或者是其它的一些没有规律的值的列。这种片键能够避免数据块的大小过大的问题,但是可能会导致数据分布不均,从而影响查询性能。
3.3
基于位置的片键
基于位置的片键例如:IP、经纬度、居住地址等。这种片键能够根据地理位置将数据分布到不同的分片上,但是可能会面临数据隐私和安全的问题。
3.4
组合分片
组合分片是比较好的一种分片的选择,好的组合分片可以同时解决热点和随机读IO问题。例如:`sh.shardCollection(test.bbbb,{username:1,_id:1})`。
3.5
标签分片
标签分片可以将特定范围的数据在指定的分片中。例如,可以通过标签将{_id:18000}{_id:26000}范围的数据保存到rsa的分片上,这部分数据跨越了两个数据块。
4.片键的选择案例
片键策略没有绝对的好坏,针对不同的业务场景选择不同的分片策略。例如,有一个网站浏览记录表,表中有一个createtime字段用来记录每天记录的插入时间。使用自增字段也存在同样的问题。还有一个五大洲的用户文档表,表中有一个continent字段存储用户所在洲。如果分片的粒度太大了,会导致最后每一个分片的数据都非常的大而且没有再分的可能。
综上所述,选择MongoDB片键需要综合考虑多个因素,并根据具体的业务需求和数据特点进行选择。