1.Mongodb介绍

1.1  NoSQL

1.1.1起源

随着互联网的发展,当我们把一台服务器一台服务器变成两台服务器,当我们开始建立数据备份,当我们需要加一个缓冲层,来调整所有的查询,投入更多的硬件。 
最后,需要将数据切分多个集群上,并重构大量的应用逻辑以适应这种切分。不久之后,你就会发现被自己数月前的设计数据结构限制住了。 
随着web2.0的兴起,关系型数据库本身无法克服的缺陷越来越明显。 
主要表现为如下几点。

  1. 对数据高并发读写的需求

  2. 对海量数据的高效率存储和访问的需求。

  3. 对数据库的高可扩展性和高可用性的需求。

  4. 数据库事务一致性需求。

  5. 数据库写实性和读写时性需求。

  6. 对复杂SQL的查询,特别是对关联查询的需求。

NoSQL是Not only SQL的缩写,NoSQL不使用SQL作为查询语言。其数据存储可以不需要固定的表格模式,也经常避免使用SQL的join操作,一般有水平可扩展性的特征。

1.1.2 历史

  • NoSQL一词最早出现在1998年,是Carlo Strozzi开发的一个轻量、开源、不提供SQL功能的关系数据库。

  • 2009年,Last.fm的Johan Oskarsson发起了一次关于分布式开源数据库的讨论,来自Rackspace的Eric Evans再次提出了NoSQL概念,这时的NoSQL主要是指非关系型、分布式、不提供数据库设计模式。

  • 2009年趋势高涨,被定为“非关系型的”数据存储,相对于关系型数据库运用,这一概念无疑是一种全新思维的注入。

1.1.3 NoSQL和SQL的区别

NoSQL具有如下几点 
优点

  1. 高并发读写。

  2. 海量数据存储。

  3. 高可扩展性。

  4. 高可用性。

缺点

  1. 缺乏事务一致性。

  2. 缺乏读写实时性。

  3. 不支持复杂查询。

NoSQL数据库类型 
Key-value:key指Value的键值对,通常用hash table来实现 
列式数据库:同一列数据存在一起 
文档型数据库:Key-Value对应的键值对,Value为结构化数据产品:MongoDB 
图结构数据库:以“图”为基本存储模型,产品:Neo4j,InfoGrid,InfiniteGraph

1.2 Mongodb

1.2.1 介绍

mongoDB是一个开源的,基于分布式的,面向文档存储的非关系型数据库。是非关系型数据库当中功能最丰富、最像关系数据库的。 
mongoDB由C++编写,其名字来源于"humongous"这个单词,其宗旨在于处理大量数据。 
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常的松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。 
MongoDB最大的特点是他支持的查询语言是非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。它的特点是高性能、易部署、易使用,存储数据非常方便。 
MongoDB 没有结构化语言。如果你想创建一个新的文档类型,你不用做任何事来告诉数据库关于这些数据的结构,而仅仅是存到数据库中即可。 
简单的说,MongoDB使用类似JavaScript或PHP 的类型处理方式。也就是说,数据库是灵活的弱类型。 
虽然有一些数据是有限制条件的(大块的数据可能需要一些明确的处理),但在大多数情况下,你可以像写PHP代码一样编写你的MongoDB代码。

1.2.2特性

  • 面向集合存储,易存储对象类型的数据。 
    数据被分组到若干集合,每个集合可以包含无限个文档,可以将集合想象成RDBMS的表,区别是集合不需要进行模式定义。

  • 模式自由。 
    集合中没有行和列的概念,每个文档可以有不同的key,key的值不要求一致的数据类型。

  • 支持动态查询。 
    mongoDB支持丰富的查询表达式,查询指令使用json形式表达式。

  • 支持完全索引,包含内部对象。 
    mongoDB的查询优化器会分析查询表达式,并生成一个高效的查询计划。

  • 支持查询。

  • 支持复制和故障恢复。

  • 使用高效的二进制数据存储,包括大型对象(如视频等)。

  • 自动处理碎片,以支持云计算层次的扩展性。 
    支持水平的数据库集群,可动态添加额外的服务器。

  • 支持RUBY,PYTHON,JAVA,C++,PHP等多种语言。

  • 文件存储格式为BSON(一种JSON的扩展)。 
    BSON(Binary Serialized document Format)存储形式是指:存储在集合中的文档,被存储为键-值对的行式。键用于标识一个文档,为字符串类型,而值则可以是各种复杂文件类型。

  • 可通过网络访问

  • mongodb服务端可以运行在linux、Windows或OSX平台,支持32位和64位应用,默认端口27017.推荐运行在64位平台,因为mongodb在32位模式运行时支持的最大文件为2GB。

