Code Monkey home page Code Monkey logo

mongodbtree's Introduction

MongodbTree

Mongo 文档存储数据库

Mongodb技术
1)数据类型
   mongo的文档格式 BSON, 二进制的JSON
2)_id, ObjectId
   
3) 索引
     1)唯一索引
        唯一索引确保集合中的每一个文档的指定键都是唯一的
           db.ponapartetable.ensureIndex({"uid":1}, {"unique":true})
           典型的唯一索引"_id",在集合创建的时候自动创建,"_id"唯一索引不能被删除,其他唯一索引都是可以删除的 

     2)稀疏索引
           唯一索引会把null看做值,所以无法将多个缺少唯一索引中的键的文档插入到集合中,然而,有些情况下,你可能希望唯一索引只对
           包含相应键的文档生效,如果有一个可能存在也可能不存在的字段,但是当它存在时,它必须是唯一的,这时就可以将unique和sparse选项组合在一起使用
           db.ponapartetable.ensureIndex({"uid":1}, {"unique":true, "sparse":true})
           
          hint()强制进行全表扫描

     3) 所有的数据库索引信息全部放在system.indexes集合中,保留集合
     5) 默认情况下,Mongodb会尽可能快的创建索引,阻塞所有对数据库的读请求和写请求,一直到索引创建成功,如果希望在创建索引时仍能处理请求,可通过创建索引时指定backgroud选项,
     有请求需要处理,创建索引会暂停一下,后台创建索引比前台创建索引慢很多
5)特殊的索引与集合
     普通集合:
	     1)动态创建的
		 2)可以自动增长以容纳更多的数据
     特殊集合:
         1)预先创建好
         2)大小固定
         固定集合的行类似于循环队列,如果已经没有空间了,最老的文档会被删除用以释放空间,新插入的文档会占据这块空间.
         固定集合的访问模式与mongodb中的大部分集合不太一样:数据被顺序写入磁盘上的固定空间,因为它们在磁盘上的访问速度非常快,固定集合可以用来记录日志
         创建固定集合:
            db.createCollection("myCollection", {"capped":true, "size":1000, "max":100})
	           集合大小为1000字节,单个文档最大为100
	        db.runCommand({"convertToCapped":"ponaparte", "size":10000})
	        将ponaparte转换为固定集合,无法将固定集合转化为非固定集合
         自然排序:
            对固定集合可以进行一种特殊的排序,称为自然排序,自然排序返回的结果就是集合中文档在磁盘上的顺序 
         创建不带"_id"索引的集合, createCollection({"autoIndexId":false})
	  TTL索引:
		 这种索引为每一个文档设置一个超时时间,一个文档达到预设值的老化时间之后就会被删除,这种索引对于缓存问题非常有用
         db.ponaparte.ensureIndex({"utime":1}, {"expireAfterSecs":60 * 60 * 24})
         在utime上建立TTL索引,24小时之后失效
      全文本索引
         使用正则表达式搜索大块文本存在的问题
         1)速度非常慢
	     2)无法处理语言的额问题,比如entry, entries应该算是匹配的
      使用全文本索引可以非常快的进行文本搜索,就像内置了多种语言的分词机制的支持一样
         1)创建任何一种索引的开销都比较大,创建全文本索引的成本更高
         2)全文本索引也会导致比普通索引更为严重的性能问题,因为所有字符串都需要被分解,分词,并且保存到一个地方,因此可能会发现全文本索引的集合的写入速度比其他集合要查,
         全文本索引也会降低分片时的数据迁移速度,将数据迁移到其他分片是,所有文本都需要重新进行索引
           启用全文本索引
              db.adminCommand({"setParameter":1, "textSearchEnabled":1})
         3)全文本索引只会对字符串数据进行索引,其他数据类型会被忽略	 
         5)一个集合中最多只能有一个全文本索引
         6)全文本索引与普通索引不同的是:全文索引中索引字段的顺序不重要,重要的是索引字段的权重,一经创建,权重不可修改,可以通过删除索引方式修改权重
      地理空间索引
         2dsphere索引(地球表面数据)
	        数据格式:GeoJson格式(指定点(longtitude, latitude),线,所变形)
	     2d索引(平面地图)	
      GridFS存储文件
               
