程序员人生 网站导航

MongoDB的分片集群配置

栏目:框架设计时间:2015-07-28 08:05:29

1、分片

概念:在Mongodb里面存在另外一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求。

当MongoDB存储海量的数据时,1台机器可能不足以存储数据也足以提供可接受的读写吞吐量。这时候,我们就能够通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。


1.分片简介 分片是指将数据拆分,将其分散存在不同机器上的进程.有时也叫分区.将数据分散在不同的机器上,不需要功能 强大的大型计算机就能够存储更多的数据,处理更大的负载. 使用几近所有数据库软件都能进行手动分片,利用需要保护与若干不同数据库服务器的连接,每一个连接还是完全 独立的.利用程序管理不同服务器上的不同数据,存储查村都需要在正确的服务器上进行.这类方法可以很好的工作,但是也 难以保护,比如向集群添加节点或从集群删除节点都很困难,调剂数据散布和负载模式也不轻松. MongoDB支持自动分片,可以摆脱手动分片的管理.集群自动切分数据,做负载均衡. 2.MongoDB的自动分片 MongoDB分片的基本思想就是将集合切分成小块.这些块分散到若干片里面,每一个片只负责总数据的1部份.利用程序没必要知道 哪片对应哪些数据,乃至不需要知道数据已被拆分了,所以在分片之前要运行1个路由进程,进程名mongos,这个路由器知道 所有数据的寄存位置,所以利用可以连接它来正常发送要求.对利用来讲,它仅知道连接了1个普通的mongod.路由器知道和片的 对应关系,能够转发要求到正确的片上.如果要求有了回应,路由器将其搜集起来回送给利用. 在没有分片的时候,客户端连接mongod进程,分片时客户端会连接mongos进程.mongos对利用隐藏了分片的细节. 从利用的角度看,分片和不分片没有区分.所以需要扩大的时候,没必要修改利用程序的代码. 甚么时候需要分片: a.机器的磁盘不够用了 b.单个mongod已不能满足些数据的性能需要了 c.想将大量数据放在内存中提高性能 1般来讲,先要从不分片开始,然后在需要的时候将其转换成份片. 3.片键 设置分片时,需要从集合里面选1个键,用该键的值作为数据拆分的根据.这个键成为片键. 假定有个文档集合表示的是人员,如果选择名字"name"做为片键,第1篇可能会寄存名字以A-F开头的文档. 第2片存G-P开头的文档,第3篇存Q-Z的文档.随着增加或删除片,MongoDB会重新平衡数据,是每片的流量比较 均衡,数据量也在公道范围内(如流量较大的片寄存的数据也许会比流量下的片数据要少些) 4.将已有的集合分片 假定有个存储日志的集合,现在要分片.我们开启分片功能,然后告知MongoDB用"timestamp"作为片键,就要所有数据放到 了1个片上.可以随便插入数据,但总会是在1个片上. 然后,新增1个片.这个片建好并运行了以后,MongoDB就会把集合拆分成两半,成为块.每一个块中包括片键值在1定 范围内的所有文档,假定其中1块包括时间戳在2011.11.11前的文档,则另外一块含有2011.11.11以后的文档.其中 1块会被移动到新片上.如果新文档的时间戳在2011.11.11之前,则添加到第1块,否则添加到第2块. 5.递增片键还是随机片键 片键的选择决定了插入操作在片之间的散布. 如果选择了像"timestamp"这样的键,这个值可能不断增长,而且没有太大的中断,就会将所有数据发送到1个片上 (含有2011.11.11以后日期的那片).如果有添加了新片,再拆分数据,还是会都导入到1台服务器上.添加了新片, MongoDB肯能会将2011.11.11以后的拆分成2011.11.11⑵021.11.11.如果文档的时间大于2021.11.11以后, 所有的文档还会以最后1片插入.这就不合适写入负载很高情况,但依照片键查询会非常高效. 如果写入负载比较高,想均匀分散负载到各个片,就得选择散布均匀的片键.日志例子中时间戳的散列值,没有模式的"logMessage" 都是复合这个条件的. 不论片键随机跳跃还是稳定增加,片键的变化很重要.如,如果有个"logLevel"键的值只有3种值"DEBUG","WARN","ERROR", MongoDB不管如何也不能把它作为片键将数据分成多于3片(由于只有3个值).如果键的变化太少,但又想让其作为片键, 可以把这个键与1个变化较大的键组合起来,创建1个复合片键,如"logLevel"和"timestamp"组合. 选择片键并创建片键很像索引,以为2者原理类似.事实上,片键也是最经常使用的索引. 6.片键对操作的影响 终究用户应当没法辨别是不是分片,但是要了解选择不同片键情况下的查询有何不同. 假定还是那个表示人员的集合,依照"name"分片,有3个片,其名字首字母的范围是A-Z.下面以不同的方式查询: db.people.find({"name":"Refactor"}) mongos会将这个查询直接发送给Q-Z片,取得响应后,直接转发给客户端 db.people.find({"name":{"$lt":"L"}}) mongos会将其先发送给A-F和G-P片,然后将结果转发给客户端. db.people.find().sort({"email":1}) mongos会在所有片上查询,返回结果时还会做归并排序,确保结果顺序正确. mongos用游标从各个服务器上获得数据,所以没必要等到全部数据都拿到才向客户端发送批量结果. db.people.find({"email":"refactor@msn.cn"}) mongos其实不追踪"email"键,所以也不知道应当将查询发给那个片.所以他就向所有片顺序发送查询. 如果是插入文档,mongos会根据"name"键的值,将其发送到相应的片上.


