zoukankan      html  css  js  c++  java
  • MongoDB学习总结

    概念与说明

    MongoDB介绍

    MongoDB的名称取自“humongous(巨大的) 的中间部分 。于201085发布了最新的正式版本v1.6,这是其继1.01.21.4版本后的第四个主要稳定版本。由10gen公司为其提供商业支持。• 它是一个开源的、面向文档的数据库,属于nosql数据库中的一种。(nosql全称是”notonly sql”,是非关系型数据存储的广义定义)

    它可运行在LinuxWindowsOSX平台,支持32位和64位应用并且提供了JavaPHPRubyC#C++JavaScript等多种语言的驱动程序。

    MongoDB特性

    MongoDB是一个可扩展、高性能的下一代数据库,由C++语言编写,旨在为web应用提供可扩展的高性能数据存储解决方案。它的特点是高性能、易部署、易使用,存储数据非常方便,主要特性有:

    l        模式自由,支持动态查询、完全索引,可轻易查询文档中内嵌的对象及数组。

    l        面向集合存储,易存储对象类型的数据, 包括文档内嵌对象及数组

    l        高效的数据存储,支持二进制数据及大型对象(如照片和视频)

    l        支持复制和故障恢复;提供了主-从、主-主模式的数据复制及服务器之间的数据复制。

    l        自动分片以支持云级别的伸缩性,支持水平的数据库集群,可动态添加额外的服务器

     

    MongoDB结构

    传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB同样也是由数据库(database) 、集合(collection)、文档对象(document)三个层次组成。 MongoDB里的集合对应于关系型数据库里的表,但是集合中没有列、行和关系的概念,这体现了模式自由的特点。

    MongoDB存储的数据格式是key-value对的集合,键是字符串,值可以是数据类型集合里的任意类型,包括数组和文档对象。这种数据格式称作 BSON,即 Binary Serialized Document Notation”,是一种类似JSON的二进制序列化文档。

    MongoDB使用了内存映射文件进行数据管理,把所有空闲内存当缓存使用,且不能指定内存大小。这既是优点也是缺点:优点--可以最大限度提升性能;缺点--容易受其它程序干扰。

    数据空间采用预分配,目的是为了避免形成过多的硬盘碎片。它为每个数据库分配一系列文件,每个数据文件都会被预分配一个大小,第一个文件名字为“.0 ,大小为64MB,第二个文件“.1”为128MB ,依此类推,在32位模式运行时支持的最大文件为2GB。随着数据量的增加,可以在其数据目录里看到这些不断递增的文件。

    MongoDB没有自动递增或序列特性,BSON对象插入到数据库中时,如果没有提供“_id”字段 ,数据库会自动生成一个ObjectId对象作为“_id”的值插入到集合中作为该文档的主键

    (这就避免了其它数据库意外地选择相同的惟一标识符的情况) ,“_id”的值由4字节的时间戳,3字节的机器号,2字节的进程id以及3字节的自增计数组成。当然字段“_id”的值可以手动生成(任意类型都可),只要能够保证惟一性。

    每个插入的BSON对象大小不能超过4MB,如果超过4M时需使用 GridFS来储存数据。删除记录后不会释放已分配的空间,换句话说:原记录空间不删除。

    MongoDB二进制文件功能

    MongoDB的服务器端程序只有两个:

    Mongod.exe: MongoDB的主要的数据存储服务程序和配置服务程序。

    Mongos.exe:MongoDB的集群路由程序,负责自动分片,用于构建一个大规模的可扩展的数据库集群,这个集群可以并入动态增加的机器,可以将数据库分表存储在集群的各个节点上。

    MongoDB的客户端工具有很多,最常用的就是Mongo.exe,它做为对MongoDB的管控程序,可以使用输入命令的方式修改、查询MongoDB的数据和配置。

    MongoDB常用命令

    l        Help:查看mongodb支持的命令。

    l        db.help:查看当前数据库支持哪些方法当前数据库下的表。

    l        db.dbname.help():查看当前表collection支持哪些方法。

    l        show dbs:列出所有数据库。

    l        use test 使用数据库test ,即使这个数据库不存在也可以执行,但该数据库不会立刻被新建,要等到执行了insert之类的操作时,才会建立这个数据库。

    l        show collections 列出当前数据库的所有文档。

    l        db 显示当前数据库。

    l        show users 列出用户。

    l        db.printShardingStatus() :将当前MongoDB分片的状态打印出来。

    l        db.runCommand({ xxxx}) :在当前DB上执行一些命令。

    l        db.xxx.stats() :显示当前db的某个collection的状态。

    l        db.xxx.find():显示当前db的某个collection的所有内容。

     

    详细的MongoDBshell命令见:http://www.mongodb.org/display/DOCS/dbshell+Reference

     

    GridFS

    MongoDB自带的分布式文件系统GridFS ,可以支持海量的数据存储。

    GridFS将文件分块存储,分别将文件的元信息和文件块存入不同的collection,mongoDB提供的GridFS类将文件默认分块大小设置为256K。如果不改变设置,GridFS在存入文件时,将文件块存入db.fs.chunkscollection,将文件信息存入db.fs.files中。

    文件必须的信息有以下字段:

     {
      "_id" : <unspecified>,                  // unique ID for this file
      "length" : data_number,                 // size of the file in bytes
      "chunkSize" : data_number,              // size of each of the chunks.  Default is 256k
      "uploadDate" : data_date,               // date when object first stored
      "md5" : data_string                     // result of running the "filemd5" command on this file's chunks
    }

     文件块的信息字段包括:

    {   
      "filename" : data_string,               // human name for the file
      "contentType" : data_string,            // valid mime type for the object
      "aliases" : data_array of data_string, // optional array of alias strings
      "metadata" : data_object,               // anything the user wants to store }

    “_id”的类型可以自选,但是默认类型是BSON对象的objectid

    块信息的“files_id”是外键与files集合中的“_id”相关联。

     

    详情可参考:http://www.mongodb.org/display/DOCS/GridFS+Specification

     

    Sharding

    一个mongodb集群包括一些shards(每个shard包括一至多个mongod进程),mongos路由进程,一个或多个config服务器 

    名词:

    Shards : 每一个shards包括一个或多个存储数据的mongod进程,典型的每个shards开启多个服务来提高服务的可用性。这些mongod进程在shards中组成一个复制集(replica pairs)。

    Chunks: Chunks是一个集合中的一个数据范围,(collectionminKeymaxKey)描叙一个chunks,它介于minKeymaxKey范围之间。例如假设chunks maxsize大小是100M,如果一个文件达到或超过这个范围时,会被切分到2个新的chunks中。当一个shard的数据过量时,会将一整个chunks迁移到其他的shards上。同样,chunks也可以迁移到其他的shards上。

    Config Servers : Config服务器存储着集群的metadata信息,包括每个服务器,每个shard的基本信息和chunk信息Config服务器主要存储的是chunk信息。每一个config服务器都复制了完整的chunk信息。

     

    一个分布式集群至少需要三部分:

    1、两个或更多的Shards

    2、最少一台Config Server

    3、一个mongos路由进程。

     

    Sharding的介绍:http://www.mongodb.org/display/DOCS/Sharding+Introduction

    Sharding配置说明:http://www.mongodb.org/display/DOCS/Configuring+Sharding

    Sharding配置的官方示例:http://www.mongodb.org/display/DOCS/A+Sample+Configuration+Session

     

    MongoDB编译和构建

    1、  下载MongoDB源码并解压。

    2、  下载boost并且解压到MongoDB所在盘根目录,目录名为boost,然后编译之。如果已经拥有了Boost可以使用mklink在根目录下面创建目录链接。

    3、  下载SpiderMonkey做为js引擎库(http://github.com/dwight/vc2010_js/tree/master/src/),并解压到和mongodb文件夹同级的“js”文件夹内。

    4、  打开db/db_10.sln,选择相应的平台并且编译,有可能要修改一些语法错误。

    5、  安装pythonSCons(一种构建工具)http://www.python.org/download/releases/2.6.4/ http://sourceforge.net/projects/scons/files/scons/1.2.0/scons-1.2.0.win32.exe/download.

    6、  MongoDB文件夹中运行命令行,并且有可能需要运行VS2010设置环境变量的批处理文件vcvars*.bat

    To build:

    scons                   // build mongod

    scons mongoclient.lib   // build C++ client driver library

    scons all               // build all end user components

    scons .                 // build all including unit test

    服务架设

    MongodMongos等程序的同级目录下创建三个文件夹data_shard1data_shard2 data_config作为数据库目录。

    1shard1启动

    start mongod --dbpath %cd%/data_shard1 --port 27020

    2shard2启动

    start mongod --dbpath %cd%/data_shard2 --port 27021

    3、配置服务器启动

    start mongod --dbpath %cd%/data_config --port 27022 --configsvr

    4、路由服务器启动(使用的默认的端口27017

    start mongos --configdb 127.0.0.1:27022

    5、启动mongo,也使用默认端口,连接的是mongos.此时config服务器中有默认的admin数据库。

    使用use admin切换成admin数据库

    > config = connect("127.0.0.1:27022")

    > config = config.getSisterDB("config")

    使用db.runCommand({addshard: "127.0.0.1:27020", allowLocal:1, maxSize:100}) 添加shard1

    使用db.runCommand({addshard: "127.0.0.1:27021", allowLocal:1, maxSize:100}) 添加shard2

    6、创建一个可以被sharding的数据库test

    >test=db.getSisterDB("test")

    >db.runCommand({enablesharding:"test"})

    一旦设置了某数据库可以被sharding,那么此数据库中的不同数据集就会放在不同的分片上。

    7、数据集分块:db.runCommand( { shardcollection : "test.fs.chunks", key:{files_id:1}}) ,此数据集的主shards被设置为了shard1

    8、查看分块状态:db.printShardingStatus()

     

    经过以上步骤,就架设成功了一个MongoDB集群,每个Shards的容量由“maxSize100”限定为了100M大小,并且test.fs.chunks这个collection里的内容会被自动分片存放。

    实例分析

    在上面的程序架设好了之后,使用MongoDB工具集中的Mongofiles.exe程序连续地put一个20M的文件。

    使用db.fs.chunks.stats()命令查看chunks的分块状态得知mongos优先将文件块放在了shard1上,当shard1的大小超过一定规模后(这个规模又不是maxSize设定的100M)才会将文件块迁移向Shard2

    chunks这个collectionShard2上面占用的空间大于100M之后(实际上是108906496字节)mongos不断提示“[Balancer] no availalable shards to take chunks”,然后我又新建了shard3同样设置为“maxsize100”并且添加到集群中,这时mongos自动将一些块迁移到shard3中。等到停止迁移后我新增块,新增的块还是先写入shard1并且不断地有chunks迁移到shard3,但是最终shard1的数据大小远大于100M

    另外,db.fs.chunksshard2的分布情况如下:

         "shard0001" : {

                           "ns" : "test.fs.chunks",

                           "count" : 340,

                           "size" : 88506100,

                           "avgObjSize" : 260312.0588235294,

                           "storageSize" : 108906496,

                           "numExtents" : 11,

                           "nindexes" : 3,

                           "lastExtentSize" : 21645312,

                           "paddingFactor" : 1,

                           "flags" : 1,

                           "totalIndexSize" : 90112,

                           "indexSizes" : {

                                   "_id_" : 32768,

                                   "files_id_1" : 24576,

                                   "files_id_1_n_1" : 32768

                           },

                           "ok" : 1

                   }

    由状态信息可知,实际储存的文件大小是88.5M,但是占用的储存空间确是108.9M,可能chunks多余的未用部分用来做了对齐操作。

     

    MongoDBC++ API使用

    想要自己编写MongoDB的客户端应用,可以先编译出MongDB的客户端静态库“mongoclient.lib”并且包含在自己的工程中。接着可以使用MongoDB源码中的一些头文件,“client/dbclient.h”,“client/gridfs.h”等。

    对于文件分布式存储来说,使用gridfs.h中的GridFSGridFileGridFSChunk等类就可以完成简单的本地文件上传、文件下载、文件块读取、内存数据上传,想完成其它更为复杂的操作把文件块当做普通的BSON对象来操作,需要自己实现代码。

    例:存储本地文件

    DBClientConnection c;

    c.connect("localhost");

    GridFS fs (c, "test");

    BSONObj file = fs.storeFile(filename.c_str(), filename.length(), filename);

  • 相关阅读:
    VScode 修改中文字体
    missing KW_END at ')' near '<EOF>'
    SQL inner join, join, left join, right join, full outer join
    SQL字符替换函数translater, replace
    SQL COOKBOOK SQL经典实例代码 笔记第一章代码
    sqlcook sql经典实例 emp dept 创建语句
    dateutil 2.5.0 is the minimum required version python
    安装postgresql后找不到服务 postgresql service
    Postgres psql: 致命错误: 角色 "postgres" 不存在
    【西北师大-2108Java】第十六次作业成绩汇总
  • 原文地址:https://www.cnblogs.com/k1988/p/2165626.html
Copyright © 2011-2022 走看看