一个mongod服务可以有建立多个数据库,每个数据库可以有多张表,这里的表名叫collection,每个collection可以存放多个文档(document),每个文档都以BSONbinary json)的形式存放于硬盘中,因此可以存储比较复杂的数据类型。它是以单文档为单位存储的,你可以任意给一个或一批文档新增或删除字段,而不会对其它文档造成影响,这就是所谓的schema-free,这也是文档型数据库最主要的优点。跟一般的key-value数据库不一样的是,它的value中存储了结构信息,所以你又可以像关系型数据库那样对某些域进行读写、统计等操作。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。Mongo还可以解决海量数据的查询效率,根据官方文档,当数据量达到50GB以上数据时,Mongo数据库访问速度是MySQL10 倍以上。

下载http://www.mongodb.org/downloads

tar fvxz mongodb-linux-x86_64-2.4.5.tgz

解压即可,不要编译安装

mv mongodb-linux-x86_64-2.4.5 mongod

cd mongod

启动之前,需要先创建数据库文件存放目录和日志文件存放目录

mkdir data

mkdir log

方式一:

vi mongod.conf

dbpath = /home/yuchunyun/mongodb/data
logpath = /home/yuchunyun/mongodb/log/mongod.log
logappend=true
port = 27017
fork = true

./bin/mongod --help可以查看参数详解

-h [ --help ]               show this usage information
  --version                   show version information查看版本信息
  -f [ --config ] arg         configuration file specifying additional options指定配置文件路径
  -v [ --verbose ]            be more verbose (include multiple times for more verbosity e.g. -vvvvv)冗余
  --quiet                     quieter output静默模式
  --port arg                  specify port number - 27017 by default指定服务监听的端口号,默认是27107,如果该服务想启动多个进程,需要指定不同的端口号
  --bind_ip arg               comma separated list of ip addresses to listen on - all local ips by default指定对外服务的绑定IP
  --maxConns arg              max number of simultaneous connections - 20000 by default支持的最大并发连接数,默认是20000
  --logpath arg               log file to send write to instead of stdout - has to be a file, not directory指定日志文件存放路径(不是文件夹)
  --logappend                 append to logpath instead of over-writing指定日志是以追加的方式纪录,不然就会覆盖
  --pidfilepath arg           full path to pidfile (if not set, no pidfile is created)指定PID文件路径
  --keyFile arg               private key for cluster authentication
  --setParameter arg          Set a configurable parameter
  --nounixsocket              disable listening on unix sockets
  --unixSocketPrefix arg      alternative directory for UNIX domain sockets (defaults to /tmp)
  --fork                      fork server process创建子进程方式启动服务,也就是后台启动
  --syslog                    log to system's syslog facility instead of file or stdout
  --auth                      run with security启动客户端的认证机制
  --cpu                       periodically show cpu and iowait utilization周期显示CPU和IO的使用情况
  --dbpath arg                directory for datafiles - defaults to /data/db/指定数据库存储目录,默认是/data/db。
  --diaglog arg               0=off 1=W 2=R 3=both 7=W+some reads提供的方式是读、写、读写、主要的写+部分的读
  --directoryperdb            each database will be stored in a separate directory
  --ipv6                      enable IPv6 support (disabled by default)
  --journal                   enable journaling启动日志记录(跟mysql的binlog差不多),Mongodb的数据操作将会被记录到dbpath下的journal文件夹下的文件中
  --journalCommitInterval arg how often to group/batch commit (ms)
  --journalOptions arg        journal diagnostic options
  --jsonp                     allow JSONP access via http (has security implications)允许JSONP形式通过HTTP访问(有安全影响)
  --noauth                    run without security不使用认证
  --nohttpinterface           disable http interface不启动http接口
  --nojournal                 disable journaling (journaling is on by default for 64 bit)不启动日志记录
  --noprealloc                disable data file preallocation - will often hurt performance关闭数据库文件大小预分配
  --noscripting               disable scripting engine关闭脚本引擎
  --notablescan               do not allow table scans不运行表扫描
  --nssize arg (=16)          .ns file size (in MB) for new databases新数据库ns文件的大小
  --profile arg               0=off 1=slow, 2=all
  --quota                     limits each database to a certain number of files(8 default)开启数据库配额的管理
  --quotaFiles arg            number of files allowed per db, requires --quota设定每个数据库允许的文件数
  --repair                    run repair on all dbs修复所有的数据库
  --repairpath arg            root directory for repair files - defaults to dbpath
  --rest                      turn on simple rest api
  --shutdown                  kill a running server (for init scripts)
  --slowms arg (=100)         value of slow for profile and console log
  --smallfiles                use a smaller default file size使用较小的默认文件大小
  --syncdelay arg (=60)       seconds between disk syncs (0=never, but not recommended)系统同步刷新磁盘的时间,默认是60秒
  --sysinfo                   print some diagnostic system information打印系统诊断信息
  --upgrade                   upgrade db if needed如果需要就更新数据库
