阅读更多

4顶
0踩

数据库

转载新闻 深入剖析MongoDB架构

2012-04-13 10:42 by 正式编辑 nemohq 评论(0) 有10060人浏览
近日,软件工程师Ricky Ho的在他的博客里发表了一篇关于MongoDB架构(MongoDB Architecture)的博文,虽然这是一个听起来感觉很宽泛的话题,但是作者在文章中确实对MongoDB由内至外的架构进行了剖析。本文截取了其文章中的几张重点架构示意图进行简要描述。

1、MongoDB数据文件内部结构


  • MongoDB在数据存储上按命名空间来划分,一个Collection是一个命名空间,一个索引也是一个命名空间。
  • 同一个命名空间的数据被分成很多个Extent,Extent之间使用双向链表连接。
  • 在每一个Extent中,保存了具体每一行的数据,这些数据也是通过双向链接来连接的。
  • 每一行数据存储空间不仅包括数据占用空间,还可能包含一部分附加空间,这使得在数据Update变大后可以不移动位置。
  • 索引以BTree结构实现。
2、在MongoDB中实现事务


众所周知,MongoDB只支持对单行记录的原子性修改,并不支持对多行数据的原子操作。但是通过上图中的不可思议的操作步骤,实际上你也可以自己实现该事务。其步骤如下

  • 第1步:先记录一条事务记录,将要修改的多行记录的修改值写到里面,并设置其状态为init(如果这时候操作中断,那么在重新启动时,会判断到它处于init状态,从而将其保存的多行修改操作应用到具体的行上)。
  • 第2步:然后更新具体要修改的行,将刚才写的事务记录的标识写到它的tran字段中。
  • 第3步:将事务记录的状态从init变成pending(如果在这时候操作中断,那么在重新启动时,会判断到它的状态是pending,这时查看其所有对应的多条要修改的记录,如果其tran值不为空,那么就进行第4步;如果值为空,说明第4步已经执行过了,直接将其状态从pending变成 commited就行)。
  • 第4步:将需要修改的多条记录的相应值加以修改,并且unset掉之前的tran字段。
  • 第5步:将事务记录那一条的状态从pending变成commited,事务至此完成。
其实上面的步骤并不罕见,在支持事务的DBMS中,其事务原子性提交的保证大多都与上面类似。而事务记录的tran那条记录,就类似于这些DBMS中的redolog。

3、MongoDB数据同步


MongoDB采用Replica Sets模式的同步流程

本流程可简要描述如下:

  • 红色箭头表示写操作可以写到Primary上,然后异步同步到多个Secondary上。
  • 蓝色箭头表示读操作可以从Primary或Secondary任意一个中读取。
  • 各个Primary与Secondary之间一直保持心跳同步检测,用于判断Replica Sets的状态。
4、分片机制


  • MongoDB的分片是指定一个分片key来进行,数据按范围分成不同的chunk,每个chunk的大小有限制。
  • 有多个分片节点保存这些chunk,每个节点保存一部分的chunk。
  • 每一个分片节点都是一个Replica Sets,这样保证数据的安全性。
  • 当一个chunk超过其限制的最大体积时,会分裂成两个小的chunk。
  • 当chunk在分片节点中分布不均衡时,会引发chunk迁移操作。
5、服务器角色


前面讲了分片的机制,下面是具体在分片时几种节点的角色:

  • 客户端访问路由节点mongos来进行数据读写。
  • config服务器保存了两个映射关系,一个是key值的区间对应哪一个chunk的映射关系,另一个是chunk存在哪一个分片节点的映射关系。
  • 路由节点通过config服务器获取数据信息,通过这些信息,找到真正存放数据的分片节点进行对应操作。
  • 路由节点还会在写操作时判断当前chunk是否超出限定大小。如果超出,就分列成两个chunk。
  • 对于按分片key进行的查询和update操作来说,路由节点会查到具体的chunk然后再进行相关的工作。
  • 对于不按分片key进行的查询和update操作来说,mongos会对所有下属节点发送请求然后再对返回结果进行合并。
英文原文:MongoDb Architecture
  • 大小: 54.3 KB
  • 大小: 39 KB
  • 大小: 25.6 KB
  • 大小: 23.4 KB
  • 大小: 30.9 KB
