手撕MongoDB之运维篇(一)
第一章:逻辑结构
Mongodb 逻辑结构 MySQL逻辑结构
库database 库
集合(collection) 表
文档(document) 数据行
选择之所以叫选择,肯定是痛苦的!
------->oldguo
第二章:安装部署
1、系统准备
(1)redhat或cnetos6.2以上系统
(2)系统开发包完整
(3)ip地址和hosts文件解析正常
(4)iptables防火墙&SElinux关闭
(5)关闭大页内存机制
########################################################################
root用户下
在vi /etc/rc.local最后添加如下代码
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
其他系统关闭参照官方文档:
https://docs.mongodb.com/manual/tutorial/transparent-huge-pages/
为什么要关闭?
Transparent Huge Pages (THP) is a Linux memory management system
that reduces the overhead of Translation Lookaside Buffer (TLB)
lookups on machines with large amounts of memory by using larger memory pages.
However, database workloads often perform poorly with THP,
because they tend to have sparse rather than contiguous memory access patterns.
You should disable THP on Linux machines to ensure best performance with MongoDB.
############################################################################
修改 vim /etc/security/limits.conf
#* - nofile 65535
2、mongodb安装
(1)创建所需用户和组
useradd mongod
passwd mongod
(2)创建mongodb所需目录结构
mkdir -p /mongodb/conf
mkdir -p /mongodb/log
mkdir -p /mongodb/data
(3)上传并解压软件到指定位置
上传到:
cd /server/tools/
解压:
tar xf mongodb-linux-x86_64-rhel70-3.2.16.tgz
拷贝目录下bin程序到/mongodb/bin
cp -a /server/tools/mongodb-linux-x86_64-rhel70-3.2.16/bin/* /mongodb/bin
(4)设置目录结构权限
chown -R mongod:mongod /mongodb
(5)设置用户环境变量
su - mongod
vi .bash_profile
export PATH=/mongodb/bin:$PATH
source .bash_profile
(6)启动mongodb
su - mongod
mongod --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log --port=27017 --logappend --fork
(7)登录mongodb
[[email protected] ~]$ mongo
注:连接之后会有warning,需要修改(使用root用户)
vim /etc/security/limits.conf
#* - nofile 65535
reboot重启生效
(8)使用配置文件
vim /mongodb/conf/mongodb.conf
logpath=/mongodb/log/mongodb.log
dbpath=/mongodb/data
port=27017
logappend=true
fork=true
+++++++++++++++++++
关闭mongodb
mongod -f /mongodb/conf/mongodb.conf --shutdown
使用配置文件启动mongodb
mongod -f /mongodb/conf/mongodb.conf
(YAML模式:)
NOTE:
YAML does not support tab characters for indentation: use spaces instead.
–系统日志有关
systemLog:
destination: file
path: “/mongodb/log/mongodb.log” --日志位置
logAppend: true --日志以追加模式记录
–数据存储有关
storage:
journal:
enabled: true
dbPath: “/mongodb/data” --数据路径的位置
– 进程控制
processManagement:
fork: true --后台守护进程
pidFilePath: --pid文件的位置,一般不用配置,可以去掉这行,自动生成到data中
–网络配置有关
net:
bindIp: – 监听地址,如果不配置这行是监听在0.0.0.0
port: – 端口号,默认不配置端口号,是27017
– 安全验证有关配置
security:
authorization: enabled --是否打开用户名密码验证
------------------以下是复制集与分片集群有关----------------------
replication:
oplogSizeMB:
replSetName: “”
secondaryIndexPrefetch: “all”
sharding:
clusterRole:
archiveMovedChunks:
—for mongos only
replication:
localPingThresholdMs:
sharding:
configDB:
…
++++++++++++++++++++++
YAML例子
cat > /mongodb/conf/mongo.conf <<EOF
systemLog:
destination: file
path: “/mongodb/log/mongodb.log”
logAppend: true
storage:
journal:
enabled: true
dbPath: “/mongodb/data/”
processManagement:
fork: true
net:
port: 27017
bindIp: 10.0.0.51,127.0.0.1
EOF
mongod -f /mongodb/conf/mongo.conf --shutdown
mongod -f /mongodb/conf/mongo.conf
++++++++++++++++++++++
(9)mongodb的关闭方式
mongod -f mongodb.conf --shutdown
(10) systemd 管理(root)
[[email protected] ~]# cat > /etc/systemd/system/mongod.service <<EOF
[Unit]
Description=mongodb
After=network.target remote-fs.target nss-lookup.target
[Service]
User=mongod
Type=forking
ExecStart=/mongodb/bin/mongod --config /mongodb/conf/mongo.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/mongodb/bin/mongod --config /mongodb/conf/mongo.conf --shutdown
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
[[email protected] ~]# systemctl restart mongod
[[email protected] ~]# systemctl stop mongod
[[email protected] ~]# systemctl start mongod
3、mongodb常用基本操作
3.0 mongodb 默认存在的库
show databases;
admin 0.000GB
config 0.000GB
local 0.000GB
3.1 命令种类
数据库对象(库(database),表(collection),行(document))
db.命令:
DB级别命令
db 当前在的库
db.[TAB] 类似于linux中的tab功能
db.help() db级别的命令使用帮助
collection级别操作:
db.Collection_name.xxx
document级别操作:
db.t1.insert()
复制集有关(replication set):
rs.
分片集群(sharding cluster)
sh.
3.2、帮助
help
KEYWORDS.help()
KEYWORDS.[TAB]
show
use
db.help()
db.a.help()
rs.help()
sh.help()
3.3 、常用操作
–查看当前db版本
test> db.version()
–显示当前数据库
test> db
test
或
db.getName()
test
–查询所有数据库
test> show dbs
– 切换数据库
use local
switched to db local
- 查看所有的collection
show tables;
– 显示当前数据库状态
test> use local
switched to db local
local> db.stats()
– 查看当前数据库的连接机器地址
db.getMongo()
connection to 127.0.0.1
指定数据库进行连接
默认连接本机test数据库
4、mongodb对象操作:
mongo mysql
库 -----> 库
集合 -----> 表
文档 -----> 数据行
4.1 库的操作:
– 创建数据库:
当use的时候,系统就会自动创建一个数据库。
如果use之后没有创建任何集合。
系统就会删除这个数据库。
– 删除数据库
如果没有选择任何数据库,会删除默认的test数据库
//删除test数据库
test> show dbs
local 0.000GB
test 0.000GB
test> use test
switched to db test
test> db.dropDatabase()
{ “dropped” : “test”, “ok” : 1 }
集合的操作:
创建集合
方法1
admin> use app
switched to db app
app> db.createCollection(‘a’)
{ “ok” : 1 }
app> db.createCollection(‘b’)
{ “ok” : 1 }
show collections //查看当前数据下的所有集合
a b 或
db.getCollectionNames()
[ “a”, “b” ]
方法2:当插入一个文档的时候,一个集合就会自动创建。
{id : “101” ,name : “zhangsan” ,age : “18” ,gender : “male”}
use oldboy
db.oldguo.insert({id : “1021” ,name : “zhssn” ,age : “22” ,gender : “female”,address : “sz”})
db.oldguo.find({id:“101”})
{ “_id” : ObjectId(“5d36b8b6e62adeeaf0de00dc”), “id” : “101”, “name” : “zhangsan”, “age” : “18”, “gender” : “male” }
查询数据:
db.oldguo.find({id:“101”}).pretty()
{
“_id” : ObjectId(“5d36b8b6e62adeeaf0de00dc”),
“id” : “101”,
“name” : “zhangsan”,
“age” : “18”,
“gender” : “male”
}
db.oldguo.find().pretty()
{
“_id” : ObjectId(“5d36b8b6e62adeeaf0de00dc”),
“id” : “101”,
“name” : “zhangsan”,
“age” : “18”,
“gender” : “male”
}
{
“_id” : ObjectId(“5d36b8eae62adeeaf0de00dd”),
“id” : “1021”,
“name” : “zhssn”,
“age” : “22”,
“gender” : “female”,
“address” : “sz”
}
{
“_id” : ObjectId(“5d36b913e62adeeaf0de00de”),
“name” : “ls”,
“address” : “bj”,
“telnum” : “110”
}
删除集合
app> use app
switched to db app
app> db.log.drop() //删除集合
– 重命名集合
//把log改名为log1
app> db.log.renameCollection(“log1”)
{ “ok” : 1 }
app> show collections
a b c
log1
app
批量插入数据
for(i=0;i<10000;i++){db.log.insert({“uid”:i,“name”:“mongodb”,“age”:6,“date”:new
Date()})}
Mongodb数据查询语句:
– 查询集合中的记录数
app> db.log.find() //查询所有记录
注:默认每页显示20条记录,当显示不下的的情况下,可以用it迭代命令查询下一页数据。
设置每页显示数据的大小:
DBQuery.shellBatchSize=50; //每页显示50条记录
app> db.log.findOne() //查看第1条记录
app> db.log.count() //查询总的记录数
– 删除集合中的记录数
app> db.log.remove({}) //删除集合中所有记录
db.log.distinct(“name”) //查询去掉当前集合中某列的重复数据
– 查看集合存储信息
app> db.log.stats()
app> db.log.dataSize() //集合中数据的原始大小
app> db.log.totalIndexSize() //集合中索引数据的原始大小
app> db.log.totalSize() //集合中索引+数据压缩存储之后的大小 *****
app> db.log.storageSize() //集合中数据压缩存储的大小
5、用户管理 *****
注意:
验证库,建立用户时use到的库,在使用用户时,要加上验证库才能登陆。
对于管理员用户,必须在admin下创建.
- 建用户时,use到的库,就是此用户的验证库
- 登录时,必须明确指定验证库才能登录
- 通常,管理员用的验证库是admin,普通用户的验证库一般是所管理的库设置为验证库
- 如果直接登录到数据库,不进行use,默认的验证库是test,不是我们生产建议的.
use admin
mongo 10.0.0.51/admin
db.createUser
{
user: “”,
pwd: “”,
roles: [
{ role: “”,
db: “” } | “”,
…
]
}
基本语法说明:
user:用户名
pwd:密码
roles:
role:角色名
db:作用对象
role:root, readWrite,read
验证数据库:
mongo -u oldboy -p 123 10.0.0.51/oldboy
用户管理例子:
– 1. 创建超级管理员:管理所有数据库(必须use admin再去创建) *****
$ mongo
use admin
db.createUser(
{
user: “root”,
pwd: “root123”,
roles: [ { role: “root”, db: “admin” } ]
}
)
验证用户
db.auth(‘root’,‘root123’)
配置文件中,加入以下配置
security:
authorization: enabled
重启mongodb
mongod -f /mongodb/conf/mongo.conf --shutdown
mongod -f /mongodb/conf/mongo.conf
登录验证
mongo -uroot -proot123 admin
mongo -uroot -proot123 10.0.0.51/admin
或者
mongo
use admin
db.auth(‘root’,‘root123’)
查看用户:
use admin
db.system.users.find().pretty()
==================
– 2、创建库管理用户
mongo -uroot -proot123 admin
use app
db.createUser(
{
user: “admin”,
pwd: “admin”,
roles: [ { role: “dbAdmin”, db: “app” } ]
}
)
db.auth(‘admin’,‘admin’)
登录测试
mongo -uadmin -padmin 10.0.0.51/app
– 3、创建对app数据库,读、写权限的用户app01 *****
(1)超级管理员用户登陆
mongo -uroot -proot123 admin
(2)选择一个验证库
use app
(3)创建用户
db.createUser(
{
user: “app01”,
pwd: “app01”,
roles: [ { role: “readWrite” , db: “app” } ]
}
)
mongo -uapp01 -papp01 10.0.0.51/app
– 4、创建app数据库读写权限的用户并对test数据库具有读权限:
mongo -uroot -proot123 10.0.0.51/admin
use app
db.createUser(
{
user: “app03”,
pwd: “app03”,
roles: [ { role: “readWrite”, db: “app” },
{ role: “read”, db: “test” }]})
– 5、查询mongodb中的用户信息
mongo -uroot -proot123 10.0.0.51/admin
db.system.users.find().pretty()
{
“_id” : “admin.root”,
“user” : “root”,
“db” : “admin”,
“credentials” : {
“SCRAM-SHA-1” : {
“iterationCount” : 10000,
“salt” : “HsSHIKBQyMnFEzA/PSURYA==”,
“storedKey” : “dbOoQserGa/fB+JQyLqr1yXQZBM=”,
“serverKey” : “h+b/vARfWp6cmDquUN6bJo4whdc=”
}
},
“roles” : [
{
“role” : “root”,
“db” : “admin”
}
]
}
– 6、删除用户(root身份登录,use到验证库)
删除用户
。# mongo -uroot -proot123 10.0.0.51/admin
use app
db.dropUser(“app01”)
查询所有用户信息
- MongoDB复制集RS(ReplicationSet)******
6.1 基本原理
基本构成是1主2从的结构,自带互相监控投票机制(Raft(MongoDB) Paxos(mysql MGR 用的是变种))
如果发生主库宕机,复制集内部会进行投票选举,选择一个新的主库替代原有主库对外提供服务。同时复制集会自动通知
客户端程序,主库已经发生切换了。应用就会连接到新的主库。
6.2 Replication Set配置过程详解
6.2.1 规划
三个以上的mongodb节点(或多实例)
6.2.2 环境准备
多个端口:
28017、28018、28019、28020
多套目录:
su - mongod
mkdir -p /mongodb/28017/conf /mongodb/28017/data /mongodb/28017/log
mkdir -p /mongodb/28018/conf /mongodb/28018/data /mongodb/28018/log
mkdir -p /mongodb/28019/conf /mongodb/28019/data /mongodb/28019/log
mkdir -p /mongodb/28020/conf /mongodb/28020/data /mongodb/28020/log
多套配置文件
/mongodb/28017/conf/mongod.conf
/mongodb/28018/conf/mongod.conf
/mongodb/28019/conf/mongod.conf
/mongodb/28020/conf/mongod.conf
配置文件内容:
cat > /mongodb/28017/conf/mongod.conf <<EOF
systemLog:
destination: file
path: /mongodb/28017/log/mongodb.log
logAppend: true
storage:
journal:
enabled: true
dbPath: /mongodb/28017/data
directoryPerDB: true
#engine: wiredTiger
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
processManagement:
fork: true
net:
bindIp: 10.0.0.51,127.0.0.1
port: 28017
replication:
oplogSizeMB: 2048
replSetName: my_repl
EOF
\cp /mongodb/28017/conf/mongod.conf /mongodb/28018/conf/
\cp /mongodb/28017/conf/mongod.conf /mongodb/28019/conf/
\cp /mongodb/28017/conf/mongod.conf /mongodb/28020/conf/
sed ‘s#28017#28018#g’ /mongodb/28018/conf/mongod.conf -i
sed ‘s#28017#28019#g’ /mongodb/28019/conf/mongod.conf -i
sed ‘s#28017#28020#g’ /mongodb/28020/conf/mongod.conf -i
启动多个实例备用:
mongod -f /mongodb/28017/conf/mongod.conf
mongod -f /mongodb/28018/conf/mongod.conf
mongod -f /mongodb/28019/conf/mongod.conf
mongod -f /mongodb/28020/conf/mongod.conf
netstat -lnp|grep 280
6.3 配置普通复制集:
1主2从,从库普通从库
mongo --port 28017 admin
config = {_id: ‘my_repl’, members: [
{_id: 0, host: ‘10.0.0.51:28017’},
{_id: 1, host: ‘10.0.0.51:28018’},
{_id: 2, host: ‘10.0.0.51:28019’}]
}
rs.initiate(config)
查询复制集状态
rs.status();
6.4 1主1从1个arbiter
mongo -port 28017 admin
config = {_id: ‘my_repl’, members: [
{_id: 0, host: ‘10.0.0.51:28017’},
{_id: 1, host: ‘10.0.0.51:28018’},
{_id: 2, host: ‘10.0.0.51:28019’,“arbiterOnly”:true}]
}
rs.initiate(config)
【注】一个节点不能在两个复制集里同时出现。
6.5 复制集管理操作
6.5.1 查看复制集状态
rs.status(); //查看整体复制集状态
rs.isMaster(); // 查看当前是否是主节点
rs.conf(); //查看复制集配置信息
6.5.2 添加删除节点
rs.remove(“ip:port”); // 删除一个节点
rs.add(“ip:port”); // 新增从节点
rs.addArb(“ip:port”); // 新增仲裁节点
例子:
添加 arbiter节点
1、连接到主节点
[[email protected] ~]$ mongo --port 28018 admin
2、添加仲裁节点
my_repl:PRIMARY> rs.addArb(“10.0.0.53:28020”)
3、查看节点状态
my_repl:PRIMARY> rs.isMaster()
{
“hosts” : [
“10.0.0.53:28017”,
“10.0.0.53:28018”,
“10.0.0.53:28019”
],
“arbiters” : [
“10.0.0.53:28020”
],
rs.remove(“ip:port”); // 删除一个节点
例子:
my_repl:PRIMARY> rs.remove(“10.0.0.53:28019”);
{ “ok” : 1 }
my_repl:PRIMARY> rs.isMaster()
rs.add(“ip:port”); // 新增从节点
例子:
my_repl:PRIMARY> rs.add(“10.0.0.53:28019”)
{ “ok” : 1 }
my_repl:PRIMARY> rs.isMaster()
6.5.3 特殊从节点
介绍:
arbiter节点:主要负责选主过程中的投票,但是不存储任何数据,也不提供任何服务
hidden节点:隐藏节点,不参与选主,也不对外提供服务。
delay节点:延时节点,数据落后于主库一段时间,因为数据是延时的,也不应该提供服务或参与选主,所以通常会配合hidden(隐藏)
一般情况下会将delay+hidden一起配置使用
配置延时节点(一般延时节点也配置成hidden)
下面的索引不是id,而是挨个数的。
cfg=rs.conf()
cfg.members[2].priority=0
cfg.members[2].hidden=true
cfg.members[2].slaveDelay=120
rs.reconfig(cfg)
取消以上配置
cfg=rs.conf()
cfg.members[2].priority=1
cfg.members[2].hidden=false
cfg.members[2].slaveDelay=0
rs.reconfig(cfg)
配置成功后,通过以下命令查询配置后的属性
rs.conf();
6.5.4 副本集其他操作命令
查看副本集的配置信息
admin> rs.conf()
查看副本集各成员的状态
admin> rs.status()
++++++++++++++++++++++++++++++++++++++++++++++++
–副本集角色切换(不要人为随便操作)
admin> rs.stepDown()
注:
admin> rs.freeze(300) //锁定从,使其不会转变成主库
freeze()和stepDown单位都是秒。
+++++++++++++++++++++++++++++++++++++++++++++
设置副本节点可读:在副本节点执行
admin> rs.slaveOk()
eg:
admin> use app
switched to db app
app> db.createCollection(‘a’)
{ “ok” : 0, “errmsg” : “not master”, “code” : 10107 }
查看副本节点(监控主从延时)
admin> rs.printSlaveReplicationInfo()
source: 192.168.1.22:27017
syncedTo: Thu May 26 2016 10:28:56 GMT+0800 (CST)
0 secs (0 hrs) behind the primary
OPlog日志(备份恢复章节)