当前位置: 首页 > news >正文

mongodb学习篇

目录

    • 前言
    • 基本概念
      • 数据库-database
      • 集合-collection
      • 文档-document
    • 部署mongodb
      • linux安装mongodb
      • docker安装mongodb
    • MongoDB Shell (mongosh)命令行工具
    • mongodb可视化-mongodb-compass、mongo-express
    • mongodb配置文件
    • 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/SELINUX=enforcing/SELINUX=disabled/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]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/7/mongodb-org/7.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://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 'exclude=mongodb-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/SELINUX=enforcing/SELINUX=disabled/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.log"logAppend: 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]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network-online.target
Wants=network-online.target[Service]
User=mongod
Group=mongod
Environment="OPTIONS=-f /etc/mongod.conf"
Environment="MONGODB_CONFIG_OVERRIDE_NOFORK=1"
EnvironmentFile=-/etc/sysconfig/mongod
ExecStart=/usr/local/bin/mongod $OPTIONS
RuntimeDirectory=mongodb
# 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
#现在用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
[root@node1 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 mongosh

MongoDB 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/foo

mongodb可视化-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容器
[root@node2 ~]# 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
#查看容器,状态正常
[root@node2 ~]# 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
[root@node2 ~]# 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
[root@node2 ~]# 
#在浏览器访问mongo-express
http://192.168.158.130:8081

mongodb配置文件

如果是使用yum安装的mongodb,则默认的配置文件为/etc/mongod.conf。下面简单讲解一下配置文件的关键参数。

#更多配置参数请查看官网:https://www.mongodb.com/docs/manual/reference/configuration-options/
[root@node2 ~]# 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:
[root@node2 ~]# 
#更多配置参数请查看官网: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 item="planner"
比较运算符
```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 status="A" and qty<30
这样也能显示的表示逻辑与,但是不建议: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 status="A" or qty<30# 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(),  #提示输入密码,也可以直接指定字符串密码,如"admin123"roles: [{ 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: enabled

2、如果是直接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 --auth

4、使用管理员账号密码登录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个mongos,1个config server,config 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 secondaryOk=false - 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/hosts<<'EOF'
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 root@mongodb-2:/etc/mongodbRs-keyfile
chown mongod.mongod /etc/mongodbRs-keyfile
scp /etc/mongodbRs-keyfile root@mongodb-3:/etc/mongodbRs-keyfile
chown mongod.mongod /etc/mongodbRs-keyfile#修改配置文件,下面是第一个节点的配置文件,其他节点对应的修改即可
vim /etc/mongod.conf
[root@mongodb-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个节点副本集名称都要一样
[root@mongodb-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 --uri="mongodb://mongodb0.example.com:27017" [additional options]
mongodump --host="mongodb0.example.com:27017"  [additional options]
mongodump --host="mongodb0.example.com" --port=27017 [additional options]
#默认会备份全部有文档的库.--gzip表示压缩
mongodump -u "admin" -p "admin123" --authenticationDatabase admin --uri=mongodb://192.168.158.130:27017/ -o /data/mongodb-backup/$(date "+%Y%m%d%H%M%S") --gzip
或者
mongodump --host=192.168.158.130  --port=27017 -u "admin" -p "admin123" --authenticationDatabase admin  -o /data/mongodb-backup/$(date "+%Y%m%d%H%M%S")  
或者
mongodump --host=192.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 --uri=mongodb://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 --uri=mongodb://192.168.158.130:27017/ -d unit -c teachers -o /data/mongodb-backup/$(date "+%Y%m%d%H%M%S")
#2、副本集备份
#格式
mongodump --uri="mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/?replicaSet=myReplicaSetName" [additional options]
mongodump --host="myReplicaSetName/mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com" [additional options]
默认情况下,mongodb从副本集的主节点读取数据进行备份,当然你也可以指定读优先级来覆盖此默认情况:
mongodump --uri="mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/?replicaSet=myReplicaSetName&readPreference=secondary" [additional options]
mongodump --uri="mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/?replicaSet=myReplicaSetName&readPreference=secondary&readPreferenceTags=region:east" [additional options]
mongodump --host="myReplicaSetName/mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017" --readPreference=secondary [additional options]
mongodump --host="myReplicaSetName/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 --host="mongodb-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 --uri="mongodb://mongos0.example.com:27017" [additional options]
mongodump --host="mongos0.example.com:27017" [additional options]
默认情况下,mongodb从shard副本集的主节点读取数据(sh.status()命令可以查看哪个是主分片)。要覆盖默认值,您可以指定读优先级:
mongodump --uri="mongodb://mongos0.example.com:27017/?readPreference=secondary" [additional options]
mongodump --uri="mongodb://mongos0.example.com:27017/?readPreference=secondary&readPreferenceTags=region:east" [additional options]
mongodump --host="mongos0.example.com:27017" --readPreference=secondary [additional options]
mongodump --host="mongos0.example.com:27017" --readPreference='{mode: "secondary", tagSets: [ { "region": "east" } ]}' [additional options]#备份示例,链接的是mongos的IP端口
mkdir /data/mongodb-backup -p
mongodump --host="10.100.60.150:27017" --authenticationDatabase admin -u root -p root123   -o /data/mongodb-backup/$(date "+%Y%m%d%H%M%S")
mongodump --host="10.100.60.150:27017" --authenticationDatabase admin -u root -p root123 --readPreference=secondary  -o /data/mongodb-backup/$(date "+%Y%m%d%H%M%S")
#查备份的数据
cd /data/mongodb-backup/20240106141006
[root@mongodb-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
[root@mongodb-1 20240106141006]# cd unit/
[root@mongodb-1 unit]# ll		#
teacher.bson					#备份的数据是bson类型的,二进制形式的无法正常查看
teacher.metadata.json			#元数据.json类型
#使用mongodb-database-tools安装包的bsondump命令解析查看bson数据
bsondump --type=json --outFile=teacher.json --bsonFile=teacher.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/hosts<<'EOF'
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  root@mongodb-2:/etc/
scp /etc/mongod-config-server.conf  root@mongodb-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
Environment="OPTIONS=-f /etc/mongod-config-server.conf"		#改这一行即可,指定配置文件 
scp /usr/lib/systemd/system/mongod-config-server.service root@mongodb-2:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/mongod-config-server.service root@mongodb-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
Environment="OPTIONS=-f /etc/mongod-shard-1.conf"
systemctl  daemon-reload
systemctl  start mongod-shard-1.service 
scp /etc/mongod-shard-1.conf root@mongodb-2:/etc/
vim /etc/mongod-shard-1.conf	#注意修改其中的IP地址和主机名为本机IP和主机名
scp /etc/mongod-shard-1.conf root@mongodb-2:/etc/
vim /etc/mongod-shard-1.conf	#注意修改其中的IP地址和主机名为本机IP和主机名
scp /usr/lib/systemd/system/mongod-shard-1.service root@mongodb-2:/usr/lib/systemd/system/mongod-shard-1.service
scp /usr/lib/systemd/system/mongod-shard-1.service root@mongodb-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的端口得改一下即可。
最后,服务器上的端口情况如下:
[root@mongodb-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    
[root@mongodb-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.service<<'EOF'
[Unit]
Description=MongoDB Mongos Service
After=network.target[Service]
User=mongod
Group=mongod
ExecStart=/usr/bin/mongos --config /etc/mongos.conf
Restart=always
RestartSec=3
KillMode=process
TimeoutStopSec=10[Install]
WantedBy=multi-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
[root@master 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组成副本集
[root@master ~]# 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节点
[root@master ~]# 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组成副本集使用的
[root@master ~]# 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
[root@master ~]# 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
[root@master ~]# #登录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
[root@mongodb-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读取的数据。

相关文章:

mongodb学习篇

目录 前言基本概念数据库-database集合-collection文档-document 部署mongodblinux安装mongodbdocker安装mongodb MongoDB Shell (mongosh)命令行工具mongodb可视化-mongodb-compass、mongo-expressmongodb配置文件mongodb库、集合、文档库基本操作集合基本操作文档的增删改查C…...

kubernetes存储类迁移-备份恢复

背景介绍 kubernetes集群最开始使用了nfs作为存储&#xff0c;随着后续使用过程中数据量逐渐增加&#xff0c;nfs存储性能逐步出现不足&#xff0c;现增加了基于csi的分布式块存储后&#xff0c;需要对原有基于nfs存储类下的pv迁移到新的存储类下。 测试环境 k8s集群版本&am…...

python智能手机芯片

在未来&#xff0c;python智能手机芯片的发展方向可能包括以下几个方面&#xff1a; 强化处理能力&#xff1a;随着智能手机功能的不断扩展和用户需求的增加&#xff0c;处理器的性能需求也在不断提升。未来的python智能手机芯片可能会加强处理器的核心数量和频率&#xff0c;以…...

混淆技术概论

混淆技术概论 引言 在逆向工程领域&#xff0c;混淆技术是一种非常重要的技术手段&#xff0c;通过打破人们的思维惯性&#xff0c;使得逆向分析变得更加困难。本文将会介绍混淆技术的概念、分类及其应用&#xff0c;以及如何使用IPA Guard进行iOS IPA重签名。 混淆技术概述…...

pytest安装失败,报错Could not find a version that satisfies the requirement pytest

问题 安装pytest失败&#xff0c;尝试使用的命令有 pip install pytest pip3 install pytest pip install -U pytest pip install pytest -i https://pypi.tuna.tsinghua.edu.cn/simple但是都会报同样的错&#xff1a; 解决方案 发现可能是挂了梯子的原因&#xff0c;关掉…...

使用 Maven 的 dependencyManagement 管理项目依赖项

使用 Maven 的 dependencyManagement 管理项目依赖项 介绍 在开发 Java 项目时&#xff0c;管理和协调依赖项的版本号是一项重要而繁琐的任务。 而 Maven 提供了 <dependencyManagement> 元素&#xff0c;用于定义项目中所有依赖项的版本。它允许您指定项目中每个依赖…...

三英战吕布web3游戏项目启动全流程

项目是一个学习相关的很好的例子并且开源&#xff0c;原本的项目是连接goerli网络&#xff0c;但我把它修改为可连接ganache网络的项目了&#xff0c;更方便启动。 智能合约部分 进入文件 hardhat.config.js &#xff0c;增加一个钱包私钥 2.执行npm install 3.测试合约 npx ha…...

TS中的类

目录 ES6的类 类的概念 类的构成 类的创建 声明 构造函数 定义内容 创建实例 TS中的类 类声明 构造函数 属性和方法 实例化类 继承 访问修饰符 public private protected 成员访问修饰符的使用原则 访问器 只读成员与静态成员 readonly static 修饰符总…...

玩转硬件之玩改朗逸中控设备

这是一个有关一件被拆卸的朗逸中控设备的故事。这个设备已经闲置多年&#xff0c;但是它的命运发生了转变。它被改装成了一台收音机和MP3播放器。 这个设备曾经是一辆朗逸的中控屏幕&#xff0c;就是因为它没有倒车影像&#xff0c;它就被拆了下来&#xff0c;被扔在了一个角落…...

根据MySql的表名,自动生成实体类,模仿ORM框架

ORM框架可以根据数据库的表自动生成实体类&#xff0c;以及相应CRUD操作 本文是一个自动生成实体类的工具&#xff0c;用于生成Mysql表对应的实体类。 新建Winform窗体应用程序AutoGenerateForm&#xff0c;框架(.net framework 4.5)&#xff0c; 添加对System.Configuration的…...

Mac上安装tensorflow介绍留存

此预版本为 macOS 11.0 提供了硬件加速的 TensorFlow 和 TensorFlow 插件。M1 Mac 和基于 Intel 的 Mac 通过 Apple 的 ML 计算框架支持本机硬件加速。 TensorFlow r2.4rc0TensorFlow Addons 0.11.2 TensorFlow 插件 0.11.2 REQUIREMENTS 要求 macOS 11.0Python 3.8 (requir…...

【赠书第16期】码上行动:用ChatGPT学会Python编程

文章目录 前言 1 ChatGPT简介 2 Python编程简介 3 使用ChatGPT学习Python编程 4 如何使用ChatGPT学习Python编程 5 推荐图书 6 粉丝福利 前言 随着人工智能技术的不断发展&#xff0c;聊天机器人已经成为我们日常生活和工作中不可或缺的一部分。其中&#xff0c;ChatGP…...

LeetCode 每日一题 2024/1/1-2024/1/7

记录了初步解题思路 以及本地实现代码&#xff1b;并不一定为最优 也希望大家能一起探讨 一起进步 目录 1/1 1599. 经营摩天轮的最大利润1/2 466. 统计重复个数1/3 2487. 从链表中移除节点1/4 2397. 被列覆盖的最多行数1/5 1944. 队列中可以看到的人数1/6 2807. 在链表中插入最…...

7+单细胞+空转+实验验证,如何根据内容开展相关经验给你启发

导语 今天给同学们分享一篇生信文章“CD8 tissue-resident memory T cells induce oral lichen planus erosion via cytokine network”&#xff0c;这篇文章发表在Elife期刊上&#xff0c;影响因子为7.7。 结果解读&#xff1a; 单细胞RNA测序揭示了具有不同临床亚型的OLP的细…...

Verifiable Credentials可验证证书 2023 终极指南

1. 引言 Dock公司为去中心化数字身份领域的先驱者&#xff0c;其自2017年以来&#xff0c;已知专注于构建前沿的可验证证书&#xff08;Verifiable Credentials&#xff09;技术。本文将阐述何为电子证书、电子证书工作原理、以及其对组合和个人的重要性。 伪造实物证书和数字…...

R语言【sp】——SpatialPoints():创建类SpatialPoints或SpatialPointsDataFrame的对象

Package sp version 1.5-0 Description 从坐标或数据帧的坐标创建类 SpatialPoints-class 或 SpatialPointsDataFrame-class 的对象。 Usage SpatialPoints(coords, proj4stringCRS(as.character(NA)), bbox NULL)SpatialPointsDataFrame(coords, data, coords.nrs numeric…...

【Verilog】期末复习——简要说明仿真时阻塞赋值和非阻塞赋值的区别。always语句和initial语句的关键区别是什么?能否相互嵌套?

系列文章 数值&#xff08;整数&#xff0c;实数&#xff0c;字符串&#xff09;与数据类型&#xff08;wire、reg、mem、parameter&#xff09; 运算符 数据流建模 行为级建模 结构化建模 组合电路的设计和时序电路的设计 有限状态机的定义和分类 期末复习——数字逻辑电路分…...

分享一个idea插件MyBatisX的Bug

分享一个idea插件MyBatisX的Bug The plugin com.baomidou.plugin.idea. mybatisx failed to save settings and has been disabled. Please restart IntelliJ IDEAjava.lang.Throwableat com.intellij.openapi.project.DumbServiceImpl.queueTask(DumbServiceImpl.java:293)at…...

Linux网络

一、Linux网络 查看基础的网络配置 网关、路由&#xff1a;route —n 网关、路由route —nIP地址ifconfig ip aDNS 服务器cat /etc/resolv.conf主机名hostname网络连接状态ss、netstat、syn—sent域名解析nalookup、host 1.1 ifconfig 网络接口配置 临时性修改网卡 …...

Copilot 插件的使用介绍:如何快速上手

GitHub Copilot 本文主要介绍如何通过脚本工具激活 GitHub Copilot 插件&#xff0c;提供安装及激活图文教程&#xff0c;大家按下面操作即可激活GitHub Copilot插件&#xff0c;免费使用Ai编码工具 一、GitHub Copilot 介绍 GitHub Copilot 是由 GitHub 和 OpenAI 共同开发的…...

kubesphere和k8s的使用分享

文章目录 什么是kubernetesKubernetes的部分核心概念互式可视化管理平台与kubernetes的关系市面是常见的kubernetes管理平台 什么是kubesphereKubesphere默认安装的组件Kubesphere涉及的服务组件kubesphere的安装Kubesphere相关的内容 什么是kubernetes 就在这场因“容器”而起…...

macos m1如何安装指定版本的redis

安装指定版本的Redis在macOS M1上可以通过Homebrew进行操作。Homebrew是一个在macOS上管理软件包的常用工具。 要安装特定版本的Redis&#xff0c;请首先确保已经安装了Homebrew。然后&#xff0c;可以通过以下步骤安装指定版本的Redis&#xff1a; 步骤&#xff1a; 查找可用…...

python 多线程 守护线程

daemon线程&#xff1a;守护线程&#xff0c;优先级别最低&#xff0c;一般为其它线程提供服务。通常&#xff0c;daemon线程体是一个无限循环。如果所有的非daemon线程(主线程以及子线程&#xff09;都结束了&#xff0c;daemon线程自动就会终止。t.daemon 属性&#xff0c;设…...

以unity技术开发视角对android权限的讲解

目录 前言 Android权限分类 普通权限 普通权限定义 普通权限有哪些 危险权限 危险权限的定义 危险权限有哪些 动态申请权限实例 申请单个权限实例 第一步&#xff1a;在清单文件中声明权限 第二步&#xff1a;在代码中进行动态申请权限 申请多个权限实例 第一步&am…...

910b上跑Chatglm3-6b进行流式输出【pytorch框架】

文章目录 准备阶段避坑阶段添加代码结果展示 准备阶段 配套软件包Ascend-cann-toolkit和Ascend-cann-nnae适配昇腾的Pytorch适配昇腾的Torchvision Adapter下载ChatGLM3代码下载chatglm3-6b模型&#xff0c;或在modelscope里下载 避坑阶段 每个人的服务器都不一样&#xff0…...

2024年江苏省职业院校技能大赛高职学生组软件测试—任务五接口测试题目

2024年江苏省职业院校技能大赛高职学生组软件测试任务五 接口测试 任务要求 题目1&#xff1a;登录接口脚本编写和执行测试。 1、登录接口描述如下&#xff1a; 接口功能&#xff1a;提供用户登录功能处理&#xff0c;根据传入的用户名和密码判断登录状态。 接口地址&…...

螺旋数字矩阵 - 华为OD统一考试

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 100分 题解&#xff1a; Java / Python / C 题目描述 疫情期间&#xff0c;小明隔离在家&#xff0c;百无聊赖&#xff0c;在纸上写数字玩。他发明了一种写法: 给出数字个数n和行数m (0 < n < 999&#xff0c;…...

更改ERPNEXT源

更改ERPNEXT源 一&#xff0c; 更改源 针对已经安装了erpnext的&#xff0c;需要更改源的情况&#xff1a; 1, 更改为官方默认源, 进入frapp-bench的目录&#xff0c; 然后执行: bench remote-reset-url frappe //重设frappe的源为官方github地址。 bench remote-reset-url…...

配置基本QinQ示例

QinQ简介 定义 QinQ&#xff08;802.1Q-in-802.1Q&#xff09;技术是一项扩展VLAN空间的技术&#xff0c;通过在802.1Q标签报文的基础上再增加一层802.1Q的Tag来达到扩展VLAN空间的功能&#xff0c;可以使私网VLAN透传公网。由于在骨干网中传递的报文有两层802.1Q Tag&#x…...

界面控件DevExpress Blazor Grid v23.2 - 支持全新的单元格编辑模式

DevExpress Blazor UI组件使用了C#为Blazor Server和Blazor WebAssembly创建高影响力的用户体验&#xff0c;这个UI自建库提供了一套全面的原生Blazor UI组件&#xff08;包括Pivot Grid、调度程序、图表、数据编辑器和报表等&#xff09;。 在这篇文章中&#xff0c;我们将介…...

大连网站制作 姚喜运/杭州优化公司在线留言

凌晨四点的东方是什么样子的&#xff0c;这个世界上恐怕只有科比和加班的程序员知道。 如果不是隔壁的高楼挡住了我的视线&#xff0c;我想东方的鱼肚白一定被我尽收眼底。想想都很多年没有去亲眼看日出了&#xff0c;但j是这却是这近一年第四次通宿加班了&#xff0c;也是游戏…...

在手机上怎么注册公司/一个网站可以优化多少关键词

智能家居网络随着集成技术、通信技术、互操作能力和布线标准的实现而不断改进。它涉及对家庭网络内所有的智能家具、设备和系统的操作、管理以及集成技术的应用 。其技术特点表现如下&#xff1a; 1&#xff0e;通过家庭网关及其系统软件建立智能家居平台系统 家庭网关是智能…...

怎么知道网站有没有备案/2345网址导航删除办法

React 路由理解: 什么是路由&#xff1f;1: 一个路由就是一个映射关系(key: value);2: key: 为路径, value: 为function 或者component路由的分类:后端路由: 理解为: value是 functuion, 用来处理客户提交的请求。注册路由: router.get(path, (ctx, next)> {});工作过程: 当…...

企业网站商城/2345浏览器影视大全

官方资源Vue官方网站 Vue.js&#xff01;Vue官方教程介绍 — Vue.js&#xff01;&#xff01;本文的官方视频教程&#xff1a;Vue.js 教程Vue是什么&#xff1f;Vue是一个前端网页js文件。里面提供了很多好用的功能&#xff0c;如果你的前端HTML页面包含了这个文件&#xff0c;…...

做耳鼻喉医院网站多少钱/嘉兴seo外包公司费用

通常&#xff0c;我们用ArcGIS批量出图的时候&#xff0c;需要借助“数据驱动页面”这个功能&#xff0c;以某个图层作为分幅框&#xff0c;在布局视图下批量输出分幅框内的图形。 “数据驱动页面”可以基于单个地图文档方便快捷地创建一系列布局页面&#xff0c;要素图层或索…...

wordpress中文 apP/线上营销推广方式都有哪些

格式内容清洗 1.格式内容清洗产生的原因 数据是由人工收集或用户填写而来,格式内容可能存在问题不同版本的程序产生的内容或格式不一致不同数据源采集的数据内容和格式定义不一致2.时间、日期格式不一致清洗 根据实际情况,把时间/日期转换成统一的表示方式 日期格式不一致:…...