来自: NoSQLFan
4
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 代码题(63)— 字符串拷贝

    1、strcpy函数的实现 编写 strcpy 函数 已知 strcpy 函数的原型是 Char *strcpy(char *strDest,const char *strSrc); 其中 strDest 是目的字符串, strSrc 是源字符串。 (1) 不调用 c++ 、 /c 的字符串库函数,请编写函数 strcpy (2) Strcpy 能把 strSrc 的内容复制...

  • 字符串复制函数

    #include #include #include void my_strcpy(char *dest ,const char *src) {     while(*src)     {         *dest++ = *src++;     }     *dest = 0;   } char * my_strcpy1(char *dest ,const char *

  • 使用函数实现字符串部分复制.本题要求编写函数,将输入字符串t中从第m个字符开始的全部字符复制到字符串s中

    使用函数实现字符串部分复制 (20分) 本题要求编写函数,将输入字符串t中从第m个字符开始的全部字符复制到字符串s中。 函数接口定义: void strmcpy( char *t, int m, char *s ); 函数strmcpy将输入字符串char *t中从第m个字符开始的全部字符复制到字符串char *s中。若m超过输入字符串的长度,则结果字符串应为空串。 裁判测试程序样例: #incl...

  • 字符串拷贝操作

    #include <stdio.h> #include <stdlib.h>void copy_str(char *from, char *to) { while(*from!='\0') { *to++ = *from++; } *to = '\0'; // **①** }void main() { char *from = "I am a

  • 字符串复制问题(二)

    问题:编程序用逐个字符复制方式,实现字符串的复制 为了编程方便,我们调用字符串复制函数strcpy 源程序: #include&amp;lt;stdio.h&amp;gt; #include&amp;lt;string.h&amp;gt; main() { chars[20]=&quot;I love the world!&quot;,t[20]; strcpy(t,s);//此函数的地一个参数必须是字符数组名,第二个参...

  • php.ini post,关于config:php.ini $ _POST为未知原因为空(localhost)

    今天发现$ _POST数组完全为空。这是我正在测试的一种基本形式,并且可以在远程主机上正常运行,因此我检查了php.ini文件。我发现enable_post_data_reading设置为"关闭"并注释(尽管文档说默认情况下它已启用)。我以为...

  • this.$toast() 了解一下?

    前言 在平时的开发过程中,我们总是先写好一个组件,然后在需要的页面中用 import 引入即可,但如果是下面这种类型的组件呢

  • ajax post 不起作用,Jquery ajax post请求不起作用

    我用ajax提交了一个简单的表单,但它总是给我一个错误。所有的错误都是“错误”。没有代码,没有描述。没有什么,当它失败时我会提醒它。带jQuery的Javascript:$(document).ready(function(){$(".post-input")....

  • 字节一面:post为什么会发送两次请求?

    最近博主在**字节面试**中遇到这样一个面试题,这个问题也是前端面试的高频问题,因为在前端开发的日常开发中我们总是会与post请求打交道,一个小小的post请求也是牵扯到很多知识点的,博主在这给大家细细道来。

  • 为什么要禁止除GET和POST之外的HTTP方法?

    因此,有必要说明一下,为什么要禁止除GET和POST之外的HTTP方法。 换句话说,对于这些HTTP不安全方法,到底有多不安全呢? 一、HTTP请求方法有哪些 根据HTTP标准,HTTP请求可以使用多种方法,其功能描述如下所示...

  • string函数原型实现

    strlen函数 形式:strlen(地址) 功能:测试一个字符串从标识的地址开始到**\0**的所有非\0的字符个数 #include &lt;stdio.h&gt; #define n 81 int strlength(char s[]) { int i=0,cnt=0; while(s[i]!=\0) { cnt++; i++; } return cnt; } int ma...

  • C中的字符串拷贝问题

    1.为什么用strlcpy而不是strcpy、strncpy   strcpy 函数原型: #include char *strcpy(char *dest, constchar *src); 功能:把字符串src中的内容copy到dest中,包括字符串src的结束标志’\0’也一起copy,返回:指向dest的指针。 存在的安全问题:          当strlen(src)

  • 【python】request.post报错显示服务器内部错误500

    python调用request.post的时候,报错500

  • Vue使用axios发送post请求,后端无法接收怎么处理?(Djnago后台)

    今天终于解决了一个困扰很久的问题,在使用Vue进行前端项目的搭建时,通常采用axios作为数据传输的工具,我们会发现,使用get请求一切都正常,但是使用post请求,会发生一些奇怪的事情。这次我使用的是python的web...

  • ajax options 禁止_关于http:为什么发送OPTIONS请求,我可以禁用它吗?

    我发现每当我使用Chrome进行POST,GET到我的API时,总会在真实请求之前发送OPTIONS请求,这非常烦人。 目前我让服务器忽略任何OPTIONS请求。 现在我的问题是发送OPTIONS请求以加倍服务器负载是什么好事? 有没有...

  • 为什么大型网站都采用get方法,而非post方法

    在网上摘到一段比较有用的话  减低服务器流量压力 ...所谓安全的意味着该操作用于获取信息而非修改信息。换句话说,GET 请求一般不应产生副作用。幂等的意味着对同一 URL 的多个请求应该返回同样的结果。...

  • 面试官:为什么 Activity.finish() 之后 10s 才 onDestroy ?

    为什么不能使用 Application Context 显示 Dialog? OOM 可以被 try catch 吗? Activity.finish() 之后十秒才回调 onDestroy ? 本文永久更新地址: https://xiaozhuanlan.com/topic/2916834507 目录 没有及时...

  • python获取post请求_如何从请求中获取POST数据?

    我刚刚用django设置了一个apache服务器,为了测试它,在views.py中创建了一个非常简单的函数channel = rabbit_connection()@csrf_protect@csrf_exemptdef index(request):data={'text': 'Food truck is awesome!...

  • POST status code: 405 Method Not Allowed, 但是GET 方法可行,折腾两天,问题居然是...

    我希望用axios来发起一个POST请求,但是老是报错 status code: 405 Method Not Allowed 。但是奇怪的是GET就可以。 我反复调试各种参数, 是不是url不对,相对路径换成绝对路径? 是不是请求头不对,尝试各种content-...

  • 简单的 HTTP 调用,为什么时延这么大?

    可能你乍一看觉得这不是很正常吗,有什么好奇怪的?其实不然,我再来说下一些基本信息,该后端的 HTTP 服务并没有什么业务逻辑,只是将一段字符串转成大写然后返回,字符串长度也仅只有 100  字符,另外网络 ping ...

Global site tag (gtag.js) - Google Analytics