6)聚合
      常用的聚合工具
         1)聚合框架
            使用聚合框架可以对集合中的文档进行变换和组合,基本上,可用多个构件创建一个管道(pipeline),用于对一连串的文档进行处理,这些构件包括筛选(filtering),投射(projecting),分组(grouping), 限制(limiting)和跳过(skipping)
 
            Mongodb不允许单一的聚合操作占用过多的系统内存,如果mongodb发现某个聚合操作占用了超过20%内存,这个操作就会被直接输出错误
         2)MapReduce
            有些问题过于复杂,无法使用聚合框架的查询语言来表达,这时可以使用MapReduce,MapReduce使用js作为查询语言,js作为查询语言,因此它能够表达任意复杂的逻辑,然而MapReduce非常慢,不应该用在实时的数据分析中。
 
            MapReduce能够在多台服务器之间并行执行,它会将一个大问题拆分为多个小问题,将多个小问题发送到不同机器上,每台机器只负责完成一部分工作,所有机器都完成后,再将这些零碎的解决方案合并为一个完整的解决方案
           
            MapReduce的几个步骤
              1)映射(map)
	             将操作映射到集合中的每一个文档
	          2)中间环节 洗牌 (shuffle)
	             按照键分组,将产生的键值组成列表放到对应的键中
	          3)化简(reduce)
                 把列表中的值化简称一个单值,这个值被返回,然后接着进行洗牌,直到每个键的列表只有一个值为止,这个值就是最终结果
         3) 聚合命令
            1) count
            2) distinct
            3) group 