2.如何分片?

1.建立分片 建立分片有两步:启动实际的服务器,然后决定怎样切分数据. 分片1般会有3个组成部份: a.片 片就是保存子集合数据的容器,片可是单个的mongod服务器(开发和测试用),也能够是副本集(生产用).所以1片 有多台服务器,也只能有1个主服务器,其他的服务器保存相同的数据. b.mongos mongos就是MongoDB配的路由器进程.它路由所有的要求,然后将结果聚合.它本身其实不存储数据或配置信息 但会缓存配置服务器的信息. c.配置服务器 配置服务器存储了集群的配置信息:数据和片的对应关系.mongos不永久存房数据,所以需要个地方寄存分片的配置. 它会从配置服务器获得同步数据. 8.启动服务器 首先要启动配置服务器和mongos.配置服务器需要先启动.由于mongos会用到其上的配置信息. 配置服务器的启动就像普通的mongod1样 mongod --dbpath "F:mongodbsconfig" --port 20000 --logpath "F:mongologsconfigMongoDB.txt" --rest 配置服务器不需要很多的空间和资源(200M实际数据大约占用1kB的配置空间) 建立mongos进程,1共利用程序连接.这类路由服务器连接数据目录都不需要,但1定要指明配置服务器的位置: mongos --port 30000 --configdb 127.0.0.1:20000 --logpath "F:mongologsmongosMongoDB.txt" 分片管理通常是通过mongos完成的. 添加片 片就是普通的mongod实例(或副本集) mongod --dbpath "F:mongodbsshard" --port 10000 --logpath "F:mongologsshardMongoDB.txt" --rest mongod --dbpath "F:mongodbsshard1" --port 10001 --logpath "F:mongologsshard1MongoDB.txt" --rest 连接刚才启动的mongos,为集群添加1个片.启动shell,连接mongos: 肯定连接的是mongos而不是mongod,通过addshard命令添加片: >mongo 127.0.0.1:30000 mongos> db.runCommand( ... { ... "addshard":"127.0.0.1:10000", ... "allowLocal":true ... } ... ) Sat Jul 21 10:46:38 uncaught exception: error { "$err" : "can't find a shard to put new db on", "code" : 10185 } mongos> use admin switched to db admin mongos> db.runCommand( ... { ... "addshard":"127.0.0.1:10000", ... "allowLocal":1 ... } ... ) { "shardAdded" : "shard0000", "ok" : 1 } mongos> db.runCommand( ... { ... "addshard":"127.0.0.1:10001", ... "allowLocal":1 ... } ... ) { "shardAdded" : "shard0001", "ok" : 1 } 当在本机运行片的时候,得设定allowLocal键为1.MongoDB尽可能避免由于毛病的配置,将集群配置到本地, 所以得让它知道这仅仅是开发,而且我们很清楚自己在做甚么.如果是生产环境中,则要将其部署在不同的机器上. 想添加片的时候,就运行addshard.MongoDB会负责将片集成到集群. 切分数据 --- 继续在mongos连接上操作 MongoDB不会将存储的每条数据都直接发布,得先在数据库和集合的级别将分片功能打开. E:mongoin>db.runCommand({"enablesharding":"test"})//将test数据库启用分片功能. 对数据库分片后,其内部的集合便会存储到不同的片上,同时也是对这些集合分片的前置条件. 在数据库级别启用了分片以后,就能够使用shardcollection命令堆积和进行分片: db.runCommand({"shardcollection":"test.refactor","key":{"name":1}})//对test数据库的refactor集合进行分片,片键是name 如果现在对refactor集合添加数据,就会根据"name"的值自动分散到各个片上.



3.操作示例:

1.启动配置服务器

D:mongodbmongo1in>mongod --dbpath=D:mongodbmongo1config --port 20000 --logpath=D:mongodbmongo1logsconfigMongoDB.txt --rest



2.MongoDB配置的路由器进程服务器   --   分片管理通常是通过mongos完成的.



D:mongodbmongo1in>mongos --port 3000 --configdb 127.0.0.1:20000 --logpath=D:mongodbmongo1logsmongosMongoDB.txt





3.建立分片,即普通的mongod实例

分片1:
D:mongodbmongo1in>mongod --port 10000 --dbpath=D:mongodbmongo1db1 --logpath=D:mongodbmongo1 logsshardMongoDB.txt --rest
分片2: D:mongodbmongo1in>mongod --port 10001 --dbpath=D:mongodbmongo1db2 --logpath=D:mongodbmongo1 logsshard1MongoDB.txt --rest




4.连接刚才启动的mongos,为集群添加1个片.启动shell,连接mongos:


D:mongodbmongo1in>mongos --port 3000 --configdb 127.0.0.1:20000 --logpath=D:mongodbmongo1logsmongosMongoDB.txt






------分隔线----------------------------
------分隔线----------------------------

最新技术推荐