MongoDB概要
- MongoDB保存的是“JSON Document”,并非一般的PDF,WORD文档
- MongoDB内部使用类似于Json的bson格式
- 内部执行引擎为JS解释器。把文档存储成bson结构,在查询时转换为JS对象,并可以通过熟悉的js语法来操作
- MongoDB被称为最像RDBMS 的NoSQL,支持事务,锁,索引类似于MySQL
http://www.mongodb.com/
http://docs.mongodb.com/
- 主要用途
- 应用数据库,比如:存储银行,保险公司流水信息,类似于Oracle,MySQL海量数据处理,大数据分析
- 网站数据、缓存等大尺寸、低价值的数据
- 在高伸缩性的场景,用于对象及JSON数据的存储
- 对比关系型数据库
- 什么时候使用MongoDB
- 数据量是有亿万级或者需要不断扩容
- 需要2000-3000以上的读写每秒
- 新应用,需求会变,数据模型无法确定
- 需要整合多个外部数据源
- 系统需要99.999%高可用
- 系统需要大量的地理位置查询
- 系统需要提供最小的latency
- 管理的主要数据对象<10
- 满足上面一条,可以考虑MongoDB;当有2个以上的时候:MongoDB是不二的选择!
- 逻辑结构
- MongoDB和关系型数据库最大的不同:
- 传统型数据库:结构化数据,定好了表结构后,每一行的内容必须符合表结构,就是说一列的个数和类型都一样
- MongoDB文档型数据库:表中的每个文档都可以有自己独特的结构,即json对象都可以有自己独特的属性和值
- MongoDB 常见部署架构
- MongoDB 相关工具和应用
MongoDB 部署和访问
- MongoDB二进制部署
#二进制安装
#!/bin/bash
MONGODB_VERSOIN=ubuntu2204-6.0.6
MONGODB_FILE=mongodb-linux-x86_64-${MONGODB_VERSOIN}.tgz
URL=https://fastdl.mongodb.org/linux/$MONGODB_FILE
MONGODB_DIR=/mongodb
INSTALL_DIR=/usr/local
PORT=27017
MY_IP=`hostname -I|awk '{print $1}'`
. /etc/os-release
color () {
RES_COL=60
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;33m"
SETCOLOR_NORMAL="echo -en \E[0m"
echo -n "$1" && $MOVE_TO_COL
echo -n "["
if [ $2 = "success" -o $2 = "0" ] ;then
${SETCOLOR_SUCCESS}
echo -n $" OK "
elif [ $2 = "failure" -o $2 = "1" ] ;then
${SETCOLOR_FAILURE}
echo -n $"FAILED"
else
${SETCOLOR_WARNING}
echo -n $"WARNING"
fi
${SETCOLOR_NORMAL}
echo -n "]"
echo
}
system_prepare () {
[ -e $MONGODB_DIR -o -e $INSTALL_DIR/mongodb ] && { color "MongoDB 数据库已安装!" 1;exit; }
if [ $ID = "centos" -o $ID = "rocky" ];then
rpm -q curl &> /dev/null || yum install -y -q curl
elif [ $ID = "ubuntu" ];then
dpkg -l curl &> /dev/null || apt -y install curl
else
color '不支持当前操作系统!' 1
exit
fi
if [ -e /etc/rc.local ];then
echo "echo never > /sys/kernel/mm/transparent hugepage/enabled" >> /etc/rc.local
else
cat > /etc/rc.local <<EOF
#!/bin/bash
echo never > /sys/kernel/mm/transparent hugepage/enabled
EOF
fi
chmod +x /etc/rc.local
}
mongodb_file_prepare () {
if [ ! -e $MONGODB_FILE ];then
curl -O $URL || { color "MongoDB 数据库文件下载失败" 1; exit; }
fi
}
install_mongodb () {
id mongod &> /dev/null || useradd -m -s /bin/bash mongod
tar xf $MONGODB_FILE -C $INSTALL_DIR
ln -s $INSTALL_DIR/mongodb-linux-x86_64-${MONGODB_VERSOIN} $INSTALL_DIR/mongodb
#mongod --dbpath $db_dir --bind_ip_all --port $PORT --logpath $db_dir/mongod.log --fork
}
config_mongodb(){
echo PATH=$INSTALL_DIR/mongodb/bin/:'$PATH' > /etc/profile.d/mongodb.sh
. /etc/profile.d/mongodb.sh
mkdir -p $MONGODB_DIR/{conf,data,log}
cat > $MONGODB_DIR/conf/mongo.conf <<EOF
systemLog:
destination: file
path: "$MONGODB_DIR/log/mongodb.log"
logAppend: true
storage:
dbPath: "$MONGODB_DIR/data/"
journal:
enabled: true
processManagement:
fork: true
net:
port: 27017
bindIp: 0.0.0.0
EOF
chown -R mongod.mongod $MONGODB_DIR/
cat > /lib/systemd/system/mongod.service <<EOF
[Unit]
Descriptinotallow=mongodb
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
User=mongod
Group=mongod
ExecStart=$INSTALL_DIR/mongodb/bin/mongod --config $MONGODB_DIR/conf/mongo.conf
ExecReload=/bin/kill -s HUP \$MAINPID
ExecStop=$INSTALL_DIR/bin/mongod --config $MONGODB/conf/mongo.conf --shutdown
PrivateTmp=true
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for mongod as specified in
# https://docs.mongodb.com/manual/reference/ulimit/#recommended-ulimit-settings
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now mongod &>/dev/null
}
start_mongodb() {
systemctl is-active mongod.service &>/dev/null
if [ $? -eq 0 ];then
echo
color "MongoDB 安装完成!" 0
else
color "MongoDB 安装失败!" 1
exit
fi
}
system_prepare
mongodb_file_prepare
install_mongodb
config_mongodb
start_mongodb
----------------------------------------------------
#安装
[root@ubuntu2204 ~]#bash install_mongodb.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 68.9M 100 68.9M 0 0 4457k 0 0:00:15 0:00:15 --:--:-- 5896k
MongoDB 安装完成! [ OK ]
[root@ubuntu2204 ~]#systemctl status mongod.service
● mongod.service - mongodb
Loaded: loaded (/lib/systemd/system/mongod.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2023-06-05 08:31:23 UTC; 5min ago
Process: 880 ExecStart=/usr/local/mongodb/bin/mongod --config /mongodb/conf/mongo.conf (code=exited, status=0/SUCCESS)
Main PID: 882 (mongod)
Memory: 64.3M
CPU: 2.873s
CGroup: /system.slice/mongod.service
└─882 /usr/local/mongodb/bin/mongod --config /mongodb/conf/mongo.conf
Jun 05 08:31:21 ubuntu2204 systemd[1]: Starting mongodb...
Jun 05 08:31:21 ubuntu2204 mongod[880]: about to fork child process, waiting until server is ready for connections.
Jun 05 08:31:22 ubuntu2204 mongod[882]: forked process: 882
Jun 05 08:31:23 ubuntu2204 mongod[880]: child process started successfully, parent exiting
Jun 05 08:31:23 ubuntu2204 systemd[1]: Started mongodb.
[root@ubuntu2204 ~]#ss -nltp |grep mongod
LISTEN 0 4096 0.0.0.0:27017 0.0.0.0:* users:(("mongod",pid=882,fd=15))
[root@ubuntu2204 ~]#ps aux|grep mongod
mongod 882 0.6 5.0 2603212 101880 ? Sl 08:31 0:05 /usr/local/mongodb/bin/mongod --config /mongodb/conf/mongo.conf
root 945 0.0 0.1 4020 2176 pts/0 S+ 08:45 0:00 grep --color=auto mongod
- 客户端连接
#旧版的客户端工具使用mongo,新版已被mongosh代替
[root@ubuntu2204 ~]#ls /usr/local/mongodb/bin/
install_compass mongod mongos
#安装mongosh
#导入公钥
[root@ubuntu2204 ~]#wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | sudo apt-key add -
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
OK
#配置仓库文件
[root@ubuntu2204 ~]#echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list
deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 multiverse
#更新索引
[root@ubuntu2204 ~]#apt-get update
#安装最新版本
[root@ubuntu2204 ~]#apt-get install -y mongodb-mongosh
#连接使用
[root@ubuntu2204 ~]#mongosh
Current Mongosh Log ID: 647da373c89e612c843232d6
Connecting to: mongodb://127.0.0.1:27017/?directCnotallow=true&serverSelectinotallow=2000&appName=mongosh+1.9.1
Using MongoDB: 6.0.6
Using Mongosh: 1.9.1
For mongosh info see: https://docs.mongodb.com/mongodb-shell/
To help improve our products, anonymous usage data is collected and sent to MongoDB periodically (https://www.mongodb.com/legal/privacy-policy).
You can opt-out by running the disableTelemetry() command.
------
The server generated these startup warnings when booting
2023-06-05T08:31:21.860+00:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
2023-06-05T08:31:23.249+00:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
2023-06-05T08:31:23.249+00:00: vm.max_map_count is too low
------
test> help
Shell Help:
use Set current database
show 'show databases'/'show dbs': Print a list of all available databases.
'show collections'/'show tables': Print a list of all collections for current database.
'show profile': Prints system.profile information.
'show users': Print a list of all users for current database.
'show roles': Print a list of all roles for current database.
'show log <type>': log for current connection, if type is not set uses 'global'
'show logs': Print all logs.
exit Quit the MongoDB shell with exit/exit()/.exit
quit Quit the MongoDB shell with quit/quit()
Mongo Create a new connection and return the Mongo object. Usage: new Mongo(URI, options [optional])
connect Create a new connection and return the Database object. Usage: connect(URI, username [optional], password [optional])
it result of the last line evaluated; use to further iterate
version Shell version
load Loads and runs a JavaScript file into the current shell environment
enableTelemetry Enables collection of anonymous usage data to improve the mongosh CLI
disableTelemetry Disables collection of anonymous usage data to improve the mongosh CLI
passwordPrompt Prompts the user for a password
sleep Sleep for the specified number of milliseconds
print Prints the contents of an object to the output
printjson Alias for print()
convertShardKeyToHashed Returns the hashed value for the input using the same hashing function as a hashed index.
cls Clears the screen like console.clear()
isInteractive Returns whether the shell will enter or has entered interactive mode
For more information on usage: https://docs.mongodb.com/manual/reference/method
MongoDB增删改查
- 使用python添加测试数据
#使用python添加测试数据
[root@ubuntu2204 ~]#apt -y install python3
[root@ubuntu2204 ~]#apt -y install python3-pip
[root@ubuntu2204 ~]#pip3 install pymongo
Collecting pymongo
Downloading pymongo-4.3.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (492 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 492.9/492.9 KB 18.0 kB/s eta 0:00:00
Collecting dnspython<3.0.0,>=1.16.0
Downloading dnspython-2.3.0-py3-none-any.whl (283 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 283.7/283.7 KB 13.0 kB/s eta 0:00:00
Installing collected packages: dnspython, pymongo
Successfully installed dnspython-2.3.0 pymongo-4.3.3
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
[root@ubuntu2204 ~]#cat test_mongodb.py
#!/usr/bin/python3
from pymongo import MongoClient
# 客户端连接
#client = MongoClient(host='127.0.0.1', port=27017)
client = MongoClient('mongodb://127.0.0.1:27017')
print(client)
# 指定数据库 # Database类
#db = client.test
db = client['test']
print(db)
# 集合Collection类 - 直接使用未创建数据库时存在数据的情况下会自动创建改数据库
users = db.users
print(users)
for i in range(10):
user = {'id':i, 'name':'moore' + str(i), 'age':20}
users.insert_one(user)
for x in users.find():
print(x)
client.close()
[root@ubuntu2204 ~]#chmod +x test_mongodb.py
[root@ubuntu2204 ~]#./test_mongodb.py
MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, cnotallow=True)
Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, cnotallow=True), 'test')
Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, cnotallow=True), 'test'), 'users')
{'_id': ObjectId('647dc6571f9356af3d9c2537'), 'id': 0, 'name': 'moore0', 'age': 20}
{'_id': ObjectId('647dc6571f9356af3d9c2538'), 'id': 1, 'name': 'moore1', 'age': 20}
{'_id': ObjectId('647dc6571f9356af3d9c2539'), 'id': 2, 'name': 'moore2', 'age': 20}
{'_id': ObjectId('647dc6571f9356af3d9c253a'), 'id': 3, 'name': 'moore3', 'age': 20}
{'_id': ObjectId('647dc6571f9356af3d9c253b'), 'id': 4, 'name': 'moore4', 'age': 20}
{'_id': ObjectId('647dc6571f9356af3d9c253c'), 'id': 5, 'name': 'moore5', 'age': 20}
{'_id': ObjectId('647dc6571f9356af3d9c253d'), 'id': 6, 'name': 'moore6', 'age': 20}
{'_id': ObjectId('647dc6571f9356af3d9c253e'), 'id': 7, 'name': 'moore7', 'age': 20}
{'_id': ObjectId('647dc6571f9356af3d9c253f'), 'id': 8, 'name': 'moore8', 'age': 20}
{'_id': ObjectId('647dc6571f9356af3d9c2540'), 'id': 9, 'name': 'moore9', 'age': 20}
- Mongosh访问数据
test> show collections
users
test> db.users.find()
[
{
_id: ObjectId("647dc6571f9356af3d9c2537"),
id: 0,
name: 'moore0',
age: 20
},
{
_id: ObjectId("647dc6571f9356af3d9c2538"),
id: 1,
name: 'moore1',
age: 20
},
{
_id: ObjectId("647dc6571f9356af3d9c2539"),
id: 2,
name: 'moore2',
age: 20
},
{
_id: ObjectId("647dc6571f9356af3d9c253a"),
id: 3,
name: 'moore3',
age: 20
},
{
_id: ObjectId("647dc6571f9356af3d9c253b"),
id: 4,
name: 'moore4',
age: 20
},
{
_id: ObjectId("647dc6571f9356af3d9c253c"),
id: 5,
name: 'moore5',
age: 20
},
{
_id: ObjectId("647dc6571f9356af3d9c253d"),
id: 6,
name: 'moore6',
age: 20
},
{
_id: ObjectId("647dc6571f9356af3d9c253e"),
id: 7,
name: 'moore7',
age: 20
},
{
_id: ObjectId("647dc6571f9356af3d9c253f"),
id: 8,
name: 'moore8',
age: 20
},
{
_id: ObjectId("647dc6571f9356af3d9c2540"),
id: 9,
name: 'moore9',
age: 20
}
]
用户及权限管理
MongoDB数据库默认是没有用户名及密码的,即无权限访问限制。为了方便数据库的管理和安全,应启用认证和创建数据库用户
- 用户验证库
- 创建用户时,use所在的库就是此用户的验证库
- 登录时,必须明确指定验证库才能登录
- 一个数据库可以成为多个用户的验证库,但一个用户只能使用一个验证库
- 对于管理员用户,必须在admin下创建,即管理员用的验证库是admin
- 普通用户的验证库一般是所管理的库
- 如果直接登录到数据库,不进行use,默认的验证库是test
- 从3.6版本开始,配置文件中不添加bindIp参数,默认不允许远程登录,只能本地管理员登录
- 系统内置角色说明
#内置角色说明
read 允许用户读取指定非系统数据库
readWrite 允许用户读写指定非系统数据库
dbAdmin 允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
userAdmin 允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
clusterAdmin 只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
readAnyDatabase 只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase 只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase 只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase 只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
root 只在admin数据库中可用。超级账号,超级权限
更多关于用户权限的说明参照:https://docs.mongodb.com/manual/core/security-built-in-roles/
- 开启用户认证
#注意:启用认证后,仍然可以直接登录,但无权限做数据操作,但可以创建用户
#方法1:命令行方式通过“--auth”参数
mongod --auth --port 27017 --dbpath /data/db
#方法2,修改配置文件中,加入以下配置
cat >> /mongodb/conf/mongo.conf <<EOF
security:
authorization: enabled
EOF
systemctl restart mongod
#自定义配置文件
[root@ubuntu2204 ~]#cat /mongodb/conf/mongo.conf
systemLog:
destination: file
path: "/mongodb/log/mongodb.log"
logAppend: true
storage:
dbPath: "/mongodb/data/"
journal:
enabled: true
processManagement:
fork: true
net:
port: 27017
bindIp: 0.0.0.0
security:
authorization: enabled
- 创建MongoDB的超级管理员
test> use admin
switched to db admin
#创建超级管理员superuser(也可以是任意用户名)管理所有数据库(必须use admin再去创建,因为超级用户是存放在admin库中的
admin> db.createUser ( {user: "superuser",pwd: "123456",roles: [{role: "root", db: "admin"}]})
{ ok: 1 }
#验证用户
admin> db.auth('superuser', '123456')
{ ok: 1 }
#用户密码登录
[root@ubuntu2204 ~]#mongosh -u superuser -p 123456 --host 127.0.0.1
Current Mongosh Log ID: 647ec4ef8784d79e355b4e28
Connecting to: mongodb://<credentials>@127.0.0.1:27017/?directCnotallow=true&serverSelectinotallow=2000&appName=mongosh+1.9.1
Using MongoDB: 6.0.6
Using Mongosh: 1.9.1
For mongosh info see: https://docs.mongodb.com/mongodb-shell/
------
The server generated these startup warnings when booting
2023-06-06T05:25:35.562+00:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
2023-06-06T05:25:37.330+00:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
2023-06-06T05:25:37.330+00:00: vm.max_map_count is too low
------
- 基于超级管理员创建一个普通用户
use test
test> db.createUser(
... {
... user: "myTester",
... pwd: passwordPrompt(), //交互式指定密码
... roles: [ { role: "readWrite", db: "test" },
... { role: "read", db: "test2" } ]
... }
... )
Enter password
123456
******{ ok: 1 }
#查看用户
test> db.getUsers()
{
users: [
{
_id: 'test.myTester',
userId: new UUID("0436b796-38c8-45d9-bb0c-fbb4c9ca00e5"),
user: 'myTester',
db: 'test',
roles: [
{ role: 'readWrite', db: 'test' },
{ role: 'read', db: 'test2' }
],
mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]
}
],
ok: 1
}
#尝试登录
[root@ubuntu2204 ~]#mongosh --port 27017 -u "myTester" --authenticationDatabase "test" -p
Enter password: ******
Current Mongosh Log ID: 647ec707f379d46d90484292
Connecting to: mongodb://<credentials>@127.0.0.1:27017/?directCnotallow=true&serverSelectinotallow=2000&authSource=test&appName=mongosh+1.9.1
Using MongoDB: 6.0.6
Using Mongosh: 1.9.1
For mongosh info see: https://docs.mongodb.com/mongodb-shell/
test>
- 创建/删除应用用户
#创建
use mooreyxia
db.createUser (
{
user: "app01",
pwd: "123456",
roles: [{role: "readWrite", db: "mooreyxia"}]
}
)
db.createUser (
{
user: "app02",
pwd: "123456",
roles: [{role: "readWrite", db: "mooreyxia"}]
}
)
#连接测试
mongo -uapp01 -p123456
mongo -uapp01 -p123456 mooreyxia
mongo -uapp01 -p123456 10.0.0.100/mooreyxia
mongo -uapp02 -p123456 10.0.0.100/mooreyxia
#查询mongodb中的用户信息
mongo -uroot -p123456 10.0.0.100/admin
db.system.users.find().pretty()
#删除
#以管理员root身份登录,use到被删除用户的验证库才能删除用户
use mooreyxia
db.createUser ( {user: "app02" , pwd: "app02", roles:[ { role: "readWrite" , db: "magedu" }]})
mongo -uroot -p123456 10.0.0.100/admin
use mooreyxia
db.dropUser ("app02")
MongoDB 复制集
基本原理
- 复制集 Replica Set
- MongDB 像MySQL一样,支持类似的主从复制架构,但无法实现自动故障转移,所以官方推荐使用复制集
- MongoDB复制集是将数据同步在多个服务器的过程
- 复制集提供了数据的冗余备份,并在多个服务器上存储数据副本,保证数据的安全性
- 复制集还允许从硬件故障和服务中断中恢复数据。当故障时,会自动选举新master节点,实现集群的高可用
- 复制集 Replica Set 功能
- 数据高可用性
- 异地容灾,实现灾难恢复
- 无需停机维护(如备份,重建索引,压缩)
- 分布式读取数据,读操作的负载均衡
- 复制集 Replica Set 架构
MongoDB的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据
MongoDB各个节点常见的搭配方式为:一主一从、一主两从此方式最多
主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致
客户端写入数据到主节点时, 主节点与从节点进行数据交互保障数据的一致性
- 复制集特征:
- N 个奇数节点的集群
- 基于选举机制,任何节点可作为主节点
- 所有写入操作都在主节点上,所以增加节点不会提高系统写性能,可以提升读性能
- 主节点故障时,会自动选举出新节点代替,自动故障转移
- 多个节点数据同步的实现
- 当一个修改操作,无论是插入、更新或删除,到达主节点时,它对数据的操作将被记录下来(经过一些必要的转换)这些记录称为oplog
- 从节点通过在主节点上打开一个tailable游标不断获取新进入主节点的oplog,并在自己的数据上回放,以此保持跟主节点的数据一致
- 复制集模式中主要角色和选举
#主节点[Primary]
接收所有的写请求,然后把修改同步到所有Secondary。一个Replica Set只能有一个Primary节点,当Primary挂掉后,其他Secondary或者Arbiter节点会重新选举出来一个主节点。默认读请求也是发到Primary节点处理的,如果需要转发到Secondary,需要在客户端修改一下连接配置。
#副本节点[Secondary]
与主节点保持同样的数据集。当主节点挂掉的时候,可以参与选举出新主节点
#仲裁者[Arbiter]
不保存数据,不参与选主,只进行选主投票。使用Arbiter可以减轻数据存储的硬件需求,Arbiter跑起来几乎没什么大的硬件资源需求,在生产环境下它和其他数据节点不要部署在同一台机器上。实际生产环境当前不推存使用Arbiter节点类型
#MongoDB 使用Raft选举机制,而MySQL MGR 用的是Paxos,而Raft本质是Paxos的变种
注意,一个自动failover的Replica Set节点数必须为奇数,目的是选主投票的时候要有一个大多数才能进行选主决策。
复制集实现
- 复制集环境规划
- 复制集要求三个以上的 MongoDB节点或者实例,下面案例以多实例,采用多个端口: 28017、28018、28019实现
- 准备配置文件
#在所有环境下安装同一版本的mongodb
mongodb-linux-x86_64-ubuntu2204-6.0.6.tgz
#在配置文件中添加复制集名称
[root@ubuntu2204 ~]#vim /mongodb/conf/mongo.conf
[root@ubuntu2204 ~]#cat /mongodb/conf/mongo.conf
systemLog:
destination: file
path: "/mongodb/log/mongodb.log"
logAppend: true
storage:
dbPath: "/mongodb/data/"
journal:
enabled: true
processManagement:
fork: true
net:
port: 27017
bindIp: 0.0.0.0
replication:
replSetName: myrepl
#复制到其他机器上并重启服务
[root@ubuntu2204 ~]#scp /mongodb/conf/mongo.conf 192.168.11.201:/mongodb/conf/mongo.conf
root@192.168.11.201's password:
mongo.conf 100% 258 181.2KB/s 00:00
[root@ubuntu2204 ~]#scp /mongodb/conf/mongo.conf 192.168.11.202:/mongodb/conf/mongo.conf
root@192.168.11.202's password:
mongo.conf 100% 258 183.5KB/s 00:00
[root@ubuntu2204 ~]#systemctl restart mongod
#初始化复制集1主2从,在任意的机器内都可
[root@ubuntu2204 ~]#mongosh
...
test> config = { _id: 'myrepl', members: [ { _id: 0, host: '192.168.11.200:27017' }, { _id: 1, host: '192.168.11.201:27017' }, { _id: 2, host: '192.168.11.202:27017' }] }
{
_id: 'myrepl',
members: [
{ _id: 0, host: '192.168.11.200:27017' },
{ _id: 1, host: '192.168.11.201:27017' },
{ _id: 2, host: '192.168.11.202:27017' }
]
}
test> rs.initiate(config)
{
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1686226254, i: 1 }),
signature: {
hash: Binary(Buffer.from("0000000000000000000000000000000000000000", "hex"), 0),
keyId: Long("0")
}
},
operationTime: Timestamp({ t: 1686226254, i: 1 })
}
myrepl [direct: secondary] test>
#确认后显示当前节点为主节点
myrepl [direct: primary] test>
#查询节点信息
myrepl [direct: primary] test> rs.isMaster()
{
topologyVersion: {
processId: ObjectId("6481bca095dd01bedce07340"),
counter: Long("6")
},
hosts: [
'192.168.11.200:27017',
'192.168.11.201:27017',
'192.168.11.202:27017'
],
setName: 'myrepl',
setVersion: 1,
ismaster: true,
secondary: false,
primary: '192.168.11.200:27017',
me: '192.168.11.200:27017',
electionId: ObjectId("7fffffff0000000000000001"),
lastWrite: {
opTime: { ts: Timestamp({ t: 1686226546, i: 1 }), t: Long("1") },
lastWriteDate: ISODate("2023-06-08T12:15:46.000Z"),
majorityOpTime: { ts: Timestamp({ t: 1686226546, i: 1 }), t: Long("1") },
majorityWriteDate: ISODate("2023-06-08T12:15:46.000Z")
},
maxBsonObjectSize: 16777216,
maxMessageSizeBytes: 48000000,
maxWriteBatchSize: 100000,
localTime: ISODate("2023-06-08T12:15:53.135Z"),
logicalSessionTimeoutMinutes: 30,
connectionId: 4,
minWireVersion: 0,
maxWireVersion: 17,
readOnly: false,
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1686226546, i: 1 }),
signature: {
hash: Binary(Buffer.from("0000000000000000000000000000000000000000", "hex"), 0),
keyId: Long("0")
}
},
operationTime: Timestamp({ t: 1686226546, i: 1 }),
isWritablePrimary: true
}
#确认主从节点的数据同步
#在主节点添加一万条记录
myrepl [direct: primary] test> for(i=0;i<10000;i++){db.random.insertOne({num: Math.random()* 100000})}
myrepl [direct: primary] test> db.random.countDocuments()
10000
#此时从节点将自动同步主节点数据,从节点只读
#从节点要开启查阅权限
myrepl [direct: secondary] test> rs.secondaryOk()
DeprecationWarning: .setSecondaryOk() is deprecated. Use .setReadPref("primaryPreferred") instead
Setting read preference from "primary" to "primaryPreferred"
myrepl [direct: secondary] test> db.random.countDocuments()
10000