什么网站能免费做公众号封面,pc蛋蛋网站怎么做,在阿里国际站做的网站,网站登录密码忘记目录 前言基本概念数据库-database集合-collection文档-document 部署mongodblinux安装mongodbdocker安装mongodb MongoDB Shell (mongosh)命令行工具mongodb可视化-mongodb-compass、mongo-expressmongodb配置文件mongodb库、集合、文档库基本操作集合基本操作文档的增删改查C… 目录 前言基本概念数据库-database集合-collection文档-document 部署mongodblinux安装mongodbdocker安装mongodb MongoDB Shell (mongosh)命令行工具mongodb可视化-mongodb-compass、mongo-expressmongodb配置文件mongodb库、集合、文档库基本操作集合基本操作文档的增删改查CURD插入文档查询文档更新文档删除文档 mongodb的访问控制理解mongodb的用户、库的关系admin库的作用mongodb内置角色登录admin库创建管理员用户修改配置文件启用账号密码认证创建超级管理员创建数据库普通用户删除用户 mongodb的高可用架构Replica Set 副本集模式mongodump工具-备份mongodb分片集群的三大组件分片集群的架构 部署mongodb分片集群k8s搭建mongodb分片集群分片集群-总结 前言
本篇来简单的学习mongodb。后期深入学习还需要多看官网文档https://www.mongodb.com/docs/manual/ mongodb是一个nosql类型的数据库其存储数据简单看就是json类型的数据格式mongodb中也有数据库的概念数据库中有集合集合中有文档一个文档其实就是一个json类型的数据这里的集合和文档其实可以类比于mysql中表和数据行的概念。
基本概念
数据库-database
MongoDB 中多个文档组成集合多个集合组成数据库。一个MongoDB 实例可以承载多个数据库。它们之间可以看作相互独立每个数据库都有独立的权限控制。在磁盘上不同的数据库存放在不同的文件中。MongoDB 中存在以下3个系统数据库。
● Admin 数据库一个权限数据库,如果创建用户的时候将该用户添加到admin数据库中,那么该用户就自动继承了所有数据库的权限。
● Local 数据库这个数据库永远不会被复制可以用来存储本地单台服务器的任意集合。
● Config 数据库当MongoDB使用分片模式时,config 数据库在内部使用,用于保存分片的信息。集合-collection
集合就是一组文档类似于关系数据库中的表。集合是无模式的集合中的文档可以是各式各样的。例如{“hello,word”:“Mike”}和{“foo”: 3}它们的键不同值的类型也不同但是它们可以存放在同一个集合中也就是不同模式的文档都可以放在同一个集合中。既然集合中可以存放任何类型的文档那么为什么还需要使用多个集合这是因为所有文档都放在同一个集合中无论对于开发者还是管理员都很难对集合进行管理而且这种情形下对集合的查询等操作效率都不高。所以在实际使用中往往将文档分类存放在不同的集合中例如对于网站的日志记录可以根据日志的级别进行存储Info级别日志存放在Info 集合中Debug 级别日志存放在Debug 集合中这样既方便了管理也提供了查询性能。但是需要注意的是这种对文档进行划分来分别存储并不是MongoDB 的强制要求用户可以灵活选择。 可以使用“.”按照命名空间将集合划分为子集合。例如对于一个博客系统可能包括blog.user 和blog.article 两个子集合这样划分只是让组织结构更好一些blog 集合和blog.user、blog.article 没有任何关系。虽然子集合没有任何特殊的地方但是使用子集合组织数据结构清晰这也是MongoDB 推荐的方法。
文档-document
文档是MongoDB中数据的基本单位类似于关系数据库中的行但是比行复杂。多个键及其关联的值有序地放在一起就构成了文档。不同的编程语言对文档的表示方法不同在JavaScript 中文档表示为 {“greeting”:“hello,world”} 这个文档只有一个键“greeting”对应的值为“hello,world”。多数情况下文档比这个更复杂它包含多个键/值对。例如 {“greeting”:“hello,world”,“foo”: 3} 文档中的键/值对是有序的下面的文档与上面的文档是完全不同的两个文档。 {“foo”: 3 ,“greeting”:“hello,world”} 文档中的值不仅可以是双引号中的字符串也可以是其他的数据类型例如整型、布尔型等也可以是另外一个文档即文档可以嵌套。文档中的键类型只能是字符串。
部署mongodb
官方文档https://www.mongodb.com/docs/manual/ mongodb下载中心https://www.mongodb.com/download-center/community/releases
linux安装mongodb
官方文档https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-red-hat/#std-label-install-mdb-community-redhat-centos
# 1、联网yum安装mongodb建议使用yum方式安装mongodb
#环境初始化
yum install chrony -y systemctl enable --now chronyd
yum install vim lsof net-tools zip unzip tree wget curl bash-completion gcc make tcpdump bind-utils -y
sed -ri s/SELINUXenforcing/SELINUXdisabled/g /etc/selinux/config
setenforce 0
systemctl stop firewalld.service systemctl disable firewalld.service
hostnamectl set-hostname mongodb
#mongodb建议的优化,退出终端重新登录生效
echo never /sys/kernel/mm/transparent_hugepage/enabled
echo never /sys/kernel/mm/transparent_hugepage/defrag
chmod x /etc/rc.d/rc.local
cat /etc/rc.d/rc.local EOF
echo never /sys/kernel/mm/transparent_hugepage/enabled
echo never /sys/kernel/mm/transparent_hugepage/defrag
EOF
cat /etc/security/limits.conf EOF
* soft nofile 65536
* hard nofile 65536
* soft nproc 65536
* hard nproc 65536
EOF
#配置yum源
cat /etc/yum.repos.d/mongodb-org-7.0.repo EOF
[mongodb-org-7.0]
nameMongoDB Repository
baseurlhttps://repo.mongodb.org/yum/redhat/7/mongodb-org/7.0/x86_64/
gpgcheck1
enabled1
gpgkeyhttps://www.mongodb.org/static/pgp/server-7.0.asc
EOF
#安装mongodb
sudo yum install -y mongodb-org
#或安装指定版本 sudo yum install -y mongodb-org-7.0.3 mongodb-org-database-7.0.3 mongodb-org-server-7.0.3 mongodb-mongosh-7.0.3 mongodb-org-mongos-7.0.3 mongodb-org-tools-7.0.3#禁止mongodb自动更新
echo excludemongodb-org,mongodb-org-database,mongodb-org-server,mongodb-mongosh,mongodb-org-mongos,mongodb-org-tools /etc/yum.conf#使用yum安装的mongodb默认创建了mongod的用户,因为mongodb的启动需要使用单独的用户
#mongodb的配置文件/etc/mongod.conf
#从配置文件中可以看到默认的db目录是/var/lib/mongo日志目录是/var/log/mongodb
#修改绑定的主机IP
vim /etc/mongod.conf
net.port: 27017 #mongodb的默认端口,保持默认即可
net.bindIp: 127.0.0.1,192.168.100.6 #添加主机IP
#启动mongodb
systemctl start mongod.service
systemctl status mongod.service
systemctl enable mongod.service
#检查日志和数据目录
tail -222f /var/log/mongodb/mongod.log
ls /var/lib/mongo/#完整卸载mongodb,慎重
sudo systemctl stop mongod
sudo yum erase $(rpm -qa | grep mongodb-org)
sudo rm -r /var/log/mongodb
sudo rm -r /var/lib/mongo
sudo userdel -r mongod
sudo groupdel mongod # 2、使用tgz包安装mongodb
#环境初始化,安装一些linux常用的依赖
yum install chrony -y systemctl enable --now chronyd
yum install vim lsof net-tools zip unzip tree wget curl bash-completion gcc make tcpdump bind-utils -y
sed -ri s/SELINUXenforcing/SELINUXdisabled/g /etc/selinux/config
setenforce 0
systemctl stop firewalld.service systemctl disable firewalld.service
hostnamectl set-hostname mongodb
#安装mongodb所需的依赖
sudo yum install libcurl openssl xz-libs
#mongodb建议的优化退出终端重新登录使临时修改立即生效
echo never /sys/kernel/mm/transparent_hugepage/enabled
echo never /sys/kernel/mm/transparent_hugepage/defrag
chmod x /etc/rc.d/rc.local
cat /etc/rc.d/rc.local EOF
echo never /sys/kernel/mm/transparent_hugepage/enabled
echo never /sys/kernel/mm/transparent_hugepage/defrag
EOF
cat /etc/security/limits.conf EOF
* soft nofile 65536
* hard nofile 65536
* soft nproc 65536
* hard nproc 65536
EOF
#下载mongodb的tgz安装包并解压,下载地址https://www.mongodb.com/try/download/community
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-7.0.4.tgz
tar -zxvf mongodb-linux-x86_64-rhel70-7.0.4.tgz
sudo cp mongodb-linux-x86_64-rhel70-7.0.4/bin/* /usr/local/bin/
#下载并安装mongodb-shell,下载安装地址https://www.mongodb.com/docs/mongodb-shell/install/
wget https://downloads.mongodb.com/compass/mongodb-mongosh-2.1.1.x86_64.rpm
yum install ./mongodb-mongosh-2.1.1.x86_64.rpm
#创建用户创建目录
sudo groupadd mongod
sudo useradd mongod -g mongod -d /var/lib/mongo -s /bin/bash
sudo mkdir -p /var/lib/mongo
sudo mkdir -p /var/log/mongodb
sudo chown -R mongod:mongod /var/lib/mongo
sudo chown -R mongod:mongod /var/log/mongodb
#切换用户,启动mongodb
su mongod
mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --port 27017 --bind_ip 0.0.0.0 --fork
#检查
tail -222f /var/log/mongodb/mongod.log
netstat -lntup | grep 27017
ps -ef | grep mongod
#更多参数可以通过命令行帮助查看
mongod -h
#切换用户,停止mongodb
su mongod
mongod --shutdown --dbpath /var/lib/mongo
#使用配置文件启动mongodb,tag包安装的mongodb需要自己创建配置文件.Yum安装的mongodb默认会创建一个配置文件
#配置文件参考官网https://www.mongodb.com/docs/manual/reference/configuration-options/
cat /etc/mongod.conf EOF
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
processManagement:fork: truetimeZoneInfo: /usr/share/zoneinfo
net:bindIp: localhost,127.0.0.1,192.168.244.5,/tmp/mongod.sockport: 27017
storage:dbPath: /var/lib/mongo
systemLog:destination: filepath: /var/log/mongodb/mongod.loglogAppend: true
#security:
#operationProfiling:
#replication:
#sharding:
## Enterprise-Only Options
#auditLog:
EOF
#然后使用配置文件启动即可
su mongod
mongod -f /etc/mongod.conf
#直接使用配置文件停止即可
su mongod
mongod -f /etc/mongod.conf --shutdown
#使用systemd管理mongodb
#创建service服务文件
cat /usr/lib/systemd/system/mongod.service EOF
# /usr/lib/systemd/system/mongod.service
[Unit]
DescriptionMongoDB Database Server
Documentationhttps://docs.mongodb.org/manual
Afternetwork-online.target
Wantsnetwork-online.target[Service]
Usermongod
Groupmongod
EnvironmentOPTIONS-f /etc/mongod.conf
EnvironmentMONGODB_CONFIG_OVERRIDE_NOFORK1
EnvironmentFile-/etc/sysconfig/mongod
ExecStart/usr/local/bin/mongod $OPTIONS
RuntimeDirectorymongodb
# file size
LimitFSIZEinfinity
# cpu time
LimitCPUinfinity
# virtual memory size
LimitASinfinity
# open files
LimitNOFILE64000
# processes/threads
LimitNPROC64000
# locked memory
LimitMEMLOCKinfinity
# total threads (userkernel)
TasksMaxinfinity
TasksAccountingfalse
# Recommended limits for mongod as specified in
# https://docs.mongodb.com/manual/reference/ulimit/#recommended-ulimit-settings[Install]
WantedBymulti-user.target
EOF
#现在用root用户systemd管理mongodb即可,mongodb进程还是mongod用户启动的进程
usermod mongod -s /bin/false #可选,禁止mongod用户登录
systemctl start mongod.service
systemctl status mongod.service
systemctl enable mongod.service
systemctl stop mongod.service docker安装mongodb
#安装docker
参考: https://blog.csdn.net/MssGuo/article/details/122694156
#docker安装mongodb官方文档
https://www.mongodb.com/docs/manual/tutorial/install-mongodb-community-with-docker/
https://hub.docker.com/r/mongodb/mongodb-community-server/tags
#1、官网方式安装mongodb
docker pull mongodb/mongodb-community-server
docker run --name mongo -d mongodb/mongodb-community-server:latest
docker log -f mongo
docker inspect mongo
#2、自定义安装mongodb
#官网启动的mongodb默认使用的匿名卷且没有映射端口到宿主机
mkdir /var/lib/mongo
#发现只有给777权限才能正常启动mongo容器,不然一直报创建文件权限不足,不晓得为啥子
chmod 777 -R /var/lib/mongo
#启动mongodb容器
docker run --name mongo -p 27017:27017 -v /var/lib/mongo:/data/db -d mongodb/mongodb-community-server:latest
#查看挂载的文件属主属组是101 nfsnobody
[rootnode1 lib]# ll /var/lib/mongo/
-rw------- 1 101 nfsnobody 4096 Dec 28 14:29 collection-0-7528388073393714379.wt
-rw------- 1 101 nfsnobody 4096 Dec 28 14:29 collection-2-7528388073393714379.wt
#登录mongodb,容器里面内置了mongosh命令行工具
docker exec -it mongo mongoshMongoDB Shell (mongosh)命令行工具
MongoDB Shell (mongosh)是一个JavaScript和Node.js REPL环境用于与Atlas、本地或另一个远程主机上的MongoDB部署进行交互。 使用MongoDB Shell来测试查询并与MongoDB数据库中的数据进行交互。
#下载mongosh
#yum安装的mongodb默认会安装mongosh命令,如果没有安装,也可以从官网下载mongosh进行安装
#官方文档https://www.mongodb.com/docs/mongodb-shell/
#下载地址https://www.mongodb.com/try/download/shell
wget https://downloads.mongodb.com/compass/mongodb-mongosh-2.1.1.x86_64.rpm
yum install ./mongodb-mongosh-2.1.1.x86_64.rpm
which mongosh
#使用mongosh链接mongodb
# 1、链接到指定mongodb无auth,所以没有写账号密码,默认进入test库
mongosh mongodb://192.168.244.5:27017/
# 2、链接到指定mongodb的foo库无auth,所以没有写账号密码
mongosh mongodb://192.168.244.5:27017/foomongodb可视化-mongodb-compass、mongo-express
#1、官网提供的mongodb可视化是mongodb-compass
#用windows安装mongodb-compass,linux安装mongodb-compass需要图形化支持的
下载地址https://www.mongodb.com/try/download/compass
https://downloads.mongodb.com/compass/mongodb-compass-1.41.0-win32-x64.exe#2、第二种图形化是mongo-express,这里使用docker部署mongo-express,默认mongodb已经使用容器启动了
#查看mongodb容器
[rootnode2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
713fa33002c8 mongodb/mongodb-community-server:latest python3 /usr/local/… 3 minutes ago Up 3 minutes 0.0.0.0:27017-27017/tcp, :::27017-27017/tcp mongo
#启动mongo-express
#link参数语法--link 容器名称:别名 --link的原理就是在容器里面的/etc/hosts里面添加了链接对象容器的一个alias名称
docker run -d --link mongo:mongo --name mongo-express -p 8081:8081 mongo-express
#查看容器状态正常
[rootnode2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0a0944df7397 mongo-express tini -- /docker-ent… 18 seconds ago Up 17 seconds 0.0.0.0:8081-8081/tcp, :::8081-8081/tcp mongo-express
713fa33002c8 mongodb/mongodb-community-server:latest python3 /usr/local/… 10 minutes ago Up 10 minutes 0.0.0.0:27017-27017/tcp, :::27017-27017/tcp mongo
[rootnode2 ~]# docker exec -it mongo-express cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 mongo 713fa33002c8 #alias的名称
172.17.0.3 0a0944df7397
[rootnode2 ~]#
#在浏览器访问mongo-express
http://192.168.158.130:8081mongodb配置文件
如果是使用yum安装的mongodb则默认的配置文件为/etc/mongod.conf。下面简单讲解一下配置文件的关键参数。
#更多配置参数请查看官网https://www.mongodb.com/docs/manual/reference/configuration-options/
[rootnode2 ~]# cat /etc/mongod.conf
# mongod.conf# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/# where to write logging data.
systemLog: #mongodb日志相关参数destination: file #日志要发送到哪里,可选值: file or sysloglogAppend: true #为true时当mongos或mongod实例重新启动时在现有日志文件的末尾添加新的条目。#如果没有这个选项mongod将备份现有日志并创建一个新文件。Default: falsepath: /var/log/mongodb/mongod.log #日志destination是file则要指定文件路径# Where and how to store data.
storage: #mongodb数据存储相关参数dbPath: /var/lib/mongo #存储路径# how the process runs
processManagement:timeZoneInfo: /usr/share/zoneinfo# network interfaces
net: #网络配置相关参数port: 27017 #mongodb的端口,默认是27017bindIp: 127.0.0.1,192.168.158.130 # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.#security: #访问认证相关的参数,这里未启用auth认证
#operationProfiling:
#replication: #副本集相关的参数,这里部署的是单实例mongodb,未部署副本集mongodb
#sharding: #分片集群相关的参数,这里部署的是单实例mongodb,未部署分片集群mongodb
## Enterprise-Only Options
#auditLog:
[rootnode2 ~]#
#更多配置参数请查看官网https://www.mongodb.com/docs/manual/reference/configuration-options/mongodb库、集合、文档
mongodb有一个特点如果某个库下没有数据没有集合的话该库就等于不存在mongodb只要创建一个库在库下写入数据该库才会生成。如下所示登录的默认登录到test库但show database却看不到就是这个意思。 mongosh命令行工具下可以使用tab键补全命令。
#使用mongosh登录mongodb
mongosh mongodb://192.168.185.130:27017
#登录url后不指定库则默认会进入test库,但test库是空的,所以show看不到
#查看全部的数据库
test show databases
admin 40.00 KiB #系统预留库,mongodb的系统管理库
config 108.00 KiB #配置信息库,保存如分片等信息
local 72.00 KiB #本地预留库,存储关键日志#按table键可以补全
test show
show databases show dbs show collections show tables show profile show users show roles
show log show logs show startupWarnings show automationNotices show nonGenuineMongoDBCheck库基本操作
test show dbs; #显示全部的数据库
test show databases; #显示全部的数据库
test use unit; #切换数据库,如果库不存在并且存在往库里面创建集合等操作则会创建库
test use unit; #切换数据库
unit db #查询当前数据库,其实可以通过前缀符也可以看到当前数据库
unit db.dropDatabase() #切换到指定库里面,然后删除数据库,删除的是当前unit数据库(慎用)集合基本操作
unit db.createCollection(students); #创建集合,名称叫students
unit db.createCollection(blog.user) #创建集合,名称叫blog.user
unit db.createCollection(blog.article) #创建集合,名称叫blog.article
unit show collections; #查看当前库的全部集合
unit db.students.drop() #删除集合,db是关键字,students是集合名称,所以删除的是students集合文档的增删改查CURD
插入文档
#插入文档主要使用两个方法
insertOne方法与insertMany方法,如果集合不存在则默认自动创建集合.
#往students集合中插入1个文档,会自动创建唯一主键ID,db是关键字,students是集合名称,insertOne是插入方法
db.students.insertOne({name: sue,age: 26,status: pending})
#往students集合中插入多个文档,会自动创建唯一主键ID,db是关键字,students是集合名称,insertMany是插入方法
db.students.insertMany([{ item: journal, qty: 25, tags: [blank, red], size: { h: 14, w: 21, uom: cm } },{ item: mat, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },{ item: mousepad, qty: 25, tags: [gel, blue], size: { h: 19, w: 22.85, uom: cm } }
])查询文档
官网https://www.mongodb.com/docs/manual/tutorial/query-documents/ 查询集合中的文档主要使用find()方法。
#查询文档语法格式
#其中db是关键字,然后是集合名称,然后是find()方法
db.collection_name.find( { field1: { operator1: value1 }, ... } ).otherfuntion#先插入一些示例文档
db.inventory.insertMany( [{ item: journal, qty: 25, size: { h: 14, w: 21, uom: cm }, status: A },{ item: notebook, qty: 50, size: { h: 8.5, w: 11, uom: in }, status: A },{ item: paper, qty: 100, size: { h: 8.5, w: 11, uom: in }, status: D },{ item: planner, qty: 75, size: { h: 22.85, w: 30, uom: cm }, status: D },{ item: postcard, qty: 45, size: { h: 10, w: 15.25, uom: cm }, status: A }
]);#查询集合全部文档,即find()方法不加任何条件
db.inventory.find({})
db.inventory.find()
等价于mysql的
SELECT * FROM inventory#查询前n个文档
db.inventory.find().limit(n);#指定相等条件,即查询指定的key等于某个values
语法{ field1: value1, ... }
db.inventory.find( { item: planner } )
db.inventory.find( { item: planner } )
db.inventory.find( { size.uom: in } ) #使用点引用子key,因为size是嵌套的json数据
等价于mysql的
SELECT * FROM inventory WHERE itemplanner比较运算符
bash
$eq 等于
$ne 不等于
$lt 小于
$lte 小于等于
$gt 大于
$gte 大于等于
$in 匹配数组中的值,类似于mysql中的in运算符
$nin 不匹配数组中的值,类似于mysql中的not in运算符# $eq 等于运算符,查询status等于A的文档
db.inventory.find({status: {$eq: A}}) #等于可以不使用运算符直接写,如下
db.inventory.find({status: A}) #等价于上面一行
等价于mysql的
SELECT * FROM inventory WHERE status A# $ne 不等于运算符,查询status不等于A的文档
db.inventory.find({status: {$ne: A}})
等价于mysql的
SELECT * FROM inventory WHERE status !A# $lt 小于运算符,查询qty小于50的文档
db.inventory.find({qty: {$lt: 50}})
# $lte 小于运算符,查询qty小于等于50的文档
db.inventory.find({qty: {$lte: 50}})
等价于mysql的
SELECT * FROM inventory WHERE qty 50
SELECT * FROM inventory WHERE qty 50# $gt 大于运算符,查询qty大于50的文档
db.inventory.find({qty: {$gt: 50}})
# $gte 大于运算符,查询qty大于等于50的文档
db.inventory.find({qty: {$gte: 50}})
等价于mysql的
SELECT * FROM inventory WHERE qty 50
SELECT * FROM inventory WHERE qty 50# $in 匹配数组中的值,运算符要求是一个数组,数组使用[]符号,查询status值是B或C的文档
db.inventory.find({status: {$in: [B,C]}})
# $nin 不匹配数组中的值,运算符要求是一个数组,数组使用[]符号,查询status值是B或C的文档
db.inventory.find({status: {$nin: [B,C]}})
等价于mysql的
SELECT * FROM inventory WHERE status in (B,C)
SELECT * FROM inventory WHERE status not in (B,C)逻辑运算符
$and 逻辑与,基于一个或多个表达式执行逻辑AND操作,当且仅当所有表达式都为真时,结果才为真。
$or 逻辑或,逻辑OR操作,只要其中一个表达式为真,结果就为真。
$not 取反, 对结果取反# $and 逻辑与不用显示的表示,直接使用隐式的即可,
查询status等于A和qty小于30的文档
db.inventory.find({ status: A, qty: { $lt: 30 } })
等价于mysql的
SELECT * FROM inventory WHERE statusA and qty30
这样也能显示的表示逻辑与但是不建议db.inventory.find( { $and: [ { status: A }, { qty: { $lt: 30 } } ] } )# $or 逻辑或,满足其中一个条件即可
# or格式
{ $or: [ {条件1}, {条件2},{..n} ]
}
#查询status等于A或qty小于30的文档
db.inventory.find( {
$or: [ { status: A }, { qty: { $lt: 30 } } ]
}
)
等价于mysql的
SELECT * FROM inventory WHERE statusA or qty30# and和or联合使用,查询status等于A并且(qty小于30或item以p开头)的文档
db.inventory.find( {status: A,$or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
} )
等价于mysql的
SELECT * FROM inventory WHERE status A AND ( qty 30 OR item LIKE p%)# $not操作符, 对结果取反
#含义为查询qty值不大于50的文档
db.inventory.find( { qty: { $not: { $gt: 50 } } } )嵌套字段
#嵌套字段直接使用点引用即可,注意这时的字段key要使用引号扩起来
db.inventory.find( { size.uom: sz } )
db.inventory.find({size.uom: {$in: [cd,cm]}})
db.inventory.find( { size.h: { $lt: 15 }, size.uom: in, status: D } )
#下面两条查询语句等价
db.inventory.find( { size.h: 14, size.w: 21, size.uom: cm } )
db.inventory.find( { size: { h: 14, w: 21, uom: cm } } )匹配数组
#如下插入示例数据
db.inventory.insertMany([{ item: journal, qty: 25, tags: [blank, red], dim_cm: [ 14, 21 ] },{ item: notebook, qty: 50, tags: [red, blank], dim_cm: [ 14, 21 ] },{ item: paper, qty: 100, tags: [red, blank, plain], dim_cm: [ 14, 21 ] },{ item: planner, qty: 75, tags: [blank, red], dim_cm: [ 22.85, 30 ] },{ item: postcard, qty: 45, tags: [blue], dim_cm: [ 10, 15.25 ] }
]);
#上面数据对于tags字段该字段是数组类型
#查询tags数组元素是[red, blank]的文档,这种匹配要求数组元素值、个数、顺序完全一致才会匹配
db.inventory.find( {tags: [red, blank]})#使用$all 表示查询包含元素“red”和“blank”的数组,而不考虑数组中的顺序,主要包含即可
db.inventory.find( { tags: { $all: [red, blank] } } )#查询数组字段是否至少包含一个具有指定值的元素,请使用过滤器{ field: value } 其中value 是元素值
#tags是一个数组,查询tags包含字符串red作为其元素之一的文档
db.inventory.find( { tags: red } )#使用查询操作符指定数组字段中元素的条件,至少1个元素满足条件即可匹配
#格式 { array field: { operator1: value1, ... } }
db.inventory.find( { dim_cm: { $gt: 25 } } )#多条件指定查询数组元素,至少1个元素满足条件即可匹配
#下面的示例含义是集合中数组字段dim_cm中单个元素同时满足大于15并且小于20,或者一个元素满足大于15,另外一个元素小于20。
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )
下面这些都能匹配的上如下
dim_cm:[ 14, 21 ]匹配的上因为21大于15,另外一个元素14小于20、
dim_cm:[ 10, 15.25 ]匹配的上因为15.25满足大于15并且小于20
dim_cm:[ 22.85, 14 ]匹配的上因为22.85满足大于15另外一个元素14小于20
dim_cm:[ 22.85, 21, 19 ]匹配的上因为22.85满足大于15另外一个元素19小于20#使用$elemMatch操作符为数组元素指定多个条件,使至少一个数组元素满足所有指定条件
#下面的示例查询di_cm数组中至少包含一个大于22且小于30的元素的文档
db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } )#根据数组索引位置查询元素,数组元素从0开始
#使用点表示法查询时,字段和嵌套字段必须在引号内
#下面的例子查询数组dim_cm中第二个元素大于25的所有文档
db.inventory.find( { dim_cm.1: { $gt: 25 } } )
#查询数组dim_cm中第一个元素为14的所有文档
db.inventory.find( { dim_cm.0: 14 } )#使用$size操作符按数组元素个数查询文档
#例如下面的代码选择dim_cm数组中有3个元素的文档
db.inventory.find( { dim_cm: {$size: 3} } )匹配嵌套数组
#插入文档主要是嵌套数组
db.inventory.insertMany( [{ item: journal, instock: [ { warehouse: A, qty: 5 }, { warehouse: C, qty: 15 } ] },{ item: notebook, instock: [ { warehouse: C, qty: 5 } ] },{ item: paper, instock: [ { warehouse: A, qty: 60 }, { warehouse: B, qty: 15 } ] },{ item: planner, instock: [ { warehouse: A, qty: 40 }, { warehouse: B, qty: 5 } ] },{ item: postcard, instock: [ { warehouse: B, qty: 15 }, { warehouse: C, qty: 35 } ] }
]);
#下面的例子选择所有的文档,其中一个元素在stock数组中匹配指定的文档:
db.inventory.find( { instock: { warehouse: A, qty: 5 } } )
#整个嵌套文档上的相等匹配要求精确匹配指定的文档包括字段顺序。例如,下面的查询不匹配库存集合中的任何文档
db.inventory.find( { instock: { qty: 5, warehouse: A } } )#指定文档数组中嵌入字段的查询条件
#如果您不知道嵌套在数组中的文档的索引位置,请将数组字段的名称与嵌套文档中的字段名称连接起来
#下面的示例选择所有文档,其中至少有一个嵌入文档,其中包含字段qty的值小于或等于20
db.inventory.find( { instock.qty: { $lte: 20 } } )#使用数组索引查询嵌入文档中的字段,索引从0开始
#查询instock数组的第1个元素的qty字段小于等于20的文档
db.inventory.find( { instock.0.qty: { $lte: 20 } } )#使用$elemMatch操作符在嵌入文档数组上指定多个标准使至少一个嵌入文档满足所有指定的标准
#下面的例子,查询文档,stock数组中至少有一个元素其中包含字段qty等于5和字段warehouse等于A
db.inventory.find( { instock: { $elemMatch: { qty: 5, warehouse: A } } } )
instock: [ { warehouse: A, qty: 5 }, { warehouse: C, qty: 15 } ] 满足条件这说明嵌套元素里的字段顺序不论。#下面的示例查询在stock数组中至少有一个包含字段qty大于10小于等于20的嵌入文档的文档:
db.inventory.find( { instock: { $elemMatch: { qty: { $gt: 10, $lte: 20 } } } } )#找到在 instock 数组中【至少有一个嵌入文档包含 qty 10以及至少有一个嵌入文档但不一定是同一个嵌入文档包含 qty ≤20 】的文档
db.inventory.find( { instock.qty: { $gt: 10, $lte: 20 } } )
下面这些都会匹配
instock: [ { warehouse: A, qty: 40 }, { warehouse: B, qty: 5 } ]
instock: [ { warehouse: B, qty: 15 }, { warehouse: C, qty: 35 } ]#以下示例查询的文档中instock数组至少有一个包含字段qty等于5的嵌入文档并且至少有一个包含字段warehouse等于A的嵌入文档(但不一定是相同的嵌入文档):
db.inventory.find( { instock.qty: 5, instock.warehouse: A } )
下面这些都满足
instock: [ { warehouse: A, qty: 5 }, { warehouse: C, qty: 15 } ]
instock: [ { warehouse: A, qty: 40 }, { warehouse: B, qty: 5 } ]投影返回指定字段
# 投影就是手电筒从上问下照射的含义
#默认情况下MongoDB中的查询返回匹配文档中的所有字段。
#为了限制MongoDB发送给应用程序的数据量您可以包含一个投影文档来指定或限制要返回的字段。
#插入测试数据-文档
db.inventory.insertMany( [{ item: journal, status: A, size: { h: 14, w: 21, uom: cm }, instock: [ { warehouse: A, qty: 5 } ] },{ item: notebook, status: A, size: { h: 8.5, w: 11, uom: in }, instock: [ { warehouse: C, qty: 5 } ] },{ item: paper, status: D, size: { h: 8.5, w: 11, uom: in }, instock: [ { warehouse: A, qty: 60 } ] },{ item: planner, status: D, size: { h: 22.85, w: 30, uom: cm }, instock: [ { warehouse: A, qty: 40 } ] },{ item: postcard, status: A, size: { h: 10, w: 15.25, uom: cm }, instock: [ { warehouse: B, qty: 15 }, { warehouse: C, qty: 35 } ] }
]);
#默认返回文档的全部字段
db.inventory.find( { status: A } )
等价于mysql
SELECT * from inventory WHERE status A#只返回指定字段和_id字段
#注意_id字段默认就是1,如果不需要显示id需要显示的设置_id: 0
#通过设置field:1 显示的标明要投影哪些字段
#下面的操作返回与查询匹配的所有文档。在结果集中只返回匹配文档中的项、状态和(默认情况下)_id字段。
db.inventory.find( { status: A }, { item: 1, status: 1 } )
等价于mysql
SELECT _id, item, status from inventory WHERE status A
#不显示id,抑制id,因为_id字段默认就是1,如果不需要显示id需要显示的设置_id: 0
db.inventory.find( { status: A }, { item: 1, status: 1, _id: 0 } )
等价于mysql
SELECT item, status from inventory WHERE status A#返回除排除字段外的所有字段
#您可以使用投影来排除特定字段,而不是列出要在匹配文档中返回的字段
#下面的示例返回匹配文档中除了status和stock字段以外的所有字段
db.inventory.find( { status: A }, { status: 0, instock: 0 } )
#下面的示例返回全部文档中除了status和stock字段以外的所有字段
db.inventory.find( {}, { status: 0, instock: 0 } )#注意注意
#投影的字段要么都是1要么都是0,不能有些是1有些是0,但是_id除外,类比mysql的select字段,不存在既选又不选的说法
db.inventory.find( { status: A }, { status: 0, instock: 0,_id:1 } ) #正常查询
db.inventory.find( { status: A }, { status: 1, instock: 1,_id:0 } ) #正常查询
db.inventory.find( { status: A }, { status: 0, instock: 0,size:1 } ) #报错,投影的字段要么都是1要么都是0不能有些是1有些是0#返回嵌入文档中的特定字段
#可以返回嵌入文档中的特定字段。使用点表示法引用嵌入字段,并在投影文档中设置为1。
#显示item、status、size中uom字段
db.inventory.find({ status: A },{ item: 1, status: 1, size.uom: 1 } #可以这么写{ item: 1, status: 1, size: { uom: 1 } }.
)
#除了不显示size.uom字段,其他字段都显示
db.inventory.find({ status: A }, { size.uom: 0 } #可以这么写{ size: { uom: 0 } }
)#数组的嵌入
#返回数组中的项目特定数组元素
db.inventory.find( { status: A }, { item: 1, status: 1, instock.qty: 1 } )
# $slice: -1映射数组的最后一个元素
db.inventory.find( { status: A }, { item: 1, status: 1, instock: { $slice: -1 } } )null值匹配或没有的字段
#插入文档
db.inventory.insertMany([{ _id: 1, item: null }, #这行文档item字段为null { _id: 2 } #这行文档没有item字段
])
#查询item为null的文档,{item: null}查询匹配的文档要么包含值为null的item字段,要么不包含item字段
#所以查询结果会返回上面两条文档
db.inventory.find( { item: null } )#使用类型检查来查询
# { item : { $type: 10 } } 仅匹配文档中item字段值是null,null的BSON类型是10
#所以结果就是返回上面的第一文档
db.inventory.find( { item : { $type: 10 } } )#exists 匹配
#{ item : { $exists: false } } 匹配不包含item字段的文档
#返回结果就是返回上面的第二文档
db.inventory.find( { item : { $exists: false } } )更新文档
#更新文档主要有三个方法
db.collection.updateOne(filter, update, options)
db.collection.updateMany(filter, update, options)
db.collection.replaceOne(filter, update, options)
db.collection.findAndModify().
语法格式
{operator1: { field1: value1, ... },operator2: { field2: value2, ... },...
}
#插入一下测试数据文档
db.inventory.insertMany( [{ item: canvas, qty: 100, size: { h: 28, w: 35.5, uom: cm }, status: A },{ item: journal, qty: 25, size: { h: 14, w: 21, uom: cm }, status: A },{ item: mat, qty: 85, size: { h: 27.9, w: 35.5, uom: cm }, status: A },{ item: mousepad, qty: 25, size: { h: 19, w: 22.85, uom: cm }, status: P },{ item: notebook, qty: 50, size: { h: 8.5, w: 11, uom: in }, status: P },{ item: paper, qty: 100, size: { h: 8.5, w: 11, uom: in }, status: D },{ item: planner, qty: 75, size: { h: 22.85, w: 30, uom: cm }, status: D },{ item: postcard, qty: 45, size: { h: 10, w: 15.25, uom: cm }, status: A },{ item: sketchbook, qty: 80, size: { h: 14, w: 21, uom: cm }, status: A },{ item: sketch pad, qty: 95, size: { h: 22.85, w: 30.5, uom: cm }, status: A }
] );#更新一个文档
#查找item等于paper的并更新size.uom字段值为cm以及status字段值为P
#使用$currentDate操作符将lastModified字段的值更新为当前日期,如果lastModified字段不存在,$currentDate将创建该字段
db.inventory.updateOne({ item: paper },{$set: { size.uom: cm, status: P },$currentDate: { lastModified: true }}
)
更新后的文档原来是没有lastModified字段的
unit db.inventory.find({item:paper})
[{_id: ObjectId(65961d3ad6b89310d94a149d),item: paper,qty: 100,size: { h: 8.5, w: 11, uom: cm },status: P,lastModified: ISODate(2024-01-04T03:26:05.556Z)}
]
unit #更新多个文档
#使用$set操作符更新uom字段为in,status字段的值为P
#使用$currentDate操作符将lastModified字段的值更新为当前日期,如果lastModified字段不存在,$currentDate将创建该字段
db.inventory.updateMany({ qty: { $lt: 50 } },{$set: { size.uom: in, status: P },$currentDate: { lastModified: true }}
)#替代文档
#要替换文档中除了_id字段以外的全部内容,将一个全新的文档作为第二个参数传递给db.collection.replaceOne()方法
#替换文档可以具有与原始文档不同的字段,在替换文档中,您可以省略_id字段,因为_id字段是不可变的;但是,如果包含_id字段,它必须与当前值相同.
#下面示例替换指定id的文档
db.inventory.replaceOne({ _id: ObjectId(65961d3ad6b89310d94a1499) },{ item: journal, instock: [ { warehouse: A, qty: 60 }, { warehouse: B, qty: 40 } ] }
)#更多更新参照、更新操作符请查看官网删除文档
#删除文档使用两个方法
db.collection.deleteMany() #删除一个或多个文档或全部文档
db.collection.deleteOne() #删除单个文档,即使过滤器匹配到多个文档仍然只是删除第一个文档#删除集合全部文档
db.inventory.deleteMany({})
#删除status等于A的文档
db.inventory.deleteMany({ status : A })
#删除qty大于等于50的文档
db.inventory.deleteMany({qty:{$gte:50}})#删除status等于P的文档,由于是deleteOne方法,所以即使匹配到多个文档仍然只是删除第一个文档
db.inventory.deleteOne( { status: P } )mongodb的访问控制
mongodb数据库应该要设置用户账号密码来保证安全。mongodb内置了一系列的role角色来限定用户所具备的权限。结合用户和角色管理mongodb就具备安全的访问控制。
理解mongodb的用户、库的关系
mongodb的用户是基于数据库database和集合collections来进行授权和访问控制的在mongodb中用户是在特定数据库中创建的并且每个用户都可以被授予对该数据库中特定集合的不同级别的权限。 用户在MongoDB中被分配了角色Role角色定义了用户在数据库中的权限和操作。MongoDB提供了一些内置角色如读取read和写入write角色也允许用户自定义角色以满足特定需求。 当用户被创建时需要为其指定所属的数据库并且可以为该用户分配适当的角色。这样用户将只能在其所属数据库中的指定集合上执行授权的操作。
admin库的作用
在MongoDB中admin是一个特殊的系统数据库它在数据库管理和权限控制方面具有特殊的作用。下面是admin库的主要作用 1、用户管理admin库是管理MongoDB用户和角色的主要地方。它存储了用户凭据、角色定义和权限分配。通过admin库可以创建、修改和删除用户分配角色和权限以及执行与用户身份验证和授权相关的操作 2、权限控制admin库是MongoDB的权限控制中心。通过admin/库可以定义和管理数据库用户的访问权限管理员可以使用admin库中的角色和权限定义来限制用户对数据库的操作以保护敏感数据和确保系统安全。 3、集群管理admin库也用于管理MongoDB集群和副本集。通过admin库可以执行各种集群管理任务如添加和删除分片、启动和停止副本集成员、配置副本集等。 4、系统状态和监控admin库存储了与MongoDB服务器状态和监控相关的信息。通过admin库可以获取服务器的运行状态、连接信息、日志记录等。这对于系统管理和故障排除非常有用。 总之admin库是MongoDB的系统级数据库用于管理用户、权限、集群和监控等关键任务。它提供了对数据库管理和安全的细粒度控制并为管理员提供了管理和监视MongoDB实例的中心位置。
mongodb内置角色
#mongodb内置了很多角色可以参考官网
https://www.mongodb.com/docs/manual/reference/built-in-roles/#mongodb-authrole-readWriteAnyDatabase
Database user和database administration 这两类角色在每个库都内置有其他全部的内置角色都在admin库。登录admin库创建管理员用户
创建用户可以在任何数据库下创建下面例子我们模拟mongodb刚安装完成还没有开启访问认证功能所以我们要首先登录mongodb然后在admin库里面创建一个具有管理任何数据库任何数据库读写的角色的管理员权限用户上面我们说过Database user和database administration 这两个角色在每个库都内置有其他全部的内置角色都在admin库因为具有管理任何数据库任何数据库读写的角色是在admin库里的所以要在admin库里面创建管理员权限用户。
下面按照官网说明创建一个拥有userAdminAnyDatabase和readWriteAnyDatabase的管理员用户注意该用户的权限并不是超级管理员权限但权限已经足够高了。 官方文档https://www.mongodb.com/docs/manual/tutorial/configure-scram-client-authentication/#create-the-user-administrator
#先不配置访问认证,无账号密码登录mongodb
mongosh mongodb://192.168.158.130:27017/
#创建管理员用户创建完成退出
use admin #切换到admin库下创建管理员用户
db.createUser({user: admin, #管理员用户名pwd: passwordPrompt(), #提示输入密码,也可以直接指定字符串密码,如admin123roles: [{ role: userAdminAnyDatabase, db: admin },{ role: readWriteAnyDatabase, db: admin }]}
)
#解释说明
user: admin,指定管理员用户名;
pwd: passwordPrompt(), 使用passwordPrompt()方法可提示输入密码,也可以直接指定字符串密码,如admin123
userAdminAnyDatabase角色允许用户有这些权限:创建用户、授予或撤销用户的角色、创建或修改自定义角色;
readWriteAnyDatabase角色允许对任何数据库具有读写权限;
db: admin,表示该用户的身份验证数据库,一般写当前数据库即可.注意: 创建用户的数据库(在本例中为admin库)是用户的身份验证数据库,尽管用户需要对该数据库进行身份验证,但该用户可以在其他数据库中拥有角色,主要用户所关联的角色拥有足够的权限,换句话说,用户的身份验证数据库不会限制用户的特权。在MongoDB中,虽然创建用户时需要指定一个默认的数据库(上面的例子中是admin数据库),但用户是否可以在任何数据库中执行操作,取决于该用户所关联的角色是否有在该数据库上具有相应的权限。当创建新用户时,我们可以选择将其与特定的数据库关联起来,作为用户登录的身份验证数据库。例如,在上面的例子中,我们将新用户admin与admin数据库关联起来,并赋予了该用户在admin数据库上执行用户管理操作和读取/写入任何数据库数据的权限。然而,这并不意味着用户只能在与其关联的数据库中进行操作,一旦用户被创建并赋予了适当的角色和权限,它可以在任何其他数据库中执行操作,只要它具有所需的角色和权限。
因此,尽管创建用户时可以指定默认的数据库,但用户的操作范围并不仅限于该数据库。修改配置文件启用账号密码认证
上面创建了管理员账号关闭mongodb实例修改配置 1、如果是使用yum等方式安装的mongodb默认的配置文件是/etc/mongod.conf修改配置文件添加或启动参数如下
vim /etc/mongod.conf
security:authorization: enabled2、如果是直接mongod命令启动的mongodb启动时加上–auth参数即可如下 mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --port 27017 --bind_ip 0.0.0.0 --auth --fork 3、如果是docker启动的mongodb启动时加上–auth参数即可如下
docker run --name mongo -d mongodb/mongodb-community-server:latest --auth
docker run --name mongo -p 27017:27017 -v /var/lib/mongo:/data/db -d mongodb/mongodb-community-server:latest --auth4、使用管理员账号密码登录mongodb
1、命令行指定账号密码登录及用户的身份验证数据库建议使用这种
mongosh -u admin -p admin123 --authenticationDatabase admin mongodb://192.168.158.130:27017/
2、登录后再认证
mongosh mongodb://192.168.158.130:27017/ #先无账号密码登录
use admin #登录后需要先切换到admin数据库,因为admin用户是在admin库创建的,不切换操作其他任何命令都显示认证报错
db.auth(admin, admin123) #亦可以db.auth(admin, passwordPrompt()),用户认证通过就可以自由操作数据库了
use unit #因为admin用户是管理员角色,对任何数据库都要权限,所以正常切换到其他数据库创建超级管理员
想要创建一个超级管理员赋予root角色即可
#先登录数据库,--authenticationDatabase参数直接指定用户存放的数据库,也称用户的身份验证数据库,即在哪个库下创建的用户就写对应的库名
mongosh -u admin -p admin123 --authenticationDatabase admin mongodb://192.168.158.130:27017/
use admin #我们把root用户放到admin库下,因为root角色在admin库下
db.createUser({user: root,pwd: passwordPrompt(),roles: [{ role: root, db: admin }]}
)
#创建成功,可以查看当前全部用户
db.getUsers()
#退出,使用root超级管理员登录
mongosh -u root -p root --authenticationDatabase admin mongodb://192.168.158.130:27017/ 创建数据库普通用户
#参考官方文档的角色,单独数据库的管理员角色和数据库的平台用户角色
https://www.mongodb.com/docs/manual/reference/built-in-roles/#database-user-roles
https://www.mongodb.com/docs/manual/reference/built-in-roles/#database-administration-roles#为unit数据库创建数据库管理员这里创建的是unit数据库管理员角色
#创建用户时并不一定需要在admin数据库下进行,上面我们创建的用户都是管理员角色所以放在admin下而已,是因为那些角色都在admin库中
#首先得使用具有创建用户权限的用户登录,然后才能创建用户,这里我们使用上面创建的admin管理员用户先登录
mongosh -u admin -p admin123 --authenticationDatabase admin mongodb://192.168.158.130:27017/
use unit #切换到unit,我们要在这个库下创建对unit库具有管理员权限用户
db.createUser({user: unit,pwd: unit123,roles: [{ role: dbOwner, db: unit } ]}
)
#dbOwner角色表示数据库管理员,如果只想给普通用户具有读写权限那么可以给readWrite角色
#使用unit账号登录
mongosh -u unit -p unit123 --authenticationDatabase unit mongodb://192.168.158.130:27017/
test show databases; #只能看到unit数据库了
unit 200.00 KiB
test use unit
switched to db unit
unit show collections #正常
blog.article
blog.user
inventory
students
teacher
unit #这样unit用户就可以给开发使用了删除用户
#先使用具有删除用户的管理员角色登录,然后删除即可
db.dropUser(unit)mongodb的高可用架构
1、Replica Set 副本集也可称复制集最小架构是1主2从主节点负责读写从节点只读当主节点崩溃会自动从从节点选择一个成为主节点 2、shard分片集群最常见的架构是1个mongos1个config serverconfig server由3个节点组成副本集3个shard分片每个shard分片由3个节点组成副本集。
Replica Set 副本集模式
Replica Set 即可以称之为副本集也可以称之为复制集意思一样。 MongoDB中的副本集是一组维护相同数据集的mongod进程。副本集提供冗余和高可用性是所有生产部署的基础。 Primary主节点做读写Secondary用于同步主节点的数据只读。副本集的成员个数应该总是奇数。这将确保选举顺利进行。所以最小副本集是3个mongodb节点。 官方文档https://www.mongodb.com/docs/manual/replication/ 、https://www.mongodb.com/docs/manual/tutorial/deploy-replica-set/
#docker部署3节点副本集,--replSet mongodb-rs参数是指定副本集的名称
docker run --name mongo-1 -p 27017:27017 -v /opt/mongo-1:/data/db -d mongodb/mongodb-community-server:latest --replSet mongodb-rs
docker run --name mongo-2 -p 27018:27017 -v /opt/mongo-2:/data/db -d mongodb/mongodb-community-server:latest --replSet mongodb-rs
docker run --name mongo-3 -p 27019:27017 -v /opt/mongo-3:/data/db -d mongodb/mongodb-community-server:latest --replSet mongodb-rs
#登录其中一个节点,初始化副本集,初始化完成之后,前缀符号都变了
docker exec -it mongo-1 bash
mongosh
rs.initiate( {_id : mongodb-rs, #这是副本集的名称,与上面docker启动时的名称保持一致members: [ #节点IP和端口{ _id: 0, host: 192.168.158.130:27017 },{ _id: 1, host: 192.168.158.130:27018 },{ _id: 2, host: 192.168.158.130:27019 }]
})
#查看副本集的配置
rs.conf()
#查看副本集的状态
rs.status()#测试,在主库创建库写入文档,主库读写文档正常
mongodb-rs [direct: primary] test show dbs
admin 80.00 KiB
config 212.00 KiB
local 404.00 KiB
mongodb-rs [direct: primary] test use unit
mongodb-rs [direct: primary] unit db.students.insertMany([{ item: journal, qty: 25, tags: [blank, red], size: { h: 14, w: 21, uom: cm } },{ item: mat, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },{ item: mousepad, qty: 25, tags: [gel, blue], size: { h: 19, w: 22.85, uom: cm } }])
mongodb-rs [direct: primary] unit db.students.find() #正常查询#在从库测试,从库已经同步了主库的数据,但是此时不能读
mongodb-rs [direct: secondary] test show dbs
admin 80.00 KiB
config 244.00 KiB
local 420.00 KiB
unit 40.00 KiB #库已经同步了
mongodb-rs [direct: secondary] test use unit
mongodb-rs [direct: secondary] unit show collections #集合可以看到
students
mongodb-rs [direct: secondary] unit db.students.find() #查询报错
MongoServerError: not primary and secondaryOkfalse - consider using db.getMongo().setReadPref() or readPreference in the connection stringmongodb-rs [direct: secondary] unit db.getMongo().setReadPref({mode:secondaryPreferred}) #开启从库读功能
mongodb-rs [direct: secondary] unit db.students.find() #从库正常读取文档
#从库不能写数据mongodb-rs [direct: secondary] unit db.students.insertMany([
... { item: fdfd, qty: 25, tags: [blank, red], size: { h: 14, w: 21, uom: cm } },
... { item: eeeee, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },
... { item: mousephhhhhhhhhhhhhad, qty: 25, tags: [gel, blue], size: { h: 19, w: 22.85, uom: cm } }
... ])
Uncaught:
MongoBulkWriteError: not primary #从库写数据报错了,只能主库写数据
Result: BulkWriteResult {insertedCount: 0,matchedCount: 0,modifiedCount: 0,deletedCount: 0,upsertedCount: 0,upsertedIds: {},insertedIds: {0: ObjectId(6597b7e70c0e47e1f523447d),1: ObjectId(6597b7e70c0e47e1f523447e),2: ObjectId(6597b7e70c0e47e1f523447f)}
}
Write Errors: []
mongodb-rs [direct: secondary] unit #主从切换测试
#停掉主库
docker stop mongo-1
#测试发现有个从库变成主库了既然是主库那么可以写数据
db.students.insertMany([{ item: fdfd, qty: 25, tags: [blank, red], size: { h: 14, w: 21, uom: cm } },{ item: eeeee, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },{ item: mousephhhhhhhhhhhhhad, qty: 25, tags: [gel, blue], size: { h: 19, w: 22.85, uom: cm } }])mongodb-rs [direct: secondary] unit #原来是从库的现在变成主库了,正常读写
mongodb-rs [direct: primary] unit db.students.insertMany([
... { item: fdfd, qty: 25, tags: [blank, red], size: { h: 14, w: 21, uom: cm } },
... { item: eeeee, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },
... { item: mousephhhhhhhhhhhhhad, qty: 25, tags: [gel, blue], size: { h: 19, w: 22.85, uom: cm } }
... ])
{acknowledged: true,insertedIds: {0: ObjectId(6597b8330c0e47e1f5234480),1: ObjectId(6597b8330c0e47e1f5234481),2: ObjectId(6597b8330c0e47e1f5234482)}
}
mongodb-rs [direct: primary] unit db.students.find()#测试再启动停掉的节点节点就会变成从库
#至此,3节点的副本集演示完毕.#使用yum部署mongodb副本集并开启auth
#官方文档
https://www.mongodb.com/docs/manual/tutorial/deploy-replica-set-with-keyfile-access-control/
#先在3台服务器上部署mongodb,这里忽略,参考前面的部署
#配置主机名
cat /etc/hostsEOF
192.168.158.128 mongodb-1
192.168.158.129 mongodb-2
192.168.158.130 mongodb-3
EOF
#官方提示
为避免IP地址变更导致配置更新建议使用DNS主机名代替IP地址。在配置副本集成员或分片集群成员时使用DNS主机名而不是IP地址尤为重要。使用主机名而不是IP地址来配置跨拆分网络水平的集群。从MongoDB 5.0开始只配置了IP地址的节点将无法启动验证并且不会启动。
#副本集使用创建keyfile
openssl rand -base64 756 /etc/mongodbRs-keyfile
chmod 400 /etc/mongodbRs-keyfile
chown mongod.mongod /etc/mongodbRs-keyfile
scp /etc/mongodbRs-keyfile rootmongodb-2:/etc/mongodbRs-keyfile
chown mongod.mongod /etc/mongodbRs-keyfile
scp /etc/mongodbRs-keyfile rootmongodb-3:/etc/mongodbRs-keyfile
chown mongod.mongod /etc/mongodbRs-keyfile#修改配置文件,下面是第一个节点的配置文件,其他节点对应的修改即可
vim /etc/mongod.conf
[rootmongodb-1 ~]# grep -Ev #|$^ /etc/mongod.conf
systemLog: #保持默认即可destination: filelogAppend: truepath: /var/log/mongodb/mongod.log
storage: #保持默认即可dbPath: /var/lib/mongo
processManagement: #保持默认即可timeZoneInfo: /usr/share/zoneinfo
net: #保持默认即可port: 27017bindIp: 127.0.0.1,192.168.158.128,mongodb-1,localhost #这里一定要添加主机名
security: keyFile: /etc/mongodbRs-keyfile #改成keyfile路径
replication:replSetName: mongodb-rs #设置副本集的名称,3个节点副本集名称都要一样
[rootmongodb-1 ~]# #启动mongodb
systemctl start mongod.service
systemctl status mongod.service systemctl enable mongod.service
#登录其中一台初始化
mongosh mongodb://192.168.158.128:27017/
rs.initiate( {_id : mongodb-rs, #副本集的名称与配置文件里面的保持一致members: [ #这里使用IP端口表示mongodb的示例好像也是正常,没有用主机名{ _id: 0, host: 192.168.158.128:27017 },{ _id: 1, host: 192.168.158.129:27017 },{ _id: 2, host: 192.168.158.130:27017 }]
})
#查看副本集的状态
rs.status()#在主节点上创建用户,使用db.createUser()方法添加用户,用户在管理数据库上应该至少拥有userAdminAnyDatabase角色
use admin
db.createUser({user: admin,pwd: admin123,roles: [{ role: root, db: admin }]}
)
#退出重新登录主库
mongosh -u admin -p admin123 --authenticationDatabase admin mongodb://192.168.158.128:27017/
mongodb-rs [direct: primary] test show dbs;
admin 172.00 KiB
config 116.00 KiB
local 404.00 KiB
mongodb-rs [direct: primary] test use unit
switched to db unit
mongodb-rs [direct: primary] unit db.teacher.insertOne({name: Xiaoming,age:50})
{acknowledged: true,insertedId: ObjectId(6597d1b0687bd5fd7aa3707a)
}
mongodb-rs [direct: primary] unit db.teacher.find()
[{_id: ObjectId(6597d1b0687bd5fd7aa3707a),name: Xiaoming,age: 50}
]#登录从库从库开启读
mongosh -u admin -p admin123 --authenticationDatabase admin mongodb://192.168.158.129:27017/
db.getMongo().setReadPref({mode:secondaryPreferred}) #开启从库读功能mongosh -u admin -p admin123 --authenticationDatabase admin mongodb://192.168.158.130:27017/
db.getMongo().setReadPref({mode:secondaryPreferred}) #开启从库读功能#至此,3节点的副本已经部署完成,并且启用了账号密码访问认证功能mongodump工具-备份mongodb
官方文档https://www.mongodb.com/docs/database-tools/mongodump/#versioning
#查看命令帮助
mongodump --help#1、单机备份
#创建备份文件存放目录
mkdir /data/mongodb-backup -p
#格式mongodump options connection-string,其中connection-string可以使用下面3种:
mongodump --urimongodb://mongodb0.example.com:27017 [additional options]
mongodump --hostmongodb0.example.com:27017 [additional options]
mongodump --hostmongodb0.example.com --port27017 [additional options]
#默认会备份全部有文档的库.--gzip表示压缩
mongodump -u admin -p admin123 --authenticationDatabase admin --urimongodb://192.168.158.130:27017/ -o /data/mongodb-backup/$(date %Y%m%d%H%M%S) --gzip
或者
mongodump --host192.168.158.130 --port27017 -u admin -p admin123 --authenticationDatabase admin -o /data/mongodb-backup/$(date %Y%m%d%H%M%S)
或者
mongodump --host192.168.158.130:27017 -u admin -p admin123 --authenticationDatabase admin -o /data/mongodb-backup/$(date %Y%m%d%H%M%S)
#-d是备份指定的库
mongodump -u admin -p admin123 --authenticationDatabase admin --urimongodb://192.168.158.130:27017/ -d unit -o /data/mongodb-backup/$(date %Y%m%d%H%M%S)
#-d是备份指定的库-c指定备份的集合好像只能指定单个集合
mongodump -u admin -p admin123 --authenticationDatabase admin --urimongodb://192.168.158.130:27017/ -d unit -c teachers -o /data/mongodb-backup/$(date %Y%m%d%H%M%S)#2、副本集备份
#格式
mongodump --urimongodb://mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/?replicaSetmyReplicaSetName [additional options]
mongodump --hostmyReplicaSetName/mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com [additional options]
默认情况下mongodb从副本集的主节点读取数据进行备份,当然你也可以指定读优先级来覆盖此默认情况:
mongodump --urimongodb://mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/?replicaSetmyReplicaSetNamereadPreferencesecondary [additional options]
mongodump --urimongodb://mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/?replicaSetmyReplicaSetNamereadPreferencesecondaryreadPreferenceTagsregion:east [additional options]
mongodump --hostmyReplicaSetName/mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017 --readPreferencesecondary [additional options]
mongodump --hostmyReplicaSetName/mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017 --readPreference{mode: secondary, tagSets: [ { region: east } ]} [additional options]
#副本集中每个节点都可以设置节点标签,设置读取优先级时可根据节点标签来指定优先级,关于如何设置节点标签,可参考官网相关内容。#备份例子,其中mongodb-rs是副本集的名称
mkdir /data/mongodb-backup -p
mongodump --hostmongodb-rs/192.168.158.128:27017,192.168.158.129:27017,192.168.158.130:27017 -u admin -p admin123 --authenticationDatabase admin -o /data/mongodb-backup/$(date %Y%m%d%H%M%S)
# 分片集群的备份
#链接的mongos的IP和端口
mongodump --urimongodb://mongos0.example.com:27017 [additional options]
mongodump --hostmongos0.example.com:27017 [additional options]
默认情况下mongodb从shard副本集的主节点读取数据sh.status()命令可以查看哪个是主分片。要覆盖默认值您可以指定读优先级:
mongodump --urimongodb://mongos0.example.com:27017/?readPreferencesecondary [additional options]
mongodump --urimongodb://mongos0.example.com:27017/?readPreferencesecondaryreadPreferenceTagsregion:east [additional options]
mongodump --hostmongos0.example.com:27017 --readPreferencesecondary [additional options]
mongodump --hostmongos0.example.com:27017 --readPreference{mode: secondary, tagSets: [ { region: east } ]} [additional options]#备份示例,链接的是mongos的IP端口
mkdir /data/mongodb-backup -p
mongodump --host10.100.60.150:27017 --authenticationDatabase admin -u root -p root123 -o /data/mongodb-backup/$(date %Y%m%d%H%M%S)
mongodump --host10.100.60.150:27017 --authenticationDatabase admin -u root -p root123 --readPreferencesecondary -o /data/mongodb-backup/$(date %Y%m%d%H%M%S)#查备份的数据
cd /data/mongodb-backup/20240106141006
[rootmongodb-1 20240106141006]# ll
total 0
drwxr-xr-x 2 root root 128 Jan 6 14:10 admin
drwxr-xr-x 2 root root 55 Jan 6 14:10 unit
[rootmongodb-1 20240106141006]# cd unit/
[rootmongodb-1 unit]# ll #
teacher.bson #备份的数据是bson类型的二进制形式的无法正常查看
teacher.metadata.json #元数据.json类型
#使用mongodb-database-tools安装包的bsondump命令解析查看bson数据
bsondump --typejson --outFileteacher.json --bsonFileteacher.bson
cat teacher.json
{_id:{$oid:6597d1b0687bd5fd7aa3707a},name:Xiaoming,age:{$numberInt:50}}分片集群的三大组件
mongodb的分片集群主要包含以下3大组件
1、shard: Each shard contains a subset of the sharded data. As of MongoDB 3.6, shards must be deployed as a replica set.shard:每个shard包含一个分片数据的子集。从MongoDB 3.6开始分片必须作为副本集部署。
2、mongos: The mongos acts as a query router, providing an interface between client applications and the sharded cluster. Starting in MongoDB 4.4, mongos can support hedged reads to minimize latencies.mongos: mongos作为查询路由器提供客户端应用程序和分片集群之间的接口。从MongoDB 4.4开始mongos可以支持对冲读取以最小化延迟。
3、config servers: Config servers store metadata and configuration settings for the cluster. As of MongoDB 3.4, config servers must be deployed as a replica set (CSRS).配置服务器:配置服务器存储集群的元数据和配置设置。从MongoDB 3.4开始配置服务器必须部署为副本集(CSRS)。简单总结就是分片集群包含shard分片、mongos路由器、config servers配置服务器其中分片部署为副本集即最少个3个节点的副本集mongos可以有1个或多个实例,config servers也要部署为3节点的副本集。分片集群的架构
在生产集群中确保数据是冗余的系统是高可用的。对于生产分片集群部署请考虑以下几点: 将Config Servers部署为3个成员的副本集 将每个分片部署为3个成员的副本集分片至少需要两个分片来分发分片后的数据 部署一个或多个mongos路由器 图-分片集群的架构 测试开发可以使用单个实例
部署mongodb分片集群
https://www.mongodb.com/docs/manual/tutorial/deploy-shard-cluster/ 按照上面的图-分片集群的架构如果需要部署一个包含1个mongos、3个shard、1个config server的集群那么最少需要13台服务器这里使用3台服务器来搭建这样一个伪集群。
#参考前面的《Replica Set 副本集模式》中的《使用yum部署mongodb副本集并开启auth》章节以及《linux安装mongodb》
#这里部署的分片集群仅给出基本的配置过程且不开启auth
#我们通过mongod --help命令可以看出,通过指定对应的参数就可以表示该mongodb是什么角色,以及默认的shard、config server端口
Sharding options:--configsvr Declare this is a config db of a cluster; default port 27019; default dir /data/configdb--shardsvr Declare this is a shard db of a cluster; default port 27018#准备3台干净服务器并写入主机名
#从主机名也可以看的出角色分配,即shard-1{1..3}为一组副本集,其他同理
cat /etc/hostsEOF
192.168.158.128 shard-11 shard-21 shard-31 config-server-11 mongodb-1 mongos
192.168.158.129 shard-12 shard-22 shard-32 config-server-12 mongodb-2
192.168.158.130 shard-13 shard-23 shard-33 config-server-12 mongodb-3
EOF
#安装mongodb
sudo yum install -y mongodb-org
#先复制配置文件3台服务器都这样复制
cp /etc/mongod.conf /etc/mongod-shard-1.conf
cp /etc/mongod.conf /etc/mongod-shard-2.conf
cp /etc/mongod.conf /etc/mongod-shard-3.conf
cp /etc/mongod.conf /etc/mongod-config-server.conf#创建Config Server副本集
#编辑配置服务器的配置文件
vim /etc/mongod-config-server.conf
systemLog:destination: filelogAppend: truepath: /var/log/mongodb-config-server/mongod-config-server.log #指定了日志存放路径
storage:dbPath: /var/lib/mongo-config-server #指定数据存放目录
processManagement:timeZoneInfo: /usr/share/zoneinfo
net:port: 27019 #端口默认是27019bindIp: 127.0.0.1,192.168.158.128,config-server-11,localhost #指定绑定的IP
replication:replSetName: config-server #副本集的名称
sharding:clusterRole: configsvr #指定集群角色是配置服务器#3台服务器都创建目录并授权
mkdir /var/lib/mongo-config-server /var/log/mongodb-config-server/ ;
chown mongod.mongod -R /var/lib/mongo-config-server /var/log/mongodb-config-server/
#将配置服务器配置文件复制到其他两台主机上
scp /etc/mongod-config-server.conf rootmongodb-2:/etc/
scp /etc/mongod-config-server.conf rootmongodb-3:/etc/
#注意修改其他两台服务器上的配置文件改成对应的本机的IP和主机名
vim mongod-config-server.conf
#修改service服务文件,使用yum安装的mongodb默认会自动创建了service服务文件但是要修改一下其中的配置文件
cp /usr/lib/systemd/system/mongod.service /usr/lib/systemd/system/mongod-config-server.service
vim /usr/lib/systemd/system/mongod-config-server.service
grep Environment /usr/lib/systemd/system/mongod-config-server.service
EnvironmentOPTIONS-f /etc/mongod-config-server.conf #改这一行即可,指定配置文件
scp /usr/lib/systemd/system/mongod-config-server.service rootmongodb-2:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/mongod-config-server.service rootmongodb-3:/usr/lib/systemd/system/
#启动,3台都启动
systemctl daemon-reload
systemctl start mongod-config-server.service
lsof -i:27019
#登录其中一台mongodb初始化集群
mongosh mongodb://192.168.158.128:27019/
rs.initiate( {_id : config-server,configsvr: true, #指定是配置服务器members: [{ _id: 0, host: config-server-11:27019 },{ _id: 1, host: config-server-12:27019 },{ _id: 2, host: config-server-13:27019 }]
})
#查看副本集的状态
rs.status()
#自此,config-server 3节点搭建完成#创建Shard Replica Sets,先创建分片1
vim /etc/mongod-shard-1.conf
systemLog:destination: filelogAppend: truepath: /var/log/mongo-shard-1/mongo-shard-1.log
storage:dbPath: /var/lib/mongo-shard-1
processManagement:timeZoneInfo: /usr/share/zoneinfo
net:port: 27018 #端口,分片服务器默认端口是27018bindIp: 127.0.0.1,192.168.158.128,shard-11,localhost #绑定的IP地址
replication:replSetName: shard-1 #分片名称
sharding:clusterRole: shardsvr #定义是分片服务器mkdir /var/lib/mongo-shard-1 /var/log/mongo-shard-1/ ;
chown mongod.mongod -R /var/lib/mongo-shard-1 /var/log/mongo-shard-1/ ;
cp /usr/lib/systemd/system/mongod.service /usr/lib/systemd/system/mongod-shard-1.service
vim /usr/lib/systemd/system/mongod-shard-1.service
EnvironmentOPTIONS-f /etc/mongod-shard-1.conf
systemctl daemon-reload
systemctl start mongod-shard-1.service
scp /etc/mongod-shard-1.conf rootmongodb-2:/etc/
vim /etc/mongod-shard-1.conf #注意修改其中的IP地址和主机名为本机IP和主机名
scp /etc/mongod-shard-1.conf rootmongodb-2:/etc/
vim /etc/mongod-shard-1.conf #注意修改其中的IP地址和主机名为本机IP和主机名
scp /usr/lib/systemd/system/mongod-shard-1.service rootmongodb-2:/usr/lib/systemd/system/mongod-shard-1.service
scp /usr/lib/systemd/system/mongod-shard-1.service rootmongodb-3:/usr/lib/systemd/system/mongod-shard-1.service
systemctl daemon-reload
systemctl start mongod-shard-1.service #启动两台服务器mongosh mongodb://192.168.158.128:27018
rs.initiate({_id : shard-1,members: [{ _id : 0, host : shard-11:27018 },{ _id : 1, host : shard-12:27018 },{ _id : 2, host : shard-13:27018 }]}
)
rs.status()#同理,创建分片2和3这里不在演示注意由于我的是都在相同服务器上所以创建分片2和3的端口得改一下即可。
最后,服务器上的端口情况如下
[rootmongodb-1 ~]# netstat -lntup| grep mon | grep 192.168.158.128
tcp 0 0 192.168.158.128:27018 0.0.0.0:* LISTEN 128167/mongod #shard-1
tcp 0 0 192.168.158.128:27019 0.0.0.0:* LISTEN 117996/mongod #config-server
tcp 0 0 192.168.158.128:27028 0.0.0.0:* LISTEN 22133/mongod #shard-2
tcp 0 0 192.168.158.128:27038 0.0.0.0:* LISTEN 30355/mongod #shard-2
[rootmongodb-1 ~]# 至此1个config-server和3个shard已经搭建完成。#创建mongos
mongos --help
cp /etc/mongod.conf /etc/mongos.conf
mkdir -p /var/log/mongos/ ; chown mongod.mongod -R /var/log/mongos/
vim /etc/mongos.conf
systemLog:destination: filelogAppend: truepath: /var/log/mongos/mongos.log
processManagement:timeZoneInfo: /usr/share/zoneinfo
net:port: 27017 #端口bindIp: 127.0.0.1,192.168.158.128,mongos,localhost
sharding: #格式 分片服务器的副本集的名称/分片服务器节点1,分片服务器节点1,分片服务器节点1configDB: config-server/config-server-11:27019,config-server-12:27019,config-server-13:27019cat /usr/lib/systemd/system/mongos.serviceEOF
[Unit]
DescriptionMongoDB Mongos Service
Afternetwork.target[Service]
Usermongod
Groupmongod
ExecStart/usr/bin/mongos --config /etc/mongos.conf
Restartalways
RestartSec3
KillModeprocess
TimeoutStopSec10[Install]
WantedBymulti-user.targetEOF
systemctl daemon-reload
systemctl start mongos.service
lsof -i:27017
#至此mongos.service部署完成#mongosh连接分片集群,这里连接的是mongos的主机或IP端口
mongosh --host mongos --port 27017
#为集群添加分片,使用addShard方法
#前面mongos配置文件我们只是配置了mongos所连接的config-server,还没有为mongos添加分片,现在为集群添加前面我们部署好的3个分片
#格式 sh.addShard( replSetName/s1-mongo1.example.net:27018,s1-mongo2.example.net:27018,s1-mongo3.example.net:27018)
sh.addShard( shard-1/shard-11:27018,shard-12:27018,shard-13:27018)
sh.addShard( shard-2/shard-21:27028,shard-22:27028,shard-23:27028)
sh.addShard( shard-3/shard-31:27038,shard-32:27038,shard-33:27038)
#查看分片集群状态
sh.status()
#创建unit库
test use unit; #切换数据库,如果库不存在并且存在往库里面创建集合等操作则会创建库
#开启库的分片功能
sh.enableSharding(unit)
#创建集合
db.createCollection(teacher)
#分片集合初始化,表示对集合的哪个字段执行哪种分片策略,这里是id字段执行哈希分片
#格式sh.shardCollection(database.collection, { shard key field : hashed } )
sh.shardCollection(unit.teacher,{_id: hashed})
#插入数据测试是否分片正常
db.teacher.insertMany([{ item: journal, qty: 25, tags: [blank, red], size: { h: 14, w: 21, uom: cm } },{ item: mat, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },{ item: mousepad, qty: 25, tags: [gel, blue], size: { h: 19, w: 22.85, uom: cm } },{ item: journal, qty: 25, tags: [blank, red], size: { h: 14, w: 21, uom: cm } },{ item: yat, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },{ item: gtyrnal, qty: 25, tags: [blank, red], size: { h: 14, w: 21, uom: cm } },{ item: drf, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },{ item: werrnal, qty: 25, tags: [blank, red], size: { h: 14, w: 21, uom: cm } },{ item: ljkh, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },{ item: hat, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },
])
#查看数据分布,文档已经均衡的分布在shard1、shard2、shard3上了
db.teacher.getShardDistribution()#至此,分片集群已经搭建完成k8s搭建mongodb分片集群
官方给的k8s安装mongodb是使用operator安装的而且是企业版不是社区版。这里使用bitnami仓库的chart包来部署mongodb分片集群。 首先有一个完整的k8s集群且有默认存储类。默认已经搭建完成。
#添加常用的helm仓库
helm repo add mongodb https://mongodb.github.io/helm-charts #这个是mongodb官方的helm仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add stable http://mirror.azure.cn/kubernetes/charts
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
helm repo update
[rootmaster mongodb-sharded]# helm search repo mongodb | grep -vi DEPRECATED
NAME CHART VERSION APP VERSION DESCRIPTION
aliyun/mongodb 0.4.27 3.7.1 NoSQL document-oriented database that stores JS...
aliyun/mongodb-replicaset 2.3.1 3.6 NoSQL document-oriented database that stores JS...
bitnami/mongodb 14.4.10 7.0.5 MongoDB(R) is a relational open source NoSQL da...
bitnami/mongodb-sharded 7.2.1 7.0.5 MongoDB(R) is an open source NoSQL database tha...
mongodb/mongodb-atlas-operator 2.0.1 2.0.1 MongoDB Atlas Operator - a Helm chart for insta...
mongodb/mongodb-atlas-operator-crds 2.0.1 2.0.1 MongoDB Atlas Operator CRDs - Helm chart for in...
mongodb/atlas-cluster 0.1.9 0.8.1 A Helm chart to manage Atlas resources with Atl...
mongodb/atlas-deployment 1.0.1 1.0.0 A Helm chart to manage Atlas resources with Atl...
mongodb/community-operator 0.9.0 0.9.0 MongoDB Kubernetes Community Operator
mongodb/community-operator-crds 0.9.0 0.9.0 MongoDB Kubernetes Community Operator - CRDs
mongodb/enterprise-database 1.13.0 MongoDB Kubernetes Enterprise Database.
mongodb/enterprise-operator 1.24.0 MongoDB Kubernetes Enterprise Operator
mongodb/sample-app 0.1.0 0.1.0 A sample application to install in your Kuberne...
#我们下载bitnami的bitnami/mongodb-sharded chart包,这里不使用mongodb官方的operator
helm pull bitnami/mongodb-sharded
tar xf mongodb-sharded-7.2.1.tgz
cd mongodb-sharded
#修改配置文件,下面讲解主要修改的参数,其他参数保持默认即可
vim values.yaml
global.storageClass: nfs-storageclass #指定存储类
auth.enabled: true #开启认证,默认开启,保持默认即可
auth.rootUser: root #mongodb的超级管理员root用户
rootPassword: root123 #指定root用户密码,需自定义
shards: 3 #自定义分片数量,默认是2,建议最少是两个,因为两个shard才存在分片的意义
common.containerPorts.mongodb: 27017 #容器里mongodb端口,不管是config server还是shard,容器里都是这个端口
configsvr.replicaCount: 3 #config server的pod副本数,默认只有1个config server.
mongos.replicaCount: 1 #mongos的数量,可以定义多个,默认1个,默认mongos不需要持久化数据
shardsvr.dataNode.replicaCount: 3 #shard的节点数,即3个pod组成一个shard分片副本集
#从templates目录下的config-server、shard、mongos目录下的模板我们可以得知,
#默认只会创建一个config server,mongos的数量也是默认1个,shard分片的数量可以在values.yaml定义每个shard分片包含的pod节点数也可在values.yaml定义,在上面的定义中我们最终创建的mongodb分片集群将会是包含1个mongos,1个config server,config server由3个pod组成副本集,3个shard分片,每个shard分片有3个pod组成副本集.#安装mongodb分片集群
helm install mongodb . -n default
#查看pod,1个mongos,1个config server,config server由3个pod组成副本集,3个shard分片,每个shard分片有3个pod组成副本集
[rootmaster ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mongodb-mongodb-sharded-configsvr-0 1/1 Running 0 13m #config server的第1个pod节点
mongodb-mongodb-sharded-configsvr-1 1/1 Running 0 11m #config server的第2个pod节点
mongodb-mongodb-sharded-configsvr-2 1/1 Running 0 10m #config server的第3个pod节点
mongodb-mongodb-sharded-mongos-7b958d479f-jz6hd 1/1 Running 0 13m #mongos
mongodb-mongodb-sharded-shard0-data-0 1/1 Running 0 13m #shard0的第1个pod节点
mongodb-mongodb-sharded-shard0-data-1 1/1 Running 0 6m1s #shard0的第2个pod节点
mongodb-mongodb-sharded-shard0-data-2 1/1 Running 0 2m15s #shard0的第3个pod节点
mongodb-mongodb-sharded-shard1-data-0 1/1 Running 0 13m #shard1的第1个pod节点
mongodb-mongodb-sharded-shard1-data-1 1/1 Running 0 12m #shard1的第2个pod节点
mongodb-mongodb-sharded-shard1-data-2 1/1 Running 0 11m #shard1的第3个pod节点
mongodb-mongodb-sharded-shard2-data-0 1/1 Running 0 13m #shard2的第1个pod节点
mongodb-mongodb-sharded-shard2-data-1 1/1 Running 0 10m #shard2的第2个pod节点
mongodb-mongodb-sharded-shard2-data-2 1/1 Running 0 6m21s #shard2的第3个pod节点
[rootmaster ~]# kubectl get sts
NAME READY AGE
mongodb-mongodb-sharded-configsvr 3/3 22m
mongodb-mongodb-sharded-shard0-data 3/3 22m
mongodb-mongodb-sharded-shard1-data 3/3 22m
mongodb-mongodb-sharded-shard2-data 3/3 22m
# mongodb创建了两个service
# mongodb-mongodb-sharded的标签选择器是对应于mongos的,所以该svc用于内部其他应用链接mongodb
# mongodb-mongodb-sharded-headless是config server和shard内部的pod组成副本集使用的
[rootmaster ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mongodb-mongodb-sharded ClusterIP 10.100.60.150 none 27017/TCP 21m
mongodb-mongodb-sharded-headless ClusterIP None none 27017/TCP 21m
[rootmaster ~]# kubectl get sts -oyaml| grep serviceName #可以看到config server和shard都使用了相同的无头服务serviceName: mongodb-mongodb-sharded-headlessserviceName: mongodb-mongodb-sharded-headlessserviceName: mongodb-mongodb-sharded-headlessserviceName: mongodb-mongodb-sharded-headless
[rootmaster ~]# #登录config server的第1个pod节点
kubectl exec -it mongodb-mongodb-sharded-configsvr-0 -- bash
mongosh mongodb://127.0.0.1:27017 --authenticationDatabase admin -u root -p root123
rs.status() #查看是3个members表示正常
#登录shard0的第1个pod节点
kubectl exec -it mongodb-mongodb-sharded-shard0-data-0 -- bash
mongosh mongodb://127.0.0.1:27017 --authenticationDatabase admin -u root -p root123
rs.status() #查看是3个members表示正常
#登录shard1的第1个pod节点
kubectl exec -it mongodb-mongodb-sharded-shard1-data-0 -- bash
mongosh mongodb://127.0.0.1:27017 --authenticationDatabase admin -u root -p root123
rs.status() #查看是3个members表示正常
#登录shard2的第1个pod节点
kubectl exec -it mongodb-mongodb-sharded-shard2-data-0 -- bash
mongosh mongodb://127.0.0.1:27017 --authenticationDatabase admin -u root -p root123
rs.status() #查看是3个members表示正常#插入文档,链接的mongodb-mongodb-sharded,该svc对应的pod是mongos
[rootmongodb-1 ~]# kubectl get svc mongodb-mongodb-sharded
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mongodb-mongodb-sharded ClusterIP 10.100.60.150 none 27017/TCP 43m
#链接到分片集群
mongosh mongodb://10.100.60.150:27017 --authenticationDatabase admin -u root -p root123
#查看分片集群状态
sh.status()
#创建/切换unit库
use unit;
#开启库的分片功能
sh.enableSharding(unit)
#创建集合
db.createCollection(teacher)
#分片集合初始化,表示对集合的哪个字段执行哪种分片策略,这里是id字段执行哈希分片
#格式sh.shardCollection(database.collection, { shard key field : hashed } )
sh.shardCollection(unit.teacher,{_id: hashed})
#插入数据测试是否分片正常
db.teacher.insertMany([{ item: journal, qty: 25, tags: [blank, red], size: { h: 14, w: 21, uom: cm } },{ item: mat, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },{ item: mousepad, qty: 25, tags: [gel, blue], size: { h: 19, w: 22.85, uom: cm } },{ item: journal, qty: 25, tags: [blank, red], size: { h: 14, w: 21, uom: cm } },{ item: yat, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },{ item: gtyrnal, qty: 25, tags: [blank, red], size: { h: 14, w: 21, uom: cm } },{ item: drf, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },{ item: werrnal, qty: 25, tags: [blank, red], size: { h: 14, w: 21, uom: cm } },{ item: ljkh, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },{ item: hat, qty: 85, tags: [gray], size: { h: 27.9, w: 35.5, uom: cm } },
])
#查看数据分布,文档已经均衡的分布在shard1、shard2、shard3上了
db.teacher.getShardDistribution()#至此,k8s搭建的mongodb分片集群已经搭建完成分片集群-总结
分片集群其实就是把文档均分在每个shard上而每个shard又是由3个副本集构成副本集直接相互同步数据。 这样当你单独登录某个shard查询文档此时查看到的文档肯定是不全的仅仅是部分文档主要登录mongos时查询的文档才是最全的所以分片集群都是使用mongos的IP和端口进行登录链接mongodb。 在使用mongodump命令备份分片集群时链接的是mongos的IP端口所以备份的肯定是全部的文档不在乎你是从主还是secondary shard读取的数据。