MongoDB学习笔记九:分片
分片(sharding)是指将数据拆分,将其分散存在不同的机器上的过程。有事也用分区(partitioning)来表示这个概念。将数据分散到不同的机器上,不需要功能强大的大型计算机既可以存储更多的数据,处理更大的负载。
『MongoDB中的自动分片』
MongoDB在分片之前要运行一个路由进程,该进程名为mongos。这个路由器知道多有数据的存放位置,所以应用可以连接它来正常发送请求。mongos对应用隐藏了分片的细节。
何时分片?
· 机器的磁盘不够用了。
· 单个mongod已经不能满足写数据的性能需要了。
· 想将大量数据放在内存中提高性能。
『片键』
设置分片时,需要从集合里面选一个键,用改键的值作为数据拆分的依据。这个键成为片键(shard key)。
随着添加(或者删除)片,MongoDB会重新平衡数据,使每片的流量都比较均匀,数据量也在合理范围内。
『将已有的集合分片』
假设有个存储日志的集合,现在要分片。我们开启分片功能,然后告诉MongoDB用"timestamp"作为片键,就把所有数据放到了一个片上。可以随意插入数据,但总会是在一个片上。
而后,增加一个片。这个片建好并运行了以后,MongoDB就会把集合拆分成两半,称为块。每个块中包含片键值在一定范围内的所有文档,所以就假设其中一块包含时间戳在2003年6月26日以前的文档,另一块含有2003年6月27日以后的文档。其中一块会被移动到新片上。
如果新文档的时间戳在2003年6月27日之前,则添加到第一个块,否则就加到另一个块。
【建立分片】
建立分片有两步:启动实际的服务器,然后决定怎么切分数据。
分片一般会有3个组成部分:
· 片
片就是保存子集合数据的容器。片可以是单个的mongod服务器(开发和测试用),也可以是副本集(生产用)。所以,几遍一片内有多台服务器,也只能有一个主服务器,其他的服务器保存相同的数据。
· mongos
mongos就是MongoDB各版本中都配的路由器进程。它路由所有请求,然后将结果聚合。它本身并不存储数据或者配置信息(但会缓存配置服务器的信息)。
· 配置服务器
配置服务器存储了集群的配置信息:数据和片的对应关系。mongos不永久存放数据,所以需要个地方存放分片配置。他会从配置服务器获取同步数据。
『启动服务器』
首先要启动配置服务器和mongos。配置服务器需要最先启动,因为mongos会用到其上的配置信息。配置服务器的启动就像普通mongod一样。
$ mkdir -p ~/dbs/config
$ ./mongod --dbpath ~/dbs/config --port 20000
配置服务器不需要很多空间和资源(200MB实际数据大约占用1KB的配置空间)。
现在就可以建立mongos进程,以供应用程序连接。这种路由服务器连数据目录都不需要,但一定要指明配置服务器的位置:
$ ./mongos --port 30000 --configdb localhost:20000
分片管理通常是通过mongos完成的。
添加片
片就是普通的mongod实例(或者副本集):
$ mkdir -p ~/dbs/shard1
$ ./mongod --dbpath ~/dbs/shard1 --port 10000
现在连接刚才启动的mongos,为集群添加一个片。启动shell,连接mongos:
$ ./mongo localhost:30000/admin
MongoDB shell version: 1.6.0
url: localhost:30000/adminconnecting to localhost:30000/admin
type "help" for help
>
确定连接的是mongos而不是mongod后,就可以通过addshard命令添加片了:
> db.runCommand({addShard : "localhost:10000", allowLocal : true})
{
"added" : "localhost:10000",
"ok" : true
}
挡在localhost上运行分片时,得设定"allowLocal"键。MongoDB尽量避免由于错误配置,将集群配置到本地,所以得让它知道这仅仅是开发,而且我们很清楚自己在做什么。如果实在生产环境中,则要将其部署在不同的机器上。
想添加片的时候,就运行addShard。MongoDB会负责将片集成到集群。
『切分数据』
MongoDB不会将存储的每一条数据都直接发布,得先在数据库和集合的级别将分片功能打开。下面的例子将以"_id"为急转切分foo数据库的bar集合。首先得开启foo的分片功能:
> db.runCommand({"enablesharding" : "foo"})
对数据库分片后,其内部的集合便会存储到不同的片上,同时也是对这些集合分片的前置条件。
在数据库的级别启动了分片以后,就可以使用shardCollection命令来对集合进行分片了:
> db.runCommand({"shardCollection" : "foo.bar", "key" : {"_id" : 1}})
这样集合就按照"_id"分片了,在添加数据,就会依据"_id"的值自动分散到各个片上。
【生产配置】
成功地构建分片需要如下条件:
· 多个配置服务器。
· 多个mongos服务器。
· 每个片都是副本集。
· 正确设置w。
例:设置3个配置服务器:
$ mkdir -p ~/dbs/config1 ~/dbs/config2 ~/dbs/config3
$ ./mongod --dbpath ~/dbs/config1 --port 20001
$ ./mongod --dbpath ~/dbs/config2 --port 20002
$ ./mongod --dbpath ~/dbs/config3 --port 20003
然后,启动mongos的时候应将其连接到这3个配置服务器:
$ ./mongos --configdb localhost:20001,localhost:20002,localhost:20003
配置服务器使用的是两步提交机制——而不是普通MongoDB的异步复制——来维护集群配置的不同副本。这样能保证集群状态的一致性。这也意味着,某台配置服务器宕掉了以后,集群配置信息将是只读的。客户端还能够读写,但是只有所有配置服务器备份了以后才能重新均衡数据。
mongos的数量不受限制。建议针对一个应用服务器只运行一个mongos进程。这样每个应用服务器就可以与mongos进行本地回鹘,如果服务器不工作了,就不会有应用试图与不在的mongos通话了。
『健壮的片』
生产环境中,每个片都应是副本集。这样单个的服务器坏了,就不会导致整个片失效。用addshard命令就可以将副本集作为片添加。添加时只要指定副本集的名字和种子就好了。
比如要添加副本集foo,其中包含一个服务器prod.example.com:27017(还有别的服务器),就可以使用下列命令将其添加到集群里:
> db.runCommand({"addshard" : "foo/prod.example.com:27017"})
如果prod.example.com挂了,mongos会知道它所连接的是一个副本集,并会使用新的主节点。
【管理分片】
分片信息主要存放在config数据库上,这样就能被任何连接到mongos的进程访问到了。
『配置集合』
下几节的代码都假设已经在shell中连接了mongos,并且已经运行了use config。
⒈片
可以在shards集合中查到所有的片:
> db.shards.find()
{ "_id" : "shard0", "host" : "localhost:10000" }
{ "_id" : "shard1", "host" : "localhost:10001" }
⒉数据库
databases集合含有已经在片上的数据库列表和一些相关信息:
> db.databases.find()
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "foo", "partitioned" : false, "primary" : "shard1" }
{ "_id" : "x", "partitioned" : false, "primary" : "shard0" }
{
"_id" : "test",
"partitioned" : true,
"primary" : "shard0",
"sharded" : {
"test.foo" : {
"key" : {"x" : 1},
"unique" : false
}
}
}
这里是全部可用的数据库和一些基本信息。
· "_id",字符串
"_id"表示数据名。
· "partitioned",布尔型
如果为true,则表示已经启用分片功能。
· "primary",字符串
这个值与片的"_id"相对应,表明这个数据库的“大本营”在哪里。不论分片与否,数据库总是会有个大本营的。要是分片了的话,创建数据库时会随机选择一个片。也就是说,大本营是开始创建数据库文件的位置。虽然分片时数据库也会用到很多别的服务器,但是会从这个片开始。
⒊块
块信息保存在chunks集合中。它有很多有趣的东西,也可以看到数据到底是怎么切分到集群的:
> db.chunks.find()
{
"_id" : "test.foo-x_MinKey",
"lastmod" : { "t" : 1276636243000, "i" : 1 },
"ns" : "test.foo",
"min" : {
"x" : { $minKey : 1 }
},
"max" : {
"x" : { $maxKey : 1 }
},
"shard" : "shard0"
}
单块的集合就是这样的:块的范围从-∞(MinKey)到∞(MaxKey)。
MongoDB学习笔记九:分片的更多相关文章
- MongoDB 学习笔记之 分片和副本集混合运用
分片和副本集混合运用: 基本架构图: 搭建详细配置: 3个shard + 3个replicat set + 3个configserver + 3个Mongos shardrsname Primary ...
- MongoDB学习笔记(六)--复制集+sharding分片 && 总结
复制集+sharding分片 背景 主机 IP 服务及端口 Server A ...
- MongoDB学习笔记(五)--复制集 && sharding分片
主从复制 主从节点开启 主节 ...
- mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)
最后更新时间:2017-07-13 11:10:49 原始文章链接:http://www.lovebxm.com/2017/07/13/mongodb_primer/ MongoDB - 简介 官网: ...
- MongoDB学习笔记(四)--索引 && 性能优化
索引 基础索引 ...
- MongoDB学习笔记(1):MongoDB的安装和说明
MongoDB学习笔记(1):MongoDB的安装和说明 快速开始 下载地址 官网下载: https://www.mongodb.com/download-center?jmp=nav#communi ...
- MongoDB学习笔记:MongoDB 数据库的命名、设计规范
MongoDB学习笔记:MongoDB 数据库的命名.设计规范 第一部分,我们先说命名规范. 文档 设计约束 UTF-8 字符 不能包含 \0 字符(空字符),这个字符标识建的结尾 . 和 $ ...
- MongoDB学习笔记:快速入门
MongoDB学习笔记:快速入门 一.MongoDB 简介 MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统.在高负载的情况下,添加更多的节点,可以保证服务器性能.M ...
- MongoDB学习笔记系列
回到占占推荐博客索引 该来的总会来的,Ef,Redis,MVC甚至Sqlserver都有了自己的系列,MongoDB没有理由不去整理一下,这个系列都是平时在项目开发时总结出来的,希望可以为各位一些帮助 ...
随机推荐
- MVC教程相关
本教程所有文章导航 本系列共10篇文章,翻译自Asp.Net MVC4 官方教程,由于本系列文章言简意赅,篇幅适中,从一个示例开始讲解,全文最终完成了一个管理影片的小系统,非常适合新手入门Asp.Ne ...
- 【kate整理】matlab求商,求余数
a/b=q...r a=b*q+r r为余数 fix(a/b) 求商rem(a,b) 求余数还可以 mod(a,b) 两者的区别是余数的符号,rem与a相同,而mod与b相同 例1: & ...
- SQL简单语法
(1)select SELECT 列名称 FROM 表名称 (2)distinct SELECT DISTINCT 列名称 FROM 表名称 SELECT * FROM 表名称 (3)where SE ...
- SharePoint Site "Language Settings"功能与CSOM的对应
博客地址:http://blog.csdn.net/FoxDave SharePoint网站中的语言设置:"Language Settings",可以用CSOM通过Site的一些 ...
- matlab初学之plot颜色和线型
文章出处: http://jiangshuxia.9.blog.163.com/blog/static/3487586020116711375339/ 字母 颜色 标点 ...
- cocostudio 骨骼动画 setContentScaleFactor
最近在看骨骼动画,看上去挺容易的,但是照着例子做的时候却出现问题了,骨骼之间出现了很大的缝隙,找了很久才发现原来setContentScaleFactor的原因, 出现间隙,是因为各个骨骼是单独在做缩 ...
- MongoDB学习
最近在学习,参考一线码农的教程 http://www.cnblogs.com/huangxincheng/category/355399.html
- C++类内存布局图(成员函数和成员变量分开讨论)
一.成员函数 成员函数可以被看作是类作用域的全局函数,不在对象分配的空间里,只有虚函数才会在类对象里有一个指针,存放虚函数的地址等相关信息. 成员函数的地址,编译期就已确定,并静态绑定或动态的绑定在对 ...
- php大力力:技术排错过程中,关键点总结和心情历程(2015-10-19)
9:40 2015/10/19技术排错过程中,关键点总结和心情历程 有一个按照标题进行内容分类的函数似乎不起作用,这叫人沮丧. 在页面显示图片地址时候,在源系统和目标系统中,包含图片地址的页面代码格式 ...
- UE4 代码编写细节:静态变量
Note:因为在切换关切时,会GC掉所有GameThread线程下的Object类,如果Static是UOBject 请调用AddToRoot函数 当然如果你的UObject子类Object是在自己 ...