mongodb分片
分片是指数据拆分 将其分散在不同的机器上的过程,有时候也叫分区来表示这个概念.将数据分散到不同机器上 不需要功能强大的计算机就可以储存更多的数据,处理更大的负载.
几乎所有的数据库都能手动分片 应用程序需要维护与若干不同数据库服务器的连接,每个连接都是独立的 应用程序给I案例不同服务器上不同数据的存储,还管理在合适的数据库上查询的工作,这种方法能够很好的工作,但是难以维护 不如想集群添加节点 或者从集群删除节点都很困难 调整数据分布和负载模式也不轻松.
MongoDB支持自动分片,可以使用数据库架构对应用程序不可见,可以简化系统管理,对应用程序而言,就像连接的一台但是mongod服务器一样,MongoDB自动处理数据在分布上的分布.也更容易添加和删除分片.
MongoDB的分片机制允许你创建一个包含许多台机器的集群,将数据的子集合分散在集群中,每个分片维护着一个数据集合的子集.与单机服务器和副本集相比,使用集群架构可以使应用程序具有更大的数据处理能力.
快速建立一个简单的集群
为了对应用程序隐藏数据库架构的细节,在分片之前要先执行mongos进行一次路由过程,这个路由器维护着一个"内容列表" 指明了每个分片包含什么数据内容,应用程序只需要连接到路由武器,就可以像使用单机服务器一样进行正常请求了
单台服务器上快速建立一个集群 首先使用 --nodb选项启动mongo shell
使用ShardingTest类创建集群
cluster = new ShardingTest({"shards":3,"chunksize":1})
这个命令就会创建一个包含3个分片的集群,分别运行在30000.30001.30002端口,默认情况下,ShardingTest会在30999端口启动mongos 接下来就连接到这个mongos开始使用集群
db = (new Mongo("127.0.0.1:30999")).getDB("test")
现在的情况如上图所示,客户端shell连接到了一个mongos 现在就可以将请求发送给mongos了 他会自动将请求路由到合适的分片,客户端不需要知道分片的任何信息,比如分片数量和分片地址 只要有分片存在 就可以想mongos发送请求 他会自动将请求转发到合适的分片上
首先插入一些数据
for(var i=0;i<100000;i++) {
dd.users.insert({"username":"user"+i,"create_at": new Date()})
}
db.users.count()
可以看得到,与mongos进行交互与使用单机服务器完全一样
运行 sh.status() 可以看到集群状态 分片信息 数据库信息 集合信息
sh命令和rs命令很想 除了它是用于分片的:rs是一个全局变量 其中定义了许多分片操作的辅助函数 可以循序sh.help查看树勇的辅助函数
sh.status()输出所示 当前拥有三个分片 2个数据库其中admin是数据库自己创建的
test可能有一个不同的主分片 主分片是为每个数据库随机选择 所有数据都会位于主分片上 mongodb现在还不能自动将数据分发到不同分片上 因为他不知道你希望如何分发叔叔 必须明确指定 对于每个集合应该如何分发数据
要对一个集合分片 首先要对这个集合的数据库启动分片 sh.enableSharding("test");
现在就可以对 test数据库内的集合进行分片了 对集合分片时候 要选择一个片键 片键是集合的一个键 mongodb根据这个键拆分数据 例如如果基于 username进行分片 选择片键可以认为是选择集合中数据的顺序 它与索引是个相似的概念 随着集合的不断增长 片键就会成为集合上最重要的索引 只有被索引过的键才能够作为片键
在启动分片之前 先是希望作为片键的键上穿件索引 db.users.ensureIndex({"username":1}) 现在就可以根据 username 对集合进行分片
sh.shardCollection("test.users",{"username ":1})
在查看 sh.status() 可以看到这次输出的信息比较多:
集合被分为多个数据块 每一个集合都是集合的一个数据子集合 这些事按照片键的范围排列的({"username":minValue} -->> {"username":maxValue} 指出了每个数据块的数据范围) 通过查看输出信息中on 可以发现集合数据比较均匀地分布在不同分片上
数据块开始的键值 和结束的键值 $minKey和$maxKey 可以任务前者是负无穷 它比Mongodb的人物画值都要笑 后者比任何值都要大
关闭 cluster.stop()