1.2.3适用场景

  • 作为信息基础设施的持久化缓存层

  • 实时的插入、更新与查询,并具备应用程序实时数据存储所需的复制及高度伸缩性。

  • 文档化格式的存储及查询。

  • 由数十或数百台服务器组成的数据库

1.2.4不适用场景

  • 要求高度事务性的系统。例如对于银行或会计等需要大量原子性复杂事物的应用程序来说,还是需要关系型数据库的。

  • 传统的商业智能应用。

  • 复杂的表级联查询。

1.2.5与MySQL相比

也是从关系型和非关系型数据库间对比,主要有以下不同:

  1. 非关系型,文档之间没有联系,数据自包含,MySql有外键,连接查询等。

  2. 不支持事务,但不代表不能用于管理重要数据(MySQL的MYISAM存储引擎也不支持事务)。

  3. 无模式,集合中的文档结构不固定,可以存储各式各样的文档,文档可以嵌套,存储数组等。

  4. 没有表,行的概念,与之对应的是集合和文档。

2.Mongodb安装实践

官方网站:Mongodb官方安装文档

  • 测试环境

[root@lnmp-env ~]# cat /etc/redhat-release
CentOS release 6.7 (Final)
[root@lnmp-env ~]# uname -r
2.6.32-573.el6.x86_64
[root@lnmp-env ~]# hostname
lnmp-env
  • 添加官方yum源

