MongoDB私人学习笔记
俗话说“好记性不如烂笔头”,编程的海洋如此的浩大,养成做笔记的习惯是成功的一步!
此笔记主要是ZooKeeper3.4.9版本的笔记,并且笔记都是博主自己一字一字编写和记录,有错误的地方欢迎大家指正。
一、基础知识:
1、MongoDB的名称来源于Humongous Database,中文意思就是巨大无比的数据库,顾名思义,MongoDB就是为处理大数据而生, 以解决海量数据的存储和高效查询使用为使命。是NoSQL数据库的一种,是基于文档保存数据的形式,有C++语言编写的开源数据库系统。MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成,MongoDB 文档类似于 JSON 对象,有数值、字符串、布尔值、日期、数组、对象ID等类型,字段值还可以包含其他文档,数组及文档数组。
官方网址:https://www.mongodb.com
2、MongoDB通常在如下情形下考虑使用:
1)用作操作日志的记录,例如用户在网站上的操作行为记录。
2)记录的数据是比较松散,没有统一结构的形式的数据。因为MongoDB本身存储的数据是不需要有强硬的结构化。
3)大尺寸、低价值的数据,例如日志信息、大量的消息推送记录等数据。
4)高伸缩性的场景,因为MongoDB性能高,并且非常容易扩展,有着强大的集群功能。
注意:MongoDB本身不支持事务和多表(文档)的级联,故如果有此需求的场景,不应该使用MongoDB。
3、mongodb3.2.11-linux-x86_64-rhel70-3.2.11.tgz是基于Linux readHead系统的安装文件(CentOS系统也适合使用)。mongodb-linux-x86_64-2.4.9.tgz是旧版本的安装文件,留着备用。
注意:此笔记都是基于3.2.11版本来记录的。
mongodb.conf是基本的配置文件,本身压缩包是没有创建配置文件的,需要自己去创建。
jar_lib文件夹存放的是java连接MongoDB的jar包。jar包下载地址http://central.maven.org/maven2/org/mongodb/mongo-java-driver/
4、Mongodb与传统的关系型数据的术语对应关系:
RDBMS(关系型数据库管理系统) MongoDB
数据库 数据库
表格 集合
行 文档
列 字段
表联合 嵌入文档
主键 主键 (MongoDB 提供了 key 为 _id)
5、MongoDB默认的服务端口是27017,默认的数据库文档存储路径为 /data/db,默认情况下只允许本地通过127.0.0.1地址来访问,
如果允许通过其他ip地址来访问,则需要配置bind_ip=0.0.0.0,开放通过所有地址均可访问。
6、MongoDB的特性:
(1)对于单个文档,MongoDB的操作是原子性的,即操作单个文档是数据安全的。
(2)本身不支持事务,但是可以通过组合一些命令来达到简单的事务效果,但是无法实现复杂的事务情形。
可以参考官方网站的例子,通过两阶段提交来实现简单的事务效果。
地址:https://docs.mongodb.com/manual/tutorial/perform-two-phase-commits
(3)MongoDB默认的数据库标识是自动生成的,字段名称为_id,值为ObjectId类型,并且ObjectId内部的值是唯一的。
如果在存储数据时指定了_id字段,那么将不再自定生成。存储的格式例子:
{ "_id" : ObjectId("583c6a7a9abb612322fd08c8"), "2" : true, "a" : 1 }
{ "_id" : ObjectId("583c6be49abb612322fd08c9"), "2" : true, "a" : 1 }
{ "_id" : 123, "a" : 1 }
如果手动设置ObjectId类型,长度必须要求为24位。
(4)MongoDB的shell脚本操作使用的是JavaScript脚本语言,故拥有JavaScript语言的特性,例如区分大小写,单双引号的使用,
浮点型数值精度丢失,定制JSON对象等。
7、MongoDB的集群:
1、replica set 通过副本集的方式来达到集群的效果,但是仅仅没有负载均衡的能力。由一个主节点多个从节点的形式组成,默认所以的读写操作都在主节点上(可以设置从节点拥有读的能力,但不可以设置写操作),数据会自动同步
到从节点。当主节点宕机后,会自动选取从节点升级为主节点,接替主节点的工作,故拥有容灾备份的能力,
但是因为同一时刻只有一个主节点,所以没有负载均衡的能力。
2、sharding 通过分片区的方式来达到负载均衡的效果,但是没有容灾备份的能力。将数据进行分片,由多个服务器来分别承担分片数据,通过路由计算规则来觉得存储的数据所在的分区位置,故客户端对数据的读写操作,可能分到不同的片区由不同的服务器来处理,达到了负载均衡的能力,但是如果有个别片区的服务宕机了,那么就无法提供这一片区的数据服务,没有容灾备份的能力。
3、sharding + replica set 集合分片区和副本集的特性,将其整合在一起,使得既有容灾备份的效果,又有负载均衡的能力。相当于将sharding分片区进行分组,每个分片区组都存储完整的数据,一个组就相当于一个副本集,建立多个组就相当于有多个副本集,当一个组的sharding分片区有服务器宕机时,其他组的sharding分片区服务器能马上代替其工作。
附加:主从节点的数据复制是根据oplog(operation log)操作日志来同步的,从节点读取主节点的oplog来更新自己的数据库。oplog达到指定大小时,会滚动到文件头重新记录,覆盖掉以前的操作日志,故oplog的空间不能过于小,导致从节点同步数据丢失。
8、mongodb自带有命令形式的客户端,可以通过mongo命令登录进行操作mongodb。如果需要图形界面来操作,则需要额外安装图形界面的应用来支持,或者使用图形工具软件来连接。常用的有如下几款:
MongoDBCompass(官方版):地址为 https://www.mongodb.com/try/download/compass?jmp=docs
Robo 3T(原名:Robomongo)
mongobooster
二、使用笔记:
1、最简单的形式启动服务:
解压mongodb3.2.11-linux-x86_64-rhel70-3.2.11.tgz后,进入解压后的bin目录,执行如下命令便可以简单的启动MongoDB服务:
./mongod --dbpath=/usr/user/mongodb-linux-x86_64-rhel70-3.2.11/data/db
注意:--dbpath是指定数据库路径,必须要先创建好该路径目录。
MongoDB的数据库文档默认是存储在/data/db目录下的,如果没有预先创建好该目录会启动报错。
注意是mongod命令,不是mongo命令,bin目录下有两个名字非常相近的命令,但功能是完全不同的。
附加:MongoDB关闭服务的方式:
(1)执行mongod命令来关闭 ./mongod --shutdown --dbpath=/usr/user/mongodb-linux-x86_64-rhel70-3.2.11/data/db
必须要指定好正确的db路径,因为停止服务时要移除数据库的锁标识。
(2)进入mongo的shell操作工具(执行命令./mongo 127.0.0.1:27021来进入操作工作),切换到admin数据库来停止服务。
use admin
db.shutdownServer()
(3)查询进程进行kill掉。
ps -ef|grep mongo
kill 进程号
2、进入bin目录,可以通过 ./mongod -h 来查看更多的可执行参数,"mongod命令可以使用的参数列表.txt"就是可以执行的参数列表。
3、通过指定配置文件来启动服务:
进入解压的目录,执行命令: ./bin/mongod --config mongodb.conf
其中mongodb.conf是自己创建的配置文件(注意文件路径),其中最基本的配置内容有:
#数据库路径
dbpath=/usr/local/mongodb/db
#日志路径
logpath=/usr/local/mongodb/logs/mongodb.log
#以追加方式写入日志
logappend=true
#默认的服务端口
port=27017
#后台形式运行服务,使用此形式必须要配置日志路径
fork=true
#禁用http查看界面。默认就是关闭的。
nohttpinterface=true
4、MongoDB的http查看界面,是通过web形式展现的,默认是没开启此功能的,需要配置 nohttpinterface=false
如果想让web界面提供更多的功能,需要在启动时指定 -rest参数,如: ./bin/mongod --config mongodb.conf -rest
本地启动该服务后,可以在web查看到所有的命令 http://localhost:28017/_commands
5、常用命令:
(1)普通命令:
show dbs 查看所有的数据库
use mydb 使用mydb数据库
show collections 查看当前数据库下的所有集合(表)
db 当前数据库引用,对数据库的操作都需要db开头
db.stats() 查看当前数据库的状态
db.version() 使用的MongoDB版本号。
db.getMongo() 查看当前连接数据库的地址。
db.mydb.isCapped() 查看当前集合是否固定长度的集合。
db.createCollection("mydb") 创建集合,默认创建的是非固定长度的集合。
db.createCollection("mydb",{capped:true,size:10000,max:1000}) 创建固定长度的集合,size表示集合大小,max表示文档数。
db.runCommand({"convertToCapped":"mydb",size:10000}) 将已存在的mydb集合转换为固定长度的集合。
(2)删除命令
db.dropDatabase() 删除当前数据库。
db.col_name.drop() 删除集合。col_name是集合名词。
db.collection.remove(<query>,{justOne: <boolean>,writeConcern: <number>})
query :(可选)删除的文档的条件。
justOne : (可选)如果设为 true 或 1,则只删除一个文档。默认为false,即删除所有符合条件的文档。
writeConcern :(可选)抛出异常的级别。有-1,0,1,2级别,默认级别是1,即如果写入失败则立刻返回错误。
例子:
删除mycoll集合下的所有数据。
db.mycoll.remove({})
删除标题为mongo的所有数据。
db.mycoll.remove({"title":"mongo"})
删除标题为mongo的第一条数据。
db.mycoll.remove({"title":"mongo"},true)
(3)新增命令
db.mycoll.insert({'key01':'val01','key02':'val02'})
插入数据到mycoll集合中,如果该集合不存在,则会新建一个。
db.mycoll.save({'_id':ObjectId("56064f89ade2f21f36b03136"),'key01':'val01','key02':'val02'})
保存数据。如果有_id=56064f89ade2f21f36b03136的数据,即数据已经存在,则直接进行替换,否则就插入新的数据。
(4)更新命令
db.collection.update(<query>,<update>,{upsert: <boolean>,multi: <boolean>,writeConcern: <number>})
query : update的查询条件,类似sql update查询内where后面的。如果需要更新所有数据,则直接传入{}空json对象。
update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
writeConcern :可选,抛出异常的级别。
例子:
替换title为mongo的第一条数据,注意是替换形式,既把title为mongo的记录直接就变为title:"newMongoDB",states:"ok"。
db.mycoll.update({title:"mongo"},{title:"newMongoDB",states:"ok"},false)
更新title为mongo的第一条数据,使用了$set操作符,注意不是替换,是局部更新。
db.mycoll.update({title:"mongo"},{$set:{title:"newMongoDB",states:"ok"}})
更新title为mongo的所有数据。ps:如果该数据没有states字段,那么就好新增此字段,如果有就直接更新。
db.mycoll.update({title:"mongo"},{$set:{title:"newMongoDB",states:"ok"}},false,true)
更新title为mongo的的数据,如果不存在任何的记录,则插入更新的数据。
db.mycoll.update({title:"mongo"},{$set:{title:"newMongoDB",states:"ok"}},true,false)
更新所有的数据,所有money字段的值+1,如果money字段不存在,则新增money字段,值设置为1。
db.col.update({},{$inc:{"money":1}},{multi:true})
注意:在更新数据时,对于已经存在的字段则进行更新操作,如果该数据没有更新的字段,则会新增此字段。
(5)查询命令
db.mycoll.find() 查询mycoll集合的所有文档。
db.mycoll.findOne() 查询当前mycoll集合的文档,只获取第一条数据,并美化后才输出。
db.mycoll.find().pretty() 查询mycoll集合的所有文档,并美化后才输出。
db.mycoll.find().limit(<num>) 限制条数查询。num是限制的条数,如果没输入任何数值,则默认查询全部。
db.mycoll.find().skip(<num>) 对查询结果跳过指定的条数。num是限制的条数,如果没输入任何数值,则默认不跳过任何条数。
ps:附加命令pretty、limit等命令,是可以组合在一起使用的。
db.col.find().sort({<key>:-1}) 查询结果进行排序。key是排序字段,值-1表示降序,1表升序。可以使用多个字段按顺序排序。
ps:如果数据没有该排序字段,则认为是属于最小值,降序中排在最后。
find()和findOne()都可以带条件查询,查询的条件:
AND条件: db.mycoll.find({title:"mongo",state:"ok"}) 查询title="mongo" AND state="ok"的数据。
OR条件: db.mycoll.find({$or:[{title:"mongo"},{state:"ok"}]}) 查询title="mongo" OR state="ok"的数据。
IN关键字:db.mycoll.find({_id:{$in:[1,2,3,4]}}) 查询_id为1,2,3,4中任何一个数值的数据。
等于: {<key>:<value>} db.col.find({"by":"菜鸟教程"}) 相当于where by = '菜鸟教程'
等于写法2: {<key>:{$eq:<value>}} db.col.find({"by":{$eq:"mon"}}) 相当于where by = 'mon'
小于: {<key>:{$lt:<value>}} db.col.find({"likes":{$lt:50}}) 相当于where likes < 50
小于或等于: {<key>:{$lte:<value>}} db.col.find({"likes":{$lte:50}}) 相当于where likes <= 50
大于: {<key>:{$gt:<value>}} db.col.find({"likes":{$gt:50}}) 相当于where likes > 50
大于或等于: {<key>:{$gte:<value>}} db.col.find({"likes":{$gte:50}}) 相当于where likes >= 50
不等于: {<key>:{$ne:<value>}} db.col.find({"likes":{$ne:50}}) 相当于where likes != 50
类型查询:{<key>:{$type:<value>}} db.col.find({"likes":{$type:2}}) 查询likes字段值类型是String字符串类型的,类型详见附加。
正则表达式:{<key>:{$type:/<value>/}} db.col.find({"name":/^china/i}) 查询name名称已china开头并且不区分大小写的数据。
正则表达式写法2: db.col.find({"name":{$regex:"^china",$options:"$i"}}) 查询name名称已china开头并且不区分大小写的数据。
其他例子:
查询 title="mongo" AND (state="OK" OR date=ISODate("2016-11-29T02:48:10.115Z"))的数据
db.mycoll.find({title:"mongo",$or:[{state:"ok"},{date:ISODate("2016-11-29T02:48:10.115Z")}]})
查询 (title="mongo" AND state="OK") OR (date=ISODate("2016-11-29T02:48:10.115Z"))的数据
db.mycoll.find({$or:[{title:"mongo",state:"ok"},{date:ISODate("2016-11-29T02:48:10.115Z")}]})
find()和findOne()可以指定输出的字段:
查询标题为mongo的数据,并且只显示title和falg字段值,其中_id是默认显示的。
db.mycoll.find({"title":"mongo"},{title:1,flag:1})
查询第一条数据,并且只显示title和falg字段值,_id不显示。
db.mycoll.findOne({},{_id:0,title:1,flag:1})
(6)索引命令
db.collection.ensureIndex({<key>:-1}}, <option>) 给集合创建索引。当数据量大时,必须创建索引才能加快查询速度,注意默认_id没有加入索引的。
例子:
给mycol的title字段创建升序索引,给description字段创建降序索引,相当于传统数据库的联合索引,注意字段顺序。
db.mycoll.ensureIndex({"title":1,"description":-1})
给mycol的title字段创建升序索引,并且通过后台运行的方式来创建。ps:创建索引时会阻塞其他数据库操作,可通过后台方式来防止此情况。
db.mycoll.ensureIndex({open: 1}, {background: true})
给mycol的title字段创建升序索引,后台方式运行,并且要求title是唯一索引。dropDups表示相同的title记录是否删除,默认不删除。
db.mycoll.ensureIndex({title: 1}, {background: true,unique:true,dropDups:false})
提示:如果查询的数据字段都是同一个索引的一部分,那么直接是从索引中获取查询结果,而无需再查找文档,速度将非常的快。
例如:创建索引db.users.ensureIndex({gender:1,user_name:1}) ,然后查询db.users.find({gender:"M"},{user_name:1,_id:0})。
注意:集合中索引不能超过64个,索引名的长度不能超过125个字符,一个复合索引最多可以有31个字段。可以通过explain()来查看查询是否使用了索引。
(7)聚合命令
db.collection.aggregate(<option>) 聚合操作主要用于处理数据(例如统计、计算平均值等),并返回处理结果。
例子:
根据money字段进行分组,并统计出各分组的总金额。ps:$group操作符,_id字段是必须要写的,表示分组字段。
db.mycol.aggregate({$group:{_id:"$money",total:{$sum:"$money"}}})
先用match进行数据过滤,要求金额必须大于21小于等于60,然后对其数据进行分组,统计出总数量。
注意_id:null表示所以数据合并为一个分组。此处使用了MongoDB的概念,对match操作后的数据给group进一步操作。
db.col.aggregate([{$match:{money:{$gt:21,$lte:60}}},{$group:{_id:null,count:{$sum:1}}}])
对文档数据输出进行定制。$project操作符就是修改输出的数据。只输出_id,money,flag字段的数据,
其余字段一律不输出,并且flag的数据来源于state字段,相当于给输出字段修改名称。
db.col.aggregate({$project:{_id:1,money:1,flag:"$state"}})
6、特殊的命令详解:
(1)insert和save的区别:
insert 是直接插入数据,如果主键已经存在,则会报_id_ dup key主键重复的异常,导致插入失败。
save 也是插入数据,但是如果主键已经存在,则是直接进行更新。
(2)save和update的区别:
save 如果数据存在,则是直接进行替换,而非局部更新。
update 如果没有指定$set操作符,则和svae功能一样,是属于直接替换。
如果使用了$set操作符,则只对指定的字段进行更新,属于局部更新,并且可以同时更新多条数据。
7、MongoDB的备份与恢复:
(1)备份操作:
mongodump -h dbhost -d dbname -o dbdirectory
-h:MongDB所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017
-d:需要备份的数据库实例,例如:test
-o:备份的数据存放位置,例如:c:\data\dump,当然该目录需要提前建立,在备份完成后,
系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据。
(2)恢复操作:
mongorestore -h dbhost -d dbname --directoryperdb dbdirectory
-h:MongoDB所在服务器地址
-d:需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2
--directoryperdb:备份数据所在位置,例如:c:\data\dump\test。
--drop:恢复的时候,先删除当前数据,然后恢复备份的数据。慎用!
8、MongoDB自带的监控工具:
(1)状态监测工具:
mongostat
(2)操作耗时监测工具:
mongotop <num>
<num> 是监测间隔,表示多少秒一次获取监测数据,默认1秒。
9、默认情况下,mongodb是不需要验证的,如果要开启验证,则需要在配置文件中设置并且创建账号密码,步骤如下:
(1)进入其中一个数据库(通常是使用默认的admin库):use admin
(2)创建用户:
db.createUser({user:"admin",pwd:"tcljr@*2020",roles:["root"]})
db.createUser({user:"tcljr",pwd:"tcljr@*2020",roles:["readWrite"]})
db.createUser({user:"riskmg",pwd:"tcljr@*2020",roles:[{role:"readWrite",db:"sit-riskmg"}]})
说明:如果没有指定db,则默认是使用当前数据库名的集合。如果需要给不同数据库创建用户,需要切换到不同数据库后再创建。
(3)在配置文件中,将auth=true,然后重启mongodb服务。
(4)通过moongodb的shell客户端进入 ./bin/mongo 10.0.112.35:27017
(5)切换到对应数据库,然后进行验证:
use admin
db.auth("admin","tcljr@*2020")
注意:必须要先选择数据库,如果选择的数据库不正确,即使账号密码正确都会认证失败。
说明:如果不进行验证,则是无法查看数据库和数据的,例如show dbs会不显示任何数据库。
(6)如果是有使用副本集群,如果开启了auth=true认证,则必须要配置认证文件keyFile,否则集群节点之间无法通讯。
keyFile文件可通过 openssl rand -base64 1024 > mongodb.key 来生成,生成的字符长度如果超过1024,则可以手动删除一部分。
三、java使用MongoDB的方式:
1、http://central.maven.org/maven2/org/mongodb/mongo-java-driver/
2、SpringBoot整合mongodb:
(1)增加maven依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
(2)配置application.yml文件:
spring:
data:
#mongodb配置(集群配置(也可以用于单机))
mongodb:
uri: mongodb://10.0.112.35:27017,10.0.112.35:27018,10.0.112.36:27017,10.0.112.36:27018,10.0.112.37:27017/riskmg
#mongodb配置(单机配置)
(3)直接注入MongoTemplate依赖即可使用:
@Resource
private MongoTemplate mongoTemplate;
/*************************************************************附加*******************************************************/
1、MongoDB 中可以使用的类型如下表所示:
类型 数字
Double 1
String 2
Object 3
Array 4
Binary data 5
Undefined 6 已废弃。
Object id 7
Boolean 8
Date 9
Null 10
Regular Expression 11
JavaScript 13
Symbol 14
JavaScript (with scope) 15
32-bit integer 16
Timestamp 17
64-bit integer 18
Min key 255 Query with -1.
Max key 127
2、原子操作常用命令
$set
用来指定一个键并更新键值,若键不存在并创建。
{ $set : { field : value } }
$unset
用来删除一个键。
{ $unset : { field : 1} }
$inc
$inc可以对文档的某个值为数字型(只能为满足要求的数字)的键进行增减的操作。
{ $inc : { field : value } }
$push
用法:
{ $push : { field : value } }
把value追加到field里面去,field一定要是数组类型才行,如果field不存在,会新增一个数组类型加进去。
$pushAll
同$push,只是一次可以追加多个值到一个数组字段内。
{ $pushAll : { field : value_array } }
$pull
从数组field内删除一个等于value值。
{ $pull : { field : _value } }
$addToSet
增加一个值到数组内,而且只有当这个值不在数组内才增加。
$pop
删除数组的第一个或最后一个元素
{ $pop : { field : 1 } }
$rename
修改字段名称
{ $rename : { old_field_name : new_field_name } }
$bit
位操作,integer类型
{$bit : { field : {and : 5}}}
3、原子操作数据模型
考虑下面的例子,图书馆的书籍及结账信息。
实例说明了在一个相同的文档中如何确保嵌入字段关联原子操作(update:更新)的字段是同步的。
book = {
_id: 123456789,
title: "MongoDB: The Definitive Guide",
author: [ "Kristina Chodorow", "Mike Dirolf" ],
published_date: ISODate("2010-09-24"),
pages: 216,
language: "English",
publisher_id: "oreilly",
available: 3,
checkout: [ { by: "joe", date: ISODate("2012-10-15") } ]
}
你可以使用 db.collection.findAndModify() 方法来判断书籍是否可结算并更新新的结算信息。
在同一个文档中嵌入的 available 和 checkout 字段来确保这些字段是同步更新的:
db.books.findAndModify ( {
query: {
_id: 123456789,
available: { $gt: 0 }
},
update: {
$inc: { available: -1 },
$push: { checkout: { by: "abc", date: new Date() } }
}
} )
4、ObjectId类型
(1)ObjectId 是一个12字节 BSON 类型数据,有以下格式:
前4个字节表示时间戳
接下来的3个字节是机器标识码
紧接的两个字节由进程id组成(PID)
最后三个字节是随机数。
(2) 手动创建ObjectId对象:myobj = new ObjectId() 或者myobj = ObjectId()
(3)ObjectId的可操作api:
ObjectId("5349b4ddd2781d08c09890f4").getTimestamp() 获取对象时间戳。
new ObjectId().str 获取对象标识的字符串格式。
5、实现_id的自增长
MongoDB的主键id不支持数值自增长的形式,可以通过编写自定义函数来实现。
//自定义增长的函数
function getNextSequenceValue(sequenceName){
var sequenceDocument = db.counters.findAndModify(
{
query:{_id: sequenceName },
update: {$inc:{sequence_value:1}},
new:true //new 表示返回个性化后的文档
});
return sequenceDocument.sequence_value;
}
//使用方式
db.mycol.insert({"_id":getNextSequenceValue("productid"), "product_name":"Samsung S3","category":"mobiles"})
6、MongoDB的副本集配置:
步骤一:创建多个数据库目录。
进入/usr/user/mongodb-linux-x86_64-rhel70-3.2.11/目录,创建dbs目录,然后进入dbs目录,
创建db01、db02、db03、arb目录。
步骤二:启动MongoDB服务。
./bin/mongod --dbpath /usr/user/mongodb-linux-x86_64-rhel70-3.2.11/dbs/db01 --port 27017 --replSet myrs
./bin/mongod --dbpath /usr/user/mongodb-linux-x86_64-rhel70-3.2.11/dbs/db02 --port 27018 --replSet myrs
./bin/mongod --dbpath /usr/user/mongodb-linux-x86_64-rhel70-3.2.11/dbs/db03 --port 27019 --replSet myrs
./bin/mongod --dbpath /usr/user/mongodb-linux-x86_64-rhel70-3.2.11/dbs/arb --port 30000 --replSet myrs
步骤三:使用mongo的shell登录到其中一个服务端。
./bin/mongo 10.17.2.61:27017
步骤四:在mongo的shell中初始化副本集。
//创建配置对象。注意host主机地址切勿填写为localhost本地地址,将会导致java客户端连接出异常。
var config={_id:"myrs",members:[{_id:1,host:"10.17.2.61:27017"},{_id:2,host:"10.17.2.61:27018"},{_id:3,host:"10.17.2.61:27019"}]}
//初始化。注意只能初始化一次,mongodb会将初始化后的数据写入文件,下次重新启动服务不用再初始化。
rs.initiate(config)
注意:
rs开头表示是对replica set 副本集的操作。initiate方法只运行初始化一次。
如果想修改config配置,可以使用rs.reconfig(config:{force:true})来强制更改配置。
执行完配置后,可以通过rs.config()来看配置情况,rs.status()来查看集群状态。
步骤五:添加arbiter仲裁节点。
arbiter仲裁节点不备份数据,只是再当主服务器宕机时,有仲裁节点来选定从节点哪个变为主节点。
如果没有仲裁节点,从节点将自己从内部选取,故可以不需要仲裁节点,但要求节点数必须是奇数,如果是偶数则必须要仲裁节点。
rs.addArb("10.17.2.61:30000")
提示:如果需要动态的添加节点或删除节点,可以使用rs.add("host:port")命令来添加副本集节点,
删除从节点或者仲裁节点使用rs.remove("host:port")。
步骤六:指定一个主节点。
默认情况下,当前所以节点都是从节点,可以使用rs.status()来查看状态。
登录需要指定为主节点的mongo的shell客户端,执行命令rs.isMaster() 来提升当前节点为主节点。
提示:默认从节点是不可以做读写的,可以设置为运行从节点进行读操作,但写操作是一直都禁止的。
登录从节点的mongo的shell客户端,执行命令 rs.slaveOk(),注意只是针对当前会话的设置,
如果退出重进,需要重新执行这个命令。
步骤七:测试。
可以将主节点的进程kill掉,可以看到从节点有一个自动提升为主节点。
提升:当有节点宕机后,其他节点还是会定时的发布心跳来检测节点是否恢复,会打印大量的日志信息,需要处理好日志级别。
步骤八:java客户端连接副本集。
Builder builder = MongoClientOptions.builder();
builder.serverSelectionTimeout(3000000);
builder.requiredReplicaSetName("myrs");
builder.readConcern(readCon);
builder.writeConcern(writeCon);
MongoClientOptions op = builder.build();
/*多个副本集节点,指定多个ip地址。必须有一一列举副本集节点的ip,
*MongoClient客户端之后在指定ip的副本集读取和操作数据,如果没有指定,即使他也是副本集的一个,也不会拿取数据。
*下面的ip中,即使有一个ip的服务宕机了,也不影响操作,可以继续提供服务。
*/
List<ServerAddress> list = new ArrayList<ServerAddress>();
list.add(new ServerAddress("10.17.2.61", 27017));
list.add(new ServerAddress("10.17.2.61", 27018));
list.add(new ServerAddress("10.17.2.61", 27019));
list.add(new ServerAddress("10.17.2.61", 30000));
MongoClient client = new MongoClient(list, op);
相关文章:
MongoDB私人学习笔记
俗话说“好记性不如烂笔头”,编程的海洋如此的浩大,养成做笔记的习惯是成功的一步! 此笔记主要是ZooKeeper3.4.9版本的笔记,并且笔记都是博主自己一字一字编写和记录,有错误的地方欢迎大家指正。 一、基础知识…...
Ant Design按钮样式深度适配:实现<Button>与<a>标签颜色完美同步
Ant Design按钮样式深度适配:实现与标签颜色完美同步 问题现象诊断 组件结构原型 <Button type"link" disabled{disabled}><a href"...">下载</a> </Button>样式冲突表现 状态按钮颜色链接颜色视觉问题启用态Ant蓝…...
linux下软件安装、查找、卸载
目录 常见安装方式有三种: 1.源码安装。 2.rpm安装方式。 3.yum/apt工具级别安装。 对于前两种安装方式,因为软件可能有依赖关系(安装的软件依赖于某些库,而这些库又依赖于某些库,这些都需要手动安装)…...
鸿蒙开发深入浅出01(基本环境搭建、页面模板与TabBar)
鸿蒙开发深入浅出01(基本环境搭建、页面模板与TabBar) 1、效果展示2、下载 DevEco Studio3、创建项目4、新建页面模板5、更改应用信息6、新建以下页面7、Index.ets8、真机运行9、图片资源文件 1、效果展示 2、下载 DevEco Studio 访问官网根据自己的版本…...
【DeepSeek】-macOS本地终端部署后运行DeepSeek如何分析图片
【DeepSeek】-macOS本地终端部署后运行DeepSeek如何分析图片 根据您的需求,目前需要了解以下几个关键点及分步解决方案: --- 一、现状分析 1. Ollama 的限制: - 目前Ollama主要面向文本大模型,原生不支持直接上传/处理图片 …...
微信小程序源码逆向 MacOS
前言 日常工作中经常会遇到对小程序的渗透测试,微信小程序的源码是保存在用户客户端本地,在渗透的过程中我们需要提取小程序的源码进行问题分析,本篇介绍如何在苹果电脑 MacOS 系统上提取微信小程序的源码。 0x01 微信小程序提取 在苹果电…...
2025年2月科技热点深度解析:AI竞赛、量子突破与开源革命
引言 2025年的科技领域持续呈现爆发式增长,AI大模型竞争白热化、量子计算商业化加速、开源工具生态繁荣成为本月最受关注的议题。本文结合最新行业动态,从技术突破、商业布局到开发者生态,全面解析当前科技热点,为读者提供深度洞…...
Wireshark简单教程
1.打开Wireshark,点击最上面栏目里面的“捕获”中的“选项” 2.进入网卡选择界面,选择需要捕获的选择,这里我选择WLAN 3.双击捕获选择出现下面界面 4.点击如下图红方框即可停止捕获 5.点击下图放大镜可以进行放大 6.你也可以查询tcp报文如下图...
stm32单片机个人学习笔记16(SPI通信协议)
前言 本篇文章属于stm32单片机(以下简称单片机)的学习笔记,来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记,只能做参考,细节方面建议观看视频,肯定受益匪浅。 STM32入门教程-2023版 细…...
面试题——简述Vue 3的服务器端渲染(SSR)是如何工作的?
面试题——简述Vue3的服务器端渲染(SSR)是如何工作的? 服务器端渲染(SSR)已经成为了一个热门话题。Vue 3,作为一款流行的前端框架,也提供了强大的SSR支持。那么,Vue 3的SSR究竟是如何…...
Ubuntu 22.04安装K8S集群
以下是Ubuntu 22.04安装Kubernetes集群的步骤概要 一、设置主机名与hosts解析 # Master节点执行 sudo hostnamectl set-hostname "k8smaster" # Worker节点执行 sudo hostnamectl set-hostname "k8sworker1"# 所有节点的/etc/hosts中添加: ca…...
Ubuntu搭建esp32环境 配置打开AT指令集 websocket功能
1,搭建前提 环境搭建参考乐鑫官网给的本地编译 ESP-AT 工程方法 因为公司电脑和网络的特殊性,不能正确解析域名(仅在浏览器上可以访问) ,所以这边访问的时候改成了ssh 未了避免使用外网困难的问题,这里用…...
java八股文-消息队列
一、MQ基础篇 1. 什么是消息队列? 消息队列(MQ)是分布式系统中实现异步通信的中间件,解耦生产者和消费者。 2. 使用场景有哪些? 异步处理(如注册后发送邮件)系统解耦(不同服务通过…...
[晕事]今天做了件晕事65,gcc,cmake, pragam
文章目录 晕事cmake,unity,对gcc pragma指令有没有影响pragma指令的影响pragma指令的使用规范使用注意事项:晕事 最近在某些不能有优化的函数前加了指令 #pragma GCC optimize ("O0")我记得是这个指令只影响当前编译单元。 但是被人找上来了, 因为这个文件所牵…...
SAP-ABAP:使用ST05(SQL Trace)追踪结构字段来源的步骤
ST05 是 SAP 提供的 SQL 跟踪工具,可以记录程序运行期间所有数据库操作(如 SELECT、UPDATE、INSERT)。通过分析跟踪结果,可以精准定位程序中结构字段对应的数据库表。 步骤1:激活ST05跟踪 事务码 ST05 → 点击 Activa…...
STM32--SPI通信讲解
前言 嘿,小伙伴们!今天咱们来聊聊STM32的SPI通信。SPI(Serial Peripheral Interface)是一种超常用的串行通信协议,特别适合微控制器和各种外设(比如传感器、存储器、显示屏)之间的通信。如果你…...
cpu、mem监控
deepseek 1、安装依赖2、psutil库3、streamlit库4、实战4.1 单机CPU和内存使用率监控4.2 多机CPU和内存使用率监控 1、安装依赖 /usr/bin/python3 -m pip install psutil streamlit2、psutil库 psutil是一个跨平台的Python库,用于获取系统使用情况的信息…...
工程实践中常见的几种设计模式解析及 C++ 实现
工程实践中常见的几种设计模式解析及 C 实现 在软件工程中,设计模式是一种通用的解决方案,用于解决常见问题和优化代码结构。它们通过提供一种规范化的编程思想,帮助开发者写出更高效、可维护和可扩展的代码。本文将介绍几种在工程实践中常见…...
ollama在linux上进行部署——离线安装说明
1. 官网下载ollama压缩包 https://ollama.com/download/ollama-linux-amd64.tgz sudo tar -C /usr -xzf ollama-linux-amd64.tgz #解压安装 2. 添加systemctl服务启动文件 添加服务文件:/etc/systemd/system/ollama.service [Unit] DescriptionOllama …...
(一)趣学设计模式 之 单例模式!
目录 一、啥是单例模式?二、为什么要用单例模式?三、单例模式怎么实现?1. 饿汉式:先下手为强! 😈2. 懒汉式:用的时候再创建! 😴3. 枚举:最简单最安全的单例&a…...
基于无人机遥感的烟株提取和计数研究
一.研究的背景、目的和意义 1.研究背景及意义 烟草作为我国重要的经济作物之一,其种植面积和产量的准确统计对于烟草产业的发展和管理至关重要。传统的人工烟株计数方法存在效率低、误差大、难以覆盖大面积烟田等问题,已无法满足现代烟草种植管理的需求…...
在windows下安装windows+Ubuntu16.04双系统(上)
这篇文章的内容主要来源于这篇文章,给文章很详细的介绍了如何从windows下安装windowsubuntu16.04双系统。我刚开始装双系统都是参照这个方法,该作者前后更新了两个版本,在这里对其稍微进行整理一下。 一、准备:(这里推…...
TensorFlow 是一个由 Google 开发的开源机器学习库
TensorFlow 是一个由 Google 开发的开源机器学习库,被广泛应用于深度学习和人工智能领域。它的基本概念包括以下几点: 张量(Tensors):在 TensorFlow 中,数据的基本单位是张量,它类似于多维数组或…...
C++ day4 练习
一、练习1 找到第一天mystring练习,实现以下功能: mystring str "hello"; mystring ptr "world"; str str ptr; str ptr; str[0] H; 【代码】: #include <iostream> #include <cstring> #include &l…...
利用机器学习实现实时交易欺诈检测
以下是一个基于Python的银行反欺诈AI应用示例代码,演示如何利用机器学习实现实时交易欺诈检测。该示例使用LightGBM算法训练模型,并通过Flask框架构建实时检测API: python import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preproc…...
基于Hadoop的汽车大数据分析系统设计与实现【爬虫、数据预处理、MapReduce、echarts、Flask】
文章目录 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主 项目介绍爬虫数据概览HIve表设计Cars Database Tables 1. cars_data2. annual_sales_volume3. brand_sales_volume4. city_sales_volume5. sales_volume_by_year_and_brand6. sales_distri…...
安宝特科技 | Vuzix Z100智能眼镜+AugmentOS:重新定义AI可穿戴设备的未来——从操作系统到硬件生态,如何掀起无感智能革命?
一、AugmentOS:AI可穿戴的“操作系统革命” 2025年2月3日,Vuzix与AI人机交互团队Mentra联合推出的AugmentOS,被业内视为智能眼镜领域的“iOS时刻”。这款全球首个专为智能眼镜设计的通用操作系统,通过三大突破重新定义了AI可穿戴…...
蓝桥杯之日期题
文章目录 1.蓝桥杯必备知识点2. 题型13.需求2 1.蓝桥杯必备知识点 蓝桥杯是一个面向全国高校计算机相关专业学生的学科竞赛,涵盖多个赛道,常见的有软件类(如 C/C 程序设计、Java 软件开发、Python 程序设计)和电子类(…...
sklearn中的决策树-分类树:实例-分类树在合成数据集上的表现
分类树实例:分类树在合成数据集上的表现 代码分解 在不同结构的据集上测试一下决策树的效果(二分型,月亮形,环形) 导入 import numpy as np from matplotlib import pyplot as plt from matplotlib.colors import Li…...
es-head(es库-谷歌浏览器插件)
1.下载es-head插件压缩包,并解压缩 2.谷歌浏览器添加插件 3.使用...
AI客服-接入deepseek大模型到微信(本地部署deepseek集成微信自动收发消息)
1.本地部署 1.1 ollama Ollama软件通过其高度优化的推理引擎和先进的内存管理机制,显著提升了大型语言模型在本地设备上的运行效率。其核心采用了量化技术(Quantization)以降低模型的计算复杂度和存储需求,同时结合张量并行计算&…...
kotlin 知识点 七 泛型的高级特性
对泛型进行实化 泛型实化这个功能对于绝大多数Java 程序员来讲是非常陌生的,因为Java 中完全没有这个概 念。而如果我们想要深刻地理解泛型实化,就要先解释一下Java 的泛型擦除机制才行。 在JDK 1.5之前,Java 是没有泛型功能的,…...
正则表达式–断言
原文地址:正则表达式–断言 – 无敌牛 欢迎参观我的个人博客:正则表达式特殊字符 – 无敌牛 断言assertions 1、(?...):正向预查(positive lookahead),表示某个字符串后面应该跟着什么。但这个字符串本身…...
OceanBase数据库实战:Windows Docker部署与DBeaver无缝对接
一、前言 OceanBase 是一款高性能、高可扩展的分布式数据库,适用于大规模数据处理和企业级应用。 随着大数据和云计算的普及,OceanBase 在企业数字化转型中扮演着重要角色。学习 OceanBase 可以帮助开发者掌握先进的分布式数据库技术,提升数…...
C++:开胃菜练习项目---定长内存池的实现以及测试
项目介绍 简介 作为学习tcmalloc高并发内存池项目前的一个铺垫。 作为程序员(C/C)我们知道申请内存使用的是malloc,malloc其实就是一个通用的大众货,什么场景下都可以用,但是什么场景下都可以用就意味着什么场景下都不会有很高的性能…...
【LLM】本地部署LLM大语言模型+可视化交互聊天,附常见本地部署硬件要求(以Ollama+OpenWebUI部署DeepSeekR1为例)
【LLM】本地部署LLM大语言模型可视化交互聊天,附常见本地部署硬件要求(以OllamaOpenWebUI部署DeepSeekR1为例) 文章目录 1、本地部署LLM(以Ollama为例)2、本地LLM交互界面(以OpenWebUI为例)3、本…...
JVM相关面试题
1. 类加载与双亲委派机制 聊一下你对类加载器的理解。 类加载器是JVM用来加载类文件到内存的组件。它负责将字节码文件解析为java.lang.Class实例,并存储到运行时数据区的方法区中。类加载器分为Bootstrap ClassLoader、Extension ClassLoader和Application ClassLo…...
WordPress Course Booking System SQL注入漏洞复现 (CVE-2025-22785)(附脚本)
免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x0…...
二:前端发送POST请求,后端获取数据
接着一:可以通过端口访问公网IP之后 二需要实现:点击飞书多维表格中的按钮,向服务器发送HTTP请求,并执行脚本程序 向服务器发送HTTP请求: 发送请求需要明确一下几个点 请求方法: 由于是向服务器端发送值…...
Go语言中的信号量:原理与实践指南
Go语言中的信号量:原理与实践指南 引言 在并发编程中,控制对共享资源的访问是一个经典问题。Go语言提供了丰富的并发原语(如sync.Mutex),但当我们需要灵活限制并发数量时,信号量(Semaphore&am…...
cpp中的继承
一、继承概念 在cpp中,封装、继承、多态是面向对象的三大特性。这里的继承就是允许已经存在的类(也就是基类)的基础上创建新类(派生类或者子类),从而实现代码的复用。 如上图所示,Person是基类&…...
3DGS(三维高斯散射)与SLAM技术结合的应用
3DGS(三维高斯散射)与SLAM(即时定位与地图构建)技术的结合,为动态环境感知、高效场景建模与实时渲染提供了新的可能性。以下从技术融合原理、应用场景、优势挑战及典型案例展开分析: 一、核心融合原理 1. …...
DeepSeek赋能大模型内容安全,网易易盾AIGC内容风控解决方案三大升级
在近两年由AI引发的生产力革命的背后,一场关乎数字世界秩序的攻防战正在上演:AI生成的深度伪造视频导致企业品牌声誉损失日均超千万,批量生成的侵权内容使版权纠纷量与日俱增,黑灰产利用AI技术持续发起欺诈攻击。 与此同时&#…...
mybatis 细节(${ ..}和#{..},resultType 和 resultMap的区别,别名的使用,Mapper 代理模式)
${..}和#{..} 占位符 #{..} #{}实现的是向prepareStatement中的预处理语句中设置参数值,sql语句中#{}表示一个占位符即?。 <!-- 根据id查询用户信息 --> <select id"findUserById" parameterType"int" resultType"user"&g…...
电子科技大学考研复习经验分享
电子科技大学考研复习经验分享 本人情况:本科就读于电科软院,24年2月开始了解考研,24年3月开始数学,9月决定考本院(开始全天候图书馆学习)并开始专业课学习,11月底开始政治学习,最后…...
【python】提取word\pdf格式内容到txt文件
一、使用pdfminer提取 import os import re from pdfminer.high_level import extract_text import docx2txt import jiebadef read_pdf(file_path):"""读取 PDF 文件内容:param file_path: PDF 文件路径:return: 文件内容文本"""try:text ext…...
Selenium 与 Coze 集成
涵盖两者的基本概念、集成步骤、代码示例以及相关注意事项。 基本概念 Selenium:是一个用于自动化浏览器操作的工具集,支持多种浏览器(如 Chrome、Firefox 等),能够模拟用户在浏览器中的各种操作,如点击、输入文本、选择下拉框等,常用于 Web 应用的自动化测试。Coze:它…...
SQL注入(order by,limit),seacms的报错注入以及系统库的绕过
1:如果information_schema被过滤了,该怎么绕过 1.1:介绍一下information_schema这个库 information_schema 是一个非常重要的系统数据库,它在SQL标准中定义,并且被许多关系型数据库管理系统(RDBMS&#x…...
数据保护API(DPAPI)深度剖析与安全实践
Windows DPAPI 安全机制解析 在当今数据泄露与网络攻击日益频繁的背景下,Windows 提供的 DPAPI(Data Protection API)成为开发者保护本地敏感数据的重要工具。本文将从 双层密钥体系、加密流程、跨上下文加密、已知攻击向量与防御措施、企业…...
Sqlserver安全篇之_隐藏实例功能和禁用SQL Server Browser服务
总结: 1、隐藏实例功能和禁用SQL Server Browser服务的功能一样,对应非默认实例(且这个默认实例是1433端口)的情况下,都是需要在连接字符串中提供端口号才能连接到实例 2、隐藏实例功能后,就算开启了SQL Server Browser服务&#…...