7)复制
        在mongodb中,创建一个副本集之后就可以使用复制功能了,副本集是一组服务器,用于处理客户端请求,还有多个备份服务器用于保存主服务器的数据副本,如果主服务器崩溃了,备份服务器会自动将其中一个成员升级为主服务器

     1)创建副本集
        进入mongo shell,
    	三台服务器分别执行  mongod --replset bonaparte -f mongod.conf --fork
			config = {
	   			"_id":"bonaparte",
	   			"members":{
	       			{"_id":0, "host":"192.168.0.1:27017"},
		   			{"_id":0, "host":"192.168.0.2:27017"},
		   			{"_id":0, "host":"192.168.0.3:27017"}
	   			}
			}
         rs.initiate(config)
         任意server解析到配置对象之后,会向复制集中的其他实例发送消息,提醒它们使用最新的配置,所有成员配置完成之后,它们会自动选出一个主节点,处理请求开始
        
     2)副本集的心跳,选举,回滚
         选举:
         	当一个备份节点无法与主节点连通时,它就会联系并请求其它的副本集成员将自己选举为主节点,其它成员会做几项理性的检查
	     		1)自身是否能够与主节点连通
	     		2)希望被选举为主节点的备份节点的数据是否是最新
	     		3)有没有其它更高优先级的节点可以被选举为主节点
	     		如果要求被选举为主节点的成员能够得到大多数节点的支持,它就会成为主节点
            加入网络良好,大多数的服务器都在运行,那么选举过程是很快的,整个选举过程只会花几毫秒
            
         仲裁者
    		有时候基于保存副本成本与性能的考量,用户不需要这么多副本,对于这种部署,Mongodb支持一种特殊类型的成员,仲裁者,
			仲裁者的唯一作用就是参与选举,不会为客户端提供服务是为了满足选举中的大多数这个条件的。
         
         优先级:
    		表示一个节点渴望成为主节点的意愿
    		优先级为0的节点永远不能成为主节点

		 隐藏成员
            客户端不会向隐藏成员发送请求,隐藏成员也不会作为复制源

         延迟备份节点
            数据可能会因为人为错误而遭受毁灭性的破坏,可能有人不小心删除了主数据库,为了防止这类问题,可以使用slaveDelay设置一个延迟的备份节点,延迟备份几点的数据会比主节点的数据延迟指定的时间,当主数据库被删除,还可以从延迟数据库中恢复
	
     3)从应用程序连接到副本集
        从应用程序角度讲,使用副本集与使用单台服务器很像,默认情况下,驱动程序会连接到主节点,并且将所有的请求都路由到主节点。

     4) 副本集的组成
        Mongodb的复制功能是基于操作日志oplog实现的,操作日志包含主节点的每一次写操作,oplog是主节点的local数据库中一个固定集合,备份节点通过查询这个集合就知道需要进行复制的操作

        每个备份节点维护一个oplog,记录每次从主节点复制数据的操作,这样,每个备份节点都可以作为同步源给其它节点使用	

        复制集中的成员每隔2s向复制集中的其它成员发送心跳消息

     5)副本集的管理

     6)分片
        1)分片概念
           mongodb分片是指将数据拆分,将其分散在不同机器的过程,mongodb支持自动分片,应用程序直接连接到路由服务器就可以像单台服务器一样使用

        2)配置分片
           cluster = new ShardingTest({"shards":3, "chunksize":1})
           对数据库分片 enableSharding("bonaparte"),
           对集合分片 shardingCollection("ponaparte.collection1", {"username":1})

        3)追踪集群数据
          Mongodb将文档分组为块(chunk),每个块由给定片键特定方位内的文档组成,一个块只存在于一个分片上,所以Mongodb用一个比较小的表就能够维护跟分片的映射。例如:如用户集合的片键{"age":1},其中某个块可能是由age为3-17的文档组成的,如果得到一个{"age":5}的查询请求,它就可以将查询路由到age为3-17的数据块上

          chunk的拆分:m起初,分片的集合只有一个chunk,后续随着数据量的扩大,块逐渐变大,块拆分,块变大,块拆分的循环裂变过程

          Mongos会 记录在每个块中插入了多少条记录,一旦达到某个阈值,就会检查是否需要对块进行拆分,如果块确实需要拆分,mongos就会在配置服务器上更新这个块的配置元信息

        5) 分片的主要目的
          1)增加可用RAM
	      2)增加可用磁盘空间
	      3)减轻单台服务器都得负载
	      5)处理单个mongod无法承受的吞吐量

        6) 均衡器&&块迁移

     7)选择片键
        1)升序片键
           弊端:所有的请求都会被路由到一个分片,该片是唯一一个不断增长和拆分的块,因为它是唯一一个能够接受插入请求的块,随着新数据的不断插入,该最大块会不断的拆分出新的小块,mongodb也必须不断的将一些块移至其它分片。
        2)随机分发的片键
           由于写入数据是随机分发的,各分片增长的速度应该大致相同,这就减少了需要进行块迁移的次数
           唯一的弊端在于:mongdb随机访问超过RAM大小的数据时效率不高,然而如果拥有足够多的RAM或者是并不介意系统性能的话,使用随机片键在集群上分配负载是很好的。    
        3)基于位置的片键

        5) 散列片键
           如果追求的是数据加在速度的极致,那么散列片键是最佳选择,散列片键可使其它任何片键随机分发,因此,如果打算在大量查询中
           使用升序键,但同时又希望写入数据随机分发的话,散列片键会是非常好的选择,
           弊端:
              无法使用散列片键做指定目标的范围查询,如无需做范围查询,那么散列片键就非常合适。	
           局限性:
              不能使用unique选项,其次,与其他片键一样,不能使用数组字段,另外浮点型的值会被先取整,然后才进行散列。

     8)应用分析
        1)使用系统分析器
           可提供大量有关耗时过长的操作信息,但相应的,mongodb的整体性能会下降,打开系统分析器(系统会创建一个若干MB的固定集合),  
            db.setProfilingLevel(value)
            记录在system.profile集合中。
        2) mongotop  mongostat
           mongotop类似于linux下的top
           mongostat用于统计mongo服务器的信息

     9)数据管理
        1)建立删除索引
           前台建立索引VS后台建立索引
           在前台建立索引要比在后台建立索引耗时要少,但是索引建立期间会锁定数据库,从而导致其他操作无法进行数据读写,而在后台建立索引期间,则会定期释放写锁,从而保证其它操作的运行,这意味着在后台建立索引耗时更长,尤其是在频繁进行写入的服务器上,但后台服务器建立索引期间,可继续为客户提供服务
           db.ponaparte.ensureIndex({"name":1}, {"background":true})

           在副本集上建立索引:
             在副本集上建立索引最简单的方式,即在主节点建立索引,然后等待其被复制到其它备份节点,在较小的集合中,这一操作不会造成太大影响,如果集合较大,则会出现所有备份节点同时开始建立索引的情况,突然间所有备份节点都无法被客户端读取了,同时可能也无法及时进行同步复制,因此对于较大的集合,推荐采用的方式
	            1)关闭一个备份节点
	            2)将其作为独立的节点启动
	            3)在这一服务器上建立索引
	            5)重新将其作为成员加入副本集
	            6)对每个备份节点执行同样的操作

             完成上述操作后,只剩主节点还没有建立索引,现在又两种选择
                1)于后台在主节点建立索引
                2)关闭主节点,独立建索引,然后加入副本集,该方式会导致数据库停运一次

        2)预热数据
           重启机器或启动一台新的服务器,会耗费一定的时间供mongodb将所有需要的数据从磁盘中载入内存,如对于性能的要求很高,要求数据必须出自内存中,则将新服务器上线,并等待应用程序载入所有所需数据,这会是一项艰巨的任务
           
           1)将数据库移至内存
           2)将集合移至内存
              db.runcommand({"touch":"works", "data":true, "index":true}) 
           3) 自定义预热

        3)压缩数据
           mongodb会占用大量的磁盘空间,有时,大量的数据删除或者更新后,会在集合中产生碎片,如数据文件中有很多空闲空间,但由于这些独立的空闲区块过小,从而使得mongodb无法对这些空闲块加以利用,就产生了碎片。
              为了消除空闲空间,并高效重整集合,可使用compact命令
	             db.runcommand({"compact":"works"})

           压缩操作会消耗大量资源,不应在mongodb想客户端提供服务时执行压缩操作,推荐的做法是类似于建立索引时的做法,即在每个节点中对数据执行压缩操作,然后关闭主节点,进行最后的压缩
           在一个备份节点上进行压缩操作,会使其进入恢复状态,它会对读取请求返回错误,也无法作为一个同步源,压缩操作结束后,其会重新变回一个备份节点

           压缩操作并不会减少集合占用的磁盘空间大小,该操作只是将所有文档都安排在集合的开始部分,这样当集合继续增大时就可以使用后面的空余部分,可通过repair命令来回收磁盘空。
                db.repairDatabase()

        5)移动集合
           要想在数据库间移动集合,必须进行转储(dump)和恢复(restore)操作或者手动复制集合中的文档(找出所有,然后插入)
           db.runcommand({"cloneCollection":"works", "from":"hostname:27017"})

     10)持久性
         Mongodb会在进行写入时建立一条日志,日志中记录了此次写操作具体更改的磁盘地址和字节,因此一旦服务器停机,可以再启动时对日志进行重放,从而重新执行哪些停机前没有能够刷新到磁盘的写入操作。
         数据文件默认每60秒钟刷新一次到磁盘

     11)Mongodb监控
         电脑内存一半会有容量小且访问速度快的内存,以及容量大但访问速度慢的磁盘,当请求一页存储于磁盘上但尚未存在于内存中的数据时,系统就会产生一个缺页终端,而后将次页数据从磁盘复制到内存,从后就可以以极快的速度访问内存中的页面。

         1) 缺页中断

         工作集(引用所使用的数据,应用最常使用的数据)         
         1)整个数据集在内存中
         2)工作集在内存中
         3)索引处于内存中
         5)索引的工作集处于内存中

     12) 备份
         备份有多种方式,但无论采用哪种方式,备份操作都会增加系统的负担:备份通常需要将所有数据读取到内存中,因此,通常情况下,应对副本集的非主节点进行备份,或在空闲时段对独立服务器进行备份。

        1) 文件系统快照
           需要的前提条件
              1)文件系统支持快照
	          2)mongodb必须开启日志系统

        2) 复制数据文件
           该方式是复制数据目录中的所有文件,没有文件系统的支持,我们就无法通知复制所有文件,因此在进行备份时,必须防止数据文件
           发生改变,可以使用   
              >db.fsyncLock()
           命令做到这一点,这个命令锁定数据库,禁止任何写入,并进行同步,即将所有脏页刷新至磁盘,以确保数据目录中的文件是最新的,且不会被修改.的写入操作,而不只是已连接的数据库。
             复制完成后解锁数据库
             >db.fsyncUnLock()
        
        3) 使用mongodump
           备份和恢复的速度较慢,在处理副本集时存在一些问题
           mongodump会在当前目录建立一个转储(dump)目录,转储目录中的目录和子目录由数据库和集合组成,真正的数据存放在扩展名为
           bson的文件里,可以使用mongodb自带的bsondump查看bson文件。  
         
           mongodump存在一些问题,它并非进行快照备份,也就是说在备份的过程中,系统可能会继续 进行写入操作。于是问题出现,开始备份时mongodump先对数据库A进行转储,随后在mongodump正在对数据库B进行转储的同时,删除了数据库A,然而mongodump已经对数据库A进行了转储,于是转储得到的最终结果是得到了一个再原服务器并不存在的数据快照   

        3) 对副本集进行备份
           通常情况下,应该对副本集进行备份:
              1) 减轻主节点负担
	          2)也可以在不影响应用的情况下锁定备份节点,对副本集中的成员进行备份,推荐使用文件系统快照或者复制数据文件

        5) 对分片集群进行备份
           不可能对正在运行的分片集群进行完美的备份,因为无法及时得到集群在某一时间点完整状态的快照。然而通常情况下都会避开该限制,因为随着集群的增大,从备份中恢复整个集群的可能性越来越小,因此,在面对分片集群时,我们更关注分块的备份,即单独备份配置服务器和副本集。
           在对分片集群进行备份和恢复操作之前,应该先关闭均衡器,这是因为在过于混乱的环境中是无法得到一份前后一致的快照的。

     13) Mongodb环境部署
           设计系统架构:
              1)选择存储介质
	             1)内存
		         2)固态硬盘
		         3)机械磁盘
	             从内存中读取数据需要ns级的时间(比如100ns),而从磁盘中读取数据需要ms级的时间,使用磁盘的配置:
                    1)推荐使用RAID,冗余磁盘阵列技术
              2)CPU
                 mongodb对CPU的负载很轻,两个CPU即可满足每秒10000次的查询
              3)选择操作系统
                 64位Linux操作系统是mongodb的最好选择。
              5)交换空间
              6)文件系统
                 推荐使用ext4或者XFS文件系统作为数据卷。
              7)选择一种磁盘调度算法
                 DeadLine调度算法和CFQ(完全公平队列)调度算法是一种不错的选择
              8)禁用大内存页面

     15) 应用程序设计
         范式化:
            将数据分散到不同的集合,不同集合之间可以相互引用数据,但是引用的数据只存储在一个集合中
         反范式化:	
            将每个文档所需的数据都嵌入在文档内部,每个文档都拥有自己的数据副本,而不是所有文档共同引用同一个数据副本
         优化优化数据操作

