MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组
{
name:"sue",
age:23,
status:"A",
groups:["news","sports"]
}
MongoDB (名称来自"humongous") 是一个可扩展的高性能,开源,模式自由,面向文档的数据库。
MongoDB的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS系统(丰富的功能)架起一座桥梁,集两者的优势于一身。
网站数据:适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。 缓存:由于性能很高,也适合作为信息基础设施的缓存层。在系统重启之后,搭建的持久化缓存可以避免下层的数据源过载。 大尺寸、低价值的数据:使用传统的关系数据库存储一些数据时可能会比较贵,在此之前,很多程序员往往会选择传统的文件进行存储。 高伸缩性的场景:非常适合由数十或者数百台服务器组成的数据库。 用于对象及JSON数据的存储:MongoDB的BSON数据格式非常适合文档格式化的存储及查询。
京东,中国著名电商,使用MongoDB存储商品信息,支持比价和关注功能.
赶集网,中国著名分类信息网站,使用MongoDB记录pv浏览计数
奇虎360,著名病毒软件防护和移动应用平台,使用MongoBD支撑的HULK平台每天接受200亿次的查询.
百度云,使用MongoDB管理百度云盘中500亿条关于文件源信息的记录.
CERN,著名的粒子物理研究所,欧洲核子研究中心大型强子对撞机的数据使用MongoDB
纽约时报,领先的在线新闻门户网站之一,使用MongoDB
sourceforge.net,资源网站查找,创建和发布开源软件免费,使用MongoDB的后端存储
高度事物性的系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。 传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。 需要SQL的问题
主要组件架构图如下:
MongoDB 的美妙之处在于为你提供了这些能力:
对于小型应用程序,单台服务器就足以满足频繁的数据备份需求了。如果需要容错,可以使用副本集。在容错配置中,通常有 3 个或更多的 MongoDB 实例。这些实例当中只有一个作为主实例,如果它发生故障,其他两个辅助实例中的一个将成为主实例。这些实例中的数据都是一样的。
数据库访问角色
Read:允许用户读取指定数据库
readWrite:允许用户读写指定数据库
数据库管理角色
dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
dbOwner: 数据库拥有者(最高), 集合了dbAdmin/userAdmin/readWrite角色的权限
集群管理角色
clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
clusterManager: 集群管理角色,允许对分片和副本集集群执行管理操作,如addShard,resync等
clusterMonitor:集群监控角色,允许度分片和副本集集群监控,如查看serverStatus
hostManager:节点管理角色,允许监控和管理节点,比如killOp,shutdown等
备份恢复
backup: 备份权限,允许执行mongodump操作
restore:恢复权限,允许执行mongorestore操作
通用角色
readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
特殊角色
root:只在admin数据库中可用。超级账号,超级权限
——system:内部角色,用于集群节点通讯
使用createRole命令可以创建自定义角色,每一个角色都需要被绑定到指定的库中。普通的业务库中的角色对象只允许访问当前库的资源对象,而位于admin库的角色则没有此限制。我们定义了一个特殊的角色,用来对分散在多个业务库中的数据进行ETL处理,代码如下
# 创建角色权限
use admin
db.createRole(
{
role: "etlRole",
privileges: [
{
resource: {
db: "tracedb", collection: "etlLogs"
},
actions: [
"find",
"update",
"insert",
"remote"
]
}
],
roles: [
{ role: "read", db: "orderdb"},
{ role: "read", db: "goodsdb"},
{ role: "read", db: "userdb"}
]
},
{ w: "majority", wtimeout: 5000}
)
# 授权
use somedb
db.grantRolesToUser("bus",[{role: "readWrite",db: "dimension"}])
# 创建管理员角色
db.createUser({
user : 'testadm',
pwd : 'xxxxxx',
roles : [
'clusterAdmin',
'dbAdminAnyDatabase',
'userAdminAnyDatabase',
'readWriteAnyDatabase',
{
role: "readWrite", db: "xxxxx"
}
]
})
# 新增权限
db.grantRolesToUser("admin", [ { role:"dbAdminAnyDatabase", db:"admin"} ])
db.grantRolesToUser("test", [ { role:"readWrite", db:"apiplatform"} ])
# 针对库创建角色
db.createUser({
user : 'testadm',
pwd : 'localhost',
roles : [
{
role: "readWrite",db: "apiplatform"
}
]
})
# 删除用户
use api-platform
db.system.users.remove({user: "admin"})
# 创建数据库
use db_name
# 创建集合
db.createCollection("mycol", { capped : true, autoIndexId : true, size :
6142800, max : 10000 } )
# 文档插入
db.mycol.insert({title: 'MongoDB 教程',
description: 'MongoDB 是一个 Nosql 数据库',
by: '官网',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
# 查询所有数据
db.mycol.find()
# 文档查询
db.mycol.find().pretty()
{
"_id" : ObjectId("56063f17ade2f21f36b03133"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "菜鸟教程",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
# 条件查询
db.mycol.find({"title":"MongoDB 教程"}).pretty()
{
"_id" : ObjectId("56063f17ade2f21f36b03133"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "菜鸟教程",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
# 条件查询(or)
db.mycol.find({$or:[{"by":"官网"},{"title": "MongoDB 教程"}]}).pretty()
{
"_id" : ObjectId("56063f17ade2f21f36b03133"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "菜鸟教程",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
# 更新一条
db.mycol.find({$or:[{"by":"官网"},{"title": "MongoDB 教程"}]}).pretty()
{
"_id" : ObjectId("56063f17ade2f21f36b03133"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "菜鸟教程",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
# 更新第一条
db.mycol.update({},{})
# 全部更新
db.mycol.update({},{}, false, true)
# 添加一条
db.mycol.update({},{}, true, false)
# 删除数据
db.mycol.delete()
# 批量删除
db.mycol.deleteMany({})
详情见官网
# 下载二进制文件
yum install libcurl openssl
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.4.tgz
# 下载地址
https://repo.mongodb.org/yum/redhat/7/mongodb-org/4.0/x86_64/RPMS/mongodb-org-server-4.0.4-1.el7.x86_64.rpm
https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.4.tgz
mkdir -pv /usr/local/mongodb
tar zxvf mongodb-linux-x86_64-4.0.4.tgz -C /usr/local/src
mv /usr/local/src/mongodb-linux-x86_64-4.0.4 /usr/local/mongodb
echo 'export PATH=/usr/local/mongodb/bin:$PATH' >> /etc/profile
source /etc/profile
# 创建mongodb数据库目录
mkdir -pv /data/mongo/db
mkdir -pv /data/mongo/mongodb.cnf
mkdir -pv /data/mongo/mongo.log
# 创建启动配置文件
cat > /data/mongo/mongodb.cnf <<- 'EOF'
dbpath=/data/mongo/db
logpath=/data/mongo/mongod.log
pidfilepath=/data/mongo/mongod.pid
logappend=true
fork=true
port=27017
# 副本集
#replSet=rs0
EOF
# 启动mongo
mongod --auth -f /data/mongo/mongodb.cnf
# 进入mongo管理控制台
mongo
# 配置开机启动
cat > /etc/systemd/system/mongod.service <<- 'EOF'
[Unit]
Description=mongodb
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
ExecStart=/usr/local/mongodb/bin/mongod --config /servers/db/mongo/mongodb.cnf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/usr/local/mongodb/bin/mongod --shutdown --config /servers/db/mongo/mongodb.cnf
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
systemctl enable mongod.servcie
systemctl start mongod
# 下载
## mac版
wget https://downloads.mongodb.com/compass/mongosh-1.0.5-darwin-x64.zip
## linux
wget https://downloads.mongodb.com/compass/mongosh-0.1.0-linux.tgz
# 连接
主节点: mongo mongodb://mongodb0.example.com.local:27017
从节点: mongo mongodb://mongodb1.example.com.local:27017
副本集: mongo "mongodb://mongodb0.example.com.local:27017,mongodb1.example.com.local:27017,mongodb2.xample.com.local:27017/?replicaSet=replA"
wget https://repo.mongodb.org/yum/redhat/7Server/mongodb-org/4.4/x86_64/RPMS/mongodb-database-tools-100.3.1.x86_64.rpm -P /usr/local/src
wget https://repo.mongodb.org/yum/redhat/7Server/mongodb-org/4.4/x86_64/RPMS/mongodb-org-tools-4.4.6-1.el7.x86_64.rpm -P /usr/local/src
yum localinstall -y mongodb-database-tools-100.3.1.x86_64.rpm
yum localinstall -y mongodb-org-tools-4.4.6-1.el7.x86_64.rpm
mongoexport --host xxx --port 3717 --authenticationDatabase admin -u admin -p xxxx --db scrm_dimension --collection xxx --type=json --out scrm_dimension.json
mongoimport --host xxxx --port 3717 --authenticationDatabase admin -u admin -p xxxx --db scrm_dimension --collection xxxx --type=json --out scrm_dimension.json
MongoDB 有三种集群部署模式,分别为主从复制(Master-Slaver
)、副本集(Replica Set
)和分片(Sharding
)模式。
Master-Slaver
是一种主从副本的模式,目前已经不推荐使用。Replica Set
模式取代了 Master-Slaver
模式,是一种互为主从的关系。Replica Set
将数据复制多份保存,不同服务器保存同一份数据,在出现故障时自动切换,实现故障转移,在实际生产中非常实用。Sharding
模式适合处理大量数据,它将数据分开存储,不同服务器保存不同的数据,所有服务器数据的总和即为整个数据集Sharding
模式追求的是高性能,而且是三种集群中最复杂的。在实际生产环境中,通常将 Replica Set
和 Sharding
两种技术结合使用。
Primary
)和一个或多个从节点(Secondary
)。另外,每个从节点要知道主节点的地址,主节点记录在其上的所有操作,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
在主从复制的集群中,当主节点出现故障时,只能人工介入,指定新的主节点,从节点不会自动升级为主节点。同时,在这段时间内,该集群架构只能处于只读状态。
此集群拥有一个主节点和多个从节点,这一点与主从复制模式类似,且主从节点所负责的工作也类似,但是副本集与主从复制的区别在于:当集群中主节点发生故障时,副本集可以自动投票,选举出新的主节点,并引导其余的从节点连接新的主节点,而且这个过程对应用是透明的。
另外,从节点会定时轮询读取 oplog 日志,根据日志内容同步更新自身的数据,保持与主节点一致。
在一些场景中,用户还可以使用副本集来扩展读性能,客户端有能力发送读写操作给不同的服务器,也可以在不同的数据中心获取不同的副本来扩展分布式应用的能力。
在副本集中还有一个额外的仲裁节点(不需要使用专用的硬件设备),负责在主节点发生故障时,参与选举新节点作为主节点。
副本集中的各节点会通过心跳信息来检测各自的健康状况,当主节点出现故障时,多个从节点会触发一次新的选举操作,并选举其中一个作为新的主节点。为了保证选举票数不同,副本集的节点数保持为奇数。
副本集可以解决主节点发生故障导致数据丢失或不可用的问题,但遇到需要存储海量数据的情况时,副本集机制就束手无策了。副本集中的一台机器可能不足以存储数据,或者说集群不足以提供可接受的读写吞吐量。这就需要用到 MongoDB 的分片(Sharding)技术,这也是 MongoDB 的另外一种集群部署模式。
构建一个 MongoDB 的分片集群,需要三个重要的组件,分别是分片服务器(Shard Server
)、配置服务器(Config Server
)和路由服务器(Route Server
)。
Shard Server
每个 Shard Server 都是一个 mongod 数据库实例,用于存储实际的数据块。整个数据库集合分成多个块存储在不同的 Shard Server 中。 在实际生产中,一个 Shard Server 可由几台机器组成一个副本集来承担,防止因主节点单点故障导致整个系统崩溃。
Config Server
这是独立的一个 mongod 进程,保存集群和分片的元数据,在集群启动最开始时建立,保存各个分片包含数据的信息。
Route Server