Replication options:
  --oplogSize arg       size to use (in MB) for replication op log. default is 5% of disk space (i.e. large is good)
Master/slave options (old; use replica sets instead):
  --master              master mode主复制模式
  --slave               slave mode从复制模式
  --source arg          when slave: specify master as 当为从时,指定主的地址和端口
  --only arg            when slave: specify a single database to replicate当为从时,指定需要从主复制的单一库
  --slavedelay arg      specify delay (in seconds) to be used when applying master ops to slave
  --autoresync          automatically resync if slave data is stale自动同步
Replica set options:
  --replSet arg           arg is [/]
  --replIndexPrefetch arg specify index prefetching behavior (if secondary) [none|_id_only|all]
Sharding options:
  --configsvr           declare this is a config db of a cluster; default port 27019; default dir /data/configdb声明这是一个集群的config服务
  --shardsvr            declare this is a shard db of a cluster; default port 27018声明这是一个集群的分片

启动

./bin/mongod --config ./mongod.conf
about to fork child process, waiting until server is ready for connections.
all output going to: /home/yuchunyun/mongodb/log/mongod.log
forked process: 7685
ERROR: child process failed, exited with error number 45
sudo ./bin/mongod --config ./mongod.conf

方式二:

sudo ./bin/mongod  --port=37017 --dbpath=/home/yuchunyun/mongodb/data2/ --logpath=/home/yuchunyun/mongodb/log2/mongod2.log --fork --logappend

注:使用--fork就必须使用--logpath

ps -ef | grep mongod

mongod会启动两个端口,27017是配置文件中指定的数据库端口号,另一个端口port+1000是mongod启动的http端口号,浏览器访问http://localhost:28017,可以查看mongod的使用情况!


登陆使用:

./bin/mongo

--help可以查看参数详解
>help
>show dbs;查看已有的数据库
>use ycy;创建数据库
>db;查看现在所在的数据库,和db.getName()效果一样
>db.createCollection('test');在当前数据库中创建集合(表)“test”
>show collections;查看当前数据库中有哪些集合(表)(注:system.indexs是系统自带的索引表)
>db.test.insert({id:1,name:'ycy'});在表test中插入两条数据
>db.test.insert({id:2,name:'zw'});
>db.test.find();查询表test中的数据
>db.test.remove();删除表test中的数据
>db.test.update({id:1},{$set:{name:'yuchunyun'}});更新test表中的数据
>db.test.find({id:1});查询test表中“id”为“1”的数据
>use test;切换到test数据库
>db.table1.drop();删除table1表
>db.dropDatabase();删除当前所在数据库
>exit;退出

关闭:

a. use admin;

  db.shutdownServer();  #推荐优先使用

b. ctrl + c             #在不使用 --fork参数的时候可以使用,可能会造成数据文件损坏
c. kill / kill -2       #在无法使用 a和b的情况下使用,可能会造成数据文件损坏

d. kill -9              #不在万不得已的情况下,不要使用这个方法


权限设置

1、Mongodb没有默认管理账户,需要先添加管理员账户,再开启用户权限认证

2、切换到admin数据库,添加的账户才是管理员账户

3、用户只能在用户所在的数据库登陆,包括管理员账户

4、管理员可以管理所有数据库,但不能直接管理,需要先在admin数据库认证之后才可以

./bin/mongo

MongoDB shell version: 2.4.5
connecting to: test
>use admin;
>db.addUser('ycy01',123456);添加用户‘ycy01’,密码为‘123456’
>show collections;
>db.system.users.find();查看管理员账户信息
>use test;
>db.addUser('ycy02',123456);添加用户‘ycy02’
>db.addUser('ycy03',123456,true);添加用户‘ycy03’,只读权限
>db.system.users.find();查看数据库test的账户信息
>exit

启用auth认证,重启Mongod

./bin/mongo

MongoDB shell version: 2.4.5

connecting to: test

>show dbs;