SequoiaDB技术
   相同点:都是属于非关系型数据库,分布式数据库,支持数据分片,满足数据分片要求的数据完备
          性,可重构性和无损一致性。支持多个副本数据存储,满足高可用和性能要求。并且数据
          模型都是基于json对象存储,支持数据的增删改查。
   不同点:从上图中可以看到,SequoiaDB能支持事务处理和SQL语法,而Mongodb不支持,
          SequoiaDB支持数据压缩,而Mongodb不支持,SequoiaDB支持存储过程,而Mongodb
          支持的能力较弱。

SequoiaDB对比与其他的NoSQL有更多的方式将数据分布到多台服务器上。
    1)hash方式分布数据
       在Hash分布方式中,由于是对集合中某个字段的Hash值进行数据均匀,所以用户未来在使
       用Hash分布时,ShardingKey一定要选择集合中字段值比较随机,并且Hash值比较均匀的
       字段,这样能够保证集合中的数据被均匀的分布到各个数据分区中。
    2)Range方式分布数据
       Range分布方式,主要适用用于集合数据量大,并且集合包含某个具有比较明确的数值范围
       的字段,例如时间字段或者业务类型字段,来帮助用户做集合的范围切分。
    3)Partion方式分布数据
       Partion分布方式,和Range分布方式的适用场景比较类似,都是要求集合数据量大,并且集合
       包含某个具有比较明确的数值范围字段。
       Partion分布方式,实际上并不能够做到数据自动均匀分布到多个数据分区组,而是需要用户
       在建立子表时,人工显示此子表是被分配到哪个数据分区上,然后通过主表的attach命令将
       子表按照某个范围值挂载到主表上。
       而Partion分布方式与Range分布方式最大的不同点,在于对数据的删除上。
       在Range分布方式中,如果用户需要对集合中某个过旧的时间范围数据进行删除,用户需要调用
       Remove命令,真实的数据库磁盘中删除这部分数据,这个耗时比较久。
       而Partion分布方式中,用户同样希望删除某个过旧的时间范围数据时,用户只需要调用dettach命令,将符合时间范围的子表从主表卸载下来,即可完成数据从集合中清除的目的,
       dettach的效率非常高,基本上是秒级完成,然后用户可以对过旧的子表执行truncate命令,
       回收磁盘空间
    5)多维分区
       SequoiaDB的多维分区方式,它很好的结合了Hash分布方式和Partion分布方式的优点,能
       够让集合中的数据以更小的粒度分布到数据库多个数据分区组上。
       多维分区分布方式,主要适合的场景是集合数据量特别巨大,集合中同时包含两个关键的
       ShardingKey,一般为time和id两个字段,time字段给主子表使用,id字段和Hash分布使用,并且用户在使用集合的过程中,还可能会定期对部分数据进行空间回收。

       在真实的客户环境中,多维分区主要使用的场景为:银行的历史数据流水,业务系统历史日志表等。
