深入理解MongoDB

来源:互联网 发布:acdsee是什么软件 编辑:程序博客网 时间:2024/06/06 04:47
这是在我看完《深入理解MongoDB》后,按照自己的理解记录下来的笔记,初次接触,若有错误,敬请指出,感谢!


一.概述

MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB操作模式:
应用程序<=>mongos<=>集群

二.理解分片

1.什么是分片(sharding)?

分片(sharding)是MongoDB用来将大型集合分割到不同服务器上采用的方法。这样做是为实现3个目标:

让集群“不可见”

让应用程序知道要执行任何“增删改查”操作只需要发送请求给MongoDB这一个对象就行了,剩下的事就交给它了,不需要区分交给那个服务器,简化了应用程序端操作指令。在MongoDB中具体连接客户端与服务器端的就是叫做mongos的专有路由进程,mongos可以比喻为一个秘书,转发客户端的请求,和服务器端的响应。

保证集群总是可以读写

一个大的集合分为多个分片(shard),当其中一个进程/服务器出现问题,由运行在其他分区的其他副本接替换掉的部分继续工作。

使集群易于扩展

将大的集群分割为多个小的分区,当需要资源的时候,只需要添加小的空间。

2.分配数据

sharding操作后得到分片(shard)是集群中负责数据某一子集的一台或多台服务器。换言之,一个分片包含数据的某个子集。例如一个集群包含1000份代表网站注册用户文档,其中一个分片就可能包含200份。
若一个分片包含多个服务器,则每个服务器拥有一份完整的数据副本。

一分片一区间

