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版本的笔记,并且笔记都是博主自己一字一字编写和记录,有错误的地方欢迎大家指正。 一、基础知识…...
大数据SQL调优专题——调优切入
引入 我们都知道大数据的SQL优化,并非一蹴而就的简单任务,而是一个涉及多个环节的复杂过程。从需求提出到最终交付,任何一个环节的微小偏差都可能影响最终成果。 虽然我们的专栏名字叫大数据SQL调优,但是实际调优并不是简单对SQ…...
Idea java项目结构介绍
一般来说,一个典型的 IntelliJ IDEA Java 项目具有特定的结构,以下是对其主要部分的介绍: 项目根目录 项目的最顶层目录,包含了整个项目的所有文件和文件夹,通常以项目名称命名。在这个目录下可以找到.idea文件夹、.g…...
adb的安装
1、概念 (1)adb(android debug bridge)安卓调试桥,用于完成电脑和手机之间的通信控制。 (2)xcode来完成对于ios设备的操控,前提是有个mac电脑。 2、adb的安装 (1&…...
React + TypeScript 数据模型驱动数据字典生成示例
React TypeScript 数据模型驱动数据字典生成示例 引言:数据字典的工程价值 在现代化全栈开发中,数据字典作为业务实体与数据存储的映射桥梁,直接影响系统可维护性与团队协作效率。传统手动维护字典的方式存在同步成本高和版本管理混乱两大痛…...
Nginx 平滑升级/回滚
平滑升级和回滚的前提条件是 nginx 已经安装好,源码安装 nginx 可参考上一篇文章。在上一篇文章的基础上,nginx 已安装好且已启动,目前是 1.24 版本。 一、平滑升级 Nginx 的平滑升级(热升级)是一种 不中断服务 即可更…...
强化学习演进:GRPO 从何而来
强化学习(Reinforcement Learning, RL)是机器学习的一个分支,其核心是让智能体(Agent)通过与环境(Environment)的交互,学习如何采取最优行动(Action)以最大化…...
Uniapp 小程序复制、粘贴功能实现
在开发 Uniapp 小程序的过程中,复制和粘贴功能是非常实用且常见的交互需求。今天,我就来和大家详细分享如何在 Uniapp 中实现这两个功能。 复制功能:uni.setClipboardData方法 goResult() {uni.setClipboardData({data: this.copyContent, /…...
AOP进阶-02.通知顺序
一.通知顺序 当有多个切面类中的切入点表达式一样时,这些切面类的执行顺序是怎样的呢?如图我们将定义两个切面类,一个MyAspect2,一个MyAspect3,一个MyAspect4。执行后我们发现, 对于目标方法前的通知方法&…...
Node.js 中 fs 模块的高级用法
目录 1. 流式文件处理 示例:大文件复制 2. 文件监控 示例:使用 fs.watch 监控文件变化 3. 异步递归操作 示例:异步递归遍历目录 4. 文件权限管理 示例:修改文件权限 5. 原子操作 示例:原子重命名文件 在 Nod…...
深入探讨K8s资源管理和性能优化
#作者:曹付江 文章目录 前言:1.监控 Kubernetes 集群的资源利用率1.1 Prometheus1.2 Kubernetes 度量服务器1.3 Grafana1.4 自定义指标 2. 识别资源瓶颈2.1. 监控工具2.2. 性能剖析2.3 Kubernetes 事件和日志2.4. 群集自动扩展2.5. 负载测试…...
Buildroot 添加自定义模块-内置文件到文件系统
目录 概述实现步骤1. 创建包目录和文件结构2. 配置 Config.in3. 定义 cp_bin_files.mk4. 添加源文件install.shmy.conf 5. 配置与编译 概述 Buildroot 是一个高度可定制和模块化的嵌入式 Linux 构建系统,适用于从简单到复杂的各种嵌入式项目. buildroot的源码中bui…...
对话式AI引擎:DeepSeek技术引领多模态交互新篇章
摘要 DeepSeek技术公司推出了一项创新服务——“对话式AI引擎”,仅需两行代码即可激活任意大型AI模型的语音对话功能。这项技术使得文本型AI模型迅速转变为具备实时语音对话能力的多模态交互模型,解决了大型AI模型在语音交互方面的不足,为AI行…...
形式化数学编程在AI医疗中的探索路径分析
一、引言 1.1 研究背景与意义 在数字化时代,形式化数学编程和 AI 形式化医疗作为前沿领域,正逐渐改变着我们的生活和医疗模式。形式化数学编程是一种运用数学逻辑和严格的形式化语言来描述和验证程序的技术,它通过数学的精确性和逻辑性,确保程序的正确性和可靠性。在软件…...
HTML——前端基础1
目录 前端概述 前端能做的事情编辑 两步完成一个网页程序 前端工具的选择与安装 HTML HTML5介绍 HTML5的DOCTYPE声明 HTML基本骨架 文字标签 标题之标签 标签之段落、换行、水平线 标签之图片 标签之超文本链接 标签之文本 列表标签之有序列表 列表标签之无序…...
Blueprint —— Events
目录 一,Event Level Reset 二,Event Actor Begin Overlap 三,Event Actor End Overlap 四,Event Hit 五,Event Any Damage 六,Event Point Damage 七,Event Radial Damage 八ÿ…...
Java一揽子集合整理
Java 集合框架 List ArrayList,底层Object数组,相关方法add,remove Vector,底层Object数组,线程安全,使用 synchronized 关键字进行同步处理 Stack,继承自Vector,是一个后进先出的…...
第二十四:5.2【搭建 pinia 环境】axios 异步调用数据
第一步安装:npm install pinia 第二步:操作src/main.ts 改变里面的值的信息: <div class"count"><h2>当前求和为:{{ sum }}</h2><select v-model.number"n"> // .number 这里是…...
dubbo转http方式调用
业务背景:在当前项目下,所有前端请求均通过外层网关转发到后端这边的dubbo服务,现计划去掉网关层,由前端直接http调用后端dubbo。 解决方案:在前端调用方式不变的前提下,后端服务新建controller层…...
HybridCLR+Adressable+Springboot热更
本文章会手把手教大家如何搭建HybridCLRAdressableSpringboot热更。 创作不易,动动发财的小手点个赞。 安装华佗 首先我们按照官网的快速上手指南搭建一个简易的项目: 快速上手 | HybridCLR 注意在热更的代码里添加程序集。把用到的工具放到程序集里…...
金融行业专题|某基金公司基于超融合信创平台支持人大金仓数据库的性能评测
随着“自主可控”在 IT 基础设施领域不断深化,数据库的国产化替代也被很多金融机构提上日程。为了保证性能,大部分国产数据库都基于信创架构的裸金属服务器部署。在国产虚拟化/超融合平台上,国产数据库性能表现如何?尤其是搭配信创…...
父组件用的是原生监听,子组件用的是onClick,子组件添加了stopPropagation还是没有阻止传播
父组件用事件监听,子组件用onClick,即使子组件加了stopPropagation还是没有阻止冒泡。父组件可能使用原生的addEventListener来绑定事件,而子组件用的是React的onClick事件。这时候,虽然子组件调用了e.stopPropagation()ÿ…...
【问题解决方案】随笔 - vscode里面出现双环境解决方案
1.问题重述 (.venv) (base) 2.解决方案 看是conda还是venv环境,先给退出了 1.conda 比如Anaconda 的 (base) 环境,使用 conda deactivate2.venv deactivate然后重新激活环境即可 END...
什么是 Java 中的线程安全?
回答 Java 中的线程安全(Thread Safety)指的是在多线程环境下,当多个线程同时访问和操作共享资源(如对象、变量、数据结构等)时,能够保证程序的正确性,不会出现数据不一致、竞争条件࿰…...
【2025全网最新最全】前端Vue3框架的搭建及工程目录详解
文章目录 安装软件Node.js搭建Vue工程创建Vue工程精简Vue项目文件 Vue工程目录的解读网页标题的设置设置全局样式路由配置 安装软件Node.js 下载地址:https://nodejs.org/zh-cn/ 安装完成后,打开cmd,查看环境是否准备好 node -v npm -vnpm使用之前一定…...
大白话JavaScript闭包在实际项目中有哪些应用场景?
大白话JavaScript闭包在实际项目中有哪些应用场景? 闭包是指有权访问另一个函数作用域中的变量的函数。在实际项目中,闭包有很多应用场景,以下是一些常见的例子: 数据封装和隐私保护 场景:在开发中,有时…...
R 语言科研绘图第 27 期 --- 密度图-分组
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
QT各种版本下载安装
参考链接: 【Qt】超详细!Qt4.8.6和VS2010的配置及使用 由于QT官网一般现在进不去,所以下载一些QT版本只能通过镜像或者以前下载存储的安装包来进行,现在推荐两种方法 从参考链接中搬过来: 方案一:国内镜…...
信息系统的安全防护
文章目录 引言**1. 物理安全****2. 网络安全****3. 数据安全****4. 身份认证与访问控制****5. 应用安全****6. 日志与监控****7. 人员与管理制度****8. 其他安全措施****9. 安全防护框架**引言 从技术、管理和人员三个方面综合考虑,构建多层次、多维度的安全防护体系。 信息…...
TCPDF 任意文件读取漏洞:隐藏在 PDF 生成背后的危险
在网络安全的世界里,漏洞就像隐藏在黑暗中的“定时炸弹”,稍有不慎就会引发灾难性的后果。今天,我们要聊的是一个与 PDF 生成相关的漏洞——TCPDF 任意文件读取漏洞。这个漏洞可能让攻击者轻松读取服务器上的敏感文件,甚至获取整个…...