检查写入是否出错
	WriteResult ret = db.update({"name":"lily"},{"$set":{"age":20}});
	if(ret.getLastError() == null)
	    return true;
	else
	    return false;
	
	此时,getLastError()会查询上次操作结果是否出现错误。

###非应答式写入

         db.blogs.insert({ename:"leshami",url:"http://blog.csdn.net/leshami"},{writeConcern:{w:0}})

###应答式写入 应答式写入是默认值 db.blogs.insert({ename:"john",url:"http://blog.csdn.net/john"},{writeConcern:{w:1}})

###带journal应答式写入

###副本集应答写入

        对于使用副本集的场景,缺省情况下仅仅从主(首选)节点进行应答
	    建议修改缺省的应答情形为特定数目或者majority来保证数据的可靠
	    如下示例,w值为2,超时为5s
	            db.products.insert(
	               { item: "envelopes", qty : 100, type: "Clasp" },
	               { writeConcern: { w: 2, wtimeout: 5000 } }
	            )       
	    如果不希望每次在增删改时添加writeConcern,可以通过设置settings.getLastErrorDefaults
	    如下示例,
	            cfg = rs.conf()
	            cfg.settings = {}
	            cfg.settings.getLastErrorDefaults = { w: "majority", wtimeout: 5000 }
	            rs.reconfig(cfg)

