MongoDB 是一个基于分布式文件 存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
百度百科 官网
关于MongoDB
mongodb的集群搭建方式主要有三种,主从模式,Replica set模式,sharding模式, 三种模式各有优劣,适用于不同的场合,属Replica set应用最为广泛,主从模式现在用的较少,sharding模式最为完备,但配置维护较为复杂。 MongoDB数据文件内部结构
·MongoDB在数据存储上按命名空间来划分,一个collection是一个命名空间,一个索引也是一个命名空间
·同一个命名空间的数据被分成很多个Extent,Extent之间使用双向链表连接
·在每一个Extent中,保存了具体每一行的数据,这些数据也是通过双向链接连接的
·每一行数据存储空间不仅包括数据占用空间,还可能包含一部分附加空间,这使得在数据update变大后可以不移动位置
·索引以BTree结构实现
主从
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于"面向对象"的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
实验环境
MongoDB-主:192.168.1.1
MongoDB-从1:192.168.1.2
MongoDB-从2:192.168.1.3
MongoDB 的副本集不同于以往的主从模式。 在集群Master故障的时候,副本集可以自动投票,选举出新的Master,并引导其余的Slave服务器连接新的Master,而这个过程对于应用是透明的。可以说MongoDB的副本集是自带故障转移功能的主从复制。
实验步骤
1.各数据库基本配置如下
nmcli co modify ens33 ipv4.method manual ipv4.add 192.168.1.1/24 connection.autoconnect yes
nmcli con up ens33
tar -zxf mongodb-linux-x86_64-rhel70-4.4.6.tgz -C /usr/local/
mv /usr/local/mongodb-linux-x86_64-rhel70-4.4.6/ /usr/local/mongodb
mkdir /usr/local/mongodb/data /usr/local/mongodb/logs
[root@localhost ~]
port=27017
bind_ip=192.168.1.1
dbpath=/usr/local/mongodb/data
》》每个数据库会在其中创建一个子目录,用于防止同一个实例多次运行的 mongod.lock 也保存在此目录中。
logpath=/usr/local/mongodb/logs/mongo.log
fork=true
[root@localhost ~]
[root@localhost ~]
about to fork child process, waiting until server is ready for connections.
forked process: 4747
child process started successfully, parent exiting
--quiet
--port arg
--bind_ip arg
--logpath arg
--logappend
--pidfilepath arg
--keyFile arg
--unixSocketPrefix arg
--fork
--auth
--cpu
--dbpath arg
--diaglog arg
--directoryperdb
--journal
--journalOptions arg
--ipv6
--jsonp
--maxConns arg
--noauth
--nohttpinterface
--noprealloc
--noscripting
--notablescan
···
[root@localhost ~]
tcp 0 0 192.168.1.1:27017 0.0.0.0:* LISTEN 4747/mongod
2.开启集群
1.配置主MongoDB
[root@localhost ~]
[root@localhost ~]
port=27017
bind_ip=192.168.1.1
dbpath=/usr/local/mongodb/data
logpath=/usr/local/mongodb/logs/mongo.log
fork=true
replSet=test
2.从1+从2
[root@localhost ~]
[root@localhost ~]
···
replSet=test
3.三台启动MongoDB
mongod -f /usr/local/mongodb/data/mongo.conf
firewall-cmd --zone=public --add-port=27017/tcp --permanent
firewall-cmd --reload
4.登录测试
mongo --host 192.168.1.1
mongo --host 192.168.1.2
mongo --host 192.168.1.3
3.配置集群
[root@localhost ~]
> rs.initiate() //初始化集群
{
"info2" : "no configuration specified. Using a default configuration for the set",
"me" : "192.168.1.1:27017",
"ok" : 1
}
test:SECONDARY> rs.add('192.168.1.2:27017')
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1626246301, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1626246301, 1)
}
test:PRIMARY> rs.add(
Display all 188 possibilities? (y or n)
test:PRIMARY> rs.add('192.168.1.3:27017')
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1626246349, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1626246349, 1)
}
test:PRIMARY> rs.status() 查看集群状态
4.验证
数据是否同步
主机
test:PRIMARY> show dbs 查看数据库
admin 从权限的角度来看这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
local 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合。
config 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
test:PRIMARY> use test 切换并创建库
switched to db test db.集合名.insert({文档内容})
test:PRIMARY> db.qq.insert({id:1,name:'one'}) 创建集合并且插入数据(自己创建的库里面必须有集合 不然库创建不成功)
WriteResult({ "nInserted" : 1 })
test:PRIMARY> show collections 查看集合
qq
从机:
[root@localhost ~]
test:SECONDARY> use test
switched to db test
test:SECONDARY> rs.slaveOk() 或》rs.secondaryOk()
WARNING: slaveOk() is deprecated and may be removed in the next major release. Please use secondaryOk() instead.
test:SECONDARY> show collections
qq
主机模拟故障
test:PRIMARY> exit
bye
[root@localhost ~]
从机:
test:SECONDARY> rs.status()
···
{
"_id" : 1,
"name" : "192.168.1.2:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1062,
"optime" : {
"ts" : Timestamp(1626246881, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2021-07-14T07:14:41Z"),
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1626246650, 1),
"electionDate" : ISODate("2021-07-14T07:10:50Z"),
"configVersion" : 3,
"configTerm" : 2,
"self" : true,
"lastHeartbeatMessage" : ""
},
···
test:PRIMARY>
副本集+分片
Sharding cluster是一种可以水平扩展的模式,在数据量很大时特给力,实际大规模应用一般会采用这种架构去构建。sharding分片很好的解决了"单台服务器"磁盘空间、内存、cpu等硬件资源的限制问题,把数据水平拆分出去,降低单节点的访问压力。每个分片都是一个独立的数据库,所有的分片组合起来构成一个逻辑上的完整的数据库。因此分片机制降低了每个分片的数据操作量及需要存储的数据量,达到多台服务器来应对不断增加的负载和数据的效果。 分片 (sharding)是指将数据库拆分,将其分散在不同的机器上的过程。将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载。
分片的基本思想就是
将集合切成小块,这些块分散到若干片里,每个片只负责总数据的一部分。通过一个名为 mongos 的路由进程进行操作,mongos 知道数据和片的对应关系(通过配置服务器)。 大部分使用场景都是解决磁盘空间的问题,对于写入有可能会变差(+++里面的说明+++),查询则尽量避免跨分片查询。
使用场景
1)机器的磁盘不够用了。使用分片解决磁盘空间的问题。 2)单个mongod已经不能满足写数据的性能要求。通过分片让写压力分散到各个分片上面,使用分片服务器自身的资源。 3)想把大量数据放到内存里提高性能。和上面一样,通过分片使用分片服务器自身的资源。
要构建一个MongoDB Sharding Cluster(分片集群),需要三种角色
1)分片服务器(Shard Server)
mongod 实例,用于存储实际的数据块,实际生产环境中一个 shard server 角色可由几台机器组成一个 replica set 承担,防止主机单点故障 这是一个独立普通的mongod进程,保存数据信息。可以是一个副本集也可以是单独的一台服务器。
2)配置服务器(Config Server)
mongod 实例,存储了整个 Cluster Metadata,其中包括 chunk 信息。 这是一个独立的mongod进程,保存集群和分片的元数据,即各分片包含了哪些数据的信息。最先开始建立,启用日志功能。像启动普通的 mongod 一样启动配置服务器,指定configsvr 选项。不需要太多的空间和资源,配置服务器的 1KB 空间相当于真实数据的 200MB。保存的只是数据的分布表。
3)路由服务器(Route Server)
mongos 实例,前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用起到一个路由的功能,供程序连接。本身不保存数据,在启动时从配置服务器加载集群信息,开启 mongos 进程需要知道配置服务器的地址,指定configdb选项。
片键的意义
一个好的片键对分片至关重要。 片键必须是一个索引,通过 sh.shardCollection 会自动创建索引。一个自增的片键对写入和数据均匀分布就不是很好, 因为自增的片键总会在一个分片上写入,后续达到某个阀值可能会写到别的分片。但是按照片键查询会非常高效,随机片键对数据的均匀分布效果很好。注意尽量避免在多个分片上进行查询。在所有分片上查询mongos 会对结果进行归并排序 1)减少单机请求数,将单机负载,提高总负载 2)减少单机的存储空间,提高总存空间
实验环境
mongdb副本集+分片
one 主 192.168.2.30:27000 分片 存数据
从 192.168.2.30:27001
从 192.168.2.30:27002
two 主 192.168.2.40:27000 分片 存数据
从 192.168.2.40:27001
从 192.168.2.40:27002
config 主 192.168.2.50:27000 保存分片时生成的数据
从 192.168.2.50:27001
从 192.168.2.50:27002
route 192.168.2.60:3000 接收客户端请求
one
[root@localhost mongodb]
[root@localhost mongodb]
[root@localhost mongodb]
[root@localhost mongodb]
port=27000
bind_ip=192.168.2.30
dbpath=/usr/local/mongodb/data1
logpath=/usr/local/mongodb/logs/o1.log
fork=true
replSet=one
shardsvr=true 声明这是一个集群的分片
[root@localhost mongodb]
port=27001
bind_ip=192.168.2.30
dbpath=/usr/local/mongodb/data2
logpath=/usr/local/mongodb/logs/o2.log
fork=true
replSet=one
shardsvr=true
[root@localhost mongodb]
port=27002
bind_ip=192.168.2.30
dbpath=/usr/local/mongodb/data3
logpath=/usr/local/mongodb/logs/o3.log
fork=true
replSet=one
shardsvr=true
[root@localhost mongodb]
[root@localhost mongodb]
[root@localhost mongodb]
[root@localhost mongodb]
> rs.initiate()
one:SECONDARY> rs.add('192.168.2.30:27001')
one:PRIMARY> rs.add('192.168.2.30:27002')
two
[root@localhost mongodb]
[root@localhost mongodb]
[root@localhost mongodb]
[root@localhost mongodb]
port=27000
bind_ip=192.168.2.40
dbpath=/usr/local/mongodb/data1
logpath=/usr/local/mongodb/logs/o1.log
fork=true
replSet=two
shardsvr=true
[root@localhost mongodb]
port=27001
bind_ip=192.168.2.40
dbpath=/usr/local/mongodb/data2
logpath=/usr/local/mongodb/logs/o2.log
fork=true
replSet=two
shardsvr=true
[root@localhost mongodb]
port=27002
bind_ip=192.168.2.40
dbpath=/usr/local/mongodb/data3
logpath=/usr/local/mongodb/logs/o3.log
fork=true
replSet=two
shardsvr=true
[root@localhost mongodb]
[root@localhost mongodb]
[root@localhost mongodb]
[root@localhost mongodb]
> rs.initiate()
one:SECONDARY> rs.add('192.168.2.40:27001')
one:PRIMARY> rs.add('192.168.2.40:27002')
部署集群conf
[root@localhost ~]
[root@localhost mongodb]
[root@localhost mongodb]
[root@localhost mongodb]
port=27000
bind_ip=192.168.2.50
dbpath=/usr/local/mongodb/data1
logpath=/usr/local/mongodb/logs/o1.log
fork=true
replSet=conf
configsvr=true 声明这是一个集群的config服务
[root@localhost mongodb]
port=27001
bind_ip=192.168.2.50
dbpath=/usr/local/mongodb/data2
logpath=/usr/local/mongodb/logs/o2.log
fork=true
replSet=conf
configsvr=true
[root@localhost mongodb]
port=27002
bind_ip=192.168.2.50
dbpath=/usr/local/mongodb/data3
logpath=/usr/local/mongodb/logs/o3.log
fork=true
replSet=conf
configsvr=true
mongod -f /usr/local/mongodb/data1/mongo.conf
mongod -f /usr/local/mongodb/data2/mongo.conf
mongod -f /usr/local/mongodb/data3/mongo.conf
[root@localhost mongodb]
> rs.initiate()
conf:SECONDARY> rs.add('192.168.2.50:27001')
conf:SECONDARY> rs.add('192.168.2.50:27002')
部署路由节点
[root@localhost ~]
[root@localhost ~]
[root@localhost mongodb]
port=30000
bind_ip=192.168.2.60
logpath=/usr/local/mongodb/logs/router.log
fork=true
configdb=conf/192.168.2.50:27000,192.168.2.50:27001,192.168.2.50:27002
[root@localhost mongodb]
[root@localhost mongodb]
mongos> sh.addShard('one/192.168.2.30:27000,192.168.2.30:27001,192.168.2.30:27002')
mongos> sh.addShard('two/192.168.2.40:27000,192.168.2.40:27001,192.168.2.40:27002')
mongos> use config
switched to db config
mongos> db.settings.save({id:"chunksize",value:"1MB"})
WriteResult({ "nInserted" : 1 })
mongos> use test
switched to db test
mongos> db.user.createIndex('id:1')
mongos> sh.shardCollection('test.user',{user:1})
mongos> for (var i=1;i<=10000;i++) db.user.insert({id:1,name:'user+i'})
mongos> show collections
user
mongos> db.user.find()
two集群
two:PRIMARY> show dbs
admin 0.000GB
config 0.001GB
local 0.001GB
test 0.000GB
two:PRIMARY> use test
switched to db test
two:PRIMARY> db.user.find()
备份
mongodb的备份工具需要安装
[root@localhost ~]
[root@localhost ~]
[root@localhost ~]
[root@localhost ~]
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
> use test
switched to db test
> db.users.insert({id:1,name:'one'})
WriteResult({ "nInserted" : 1 })
> show collections
users
[root@localhost ~]
[root@localhost ~]
[root@localhost backup]
test
[root@localhost backup]
> use test
switched to db test
> db.users.drop()
true
[root@localhost backup]
[root@localhost backup]
> show dbs
mongodump -h 192.168.2.30 --port 27017 -o /all
日志切割
[root@worker01 ~]# cat export_mongo1day.sh
server_addr=10.43.157.168
db_name=activity_reports
tb_name=upload$(date +%Y\-%m)
current_timestamp=$(date -d "$(date -d "1 day ago" +%Y%m%d)" +%s)
end=$(date -d "$(date +%Y%m%d)" +%s)
declare -i end_timestamp=$end-1
out_dir=/oneday
out_file=${db_name}_${tb_name}_${current_timestamp}.json
/usr/local/mongodb-linux-x86_64-rhel70-4.0.4/bin/mongoexport --host $s-pretty -q '{"create_time": {$gte: '$current_timestamp', $lt: '$end_time
cd $out_dir; tar zcvf ${out_file}.tgz $out_file && rm -f $out_file
find /oneday -ctime +1 | xargs rm -f
以上只是个人的自我学习整理,希望大家可以多多指点!
|