vim  /etc/yum.repos.d/mongodb-org-3.2.repo
[mongodb-org-3.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.2.asc
  • 安装Mongodb

yum install -y mongodb-org

默认是安装最新稳定版本的mogodb 
安装后会有个四个依赖

mongodb-org-server      #包含的mongod守护进程和相关的配置和初始化脚本。
mongodb-org-mongos      #包含mongos进程。
mongodb-org-shell       #Contains the mongo shell。
mongodb-org-tools       #包含mogo工具包,有 mongoimport bsondump, mongodump, mongoexport, mongofiles, mongooplog, mongoperf, mongorestore, mongostat, 和mongotop。

默认配置文件放在/etc/mongodb.conf

如果报没有key认证,就执行如下命令(上边已经添加了)

rpm --import https://www.mongodb.org/static/pgp/server-3.2.asc
  • 也可以指定版本的安装mogodb

yum install -y mongodb-org-3.2.0 mongodb-org-server-3.2.0 mongodb-org-shell-3.2.0 mongodb-org-mongos-3.2.0 mongodb-org-tools-3.2.0

添加以下参数可以让yum不升级mogodb(可选) 
文件名/etc/yum.conf

exclude=mongodb-org,mongodb-org-server,mongodb-org-shell,mongodb-org-mongos,mongodb-org-tools
  • 开启mongodb

/etc/init.d/mongod start
  • 测试 
    由于是yum直接安装,mongo这个命令在环境变量中。

[root@lnmp-env ~]# mongo
MongoDB shell version: 3.2.9connecting to: test  #出现这个提示表示成功。
Server has startup warnings:
2016-09-01T09:16:19.006+0800 I CONTROL  [initandlisten]
2016-09-01T09:16:19.006+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2016-09-01T09:16:19.007+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2016-09-01T09:16:19.007+0800 I CONTROL  [initandlisten]
2016-09-01T09:16:19.007+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2016-09-01T09:16:19.007+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2016-09-01T09:16:19.007+0800 I CONTROL  [initandlisten]
2016-09-01T09:16:19.007+0800 I CONTROL  [initandlisten] ** WARNING: soft rlimits too low. rlimits set to 1024 processes, 64000 files. Number of processes should be at least 32000 : 0.5 times number of files.
2016-09-01T09:16:19.007+0800 I CONTROL  [initandlisten]
> db.foo.save({a:1})             #插入
WriteResult({ "nInserted" : 1 })
> db.foo.find()                #查询
{ "_id" : ObjectId("57c783115e60033f57550610"), "a" : 1 }
  • 关闭方法

[root@mongon-master mongo-logs]# /etc/init.d/mongod stop
Stopping mongod (via systemctl):                           [  OK  ]
  • 关闭Mongodb的方法(设置配置文件后)

[root@mongon-master mongo-logs]# ps -ef|grep mongo
root       4044      1  1 10:54 ?        00:01:45 /usr/bin/mongod --port 20000 --bind_ip 192.168.56.4 --logpath=/data/mongo-logs/mongod.log --logappend --fork --dbpath=/data/mongo-data/ --journal --autoresync --oplogSize 10 --master
root       5753   3658  0 13:04 pts/1    00:00:00 grep mongo
[root@mongon-master mongo-logs]# mongod --shutdown --dbpath /data/mongo-data/
killing process with pid: 4044
[root@mongon-master mongo-logs]# ps -ef|grep mongo
root       5760   3658  0 13:05 pts/1    00:00:00 grep mongo

3.配置文件介绍

[root@lnmp-env ~]# cat /etc/mongod.conf
#整个文件的编写是以YAML格式进行编写。
#日志文件设置
systemLog:
  destination: file
  logAppend: true #以追加方式写入日志。
  path: /var/log/mongodb/mongod.log  #日志路径。
# 数据存放设置
storage:
  dbPath: /data/mongodb-data/  #数据路径。
  journal:    # journal文件在MongoDB中的作用相当于redo日志文件在oracle中的作用,它可以在即使服务器意外宕机的情况下,将数据库操作进行重演(写日志)。
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:
#mongodb运行过程。
processManagement:                                    
  fork: true  #是否已守护进程方式运行。
  pidFilePath: /var/run/mongodb/mongod.pid  #pid文件存放位置。
# IP和端口。
net:
  port: 27017
  bindIp: 127.0.0.1   #可以监听多个端口,用逗号分隔。
#security:            #是否以安全认证方式运行,默认是不认证的非安全方式。
#operationProfiling:  #指定慢查询时间,单位毫秒,如果打开功能,则向system.profile集合写入数据。
#replication:         #复制选项。
#sharding:            #指定分片集的mongodb角色。
## Enterprise-Only Options
#auditLog:            #syslog,以json格式保存身份验证到syslog,windows下不可用,serverity级别为info,facility级别为user。
#snmp:                #运行SNMP为一个子代理

4.Mongodb主从配置

Mongodb的主从配置是使用配置文件进行同步的,本次采用的是启动Mongodb的时候进行同步数据。

  • 启动master,写入数据。

[root@mongon-master ~]# /usr/bin/mongod --port 20000 --bind_ip 192.168.56.4 --logpath=/data/mongo-logs/mongod.log --logappend --fork --dbpath=/data/mongo-data/ --journal --autoresync --oplogSize 10 --master 
about to fork child process, waiting until server is ready for connections.
forked process: 5765
child process started successfully, parent exiting
[root@mongon-master ~]# mongo 192.168.56.4:20000
MongoDB shell version: 3.2.9
connecting to: 192.168.56.4:20000/test
Server has startup warnings: 
2016-10-18T13:07:20.864+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2016-10-18T13:07:20.864+0800 I CONTROL  [initandlisten] 
> db.foo.find()
> db.foo.save({test:1})
WriteResult({ "nInserted" : 1 })
> db.foo.find()
{ "_id" : ObjectId("5805aefe75bcc5ab43eae44a"), "test" : 1 }
  • 启动slave,查看数据是否同步过来

[root@mongodb-slave ~]# mongo 192.168.56.5:20001
MongoDB shell version: 3.2.9
connecting to: 192.168.56.5:20001/test
Server has startup warnings: 
2016-07-05T06:59:57.023+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2016-07-05T06:59:57.023+0800 I CONTROL  [initandlisten] 
> db.foo.find()
{ "_id" : ObjectId("5805b17875bcc5ab43eae44d"), "test" : 1 }
  • 初次启动slave的时候没有进行同步,报如下错误。

> db.foo.find()Error: error: { "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435 }

解决方法,网络参考

>  db.getMongo().setSlaveOk();