MongDB写安全

      MongoDB Write Concern,简称MongoDB写入安全机制,是一种客户端设置,用于控制写
      入安全的级别。Write Concern 描述了MongoDB写入到mongod单实例,副本集,以及分片
      集群时何时应答给客户端。默认情况下,mongoDB文档增删改都会一直等待数据库响应
      (确认写入是否成功),然后才会继续执行。本文讲述了MongoDB 应答机制及相关参数。

      MongoDB应答机制:
              MongoDB应答机制就是说对于当前数据库的写入成功与否告知客户端(db.getLastError())。
               如下:
                   mongoDB client发出写入(或更新)请求---->mongoDB Server端写入---->通知客户端已经写入OK
               主要分为2种应答机制
                    1)应答式写入(缺省情形,安全写入,适用于数据强一致性场景)
                    2)非应答式写入(非安全写入,适用于数据弱一致性场景)
               实现方式
                    1)通过Write Concern来实现,客户端驱动调用db.getLastError()方法,错误返回给客户端
                    2)如果捕获到错误,则可以通过客户端定义的逻辑尝试再次写入或记录到特定日志等
MongDB journal技术研究

      如果不配置journal,写入wiredtiger的数据,并不会立即持久化存储,而是每分钟会做一次全量的checkpoint,将
      所有的数据持久化,如果中间出现宕机,那么数据只能恢复到最近的一次checkpoint,这样最多可能丢失1分钟的数据。

      开启journal后,每次写入记录一条操作日志(通过journal可以重新构造写入的数据)。这样,即使出现宕机,启动时
      wiredtiger会先将数据恢复到最近的一次checkpoint,然后重放后续的journal操作日志来恢复。

      MongoDB 里的 journal 行为 主要由2个参数控制,storage.journal.enabled 决定是否开启
      journal,storage.journal.commitInternalMs 决定 journal 刷盘的间隔,默认为100ms,用户
      也可以通过写入时指定 writeConcern 为 {j: ture} 来每次写入时都确保 journal 刷盘