Thu Apr 17 16:48:45.491 JavaScript execution failed: listDatabases failed:{ "ok" : 0, "errmsg" : "unauthorized" } at src/mongo/shell/mongo.js:L46由于还没有认证,所以失败

>use admin;

>db.auth('ycy01','123456');使用管理员账户'ycy01'认证。(注:密码必须用''表示,即使密码是纯数字,不然不成功!)

1(1表示成功,0表示失败)

>show dbs;再查看数据库,管理其他数据库就畅行无阻

>use test;

>exit


./bin/mongo

MongoDB shell version: 2.4.5

connecting to: test

>db.auth('ycy02','123456');使用test数据库的普通账户'ycy01'

>show collections;能够查看test数据库的表

>db.table1.insert({id:100,name:'zw',age:0});能够像test数据库中table1表插入数据

>db.table1.find();能够查看table1中的数据

>show dbs;

Thu Apr 17 16:58:41.186 JavaScript execution failed: listDatabases failed:{ "ok" : 0, "errmsg" : "unauthorized" } at src/mongo/shell/mongo.js:L46没有权限查看所有数据库

>use test2;进入test2数据库

>show collections;没有权限查看test2数据库中的表

>exit


./bin/mongo

MongoDB shell version: 2.4.5

connecting to: test

>db.auth('ycy03','123456');使用test数据库中的普通账户'ycy03'

>show collections;能够查看test数据库中的表

>db.table1.find();能够查看table1中的数据

>db.table1.insert({id:55,name:'xyz',age:1});没有权限对table1进行写操作


更改密码

使用该数据库具有写权限的用户进行验证,然后

db.addUser({'ycy03','890915'});

删除账户

使用该数据库具有写权限的用户进行验证,然后

db.system.users.remove({user:'ycy03'});即可删除该数据库中'ycy03'这个普通账户

或者db.removeUser("ycy03");




MongoDB主从复制介绍

MongoDB的主从复制其实很简单,就是在运行 主的服务器上开启mongod进程 时,加入参数--master即可,在运行从的服务 器上开启mongod进程时,加入--slave 和 --source 指定主即可,这样在主 库更新时,数据被复制到从数据库
(这里日志文件访问数据时授权用户暂时不考虑 )
下面我在单台服务器上开启2deamon来模拟2台服务器进行主从复制:

主配置文件:cat master27017.conf

dbpath = /home/yuchunyun/mongodb/data/master27017
logpath = /home/yuchunyun/mongodb/log/master27017.log
logappend = true
bind_ip = 127.0.0.1
port = 27017
fork = true
master = ture

从配置文件:cat slave37017.conf

dbpath = /home/yuchunyun/mongodb/data/slave37017
logpath = /home/yuchunyun/mongodb/log/slave37017.log
logappend=true
bind_ip = 127.0.0.1
port = 37017
fork = true
slave = ture
source = 127.0.0.1:27017

分别启动主、从:

./bin/mongod -f conf/master27017.conf

./bin/mongod -f conf/master37017.conf

ps -ef | grep mongod查看主从的端口都已启动

登陆主,插入一条数据,再登陆从,查询就会发现已同步过来

注:停止时先停从、再停主


MongoDB一般情况下都可以支持主主复制,但是在大部分情况下官方不推荐使用

./bin/mongod --dbpath=/home/yuchunyun/mongodb/data/master27017 --logpath=/home/yuchunyun/mongodb/log/master27017.log --port=27017 --master --slave --source localhost:37017 --fork
./bin/mongod --dbpath=/home/yuchunyun/mongodb/data/slave37017 --logpath=/home/yuchunyun/mongodb/log/slave37017.log --port=37017 --master --slave --source localhost:27017 --fork


./bin.mongo --port=27017创建数据库、集合collection、插入数据

./bin.mongo --port=37017创建数据库、集合collection、插入数据

发现都可以做插入、查询的操作,实现了双向同步


Mongodb使用技巧

想知道mongodb支持哪些命令 ,可以直接输入help

> help

如果想知道当前数据库支持哪些方法:

> db.help();
DB methods:
db.addUser(username, password) 添加数据库授权用户
db.auth(username, password)                访问 认证
 db.cloneDatabase(fromhost) 克隆数据库