分配数据最简单的方法就是让一分片负责一区间的数据。假设有四个分片,依次对应["a","f"),["f","n"),["n","t"),["t","{")区间,{是ASCII码表中字母z后面的字符。许多用户用首字母在范围["a","f")中的名字来注册,就导致分片1较大,我们可以调整区间使分片1对应的区间缩小,从而让分片均衡。但当分片1和分片2过载时,就不太好处理。假设分片1和分片2各有500G数据,分片3和分片4各有300G数据,此时就需要分片1转移100G数据到分片2,接着从分片2转移200G数据到分片3,最后分片3转移100G数据到分片4,从而使每个分片都具有400G数据,达到均衡。这还只是4个分片,执行这个操作一共移动了400G数据。当考虑到所有分片,可想需要移动的数据量是很大的。

一分片多区间

重新来考虑上面的情况,此时是一分片多区间。我们可以把分片1和分片2都划分为两个区间,分片1分别对应包含400G数据的["a","d")区间和包含100G数据的["d","f")区间,分片2分别对应包含400G数据["f","j")区间和100G数据["j","n")区间。我们就可以把分片1中的["d","f")区间的数据直接移动到分片3,把分片2中的[",j","n")区间的数据直接移动到分片4,相比上一种情况,只需要移动200G数据。添加新的分片也具有同样的优势——减少数据转移量。

创建块

一个区间的数据成为一个数据块(也叫块,chunk),块默认大小为200MB(兼顾可移动性和最小开销),当一个块的区间一分为二是,就变成两个块了。当提到块出不得不说片键了,如下所示
{"username":"gala","age":21}
{"username":"pinocchio","age":25}
{"username":"zaizizaizai","age":16}
如果我们选择age字段作为片键病得到一个块区间[20,30),则得到的块为:
{"username":"gala","age":21}
{"username":"pinocchio","age":25}
可以把片键理解为一个选择器(标签),也可理解为属性,即挑选符合条件的数据,在这里不仅局限于把age作为片键,username也可以作为片键,且片键值不可修改。
随着数据的增加,当一个块变大,MongoDB会自动将其分割为2个小块。若分片间数据比例失衡,MongoDB会迁移块其他分片(由叫做平衡器的进程执行),以达到分片间数据比例总是平衡的状态。同时平衡器会忽略微小的不平衡,否则会导致恶性循环。

三.建立集群

选择片键

片键的选择很重要,因为这关系到读操作的速度。以下介绍集中片键的几个常见反例,以便更好理解片键选择。

小基数片键

假设我们有3个分片,我们需要选择片键。前后端编程开发常见的建站就需要对数据分类,有用户的数据、管理员的数据、网页参数的数据,那为了方便理解和区分,就选择用户、管理员、网页参数3个片键。虽然管理员数据比较小,但用户的数据会一直增加,增加到一定程度后,MongoDB也不能分割分片里的块了,最终磁盘空间被耗尽。由于片键值数量有限,后来,就会得到一个又大又无法移动,还不能分割的块,这对数据管理造成极大的不方便。

升序片键

对大部分应用程序而言,新数据被访问的次数总是多于老数据,所以人们会尝试诸如时间戳或者objectID一类的字段作为片键。比如,社交软件上的发动态,每条动态包含消息、地点、时间,我们以时间段来分片。从一个数据块开始,随着时间推移,一个块满了,裂变为两个块,时间点继续增加,这个片键创造了一个单一且不可分散的热点。动态被发出,该时间点MongoDB需要对该时间点对应的块进行写操作,而当大量的动态在同一时间发出,MongoDB来不及对块进行写操作,就会造成堵塞,使应用程序瘫痪。

随机片键

为了避免以上的热点片键,有人选择取随机的字段来分片。采用这种字段开始还不错,但随着数据量的增加,它会变得越来越慢。现在采用随机片键,已经得到一组均匀分布于各分片的数据块。假设分片上的一个块填满并分裂了,配置服务器注意到分片2比分片1多10个块,为了抹平差距,MongoDB就将分片2中的随机5个块(块的数据量的大小不确定)经由内存发送给分片1。随着数据量的增加,这5个随机的块的数据量会很大,应发大量的磁盘IO,致使数据库变慢。

好片键

准升序键加搜索键

快速起步

若想尽快上手,可用Github上的mongos-snippets,其中有个simple-setup.py能自动地启动、配置和生成一个集群,它需要MongoDB的Python驱动。

安装MongoDB的Python驱动

sudo easy_install pymongo

下载mongos-snippets库并执行以下操作

python sharding/simple-setup.py --path=绝对路径


simple-setup.py会启动一个mongos进程,地址为localhost://27017


2017.10.29       pinocchio


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小米5s内屏碎了怎么办 小米4充电没反应怎么办 小米5手机变卡了怎么办 小米5变卡了怎么办 小米手机充电无反应怎么办 小米6相机卡顿怎么办 华为手机玩游戏发热怎么办 华为手机变慢了怎么办 华为p10手机变慢怎么办 华为手机账户密码忘记了怎么办 QQ浏览器无法加载插件怎么办 电脑开了机黑屏怎么办 扫描仪打不开运单扫描怎么办 打印机不支持64位系统怎么办 xp系统dnf闪退怎么办 w10电脑所有程序都打不开怎么办 安卓手机太卡怎么办 系统装到f盘了怎么办 虚拟机占c盘内存怎么办 外机连无线虚拟机显示受限怎么办 使用msdn下载解压后怎么办 路由80端口被占用怎么办 c盘拒绝粘贴文件怎么办 oracle数据库密码忘了怎么办 电脑开机时不显示用户名怎么办? xp系统忘记开机密码怎么办 电脑开机密码忘了怎么办 c盘满了怎么办win10 win10电脑开机密码忘了怎么办 win10的开机密码忘了怎么办 u盘中了exe病毒怎么办 眼睛长个麦粒豆怎么办 苹果手机sdk授权失败怎么办 小米5王者荣耀卡怎么办 华为p9手机电池不耐用怎么办 华为g9青春版耗电快怎么办 华为手机摄像头坏了怎么办 华为p10摄像头玻璃划痕怎么办? 华为g9手机音量小怎么办 华为7pius太卡怎么办 华为畅享7plus卡怎么办