MongoDB oplog

      oplog是MongoDB主从复制层面的一个概念,通过oplog来实现复制集节点间的数据同步,客户端将数据写入到primary
      ,primary写入数据后会记录一条oplog, secondary从primary或者其他secondry拉取oplog并重放,来确保复制集
      里每个节点存储相同的数据。

wiredtiger 提交事务时,会将所有修改操作应用,并将上述3个操作写入到一条 journal 操作日志里; 后台会周期性的checkpoint,将修改持久化,并移除无用的journal。

MongoDB的一次性写入:
 
      MongoDB 复制集里写入一个文档时,需要修改如下数据

         1)将文档数据写入对应的集合
         2)更新集合的所有索引信息
         3)写入一条oplog用于同步
      上面3个修改操作,需要确保要么都成功,要么都失败,不能出现部分成功的情况,否则

      如果数据写入成功,但索引写入失败,那么会出现某个数据,通过全表扫描能读取到,但通过索引就无法读取
      如果数据、索引都写入成功,但 oplog 写入不成功,那么写入操作就不能正常的同步到备节点,出现主备数据不
      一致的情况。MongoDB 在写入数据时,会将上述3个操作放到一个 wiredtiger 的事务里,确保「原子性」。

mongodbtree's People

Contributors

qiuqiuxiaomaomi avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.