db.commandHelp(name) returns the help for the command
db.copyDatabase(fromdb, todb, fromhost)  复制数据库
db.createCollection(name, { size : ..., capped : ..., max : ... } ) 创建表
db.currentOp() displays the current operation in the db
db.dropDatabase()        删除当前数据库
db.eval(func, args) run code server-side
db.getCollection(cname) same as db['cname'] or db.cname
db.getCollectionNames()        获取当前数据库的表名
db.getLastError() - just returns the err msg string
db.getLastErrorObj() - return full status object
db.getMongo() get the server connection object
db.getMongo().setSlaveOk() allow this connection to read from the nonmaster member of a replica pair
db.getName()
db.getPrevError()
db.getProfilingLevel()
db.getReplicationInfo()
db.getSisterDB(name) get the db at the same server as this onew
db.killOp() kills the current operation in the db
db.printCollectionStats()   打印各表的状态信息
db.printReplicationInfo()        打印主数据库的复制状态信息
db.printSlaveReplicationInfo()        打印从数据库的复制状态信息
db.printShardingStatus()                打印分片状态信息
db.removeUser(username) 删除数据库用户
db.repairDatabase() 修复数据库
db.resetError()
db.runCommand(cmdObj) run a database command.  if cmdObj is a string, turns it into { cmdObj : 1 }
db.setProfilingLevel(level) 0=off 1=slow 2=all
db.shutdownServer ()
db.version() current version of the server

如果想知道当前数据库下的表或者表 collection支持哪些方法,可以使用一下命令如:

> db.user.help();  user为表名
DBCollection help
db.foo.count()                统计表的行数
db.foo.dataSize()        统计表数据的大小
db.foo.distinct( key ) - eg. db.foo.distinct( 'x' )                按照给定的条件除重
db.foo.drop() drop the collection 删除表
db.foo.dropIndex(name)  删除指定索引
db.foo.dropIndexes() 删除所有索引
db.foo.ensureIndex(keypattern,options) - options should be an object with these possible fields: name, unique, dropDups  增加索引
db.foo.find( [query] , [fields]) - first parameter is an optional query filter. second parameter is optional set of fields to return. 根据条件查找数据
db.foo.find(...).count()
db.foo.find(...).limit(n) 根据条件查找数据并返回指定记录数
db.foo.find(...).skip(n)
db.foo.find(...).sort(...) 查找排序
db.foo.findOne([query]) 根据条件查询只查询一条数据
db.foo.getDB() get DB object associated with collection  返回表所属的库
db.foo.getIndexes() 显示表的所有索引
db.foo.group( { key : ..., initial: ..., reduce : ...[, cond: ...] } ) 根据条件分组
db.foo.mapReduce( mapFunction , reduceFunction ,  )
db.foo.remove(query) 根据条件删除数据
db.foo.renameCollection( newName ) renames the collection  重命名表
db.foo.save(obj) 保存数据
db.foo.stats()  查看表的状态
db.foo.storageSize() - includes free space allocated to this collection 查询分配到表空间大小
db.foo.totalIndexSize() - size in bytes of all the indexes 查询所有索引的大小
db.foo.totalSize() - storage allocated for all data and indexes 查询表的总大小
db.foo.update(query, object[, upsert_bool]) 根据条件更新数据
db.foo.validate() - SLOW 验证表的详细信息
db.foo.getShardVersion() - only for use with sharding


./bin/mongodump --poer 27017 -d test -o tmp/ 给数据库test做备份

./bin/mongo --port=27017

>use test;

>db.ycy.drop();删除集合ycy

>show collections;

./bin/mongorestore -d test -c ycy tmp/test/ycy.bson 把数据库test中的集合ycy恢复


5. 数据库备份
有4种方法备份数据库
a. 关闭mongod服务后,复制--dbpath参数指定的数据文件。 优点速度快,缺点需要停止mongo服务。  
b. 使用mongodump 导出数据,并用mongorestore 导入数据。 优点不需要停止mongo服务,缺点在mongodump操作时用户插入的数据可能无法备份出来。
c. fsync and lock锁定数据库的让用户只能使用read功能,再使用方法b导出并导入数据。 优点不需要停止mongo服务,缺点在数据库lock期间用户无法执行insert操作。

d. 使用slaveDB并且 使用方法c锁定slaveDB,再使用方法b导出并导入数据。 优点不需要停止mongo服务,不会影响用户insert操作(推荐使用此方法)。


6. 修复数据库
当数据库文件遭到损坏的时候有3种方法修复数据文件
a. MONGO_HOME/bin/mongod --repair
b. use test
  db.repairDatabase()
c. db.runCommand({"repairDatabase":1});



监控Mongodb状态

系统自带的mongostat命令就可以查看

[yuchunyun@t19 mongodb]$ ./bin/mongostat
connected to: 127.0.0.1
insert  query update delete getmore command flushes mapped  vsize    res faults  locked db idx miss %     qr|qw   ar|aw  netIn netOut  conn       time
    *0     *0     *0     *0       0     1|0       0    80m   402m    32m      0 local:0.0%          0       0|0     0|0    62b     2k     1   17:20:38
    *0     *0     *0     *0       0     1|0       0    80m   402m    32m      0 local:0.0%          0       0|0     0|0    62b     2k     1   17:20:39
    *0     *0     *0     *0       0     1|0       0    80m   402m    32m      0 local:0.0%          0       0|0     0|0    62b     2k     1   17:20:40
    *0     *0     *0     *0       0     1|0       0    80m   402m    32m      0 local:0.0%          0       0|0     0|0    62b     2k     1   17:20:41
    *0     *0     *0     *0       0     1|0       0    80m   402m    32m      0 local:0.0%          0       0|0     0|0    62b     2k     1   17:20:42
    *0     *0     *0     *0       0     1|0       0    80m   402m    32m      0 local:0.0%          0       0|0     0|0    62b     2k     1   17:20:43
    *0     *0     *0     *0       0     1|0       0    80m   402m    32m      0 local:0.0%          0       0|0     0|0    62b     2k     1   17:20:44
    *0     *0     *0     *0       0     1|0       0    80m   402m    32m      0     .:0.1%          0       0|0     0|0    62b     2k     1   17:20:45
    *0     *0     *0     *0       0     1|0       0    80m   402m    32m      0 local:0.0%          0       0|0     0|0    62b     2k     1   17:20:46
    *0     *0     *0     *0       0     1|0       0    80m   402m    32m      0 local:0.0%          0       0|0     0|0    62b     2k     1   17:20:47

这里的属性都可以通过mongostat --help进行查看,有几个列需要解释一下,可以帮助到我们发生性能问题时比较准备的找到定位。

faults:这是一个重要的性能指标,显示你的机器每秒页面故障的数量,这个是mongoDB映射到虚拟地址空间,而不是物理内存,这个值如果飙高的话,可能意味着你的机器没有足够的内存来存储数据和磁盘的访问。
flushes:每秒做了多少次fsync,表面多少次数据被刷新进了磁盘。
mapped:是指mmap有多少数据量,也就是服务器的内存映射,其中包含了虚拟内存和常驻内存。
locked:这个值表面全局写入锁占用了机器多少时间, 当放生全局写入锁时,所有的查询操作都将等待,直到写入锁的解锁,如果这个锁飙高有可能是你的程序那部分出现问题。
idx miss:B树未命中的比例,这个应该是我们查询的命中的实时指数,一般在特定查询中会有用到。
qr | qw:如果有太多的查询进行处理,它们就以一个队列的方式进行,如果这个值飙高的话,那么查询也会变得很慢,因为后面的队列必须等待前面的队列执行完毕,高并发时,一般队列值会升高。
另外我们还可以在mongodb shell中进行检查,使用

./bin/mongo

>db.serverStatus();这个输出很详细,但是不是实时的



Mongodb的sharding功能

Sharding 分片是一种将海量的数据水平扩展的数据库集群系统,数据分表存储在 sharding 的各个节点上

一个分布式 MongoDB 集群需要三种角色:

Mongodb的使用_第1张图片

Shard Server:即存储实际数据的分片,每个 Shard 可以是一个 mongod 实例,也可以是一组 mongod 实例构成的Replica Set。为了实现每个 Shard 内部的 auto-failover,MongoDB 官方建议每个Shard 为一组 Replica Set

Config Server为了将一个特定的collection 存储在多个 shard ,需要为该 collection 指定一个 shard key, 例如{age: 1} ,shard key 可以决定该条记录属于哪个个 chunkConfig Servers 就是用来存储: 所有 shard 节点的配置信息、每个 chunk shard key 范围、chunk在各 shard 的分布情况、该集群中所有DB collection sharding 配置信息。

Route Process:这是一个前端路由,客户端由此接入,然后询问 Config Servers 需要到哪个 Shard 上查询或保存记录,再连接相应的 Shard 进行操作,最后将结果返回给客户端。客户端只需要将原本发给 mongod 的查询或更新请求原封不动地发给 Routing Process,而不必关心所操作的记录存储在哪个 Shard 上。