# prototype-mongodb **Repository Path**: cllyl/prototype-mongodb ## Basic Information - **Project Name**: prototype-mongodb - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2020-11-25 - **Last Updated**: 2021-05-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MongoDB学习记录 ## 学习文档 #### 官网:https://www.mongodb.com/ ## 基础操作 ###### 查询数据库 ```js > show dbs; admin 0.000GB config 0.000GB local 0.000GB > # 这三个数据库都是MongoDB安装启动完成之后自带的 local: 是当前启动的本地化一些信息 admin: 管理的数据库 config: 配置数据库 > show databases; admin 0.000GB config 0.000GB local 0.000GB ``` ###### 创建或者切换数据库 ```js > use prototype; switched to db prototype # 有数据库就切换,没有就创建数据库之后切换 > show dbs; admin 0.000GB config 0.000GB local 0.000GB > # 这个时候查询不到数据库是当前数据库中没有任何的集合 ``` ###### 创建集合(类似于MySQL中创建表) ```js > db.createCollection("resume_preview"); { "ok" : 1 } # 创建一个名称为“resume_preview”的集合,其中前缀db可以理解为当前使用的数据库 > show dbs; admin 0.000GB config 0.000GB local 0.000GB prototype 0.000GB # 这个时候查询就会发现数据库已经能查询到了,所以建议创建数据库的时候同时创建集合 ``` ###### 查询集合 ```js > show tables; resume_preview > show collections; resume_preview # 通过这里基本就可以确定,可以将MongoDB中的collection集合映射为MySQL中的table表 ``` ###### 删除集合 ````js > db.resume_preview.drop function(options = {}) { const cmdObj = Object.assign({drop: this.getName()}, options); ret = this._db.runCommand(cmdObj); if (!ret.ok) { if (ret.errmsg == "ns not found") return false; throw _getErrorWithCode(ret, "drop failed: " + tojson(ret)); } return true; } > show collections; resume_preview # 查询发现集合还存在,说明删除没成功,上述删除时错误的 > db.resume_preview.drop(); true # 返回true:表示删除成功 > show collections; # 查询不到集合说明的确删除成功了 > show dbs; admin 0.000GB config 0.000GB local 0.000GB # 删除集合成功之后同样就查询不到数据库了 ```` ###### 删除数据库 ```js > db.dropDatabase(); { "dropped" : "prototype", "ok" : 1 } # 删除当前的数据库"prototype"成功 ``` ###### 插入文档(Document)数据,类似于MySQL中的表的记录Record ```js > db.resume_preview.insert({name: "陈林林",birthday: new ISODate("1994-02-05"),expectSalary:10000,gender:0,city:"郑州"}); WriteResult({ "nInserted" : 1 }) # 插入成功一条,单条插入 > db.resume_preview.insert([{name: "杨柳",birthday: new ISODate("1999-01-01"),expectSalary:5000,gender:1,city:"郑州"},{name: "苏云飞",birthday: new ISODate("1992-01-01"),expectSalary:6000,gender:0,city:"郑州"}]); BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 2, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] }) # 批量插入 ``` ###### 查询数据 > 等值查询 ```js > db.resume_preview.find({name:"陈林林"}); { "_id" : ObjectId("5fc2fc2cfe973605d8f47d16"), "name" : "陈林林", "birthday" : ISODate("1994-02-05T00:00:00Z"), "expectSalary" : 10000, "gender" : 0, "city" : "郑州" } # 简单查询,根据文档中的name字段进行查询,发现多出来了一个ID字段 # ID字段解析 "_id" : ObjectId("5fc2fc2cfe973605d8f47d16") _id为ObjectId类型的24位的字符串。是12字节长度24位的BSON类型数据。格式如下 # 前4个字节表示时间戳。可以通过ObjectId("5fc2fc2cfe973605d8f47d16").getTimestamp()查询 > ObjectId("5fc2fc2cfe973605d8f47d16").getTimestamp() ISODate("2020-11-29T01:41:00Z"),因为是东八区时间,所以和本地相差8个小时,实际插入时间位2020-11-29 09:41:00 # 接下来三个字节表示机器识别码 # 接下来两个字节是进程ID(PID:Process ID) # 最后三个字节是随机数 > db.resume_preview.find({name:"陈林林"}).pretty(); { "_id" : ObjectId("5fc2fc2cfe973605d8f47d16"), "name" : "陈林林", "birthday" : ISODate("1994-02-05T00:00:00Z"), "expectSalary" : 10000, "gender" : 0, "city" : "郑州" } # pretty()函数表示以行的形式格式化显示 ``` > 比较查询 ```js # 大于:gt # 小于:lt # 等于:eq # 不等于:ne # 大于等于: gte # 小于登录: lte > db.resume_preview.find({expectSalary:{$gte:6000}}).pretty(); { "_id" : ObjectId("5fc2fc2cfe973605d8f47d16"), "name" : "陈林林", "birthday" : ISODate("1994-02-05T00:00:00Z"), "expectSalary" : 10000, "gender" : 0, "city" : "郑州" } { "_id" : ObjectId("5fc2fd05fe973605d8f47d18"), "name" : "苏云飞", "birthday" : ISODate("1992-01-01T00:00:00Z"), "expectSalary" : 6000, "gender" : 0, "city" : "郑州" } # 上述查询期望薪资大于等于6000的 ``` > 逻辑查询 ```js # and:与条件 # 查询name字段是陈林林,并且expectSalary是10000的记录 > db.resume_preview.find({$and:[{name:"陈林林"},{expectSalary:10000}]}).pretty(); { "_id" : ObjectId("5fc2fc2cfe973605d8f47d16"), "name" : "陈林林", "birthday" : ISODate("1994-02-05T00:00:00Z"), "expectSalary" : 10000, "gender" : 0, "city" : "郑州" } # 或者使用下面的简单写法 > db.resume_preview.find({name:"陈林林",expectSalary:10000}).pretty(); { "_id" : ObjectId("5fc2fc2cfe973605d8f47d16"), "name" : "陈林林", "birthday" : ISODate("1994-02-05T00:00:00Z"), "expectSalary" : 10000, "gender" : 0, "city" : "郑州" } # or:或条件 # 查询name字段是陈林林或者杨柳的记录 > db.resume_preview.find({$or:[{name:"陈林林"},{name:"杨柳"}]}).pretty(); { "_id" : ObjectId("5fc2fc2cfe973605d8f47d16"), "name" : "陈林林", "birthday" : ISODate("1994-02-05T00:00:00Z"), "expectSalary" : 10000, "gender" : 0, "city" : "郑州" } { "_id" : ObjectId("5fc2fd05fe973605d8f47d17"), "name" : "杨柳", "birthday" : ISODate("1999-01-01T00:00:00Z"), "expectSalary" : 5000, "gender" : 1, "city" : "郑州" } # not:非条件 # 查询gender字段不是0的记录 > db.resume_preview.find({gender:{$not:{$eq:0}}}).pretty(); { "_id" : ObjectId("5fc2fd05fe973605d8f47d17"), "name" : "杨柳", "birthday" : ISODate("1999-01-01T00:00:00Z"), "expectSalary" : 5000, "gender" : 1, "city" : "郑州" } # 上述三个条件组合使用 db.resume_preview.find({$and:[{name:"陈林林"},{expectSalary:10000}],$or:[{name:"陈林林"},{name:"杨柳"}],gender:{$not:{$eq:1}}}).pretty(); # 查询(name等于陈林林并且expectSalary等于10000)并且(name等于陈林林或者杨柳)并且(gender不是1)的记录 { "_id" : ObjectId("5fc2fc2cfe973605d8f47d16"), "name" : "陈林林", "birthday" : ISODate("1994-02-05T00:00:00Z"), "expectSalary" : 10000, "gender" : 0, "city" : "郑州" } ``` > 分页查询 ```js # 对比MySQL中分页。分页的时候最好指定一个顺序。MySQL有默认排序规则这一说。 # 类似于MySQL中select * from resume_preview order by expectSalary ASC limit 2 offset 1; > db.resume_preview.find().sort({expectSalary: 1}).skip(1).limit(2).pretty(); { "_id" : ObjectId("5fc2fd05fe973605d8f47d18"), "name" : "苏云飞", "birthday" : ISODate("1992-01-01T00:00:00Z"), "expectSalary" : 6000, "gender" : 0, "city" : "郑州" } { "_id" : ObjectId("5fc2fc2cfe973605d8f47d16"), "name" : "陈林林", "birthday" : ISODate("1994-02-05T00:00:00Z"), "expectSalary" : 10000, "gender" : 0, "city" : "郑州" } ``` ###### 更新数据 ```js $set: 更新字段值.类比MySQL中update $unset: 删除字段。类比MySQL中alter table [table_name] drop column [column_name] $inc: 自增。类比于MySQL中自定义Sequence表。比MySQL中auto_increment更加的灵活 # 更新语法 db..update( # 更新的匹配选择 , # 更新的内容 , # 更新过程的配置信息 { # update和insert的融合。如果设置为true,表示如果没有匹配的记录就进行插入.默认为false,没有匹配不插入 upsert: , # 是否批量更新。默认为false。false:表示只更新匹配的第一条记录;true:表示匹配的记录全部更新 multi: , # 是否需要服务端确认,服务端对写操作的回执行为 writeConcert: } ); db.resume_preview.update( {name: "陈林林"}, {name: "陈刚"}, { upsert: false, multi: false } ); > db.resume_preview.update( ... {name: "陈林林"}, ... {name: "陈刚"}, ... { ... upsert: false, ... multi: false ... } ... ); WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) # 执行结果返回显示,匹配记录数为1,更新插入记录为0,修改记录数为1 # 使用上述更新语句,出现结果,就是原来记录里面的更新的字段全部都没有了,只保留了更新的document中指明的字段。其它的字都都被删除了。 > db.resume_preview.update({city: "郑州"},{$set:{expectSalary:7000}},{multi:true}); WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 }) > db.resume_preview.find().pretty(); { "_id" : ObjectId("5fc2fc2cfe973605d8f47d16"), "name" : "陈刚" } { "_id" : ObjectId("5fc2fd05fe973605d8f47d17"), "name" : "杨柳", "birthday" : ISODate("1999-01-01T00:00:00Z"), "expectSalary" : 7000, "gender" : 1, "city" : "郑州" } { "_id" : ObjectId("5fc2fd05fe973605d8f47d18"), "name" : "苏云飞", "birthday" : ISODate("1992-01-01T00:00:00Z"), "expectSalary" : 7000, "gender" : 0, "city" : "郑州" } # 使用上述的$set进行更新才不会出现删除字段的问题。 > db.resume_preview.update({city:"郑州"},{$set:{expectSalary: 1000}},{multi:true}); WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 }) > db.resume_preview.find().pretty(); { "_id" : ObjectId("5fc2fc2cfe973605d8f47d16"), "name" : "陈刚", "birthday" : ISODate("1994-02-05T00:00:00Z"), "city" : "郑州", "expectSalary" : 1000, "gender" : 0 } { "_id" : ObjectId("5fc2fd05fe973605d8f47d17"), "name" : "杨柳", "birthday" : ISODate("1999-01-01T00:00:00Z"), "expectSalary" : 1000, "gender" : 1, "city" : "郑州" } { "_id" : ObjectId("5fc2fd05fe973605d8f47d18"), "name" : "苏云飞", "birthday" : ISODate("1992-01-01T00:00:00Z"), "expectSalary" : 1000, "gender" : 0, "city" : "郑州" } > db.resume_preview.update({city:"郑州"},{$inc:{expectSalary: 1000}},{multi:true}); WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 }) > db.resume_preview.find().pretty(); { "_id" : ObjectId("5fc2fc2cfe973605d8f47d16"), "name" : "陈刚", "birthday" : ISODate("1994-02-05T00:00:00Z"), "city" : "郑州", "expectSalary" : 2000, "gender" : 0 } { "_id" : ObjectId("5fc2fd05fe973605d8f47d17"), "name" : "杨柳", "birthday" : ISODate("1999-01-01T00:00:00Z"), "expectSalary" : 2000, "gender" : 1, "city" : "郑州" } { "_id" : ObjectId("5fc2fd05fe973605d8f47d18"), "name" : "苏云飞", "birthday" : ISODate("1992-01-01T00:00:00Z"), "expectSalary" : 2000, "gender" : 0, "city" : "郑州" } # 将工资全部更新为1000之后,再添加1000 > db.resume_preview.update({name:"杨柳"},{$unset:{name:""}}); WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.resume_preview.find().pretty(); { "_id" : ObjectId("5fc2fc2cfe973605d8f47d16"), "name" : "陈刚", "birthday" : ISODate("1994-02-05T00:00:00Z"), "city" : "郑州", "expectSalary" : 2000, "gender" : 0 } { "_id" : ObjectId("5fc2fd05fe973605d8f47d17"), "birthday" : ISODate("1999-01-01T00:00:00Z"), "expectSalary" : 2000, "gender" : 1, "city" : "郑州" } { "_id" : ObjectId("5fc2fd05fe973605d8f47d18"), "name" : "苏云飞", "birthday" : ISODate("1992-01-01T00:00:00Z"), "expectSalary" : 2000, "gender" : 0, "city" : "郑州" } # 删除匹配记录的指定字段 ``` ###### 删除记录 ````js remove:删除记录 db..remove(,{justOne: ,writeConert: }); { justOne: 默认为false;表示匹配的所有记录都会删除;true:表示只删除匹配的第一条记录 } > db.resume_preview.remove({city:"郑州"}); WriteResult({ "nRemoved" : 3 }) > db.resume_preview.find().pretty(); > db.resume_preview.remove({city:"郑州"},{justOne: true}); WriteResult({ "nRemoved" : 1 }) > db.resume_preview.find().pretty(); { "_id" : ObjectId("5fc3326cfe973605d8f47d1a"), "name" : "苏云飞", "birthday" : ISODate("1992-01-01T00:00:00Z"), "expectSalary" : 6000, "gender" : 0, "city" : "郑州" } { "_id" : ObjectId("5fc33276fe973605d8f47d1b"), "name" : "陈林林", "birthday" : ISODate("1994-02-05T00:00:00Z"), "expectSalary" : 10000, "gender" : 0, "city" : "郑州" } # 查询发现的确少了一条记录 ```` ## 索引 ## 集群搭建 #### 安装 > 官网下载安装包 当前下载版本4.4.2,下载详细情况查看下面的截图。 ![image-20201129085631760](C:\Users\33028\AppData\Roaming\Typora\typora-user-images\image-20201129085631760.png) > 上传压缩包到服务器 ```shell [root@CLL-MASTER install]# pwd /usr/local/custom-util/mongodb/install # 安装包存放路径 ``` > 解压缩安装包 ```shell [root@CLL-MASTER install]# tar -xvf mongodb-linux-x86_64-rhel70-4.4.2.tgz -C ../station/ # 这里是安装位置 [root@CLL-MASTER station]# pwd /usr/local/custom-util/mongodb/station [root@CLL-MASTER station]# ls mongodb-linux-x86_64-rhel70-4.4.2 ``` > 启动MongoDB服务 ```shell [root@CLL-MASTER mongodb-linux-x86_64-rhel70-4.4.2]# ./bin/mongod {"t":{"$date":"2020-11-29T08:14:16.784+08:00"},"s":"I", "c":"CONTROL", "id":23285, "ctx":"main","msg":"Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'"} {"t":{"$date":"2020-11-29T08:14:16.788+08:00"},"s":"W", "c":"ASIO", "id":22601, "ctx":"main","msg":"No TransportLayer configured during NetworkInterface startup"} {"t":{"$date":"2020-11-29T08:14:16.789+08:00"},"s":"I", "c":"NETWORK", "id":4648601, "ctx":"main","msg":"Implicit TCP FastOpen unavailable. If TCP FastOpen is required, set tcpFastOpenServer, tcpFastOpenClient, and tcpFastOpenQueueSize."} {"t":{"$date":"2020-11-29T08:14:16.789+08:00"},"s":"I", "c":"STORAGE", "id":4615611, "ctx":"initandlisten","msg":"MongoDB starting","attr":{"pid":1424,"port":27017,"dbPath":"/data/db","architecture":"64-bit","host":"CLL-MASTER"}} {"t":{"$date":"2020-11-29T08:14:16.789+08:00"},"s":"I", "c":"CONTROL", "id":23403, "ctx":"initandlisten","msg":"Build Info","attr":{"buildInfo":{"version":"4.4.2","gitVersion":"15e73dc5738d2278b688f8929aee605fe4279b0e","openSSLVersion":"OpenSSL 1.0.1e-fips 11 Feb 2013","modules":[],"allocator":"tcmalloc","environment":{"distmod":"rhel70","distarch":"x86_64","target_arch":"x86_64"}}}} {"t":{"$date":"2020-11-29T08:14:16.789+08:00"},"s":"I", "c":"CONTROL", "id":51765, "ctx":"initandlisten","msg":"Operating System","attr":{"os":{"name":"CentOS Linux release 7.5.1804 (Core) ","version":"Kernel 3.10.0-862.el7.x86_64"}}} {"t":{"$date":"2020-11-29T08:14:16.789+08:00"},"s":"I", "c":"CONTROL", "id":21951, "ctx":"initandlisten","msg":"Options set by command line","attr":{"options":{}}} # 启动报错,因为路径不存在。要么创建需要的数据库的数据存储目录,要么启动的时候通过--dbpath参数指定数据存储目录 {"t":{"$date":"2020-11-29T08:14:16.791+08:00"},"s":"E", "c":"STORAGE", "id":20557, "ctx":"initandlisten","msg":"DBException in initAndListen, terminating","attr":{"error":"NonExistentPath: Data directory /data/db not found. Create the missing directory or specify another path using (1) the --dbpath command line option, or (2) by adding the 'storage.dbPath' option in the configuration file."}} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"REPL", "id":4784900, "ctx":"initandlisten","msg":"Stepping down the ReplicationCoordinator for shutdown","attr":{"waitTimeMillis":10000}} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"COMMAND", "id":4784901, "ctx":"initandlisten","msg":"Shutting down the MirrorMaestro"} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"SHARDING", "id":4784902, "ctx":"initandlisten","msg":"Shutting down the WaitForMajorityService"} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"NETWORK", "id":20562, "ctx":"initandlisten","msg":"Shutdown: going to close listening sockets"} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"NETWORK", "id":4784905, "ctx":"initandlisten","msg":"Shutting down the global connection pool"} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"STORAGE", "id":4784906, "ctx":"initandlisten","msg":"Shutting down the FlowControlTicketholder"} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"-", "id":20520, "ctx":"initandlisten","msg":"Stopping further Flow Control ticket acquisitions."} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"NETWORK", "id":4784918, "ctx":"initandlisten","msg":"Shutting down the ReplicaSetMonitor"} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"SHARDING", "id":4784921, "ctx":"initandlisten","msg":"Shutting down the MigrationUtilExecutor"} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"CONTROL", "id":4784925, "ctx":"initandlisten","msg":"Shutting down free monitoring"} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"FTDC", "id":4784926, "ctx":"initandlisten","msg":"Shutting down full-time data capture"} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"STORAGE", "id":4784927, "ctx":"initandlisten","msg":"Shutting down the HealthLog"} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"STORAGE", "id":4784929, "ctx":"initandlisten","msg":"Acquiring the global lock for shutdown"} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"-", "id":4784931, "ctx":"initandlisten","msg":"Dropping the scope cache for shutdown"} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"CONTROL", "id":20565, "ctx":"initandlisten","msg":"Now exiting"} {"t":{"$date":"2020-11-29T08:14:16.792+08:00"},"s":"I", "c":"CONTROL", "id":23138, "ctx":"initandlisten","msg":"Shutting down","attr":{"exitCode":100}} ``` > 修改安装位置 ```shell [root@CLL-MASTER mongodb-4.4.2]# mv mongodb-linux-x86_64-rhel70-4.4.2/ mongodb-4.4.2 ``` > 创建数据目录,日志目录,配置文件目录 ```shell [root@CLL-MASTER mongodb-4.4.2]# pwd /usr/local/custom-util/mongodb/station/mongodb-4.4.2 [root@CLL-MASTER mongodb-4.4.2]# mkdir conf data log ``` > 编写配置文件 ```shell [root@CLL-MASTER mongodb-4.4.2]# pwd /usr/local/custom-util/mongodb/station/mongodb-4.4.2 [root@CLL-MASTER mongodb-4.4.2]# vim conf/mongodb.conf # 数据库数据存放位置 dbpath=/usr/local/custom-util/mongodb/station/mongodb-4.4.2/data # 占用的端口 port=27017 # 类似于redis下bing_ip,指定客户端通过那个网卡连接 bind_ip=0.0.0.0 # 是否后台启动 fork=true # 日志的存放路径 logpath=/usr/local/custom-util/mongodb/station/mongodb-4.4.2/log/mongodb.log # 日志追加的形式存储路径 logappend=true # 不开启用户认证 auth=false ``` > 指定配置文件启动MongoDB数据库 ```shell [root@CLL-MASTER mongodb-4.4.2]# ./bin/mongod -f ./conf/mongodb.conf about to fork child process, waiting until server is ready for connections. forked process: 1466 child process started successfully, parent exiting # 已后台子进程方式启动,后台进程ID:1466。MongoDB启动成功之后,当前父进程就退出了! ``` > 查看是否启动成功 ````shell [root@CLL-MASTER mongodb-4.4.2]# ps -ef | grep mongo root 1466 1 1 08:28 ? 00:00:01 ./bin/mongod -f ./conf/mongodb.conf root 1502 1322 0 08:30 pts/0 00:00:00 grep --color=auto mongo ```` > 查看数据目录情况 ```shell [root@CLL-MASTER mongodb-4.4.2]# ll -h data 总用量 216K -rw-------. 1 root root 20K 11月 29 08:29 collection-0--7192320890395682479.wt -rw-------. 1 root root 20K 11月 29 08:29 collection-2--7192320890395682479.wt -rw-------. 1 root root 4.0K 11月 29 08:28 collection-4--7192320890395682479.wt drwx------. 2 root root 71 11月 29 08:31 diagnostic.data -rw-------. 1 root root 20K 11月 29 08:29 index-1--7192320890395682479.wt -rw-------. 1 root root 20K 11月 29 08:29 index-3--7192320890395682479.wt -rw-------. 1 root root 4.0K 11月 29 08:28 index-5--7192320890395682479.wt -rw-------. 1 root root 4.0K 11月 29 08:28 index-6--7192320890395682479.wt drwx------. 2 root root 110 11月 29 08:28 journal -rw-------. 1 root root 20K 11月 29 08:29 _mdb_catalog.wt -rw-------. 1 root root 5 11月 29 08:28 mongod.lock -rw-------. 1 root root 20K 11月 29 08:30 sizeStorer.wt -rw-------. 1 root root 114 11月 29 08:28 storage.bson -rw-------. 1 root root 47 11月 29 08:28 WiredTiger -rw-------. 1 root root 4.0K 11月 29 08:28 WiredTigerHS.wt -rw-------. 1 root root 21 11月 29 08:28 WiredTiger.lock -rw-------. 1 root root 1.3K 11月 29 08:31 WiredTiger.turtle -rw-------. 1 root root 60K 11月 29 08:31 WiredTiger.wt ``` > 查看日志文件情况 ```` [root@CLL-MASTER mongodb-4.4.2]# cat log/mongodb.log {"t":{"$date":"2020-11-29T08:28:57.578+08:00"},"s":"I", "c":"CONTROL", "id":23285, "ctx":"main","msg":"Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'"} {"t":{"$date":"2020-11-29T08:28:57.590+08:00"},"s":"W", "c":"ASIO", "id":22601, "ctx":"main","msg":"No TransportLayer configured during NetworkInterface startup"} {"t":{"$date":"2020-11-29T08:28:57.591+08:00"},"s":"I", "c":"NETWORK", "id":4648601, "ctx":"main","msg":"Implicit TCP FastOpen unavailable. If TCP FastOpen is required, set tcpFastOpenServer, tcpFastOpenClient, and tcpFastOpenQueueSize."} {"t":{"$date":"2020-11-29T08:28:57.594+08:00"},"s":"I", "c":"STORAGE", "id":4615611, "ctx":"initandlisten","msg":"MongoDB starting","attr":{"pid":1466,"port":27017,"dbPath":"/usr/local/custom-util/mongodb/station/mongodb-4.4.2/data","architecture":"64-bit","host":"CLL-MASTER"}} {"t":{"$date":"2020-11-29T08:28:57.594+08:00"},"s":"I", "c":"CONTROL", "id":23403, "ctx":"initandlisten","msg":"Build Info","attr":{"buildInfo":{"version":"4.4.2","gitVersion":"15e73dc5738d2278b688f8929aee605fe4279b0e","openSSLVersion":"OpenSSL 1.0.1e-fips 11 Feb 2013","modules":[],"allocator":"tcmalloc","environment":{"distmod":"rhel70","distarch":"x86_64","target_arch":"x86_64"}}}} {"t":{"$date":"2020-11-29T08:28:57.594+08:00"},"s":"I", "c":"CONTROL", "id":51765, "ctx":"initandlisten","msg":"Operating System","attr":{"os":{"name":"CentOS Linux release 7.5.1804 (Core) ","version":"Kernel 3.10.0-862.el7.x86_64"}}} {"t":{"$date":"2020-11-29T08:28:57.594+08:00"},"s":"I", "c":"CONTROL", "id":21951, "ctx":"initandlisten","msg":"Options set by command line","attr":{"options":{"config":"./conf/mongodb.conf","net":{"bindIp":"0.0.0.0","port":27017},"processManagement":{"fork":true},"security":{"authorization":"disabled"},"storage":{"dbPath":"/usr/local/custom-util/mongodb/station/mongodb-4.4.2/data"},"systemLog":{"destination":"file","logAppend":true,"path":"/usr/local/custom-util/mongodb/station/mongodb-4.4.2/log/mongodb.log"}}}} {"t":{"$date":"2020-11-29T08:28:57.598+08:00"},"s":"I", "c":"STORAGE", "id":22315, "ctx":"initandlisten","msg":"Opening WiredTiger","attr":{"config":"create,cache_size=256M,session_max=33000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000,close_scan_interval=10,close_handle_minimum=250),statistics_log=(wait=0),verbose=[recovery_progress,checkpoint_progress,compact_progress],"}} {"t":{"$date":"2020-11-29T08:28:58.297+08:00"},"s":"I", "c":"STORAGE", "id":22430, "ctx":"initandlisten","msg":"WiredTiger message","attr":{"message":"[1606609738:297633][1466:0x7f3cba4d0bc0], txn-recover: [WT_VERB_RECOVERY | WT_VERB_RECOVERY_PROGRESS] Set global recovery timestamp: (0, 0)"}} {"t":{"$date":"2020-11-29T08:28:58.297+08:00"},"s":"I", "c":"STORAGE", "id":22430, "ctx":"initandlisten","msg":"WiredTiger message","attr":{"message":"[1606609738:297682][1466:0x7f3cba4d0bc0], txn-recover: [WT_VERB_RECOVERY | WT_VERB_RECOVERY_PROGRESS] Set global oldest timestamp: (0, 0)"}} {"t":{"$date":"2020-11-29T08:28:58.316+08:00"},"s":"I", "c":"STORAGE", "id":4795906, "ctx":"initandlisten","msg":"WiredTiger opened","attr":{"durationMillis":718}} {"t":{"$date":"2020-11-29T08:28:58.316+08:00"},"s":"I", "c":"RECOVERY", "id":23987, "ctx":"initandlisten","msg":"WiredTiger recoveryTimestamp","attr":{"recoveryTimestamp":{"$timestamp":{"t":0,"i":0}}}} {"t":{"$date":"2020-11-29T08:28:58.345+08:00"},"s":"I", "c":"STORAGE", "id":4366408, "ctx":"initandlisten","msg":"No table logging settings modifications are required for existing WiredTiger tables","attr":{"loggingEnabled":true}} {"t":{"$date":"2020-11-29T08:28:58.345+08:00"},"s":"I", "c":"STORAGE", "id":22262, "ctx":"initandlisten","msg":"Timestamp monitor starting"} {"t":{"$date":"2020-11-29T08:28:58.349+08:00"},"s":"W", "c":"CONTROL", "id":22138, "ctx":"initandlisten","msg":"You are running this process as the root user, which is not recommended","tags":["startupWarnings"]} {"t":{"$date":"2020-11-29T08:28:58.350+08:00"},"s":"W", "c":"CONTROL", "id":22178, "ctx":"initandlisten","msg":"/sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never'","tags":["startupWarnings"]} {"t":{"$date":"2020-11-29T08:28:58.350+08:00"},"s":"W", "c":"CONTROL", "id":22181, "ctx":"initandlisten","msg":"/sys/kernel/mm/transparent_hugepage/defrag is 'always'. We suggest setting it to 'never'","tags":["startupWarnings"]} {"t":{"$date":"2020-11-29T08:28:58.350+08:00"},"s":"W", "c":"CONTROL", "id":22184, "ctx":"initandlisten","msg":"Soft rlimits too low","attr":{"currentValue":1024,"recommendedMinimum":64000},"tags":["startupWarnings"]} {"t":{"$date":"2020-11-29T08:28:58.351+08:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"initandlisten","msg":"createCollection","attr":{"namespace":"admin.system.version","uuidDisposition":"provided","uuid":{"uuid":{"$uuid":"cc4fca1b-e9ff-481c-b6f1-1282a1a97401"}},"options":{"uuid":{"$uuid":"cc4fca1b-e9ff-481c-b6f1-1282a1a97401"}}}} {"t":{"$date":"2020-11-29T08:28:58.356+08:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"initandlisten","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"admin.system.version","index":"_id_","commitTimestamp":{"$timestamp":{"t":0,"i":0}}}} {"t":{"$date":"2020-11-29T08:28:58.356+08:00"},"s":"I", "c":"COMMAND", "id":20459, "ctx":"initandlisten","msg":"Setting featureCompatibilityVersion","attr":{"newVersion":"4.4"}} {"t":{"$date":"2020-11-29T08:28:58.357+08:00"},"s":"I", "c":"STORAGE", "id":20536, "ctx":"initandlisten","msg":"Flow Control is enabled on this deployment"} {"t":{"$date":"2020-11-29T08:28:58.360+08:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"initandlisten","msg":"createCollection","attr":{"namespace":"local.startup_log","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"b7468e52-eb35-4b21-a115-d0c881ce4f36"}},"options":{"capped":true,"size":10485760}}} {"t":{"$date":"2020-11-29T08:28:58.366+08:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"initandlisten","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"local.startup_log","index":"_id_","commitTimestamp":{"$timestamp":{"t":0,"i":0}}}} {"t":{"$date":"2020-11-29T08:28:58.367+08:00"},"s":"I", "c":"FTDC", "id":20625, "ctx":"initandlisten","msg":"Initializing full-time diagnostic data capture","attr":{"dataDirectory":"/usr/local/custom-util/mongodb/station/mongodb-4.4.2/data/diagnostic.data"}} {"t":{"$date":"2020-11-29T08:28:58.380+08:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"LogicalSessionCacheRefresh","msg":"createCollection","attr":{"namespace":"config.system.sessions","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"2307267e-090e-473b-a8cf-cf2dabb87d95"}},"options":{}}} {"t":{"$date":"2020-11-29T08:28:58.383+08:00"},"s":"I", "c":"CONTROL", "id":20712, "ctx":"LogicalSessionCacheReap","msg":"Sessions collection is not set up; waiting until next sessions reap interval","attr":{"error":"NamespaceNotFound: config.system.sessions does not exist"}} {"t":{"$date":"2020-11-29T08:28:58.384+08:00"},"s":"I", "c":"NETWORK", "id":23015, "ctx":"listener","msg":"Listening on","attr":{"address":"/tmp/mongodb-27017.sock"}} {"t":{"$date":"2020-11-29T08:28:58.385+08:00"},"s":"I", "c":"NETWORK", "id":23015, "ctx":"listener","msg":"Listening on","attr":{"address":"0.0.0.0"}} {"t":{"$date":"2020-11-29T08:28:58.385+08:00"},"s":"I", "c":"NETWORK", "id":23016, "ctx":"listener","msg":"Waiting for connections","attr":{"port":27017,"ssl":"off"}} {"t":{"$date":"2020-11-29T08:28:58.407+08:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"LogicalSessionCacheRefresh","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"config.system.sessions","index":"_id_","commitTimestamp":{"$timestamp":{"t":0,"i":0}}}} {"t":{"$date":"2020-11-29T08:28:58.407+08:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"LogicalSessionCacheRefresh","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"config.system.sessions","index":"lsidTTLIndex","commitTimestamp":{"$timestamp":{"t":0,"i":0}}}} ```` > shell进行连接 ```shell [root@CLL-MASTER mongodb-4.4.2]# pwd /usr/local/custom-util/mongodb/station/mongodb-4.4.2 [root@CLL-MASTER mongodb-4.4.2]# ./bin/mongo # 连接客户端使用的MongoDB客户端版本 MongoDB shell version v4.4.2 # 连接信息,默认连接本机的27017端口 connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb # 建立会话 Implicit session: session { "id" : UUID("d89eec3f-393b-459a-ad60-4c82d896fa0d") } # MongoDB服务端版本 MongoDB server version: 4.4.2 --- # 启动过程警告⚠信息 The server generated these startup warnings when booting: # 不推荐使用root用户 2020-11-29T08:28:58.349+08:00: You are running this process as the root user, which is not recommended 2020-11-29T08:28:58.350+08:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never' 2020-11-29T08:28:58.350+08:00: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. We suggest setting it to 'never' # 系统可供打开的软件数量限制太小,当前是1024,推荐最小为64000 2020-11-29T08:28:58.350+08:00: Soft rlimits too low 2020-11-29T08:28:58.350+08:00: currentValue: 1024 2020-11-29T08:28:58.350+08:00: recommendedMinimum: 64000 --- --- Enable MongoDB's free cloud-based monitoring service, which will then receive and display metrics about your deployment (disk utilization, CPU, operation statistics, etc). The monitoring data will be available on a MongoDB website with a unique URL accessible to you and anyone you share the URL with. MongoDB may use this information to make product improvements and to suggest MongoDB products and deployment options to you. # 免费监控使用 To enable free monitoring, run the following command: db.enableFreeMonitoring() To permanently disable this reminder, run the following command: db.disableFreeMonitoring() --- > ``` > 退出shell连接 ``` > exit ``` > 指定参数进行连接,和MySQL一样,都是--host指定IP,--port指定端口 ```shell [root@CLL-MASTER mongodb-4.4.2]# ./bin/mongo --host 192.168.0.110 --port 27017 MongoDB shell version v4.4.2 connecting to: mongodb://192.168.0.110:27017/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("8fe3d582-84af-42a9-b291-6424ceddfaa5") } MongoDB server version: 4.4.2 --- The server generated these startup warnings when booting: 2020-11-29T08:28:58.349+08:00: You are running this process as the root user, which is not recommended 2020-11-29T08:28:58.350+08:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never' 2020-11-29T08:28:58.350+08:00: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. We suggest setting it to 'never' 2020-11-29T08:28:58.350+08:00: Soft rlimits too low 2020-11-29T08:28:58.350+08:00: currentValue: 1024 2020-11-29T08:28:58.350+08:00: recommendedMinimum: 64000 --- --- Enable MongoDB's free cloud-based monitoring service, which will then receive and display metrics about your deployment (disk utilization, CPU, operation statistics, etc). The monitoring data will be available on a MongoDB website with a unique URL accessible to you and anyone you share the URL with. MongoDB may use this information to make product improvements and to suggest MongoDB products and deployment options to you. To enable free monitoring, run the following command: db.enableFreeMonitoring() To permanently disable this reminder, run the following command: db.disableFreeMonitoring() --- > ``` > Compass(GUI工具使用) 官网推荐的连接MongoDB的GUI(Graphical User Interface面向用户的图形窗口)工具。 - 官网下载 - 解压直接使用 - 提供的功能 - 性能分析图标 - 优雅的侧边栏 - 可视化的命令执行界面 - 构建地理位置查询 - 交互式的MongoDB中的文档编辑器 - 执行计划分析 - 索引管理 - MongoDB下语法校验 - 增强版的CRUD操作。类似于JS的弱类型 - 部署更新 - 历史查询 #### 主从搭建 > 简要描述 一主一从、一主多从。主节点负责读写,从节点负责读。通过oplog进行主从复制。存在于locale数据库中。 > 存在问题 - 主库宕机之后,不能自动切换。需要手动切换 - 配置主从结构的时候,必须指定那个是主库 #### 复制集搭建 > 简要描述 主要是在主从架构的基础上,解决了主从架构的两个痛点。 oplog具有幂等性。里面的日志,不论执行多少次,结果都是一样的! > replcation_set 复制集中使用一主三从。复制集群目录规划为 安装目录:**/usr/local/custom-util/mongodb/replcation_set** 集群名称为:**splitReplSet1** 安装目录下新建四个文件夹**server1、server2、server3、server4**代表集群中四个节点,使用端口分别为**37017、37018、37019、37020** 配置文件信息如下 ``` dbpath=/usr/local/custom-util/mongodb/replcation_set/server1/data bind_ip=0.0.0.0 port=37017 fork=true logpath=/usr/local/custom-util/mongodb/replcation_set/server1/log/mongo.log replSet=splitReplSet1 ``` > 集群启动 - 先分别启动所有节点 ```shell [root@CLL-MASTER replcation_set]# ./server1/bin/mongod -f ./server1/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 2341 child process started successfully, parent exiting [root@CLL-MASTER replcation_set]# ./server2/bin/mongod -f ./server2/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 2387 child process started successfully, parent exiting [root@CLL-MASTER replcation_set]# ./server3/bin/mongod -f ./server3/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 2433 child process started successfully, parent exiting [root@CLL-MASTER replcation_set]# ps -ef | grep mongod root 1466 1 0 08:28 ? 00:04:01 ./bin/mongod -f ./conf/mongodb.conf root 2341 1 4 18:49 ? 00:00:00 ./server1/bin/mongod -f ./server1/conf/mongo.conf root 2387 1 5 18:49 ? 00:00:00 ./server2/bin/mongod -f ./server2/conf/mongo.conf root 2433 1 10 18:49 ? 00:00:00 ./server3/bin/mongod -f ./server3/conf/mongo.conf ``` - 在启动一个节点定义集群配置信息 ```js # 定义配置信息 var rscfg ={"_id":"splitReplSet1", "protocolVersion" : 1, "members":[{"_id":1,"host":"192.168.0.110:37017","priority":10},{"_id":2,"host":"192.168.0.110:37018"},{"_id":3,"host":"192.168.0.110:37019"}]} # 根据配置信息初始化集群 rs.initiate(rscfg) # 查看集群运行状态 rs.status() ``` ```js # 查看状态信息如下,注意这里的连接信息已经不只是原来的>而是变成了splitReplSet1:PRIMARY>表示splitReplSet1集群下的主节点 splitReplSet1:PRIMARY> rs.status(); { "set" : "splitReplSet1", "date" : ISODate("2020-11-29T11:02:33.116Z"), "myState" : 1, "term" : NumberLong(1), "syncSourceHost" : "", "syncSourceId" : -1, "heartbeatIntervalMillis" : NumberLong(2000), "majorityVoteCount" : 2, "writeMajorityCount" : 2, "votingMembersCount" : 3, "writableVotingMembersCount" : 3, "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1606647748, 1), "t" : NumberLong(1) }, "lastCommittedWallTime" : ISODate("2020-11-29T11:02:28.610Z"), "readConcernMajorityOpTime" : { "ts" : Timestamp(1606647748, 1), "t" : NumberLong(1) }, "readConcernMajorityWallTime" : ISODate("2020-11-29T11:02:28.610Z"), "appliedOpTime" : { "ts" : Timestamp(1606647748, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1606647748, 1), "t" : NumberLong(1) }, "lastAppliedWallTime" : ISODate("2020-11-29T11:02:28.610Z"), "lastDurableWallTime" : ISODate("2020-11-29T11:02:28.610Z") }, "lastStableRecoveryTimestamp" : Timestamp(1606647718, 3), "electionCandidateMetrics" : { "lastElectionReason" : "electionTimeout", "lastElectionDate" : ISODate("2020-11-29T11:01:58.563Z"), "electionTerm" : NumberLong(1), "lastCommittedOpTimeAtElection" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "lastSeenOpTimeAtElection" : { "ts" : Timestamp(1606647707, 1), "t" : NumberLong(-1) }, "numVotesNeeded" : 2, "priorityAtElection" : 10, "electionTimeoutMillis" : NumberLong(10000), "numCatchUpOps" : NumberLong(0), "newTermStartDate" : ISODate("2020-11-29T11:01:58.594Z"), "wMajorityWriteAvailabilityDate" : ISODate("2020-11-29T11:01:58.929Z") }, "members" : [ { "_id" : 1, "name" : "192.168.0.110:37017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 318, "optime" : { "ts" : Timestamp(1606647748, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2020-11-29T11:02:28Z"), "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "Could not find member to sync from", "electionTime" : Timestamp(1606647718, 1), "electionDate" : ISODate("2020-11-29T11:01:58Z"), "configVersion" : 1, "configTerm" : 1, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 2, "name" : "192.168.0.110:37018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 45, "optime" : { "ts" : Timestamp(1606647748, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1606647748, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2020-11-29T11:02:28Z"), "optimeDurableDate" : ISODate("2020-11-29T11:02:28Z"), "lastHeartbeat" : ISODate("2020-11-29T11:02:32.598Z"), "lastHeartbeatRecv" : ISODate("2020-11-29T11:02:33.112Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "192.168.0.110:37017", "syncSourceId" : 1, "infoMessage" : "", "configVersion" : 1, "configTerm" : 1 }, { "_id" : 3, "name" : "192.168.0.110:37019", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 45, "optime" : { "ts" : Timestamp(1606647748, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1606647748, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2020-11-29T11:02:28Z"), "optimeDurableDate" : ISODate("2020-11-29T11:02:28Z"), "lastHeartbeat" : ISODate("2020-11-29T11:02:32.598Z"), "lastHeartbeatRecv" : ISODate("2020-11-29T11:02:32.109Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "192.168.0.110:37018", "syncSourceId" : 2, "infoMessage" : "", "configVersion" : 1, "configTerm" : 1 } ], "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1606647748, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1606647748, 1) } ``` - 节点的动态增加和删除 ```js # 增加节点,注意添加节点之前先启动节点,在主节点点上面添加 [root@CLL-MASTER replcation_set]# ./server4/bin/mongod -f ./server4/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 2846 child process started successfully, parent exiting [root@CLL-MASTER replcation_set]# ./server4/bin/mongo --host=192.168.0.110 --port=37017 MongoDB shell version v4.4.2 connecting to: mongodb://192.168.0.110:37017/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("a3bed571-f09f-4667-be8d-67e8854bdd46") } MongoDB server version: 4.4.2 splitReplSet1:PRIMARY> rs.add("192.168.0.110:37020") { "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1606648109, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1606648109, 1) } # 查询结果集状态,发现节点的确增加了 splitReplSet1:PRIMARY> rs.status(); { "set" : "splitReplSet1", "date" : ISODate("2020-11-29T11:08:46.003Z"), "myState" : 1, "term" : NumberLong(1), "syncSourceHost" : "", "syncSourceId" : -1, "heartbeatIntervalMillis" : NumberLong(2000), "majorityVoteCount" : 3, "writeMajorityCount" : 3, "votingMembersCount" : 4, "writableVotingMembersCount" : 4, "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1606648109, 1), "t" : NumberLong(1) }, "lastCommittedWallTime" : ISODate("2020-11-29T11:08:29.087Z"), "readConcernMajorityOpTime" : { "ts" : Timestamp(1606648109, 1), "t" : NumberLong(1) }, "readConcernMajorityWallTime" : ISODate("2020-11-29T11:08:29.087Z"), "appliedOpTime" : { "ts" : Timestamp(1606648109, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1606648109, 1), "t" : NumberLong(1) }, "lastAppliedWallTime" : ISODate("2020-11-29T11:08:29.087Z"), "lastDurableWallTime" : ISODate("2020-11-29T11:08:29.087Z") }, "lastStableRecoveryTimestamp" : Timestamp(1606648078, 1), "electionCandidateMetrics" : { "lastElectionReason" : "electionTimeout", "lastElectionDate" : ISODate("2020-11-29T11:01:58.563Z"), "electionTerm" : NumberLong(1), "lastCommittedOpTimeAtElection" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "lastSeenOpTimeAtElection" : { "ts" : Timestamp(1606647707, 1), "t" : NumberLong(-1) }, "numVotesNeeded" : 2, "priorityAtElection" : 10, "electionTimeoutMillis" : NumberLong(10000), "numCatchUpOps" : NumberLong(0), "newTermStartDate" : ISODate("2020-11-29T11:01:58.594Z"), "wMajorityWriteAvailabilityDate" : ISODate("2020-11-29T11:01:58.929Z") }, "members" : [ { "_id" : 1, "name" : "192.168.0.110:37017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 691, "optime" : { "ts" : Timestamp(1606648109, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2020-11-29T11:08:29Z"), "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "electionTime" : Timestamp(1606647718, 1), "electionDate" : ISODate("2020-11-29T11:01:58Z"), "configVersion" : 2, "configTerm" : 1, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 2, "name" : "192.168.0.110:37018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 418, "optime" : { "ts" : Timestamp(1606648109, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1606648109, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2020-11-29T11:08:29Z"), "optimeDurableDate" : ISODate("2020-11-29T11:08:29Z"), "lastHeartbeat" : ISODate("2020-11-29T11:08:45.112Z"), "lastHeartbeatRecv" : ISODate("2020-11-29T11:08:45.136Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "192.168.0.110:37017", "syncSourceId" : 1, "infoMessage" : "", "configVersion" : 2, "configTerm" : 1 }, { "_id" : 3, "name" : "192.168.0.110:37019", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 418, "optime" : { "ts" : Timestamp(1606648109, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1606648109, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2020-11-29T11:08:29Z"), "optimeDurableDate" : ISODate("2020-11-29T11:08:29Z"), "lastHeartbeat" : ISODate("2020-11-29T11:08:45.112Z"), "lastHeartbeatRecv" : ISODate("2020-11-29T11:08:45.131Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "192.168.0.110:37018", "syncSourceId" : 2, "infoMessage" : "", "configVersion" : 2, "configTerm" : 1 }, { "_id" : 4, "name" : "192.168.0.110:37020", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 16, "optime" : { "ts" : Timestamp(1606648109, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1606648109, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2020-11-29T11:08:29Z"), "optimeDurableDate" : ISODate("2020-11-29T11:08:29Z"), "lastHeartbeat" : ISODate("2020-11-29T11:08:45.123Z"), "lastHeartbeatRecv" : ISODate("2020-11-29T11:08:45.834Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "configVersion" : 2, "configTerm" : 1 } ], "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1606648109, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1606648109, 1) } rs.add("192.168.0.110:37020") # 删除slave节点,注意删除节点,只能删除slave节点 rs.remove("192.168.0.110:37019") ``` > 检测集群同步状态 ```js # 主节点创建数据库和集合 splitReplSet1:PRIMARY> use prototype switched to db prototype splitReplSet1:PRIMARY> db.createCollection("resume_preview"); { "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1606648207, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1606648207, 1) } splitReplSet1:PRIMARY> show dbs; admin 0.000GB config 0.000GB local 0.000GB prototype 0.000GB # 从节点查看数据库和集合 splitReplSet1:SECONDARY> show dbs; uncaught exception: Error: listDatabases failed:{ "topologyVersion" : { "processId" : ObjectId("5fc37e93af4b56de70585d92"), "counter" : NumberLong(5) }, "operationTime" : Timestamp(1606648338, 1), "ok" : 0, # 不是主节点,而且没有设置slaveOk=true "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotPrimaryNoSecondaryOk", "$clusterTime" : { "clusterTime" : Timestamp(1606648338, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs/<@src/mongo/shell/mongo.js:147:19 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:99:12 shellHelper.show@src/mongo/shell/utils.js:937:13 shellHelper@src/mongo/shell/utils.js:819:15 @(shellhelp2):1:1 # 这种情况下解决办法 splitReplSet1:SECONDARY> rs.slaveOk(); WARNING: slaveOk() is deprecated and may be removed in the next major release. Please use secondaryOk() instead. # 提示当前方法将要被移除,使用secondaryOk()函数替换 splitReplSet1:SECONDARY> show dbs; admin 0.000GB config 0.000GB local 0.000GB prototype 0.000GB splitReplSet1:SECONDARY> use prototype; switched to db prototype splitReplSet1:SECONDARY> show tables; resume_preview # 从节点同步和查询正常 # 主库进行记录的插入,然后再在从节点进行查询 splitReplSet1:PRIMARY> use prototype; switched to db prototype splitReplSet1:PRIMARY> show tables; resume_preview splitReplSet1:PRIMARY> db.resume_preview.insert({name:"陈林林",split:"splitReplcationSet1"}); WriteResult({ "nInserted" : 1 }) splitReplSet1:PRIMARY> db.resume_preview.find().pretty(); { "_id" : ObjectId("5fc383764097b9ff4a3f279c"), "name" : "陈林林", "split" : "splitReplcationSet1" } # 主节点插入正常,从节点进行查询 splitReplSet1:SECONDARY> show dbs; uncaught exception: Error: listDatabases failed:{ "topologyVersion" : { "processId" : ObjectId("5fc37e9b87ec3b67b0504653"), "counter" : NumberLong(5) }, "operationTime" : Timestamp(1606648738, 1), "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotPrimaryNoSecondaryOk", "$clusterTime" : { "clusterTime" : Timestamp(1606648738, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs/<@src/mongo/shell/mongo.js:147:19 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:99:12 shellHelper.show@src/mongo/shell/utils.js:937:13 shellHelper@src/mongo/shell/utils.js:819:15 @(shellhelp2):1:1 splitReplSet1:SECONDARY> rs.secondaryOk(); splitReplSet1:SECONDARY> show dbs; admin 0.000GB config 0.000GB local 0.000GB prototype 0.000GB splitReplSet1:SECONDARY> use prototype; switched to db prototype splitReplSet1:SECONDARY> db.resume_preview.find().pretty(); { "_id" : ObjectId("5fc383764097b9ff4a3f279c"), "name" : "陈林林", "split" : "splitReplcationSet1" } # 从节点查询数据正常 ``` > 主节点宕机,从节点自动切换检测 ```shell [root@CLL-MASTER replcation_set]# ps -ef | grep mongod root 1466 1 0 08:28 ? 00:04:12 ./bin/mongod -f ./conf/mongodb.conf root 2513 1 1 18:57 ? 00:00:21 ./server1/bin/mongod -f ./server1/conf/mongo.conf root 2563 1 1 18:57 ? 00:00:18 ./server2/bin/mongod -f ./server2/conf/mongo.conf root 2613 1 1 18:57 ? 00:00:17 ./server3/bin/mongod -f ./server3/conf/mongo.conf root 2846 1 1 19:07 ? 00:00:10 ./server4/bin/mongod -f ./server4/conf/mongo.conf root 3049 1322 0 19:21 pts/0 00:00:00 grep --color=auto mongod [root@CLL-MASTER replcation_set]# kill -9 2513 [root@CLL-MASTER replcation_set]# ps -ef | grep mongod root 1466 1 0 08:28 ? 00:04:12 ./bin/mongod -f ./conf/mongodb.conf root 2563 1 1 18:57 ? 00:00:18 ./server2/bin/mongod -f ./server2/conf/mongo.conf root 2613 1 1 18:57 ? 00:00:18 ./server3/bin/mongod -f ./server3/conf/mongo.conf root 2846 1 1 19:07 ? 00:00:10 ./server4/bin/mongod -f ./server4/conf/mongo.conf root 3059 1322 0 19:21 pts/0 00:00:00 grep --color=auto mongod [root@CLL-MASTER replcation_set]# ./server1/bin/mongo --host=192.168.0.110 --port=37017 MongoDB shell version v4.4.2 connecting to: mongodb://192.168.0.110:37017/?compressors=disabled&gssapiServiceName=mongodb Error: couldn't connect to server 192.168.0.110:37017, connection attempt failed: SocketException: Error connecting to 192.168.0.110:37017 :: caused by :: Connection refused : connect@src/mongo/shell/mongo.js:374:17 @(connect):2:6 exception: connect failed exiting with code 1 [root@CLL-MASTER replcation_set]# ./server2/bin/mongo --host=192.168.0.110 --port=37018 MongoDB shell version v4.4.2 connecting to: mongodb://192.168.0.110:37018/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("cd8f418c-2b3b-485c-8629-6e9d53713d25") } MongoDB server version: 4.4.2 --- The server generated these startup warnings when booting: 2020-11-29T18:57:24.609+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted 2020-11-29T18:57:24.609+08:00: You are running this process as the root user, which is not recommended 2020-11-29T18:57:24.609+08:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never' 2020-11-29T18:57:24.609+08:00: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. We suggest setting it to 'never' 2020-11-29T18:57:24.609+08:00: Soft rlimits too low 2020-11-29T18:57:24.609+08:00: currentValue: 1024 2020-11-29T18:57:24.609+08:00: recommendedMinimum: 64000 --- --- Enable MongoDB's free cloud-based monitoring service, which will then receive and display metrics about your deployment (disk utilization, CPU, operation statistics, etc). The monitoring data will be available on a MongoDB website with a unique URL accessible to you and anyone you share the URL with. MongoDB may use this information to make product improvements and to suggest MongoDB products and deployment options to you. To enable free monitoring, run the following command: db.enableFreeMonitoring() To permanently disable this reminder, run the following command: db.disableFreeMonitoring() --- splitReplSet1:PRIMARY> # 检测原来的主节点已经不能连接,连接37018节点,发现已经自动切换为主节点 # 启动37017节点 [root@CLL-MASTER replcation_set]# ./server1/bin/mongod -f ./server1/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 3099 child process started successfully, parent exiting [root@CLL-MASTER replcation_set]# ./server1/bin/mongo --host=192.168.0.110 --port=37017 MongoDB shell version v4.4.2 connecting to: mongodb://192.168.0.110:37017/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("666a3ccd-5378-4ba2-8917-796c170fe9fa") } MongoDB server version: 4.4.2 --- The server generated these startup warnings when booting: 2020-11-29T19:23:48.756+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted 2020-11-29T19:23:48.756+08:00: You are running this process as the root user, which is not recommended 2020-11-29T19:23:48.756+08:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never' 2020-11-29T19:23:48.756+08:00: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. We suggest setting it to 'never' 2020-11-29T19:23:48.756+08:00: Soft rlimits too low 2020-11-29T19:23:48.756+08:00: currentValue: 1024 2020-11-29T19:23:48.756+08:00: recommendedMinimum: 64000 --- --- Enable MongoDB's free cloud-based monitoring service, which will then receive and display metrics about your deployment (disk utilization, CPU, operation statistics, etc). The monitoring data will be available on a MongoDB website with a unique URL accessible to you and anyone you share the URL with. MongoDB may use this information to make product improvements and to suggest MongoDB products and deployment options to you. To enable free monitoring, run the following command: db.enableFreeMonitoring() To permanently disable this reminder, run the following command: db.disableFreeMonitoring() --- splitReplSet1:PRIMARY> # 重新启动37017节点,发现37017自动加入集群,并且为主节点。是因为集群配置中优先级较高 ``` > 添加冲裁节点 ```js # 添加冲裁节点,只进行选举,不参与读写操作 rs.addArb("192.168.0.110:37020") ``` #### 分片复制集搭建 > 简要描述 三个分片节点,每个分片节点分为一主两从。 分片节点1:192.168.0.110 一主两从分别为: 47017、47018、47019 分片节点2:192.168.0.111 ``` [root@CLL-MASTER sharding]# ls shard1 shard2 shard3 [root@CLL-MASTER sharding]# pwd /usr/local/custom-util/mongodb/sharding ``` ``` 分片配置信息如下 dbpath=/usr/local/custom-util/mongodb/sharding/shard3/data bind_ip=0.0.0.0 port=47019 fork=true logpath=/usr/local/custom-util/mongodb/sharding/shard3/log/mongo.log replSet=sharding1 shardsvr=true ``` 一主两从分别为: 47017、47018、47019 分片节点3:192.168.0.112 一主两从分别为: 47017、47018、47019 ```shell 启动第一个分片集 [root@CLL-MASTER mongodb]# ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard1/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 3777 child process started successfully, parent exiting [root@CLL-MASTER mongodb]# ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard2/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 3821 child process started successfully, parent exiting [root@CLL-MASTER mongodb]# ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard3/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 3864 child process started successfully, parent exiting [root@CLL-MASTER mongodb]# ps -ef | grpe mongod -bash: grpe: 未找到命令 [root@CLL-MASTER mongodb]# ps -ef | grep mongod root 3338 1 1 19:43 ? 00:00:30 ./config1/bin/mongod -f ./config1/conf/mongo.conf root 3389 1 1 19:43 ? 00:00:27 ./config2/bin/mongod -f ./config2/conf/mongo.conf root 3441 1 1 19:43 ? 00:00:27 ./config3/bin/mongod -f ./config3/conf/mongo.conf root 3777 1 4 20:13 ? 00:00:00 ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard1/conf/mongo.conf root 3821 1 4 20:13 ? 00:00:00 ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard2/conf/mongo.conf root 3864 1 6 20:13 ? 00:00:00 ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard3/conf/mongo.conf root 3910 1322 0 20:13 pts/0 00:00:00 grep --color=auto mongod ``` ```js 配置第一个分片集 var cfg ={"_id":"sharding1","protocolVersion":1,"members":[{"_id":1,"host":"192.168.0.110:47017"},{"_id":2,"host":"192.168.0.110:47018"},{"_id":3,"host":"192.168.0.110:47019"} ]}; rs.initiate(cfg); rs.status(); [root@CLL-MASTER mongodb]# ./station/mongodb-4.4.2/bin/mongo --host=192.168.0.110 --port=47017 MongoDB shell version v4.4.2 connecting to: mongodb://192.168.0.110:47017/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("d26c4657-fdb9-425f-9abe-76a78250a47f") } MongoDB server version: 4.4.2 --- The server generated these startup warnings when booting: 2020-11-29T20:13:30.481+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted 2020-11-29T20:13:30.481+08:00: You are running this process as the root user, which is not recommended 2020-11-29T20:13:30.481+08:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never' 2020-11-29T20:13:30.482+08:00: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. We suggest setting it to 'never' 2020-11-29T20:13:30.482+08:00: Soft rlimits too low 2020-11-29T20:13:30.482+08:00: currentValue: 1024 2020-11-29T20:13:30.482+08:00: recommendedMinimum: 64000 --- --- Enable MongoDB's free cloud-based monitoring service, which will then receive and display metrics about your deployment (disk utilization, CPU, operation statistics, etc). The monitoring data will be available on a MongoDB website with a unique URL accessible to you and anyone you share the URL with. MongoDB may use this information to make product improvements and to suggest MongoDB products and deployment options to you. To enable free monitoring, run the following command: db.enableFreeMonitoring() To permanently disable this reminder, run the following command: db.disableFreeMonitoring() --- > var cfg ={"_id":"sharding1","protocolVersion":1,"members":[{"_id":1,"host":"192.168.0.110:47017"},{"_id":2,"host":"192.168.0.110:47018"},{"_id":3,"host":"192.168.0.110:47019"}]}; > rs.initiate(cfg); { "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1606652230, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1606652230, 1) } sharding1:SECONDARY> rs.status(); { "set" : "sharding1", "date" : ISODate("2020-11-29T12:17:14.439Z"), "myState" : 2, "term" : NumberLong(0), "syncSourceHost" : "", "syncSourceId" : -1, "heartbeatIntervalMillis" : NumberLong(2000), "majorityVoteCount" : 2, "writeMajorityCount" : 2, "votingMembersCount" : 3, "writableVotingMembersCount" : 3, "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "lastCommittedWallTime" : ISODate("1970-01-01T00:00:00Z"), "appliedOpTime" : { "ts" : Timestamp(1606652230, 1), "t" : NumberLong(-1) }, "durableOpTime" : { "ts" : Timestamp(1606652230, 1), "t" : NumberLong(-1) }, "lastAppliedWallTime" : ISODate("2020-11-29T12:17:10.122Z"), "lastDurableWallTime" : ISODate("2020-11-29T12:17:10.122Z") }, "lastStableRecoveryTimestamp" : Timestamp(0, 0), "members" : [ { "_id" : 1, "name" : "192.168.0.110:47017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 225, "optime" : { "ts" : Timestamp(1606652230, 1), "t" : NumberLong(-1) }, "optimeDate" : ISODate("2020-11-29T12:17:10Z"), "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "Could not find member to sync from", "configVersion" : 1, "configTerm" : -1, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 2, "name" : "192.168.0.110:47018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 4, "optime" : { "ts" : Timestamp(1606652230, 1), "t" : NumberLong(-1) }, "optimeDurable" : { "ts" : Timestamp(1606652230, 1), "t" : NumberLong(-1) }, "optimeDate" : ISODate("2020-11-29T12:17:10Z"), "optimeDurableDate" : ISODate("2020-11-29T12:17:10Z"), "lastHeartbeat" : ISODate("2020-11-29T12:17:14.138Z"), "lastHeartbeatRecv" : ISODate("2020-11-29T12:17:14.246Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "configVersion" : 1, "configTerm" : -1 }, { "_id" : 3, "name" : "192.168.0.110:47019", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 4, "optime" : { "ts" : Timestamp(1606652230, 1), "t" : NumberLong(-1) }, "optimeDurable" : { "ts" : Timestamp(1606652230, 1), "t" : NumberLong(-1) }, "optimeDate" : ISODate("2020-11-29T12:17:10Z"), "optimeDurableDate" : ISODate("2020-11-29T12:17:10Z"), "lastHeartbeat" : ISODate("2020-11-29T12:17:14.138Z"), "lastHeartbeatRecv" : ISODate("2020-11-29T12:17:14.244Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "configVersion" : 1, "configTerm" : -1 } ], "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1606652230, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1606652230, 1) } ``` > 使用SCP传输到两外两台服务器 ```shell [root@CLL-MASTER mongodb]# scp -r install CLL-SLAVE1:/usr/local/custom-util/mongodb/ mongodb-linux-x86_64-rhel70-4.4.2.tgz 100% 68MB 85.7MB/s 00:00 [root@CLL-MASTER mongodb]# scp -r sharding/shard1/conf/mongo.conf CLL-SLAVE1:/usr/local/custom-util/mongodb/sharding/shard1/conf/ mongo.conf 100% 197 73.6KB/s 00:00 [root@CLL-MASTER mongodb]# scp -r sharding/shard2/conf/mongo.conf CLL-SLAVE1:/usr/local/custom-util/mongodb/sharding/shard2/conf/ mongo.conf 100% 197 141.2KB/s 00:00 [root@CLL-MASTER mongodb]# scp -r sharding/shard3/conf/mongo.conf CLL-SLAVE1:/usr/local/custom-util/mongodb/sharding/shard3/conf/ mongo.conf ``` ```shell # 启动分片复制集 [root@CLL-SLAVE2 mongodb]# ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard1/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 1547 child process started successfully, parent exiting [root@CLL-SLAVE2 mongodb]# ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard2/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 1590 child process started successfully, parent exiting [root@CLL-SLAVE2 mongodb]# ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard3/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 1633 child process started successfully, parent exiting [root@CLL-SLAVE2 mongodb]# ps -ef | grep mongod root 1547 1 4 20:30 ? 00:00:00 ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard1/conf/mongo.conf root 1590 1 4 20:30 ? 00:00:00 ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard2/conf/mongo.conf root 1633 1 6 20:30 ? 00:00:00 ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard3/conf/mongo.conf ``` ````js [root@CLL-SLAVE2 mongodb]# ./station/mongodb-4.4.2/bin/mongo --host=192.168.0.112 --port=47017 MongoDB shell version v4.4.2 connecting to: mongodb://192.168.0.112:47017/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("e7f91054-b2ec-4b2e-b134-183411838f52") } MongoDB server version: 4.4.2 Welcome to the MongoDB shell. For interactive help, type "help". For more comprehensive documentation, see https://docs.mongodb.com/ Questions? Try the MongoDB Developer Community Forums https://community.mongodb.com --- The server generated these startup warnings when booting: 2020-11-29T20:30:38.401+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted 2020-11-29T20:30:38.401+08:00: You are running this process as the root user, which is not recommended 2020-11-29T20:30:38.402+08:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never' 2020-11-29T20:30:38.402+08:00: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. We suggest setting it to 'never' 2020-11-29T20:30:38.402+08:00: Soft rlimits too low 2020-11-29T20:30:38.402+08:00: currentValue: 1024 2020-11-29T20:30:38.402+08:00: recommendedMinimum: 64000 --- --- Enable MongoDB's free cloud-based monitoring service, which will then receive and display metrics about your deployment (disk utilization, CPU, operation statistics, etc). The monitoring data will be available on a MongoDB website with a unique URL accessible to you and anyone you share the URL with. MongoDB may use this information to make product improvements and to suggest MongoDB products and deployment options to you. To enable free monitoring, run the following command: db.enableFreeMonitoring() To permanently disable this reminder, run the following command: db.disableFreeMonitoring() --- > # 配置分片复制集 var cfg={"_id":"sharding3","protocolVersion":1,"members":[{"_id":1,"host":"192.168.0.112:47017"},{"_id":2,"host":"192.168.0.112:47018"},{"_id":3,"host":"192.168.0.112:47019"}]}; rs.initiate(cfg); rs.status(); ```` #### 配置集搭建 配置集中使用一主两从。配置集群目录规划为 安装目录:**/usr/local/custom-util/mongodb/config-server** 配置集名称为:**configServerSet** 安装目录下新建四个文件夹**config1、config2、config3**代表集群中三个节点,使用端口分别为**27018、27019、27020** ``` [root@CLL-MASTER install]# cd ../config-server/ [root@CLL-MASTER config-server]# clear [root@CLL-MASTER config-server]# ls mongodb-linux-x86_64-rhel70-4.4.2 [root@CLL-MASTER config-server]# mv mongodb-linux-x86_64-rhel70-4.4.2 config1 [root@CLL-MASTER config-server]# ls config1 [root@CLL-MASTER config-server]# cp -r config1 config2 [root@CLL-MASTER config-server]# ls config1 config2 [root@CLL-MASTER config-server]# cp -r config1 config3 ``` ```shell # 配置集配置文件信息如下 [root@CLL-MASTER config-server]# cat config1/conf/mongo.conf dbpath=/usr/local/custom-util/mongodb/config-server/config1/data bind_ip=0.0.0.0 port=27018 fork=true logpath=/usr/local/custom-util/mongodb/config-server/config1/log/mongo.log replSet=configServerSet # 表示这是一个配置集节点 configsvr=true ``` ```shell # 配置集中节点启动 [root@CLL-MASTER config-server]# ./config1/bin/mongod -f ./config1/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 3338 child process started successfully, parent exiting [root@CLL-MASTER config-server]# ./config2/bin/mongod -f ./config2/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 3389 child process started successfully, parent exiting [root@CLL-MASTER config-server]# ./config3/bin/mongod -f ./config3/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 3441 child process started successfully, parent exiting [root@CLL-MASTER config-server]# ps -ef | grep mongod root 1466 1 0 08:28 ? 00:04:21 ./bin/mongod -f ./conf/mongodb.conf root 2563 1 1 18:57 ? 00:00:35 ./server2/bin/mongod -f ./server2/conf/mongo.conf root 2613 1 1 18:57 ? 00:00:33 ./server3/bin/mongod -f ./server3/conf/mongo.conf root 2846 1 1 19:07 ? 00:00:26 ./server4/bin/mongod -f ./server4/conf/mongo.conf root 3099 1 1 19:23 ? 00:00:18 ./server1/bin/mongod -f ./server1/conf/mongo.conf root 3338 1 5 19:43 ? 00:00:01 ./config1/bin/mongod -f ./config1/conf/mongo.conf root 3389 1 7 19:43 ? 00:00:01 ./config2/bin/mongod -f ./config2/conf/mongo.conf root 3441 1 10 19:43 ? 00:00:01 ./config3/bin/mongod -f ./config3/conf/mongo.con ``` ```js # 配置集配置并初始化 [root@CLL-MASTER config-server]# ./config1/bin/mongo --host=192.168.0.110 --port=27018 var cscfg={"_id":"configServerSet","members":[ {"_id":1,"host":"192.168.0.110:27018"},{"_id":2,"host":"192.168.0.110:27019"}, {"_id":3,"host":"192.168.0.110:27020"}]}; rs.initiate(cscfg); > var cscfg={"_id":"configServerSet","members":[ {"_id":1,"host":"192.168.0.110:27018"},{"_id":2,"host":"192.168.0.110:27019"}, {"_id":3,"host":"192.168.0.110:27020"}]}; > rs.initiate(cscfg); { "ok" : 1, "$gleStats" : { "lastOpTime" : Timestamp(1606650575, 1), "electionId" : ObjectId("000000000000000000000000") }, "lastCommittedOpTime" : Timestamp(0, 0), "$clusterTime" : { "clusterTime" : Timestamp(1606650575, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1606650575, 1) } configServerSet:SECONDARY> ``` ```js # 查看配置集群状态 configServerSet:SECONDARY> rs.status(); { "set" : "configServerSet", "date" : ISODate("2020-11-29T11:50:48.887Z"), "myState" : 1, "term" : NumberLong(1), "syncSourceHost" : "", "syncSourceId" : -1, "configsvr" : true, "heartbeatIntervalMillis" : NumberLong(2000), "majorityVoteCount" : 2, "writeMajorityCount" : 2, "votingMembersCount" : 3, "writableVotingMembersCount" : 3, "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1606650648, 1), "t" : NumberLong(1) }, "lastCommittedWallTime" : ISODate("2020-11-29T11:50:48.098Z"), "readConcernMajorityOpTime" : { "ts" : Timestamp(1606650648, 1), "t" : NumberLong(1) }, "readConcernMajorityWallTime" : ISODate("2020-11-29T11:50:48.098Z"), "appliedOpTime" : { "ts" : Timestamp(1606650648, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1606650648, 1), "t" : NumberLong(1) }, "lastAppliedWallTime" : ISODate("2020-11-29T11:50:48.098Z"), "lastDurableWallTime" : ISODate("2020-11-29T11:50:48.098Z") }, "lastStableRecoveryTimestamp" : Timestamp(1606650648, 1), "electionCandidateMetrics" : { "lastElectionReason" : "electionTimeout", "lastElectionDate" : ISODate("2020-11-29T11:49:46.890Z"), "electionTerm" : NumberLong(1), "lastCommittedOpTimeAtElection" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "lastSeenOpTimeAtElection" : { "ts" : Timestamp(1606650575, 1), "t" : NumberLong(-1) }, "numVotesNeeded" : 2, "priorityAtElection" : 1, "electionTimeoutMillis" : NumberLong(10000), "numCatchUpOps" : NumberLong(0), "newTermStartDate" : ISODate("2020-11-29T11:49:46.939Z"), "wMajorityWriteAvailabilityDate" : ISODate("2020-11-29T11:49:48.248Z") }, "members" : [ { "_id" : 1, "name" : "192.168.0.110:27018", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 434, "optime" : { "ts" : Timestamp(1606650648, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2020-11-29T11:50:48Z"), "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "electionTime" : Timestamp(1606650586, 1), "electionDate" : ISODate("2020-11-29T11:49:46Z"), "configVersion" : 1, "configTerm" : 1, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 2, "name" : "192.168.0.110:27019", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 73, "optime" : { "ts" : Timestamp(1606650646, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1606650646, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2020-11-29T11:50:46Z"), "optimeDurableDate" : ISODate("2020-11-29T11:50:46Z"), "lastHeartbeat" : ISODate("2020-11-29T11:50:46.944Z"), "lastHeartbeatRecv" : ISODate("2020-11-29T11:50:48.465Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "192.168.0.110:27018", "syncSourceId" : 1, "infoMessage" : "", "configVersion" : 1, "configTerm" : 1 }, { "_id" : 3, "name" : "192.168.0.110:27020", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 73, "optime" : { "ts" : Timestamp(1606650646, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1606650646, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2020-11-29T11:50:46Z"), "optimeDurableDate" : ISODate("2020-11-29T11:50:46Z"), "lastHeartbeat" : ISODate("2020-11-29T11:50:46.944Z"), "lastHeartbeatRecv" : ISODate("2020-11-29T11:50:48.476Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "192.168.0.110:27018", "syncSourceId" : 1, "infoMessage" : "", "configVersion" : 1, "configTerm" : 1 } ], "ok" : 1, "$gleStats" : { "lastOpTime" : Timestamp(1606650575, 1), "electionId" : ObjectId("7fffffff0000000000000001") }, "lastCommittedOpTime" : Timestamp(1606650648, 1), "$clusterTime" : { "clusterTime" : Timestamp(1606650648, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1606650648, 1) } ``` #### 路由集搭建 > 简要描述 在192.168.0.111服务器上搭建一个路由节点。 ```shell port=27017 bind_ip=0.0.0.0 fork=true logpath=/route.log configdb=configsvr/192.168.0.110:27018,192.168.0.110:27019,192.168.0.110:27020 ``` ```shell # 启动路由节点 [root@CLL-SLAVE1 mongodb]# ./station/mongodb-4.4.2/bin/mongos -f ./route/conf/mongo.conf about to fork child process, waiting until server is ready for connections. forked process: 1874 child process started successfully, parent exiting [root@CLL-SLAVE1 mongodb]# ps -ef | grep mongo root 1578 1 1 20:27 ? 00:00:16 ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard1/conf/mongo.conf root 1621 1 0 20:27 ? 00:00:12 ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard2/conf/mongo.conf root 1664 1 0 20:27 ? 00:00:12 ./station/mongodb-4.4.2/bin/mongod -f ./sharding/shard3/conf/mongo.conf root 1874 1 0 20:48 ? 00:00:00 ./station/mongodb-4.4.2/bin/mongos -f ./route/conf/mongo.conf ``` ```js # 路由节点连接,注意这里显示的是mongos>代表的是路由节点 mongos> sh.status(); --- Sharding Status --- sharding version: { "_id" : 1, "minCompatibleVersion" : 5, "currentVersion" : 6, "clusterId" : ObjectId("5fc38adaaa24a39ff0f019fa") } shards: active mongoses: autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: no Failed balancer rounds in last 5 attempts: 0 Migration Results for the last 24 hours: No recent migrations databases: { "_id" : "config", "primary" : "config", "partitioned" : true } ``` ```` # 路由节点,添加分片节点信息 sh.addShard("sharding1/192.168.0.110:47017,192.168.0.110:47018,192.168.0.110:47019"); mongos> sh.addShard("sharding1/192.168.0.110:47017,192.168.0.110:47018,192.168.0.110:47019"); { "shardAdded" : "sharding1", "ok" : 1, "operationTime" : Timestamp(1606654552, 3), "$clusterTime" : { "clusterTime" : Timestamp(1606654552, 3), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } sh.addShard("sharding2/192.168.0.111:47017,192.168.0.111:47018,192.168.0.111:47019"); sh.addShard("sharding3/192.168.0.112:47017,192.168.0.112:47018,192.168.0.112:47019"); ```` ``` # 指定分片数据库和分片策略 sh.enableSharding("prototype"); # 这里使用name的hash分片。如果是普通分片,可以写成1或者-1 sh.shardCollection("prototype.resume_preview",{"name":"hashed"}); ``` ``` # 进行分片复制集测试 for(var i=1;i <= 1000; i++){ db.resume_preview.insert({"name":"test"+i,expectSalary:(Math.random()*20000).toFixed(2)}); } sharding1:PRIMARY> db.resume_preview.count(); 352 sharding2:PRIMARY> db.resume_preview.count(); 346 sharding3:PRIMARY> db.resume_preview.count(); 302 ``` ## JAVA应用 #### JAVA简单应用 > 创建模块引入依赖 ```xml prototype-mongodb com.cll.prototype 1.0-SNAPSHOT 4.0.0 mongodb-java 直接使用原生JAVA连接MongoDB org.mongodb mongo-java-driver ${mongo-java-driver.version} ``` > 编写JAVA连接MongoDB的工具类 ```java package com.cll.prototype.mongo.direct.util; import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import org.bson.Document; /** * 描述信息: * 构建客户端与Mongo Server连接的客户端的工具类 * @author CLL * @version 1.0 * @date 2020/11/29 13:44 */ public class MongoClientUtil { private static final String DEFAULT_DATABASE = "prototype"; private static final String DEFAULT_COLLECTION = "resume_preview"; public static MongoClient getClientInstance(){ MongoClient mongoClient = new MongoClient("192.168.0.110", 27017); // MongoDatabase db = mongoClient.getDatabase("prototype"); // MongoCollection resumePreview = db.getCollection("resume_preview"); return mongoClient; } public static MongoDatabase getDatabase(MongoClient mongoClient, String database){ if (null == mongoClient) { mongoClient = getClientInstance(); } if (null == database || "".equals(database)) { database = DEFAULT_DATABASE; } return mongoClient.getDatabase(database); } public static MongoCollection getCollection(MongoDatabase database, String collectionName){ if (null == database) { database = getDatabase(null, null); } if (null == collectionName || "".equals(collectionName)) { collectionName = DEFAULT_COLLECTION; } return database.getCollection(collectionName); } public static void close(MongoClient mongoClient){ mongoClient.close(); } } ``` > 编写测试方法 ```java package com.cll.prototype.mongo.direct.demo; import com.cll.prototype.mongo.direct.util.MongoClientUtil; import com.mongodb.MongoClient; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoCollection; import com.mongodb.client.model.Filters; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; import org.bson.Document; import org.bson.types.ObjectId; import java.util.Date; /** * 描述信息: * 新增文档记录 * @author CLL * @version 1.0 * @date 2020/11/29 13:44 */ public class DocumentDemo { public static void main(String[] args) { // insert(); // update(); // replace(); delete(); select(); } public static void insert(){ MongoClient clientInstance = MongoClientUtil.getClientInstance(); MongoCollection collection = MongoClientUtil.getCollection(MongoClientUtil.getDatabase(clientInstance, ""), null); // 注意这里的时间。现在虽然插入的1993-01-01默认为0点,所以向前推进8个小时之后,数据库存储的就是1992-12-31 16:00:00 Document document = Document.parse("{name: '王楠', birthday: new ISODate('1993-01-01'), city: '北京', gender: 0, expectSalary: 15000}"); collection.insertOne(document); MongoClientUtil.close(clientInstance); } /** * 导致其它字段删除 */ public static void replace(){ MongoClient clientInstance = MongoClientUtil.getClientInstance(); MongoCollection collection = MongoClientUtil.getCollection(MongoClientUtil.getDatabase(clientInstance, ""), null); Document queryBson = new Document(); queryBson.append("name", "陈林林"); Document updateBson = new Document(); updateBson.append("gender", 1); UpdateResult updateResult = collection.replaceOne(queryBson, updateBson); System.out.println(updateResult.toString()); clientInstance.close(); } /** * 修改的时候如果没有字段,会写入指定的字段 */ public static void update(){ MongoClient clientInstance = MongoClientUtil.getClientInstance(); MongoCollection collection = MongoClientUtil.getCollection(MongoClientUtil.getDatabase(clientInstance, ""), null); Document queryBson = new Document(); queryBson.append("gender", 1); Document updateBson = new Document(); updateBson.append("name", "陈林林"); updateBson.append("city", "郑州"); updateBson.append("gender", 0); updateBson.append("birthday", new Date()); updateBson.append("expectSalary", 10000); Document updateBsonInfo = new Document(); updateBsonInfo.append("$set", updateBson); UpdateResult updateResult = collection.updateOne(queryBson, updateBsonInfo); System.out.println(updateResult.toString()); clientInstance.close(); } public static void select(){ MongoClient clientInstance = MongoClientUtil.getClientInstance(); MongoCollection collection = MongoClientUtil.getCollection(MongoClientUtil.getDatabase(clientInstance, ""), null); Document queryBson = new Document(); queryBson.append("gender", 0); Document sortBson = new Document(); sortBson.append("expectSalary", -1); FindIterable findIterable = collection.find(queryBson).sort(sortBson); for (Document resume : findIterable) { System.out.println(resume); } // FindIterable expectSalary = collection.find(Filters.gt("expectSalary", 6000)).sort(sortBson); // for (Document resume : expectSalary) { // System.out.println(resume); // } clientInstance.close(); } public static void delete(){ MongoClient clientInstance = MongoClientUtil.getClientInstance(); MongoCollection collection = MongoClientUtil.getCollection(MongoClientUtil.getDatabase(clientInstance, ""), null); Document deleteBson = new Document(); deleteBson.append("_id", new ObjectId("5fc33276fe973605d8f47d1b")); DeleteResult deleteResult = collection.deleteOne(deleteBson); System.out.println("deleteResult = " + deleteResult.toString()); clientInstance.close(); } } ``` #### Spring中使用 > 创建模块引入依赖 ```xml prototype-mongodb com.cll.prototype 1.0-SNAPSHOT 4.0.0 mongodb-spring 在Spring的环境中使用MongoDB org.springframework.data spring-data-mongodb ${spring-data-mongodb.version} org.projectlombok lombok ${lombok.version} provided ``` > 编写配置文件 ```xml ``` > 编写实体类 ```java package com.cll.prototype.spring.bean; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.Date; /** * 描述信息: * * @author CLL * @version 1.0 * @date 2020/11/29 14:45 */ @Data @NoArgsConstructor @AllArgsConstructor public class ResumePreview { /** * MongoDB中的ObjectId类型的_id */ private String id; /** * 城市 */ private String city; /** * 姓名 */ private String name; /** * 性别 * 0:男 * 1:女 */ private Integer gender; /** * 出生日期 */ private Date birthday; /** * 期望薪资 */ private Double expectSalary; } ``` > 编写持久层接口 ```java package com.cll.prototype.spring.dao; import com.cll.prototype.spring.bean.ResumePreview; /** * 描述信息: * * @author CLL * @version 1.0 * @date 2020/11/29 14:51 */ public interface ResumePreviewDao { /** * 添加简历预览信息 * @param resumePreview 简历概要 */ void insertResumePreview(ResumePreview resumePreview); } ``` > 编写持久层实现类 ```java package com.cll.prototype.spring.dao.impl; import com.cll.prototype.spring.bean.ResumePreview; import com.cll.prototype.spring.dao.ResumePreviewDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.stereotype.Repository; /** * 描述信息: * * @author CLL * @version 1.0 * @date 2020/11/29 14:52 */ @Repository public class ResumePreviewDaoImpl implements ResumePreviewDao { @Autowired private MongoTemplate mongoTemplate; /** * 根据实体类名称生成集合名称 * @param resumePreview 简历概要 */ @Override public void insertResumePreview(ResumePreview resumePreview) { mongoTemplate.insert(resumePreview, "resume_preview"); } } ``` > 编写测试DEMO - 编写添加测试Demo ```java public static void insertTest() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-context.xml"); ResumePreviewDao bean = context.getBean(ResumePreviewDao.class); ResumePreview resumePreview = new ResumePreview(); // 如果设置ID,就使用这个ID,如果没有设置,就会自动生成 // resumePreview.setId("aaaaaaaaaaaaaaaaaaa"); resumePreview.setCity("郑州"); resumePreview.setName("苏志飞"); // 注意时间会和本地时间相差8个小时 LocalDateTime of = LocalDateTime.of(1992, 1, 2, 8, 0, 0); Date birthday = Date.from(of.atZone(ZoneId.systemDefault()).toInstant()); resumePreview.setBirthday(birthday); resumePreview.setGender(0); resumePreview.setExpectSalary(9000D); bean.insertResumePreview(resumePreview); } ``` ```js > db.resume_preview.find({name:"苏志飞"}).pretty(); { "_id" : ObjectId("5fc3586c214d140f4c9189d2"), "city" : "郑州", "name" : "苏志飞", "gender" : 0, "birthday" : ISODate("1992-01-02T00:00:00Z"), "expectSalary" : 9000, # 自动添加实体类的名称 "_class" : "com.cll.prototype.spring.bean.ResumePreview" } ``` #### SpringBoot使用 > 新建模块,引入依赖 ```xml prototype-mongodb com.cll.prototype 1.0-SNAPSHOT 4.0.0 mongodb-springboot SpringBoot环境下连接MongoDB org.springframework.boot spring-boot-starter-data-mongodb ${spring-boot-starter-data-mongodb.version} org.projectlombok lombok ${lombok.version} provided ``` > 编写配置文件 ```properties spring.data.mongodb.host=192.168.0.110 spring.data.mongodb.port=27017 spring.data.mongodb.database=prototype ``` > 编写项目启动类 ```java package com.cll.prototype.mongodb.springboot; import com.cll.prototype.mongodb.springboot.bean.ResumePreview; import com.cll.prototype.mongodb.springboot.dao.ResumePreviewDao; import com.cll.prototype.mongodb.springboot.repository.ResumePreviewRepository; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; import java.util.List; /** * 描述信息: * * @author CLL * @version 1.0 * @date 2020/11/29 16:54 */ @SpringBootApplication public class MongodbApplication { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(MongodbApplication.class); // ResumePreviewDao resumePreviewDao = applicationContext.getBean(ResumePreviewDao.class); // ResumePreview resumePreview = resumePreviewDao.findByName("王楠"); // System.out.println("result = " + resumePreview.toString()); ResumePreviewRepository resumePreviewRepository = applicationContext.getBean(ResumePreviewRepository.class); // List all = resumePreviewRepository.findAll(); // List resumePreviews = resumePreviewRepository.findByNameEquals("王楠"); List resumePreviews = resumePreviewRepository.findByNameAndExpectSalary("王楠", 15000D); System.out.println("result = " + resumePreviews); } } ``` > SpringBoot中通过MongoTemplate访问 - 编写实体类 ```java package com.cll.prototype.mongodb.springboot.bean; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.data.mongodb.core.mapping.Document; import java.util.Date; /** * 描述信息: * * @author CLL * @version 1.0 * @date 2020/11/29 14:45 */ @Data @NoArgsConstructor @AllArgsConstructor public class ResumePreview { /** * MongoDB中的ObjectId类型的_id */ private String id; /** * 城市 */ private String city; /** * 姓名 */ private String name; /** * 性别 * 0:男 * 1:女 */ private Integer gender; /** * 出生日期 */ private Date birthday; /** * 期望薪资 */ private Double expectSalary; } ``` - 编写持久层接口 ```java package com.cll.prototype.mongodb.springboot.dao; import com.cll.prototype.mongodb.springboot.bean.ResumePreview; import java.util.List; /** * 描述信息: * * @author CLL * @version 1.0 * @date 2020/11/29 14:51 */ public interface ResumePreviewDao { /** * 添加简历预览信息 * @param resumePreview 简历概要 */ void insertResumePreview(ResumePreview resumePreview); /** * 根据名称查询 * @param name 名称 * @return 查询实体 */ ResumePreview findByName(String name); /** * 根据名称查询 * @param name 名称 * @return 查询实体 */ List listByName(String name); /** * 根据名称查询 * @param name 名称 * @param expectSalary 期望薪资 * @return 查询实体 */ ResumePreview findByName(String name, Double expectSalary); } ``` - 编写持久层测试类 ```java package com.cll.prototype.mongodb.springboot.dao.impl; import com.cll.prototype.mongodb.springboot.bean.ResumePreview; import com.cll.prototype.mongodb.springboot.dao.ResumePreviewDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.stereotype.Repository; import java.util.List; /** * 描述信息: * * @author CLL * @version 1.0 * @date 2020/11/29 14:52 */ @Repository public class ResumePreviewDaoImpl implements ResumePreviewDao { @Autowired private MongoTemplate mongoTemplate; /** * 根据实体类名称生成集合名称 * @param resumePreview 简历概要 */ @Override public void insertResumePreview(ResumePreview resumePreview) { mongoTemplate.insert(resumePreview, "resume_preview"); } @Override public ResumePreview findByName(String name) { Query queryParam = new Query(); queryParam.addCriteria(Criteria.where("name").is(name)); List resumePreviewList = mongoTemplate.find(queryParam, ResumePreview.class, "resume_preview"); return resumePreviewList.isEmpty() ? null : resumePreviewList.get(0); } @Override public List listByName(String name) { Query queryParam = new Query(); queryParam.addCriteria(Criteria.where("name").is(name)); return mongoTemplate.find(queryParam, ResumePreview.class, "resume_preview"); } @Override public ResumePreview findByName(String name, Double expectSalary) { Query queryParam = new Query(); queryParam.addCriteria(Criteria.where("name").is(name).andOperator(Criteria.where("expectSalary").is(expectSalary))); List resumePreviewList = mongoTemplate.find(queryParam, ResumePreview.class, "resume_preview"); return resumePreviewList.isEmpty() ? null : resumePreviewList.get(0); } } ``` > SpringBoot中通过MongoRepository访问 - 改造实体类 ```java package com.cll.prototype.mongodb.springboot.bean; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.data.mongodb.core.mapping.Document; import java.util.Date; /** * 描述信息: * * @author CLL * @version 1.0 * @date 2020/11/29 14:45 */ @Data @NoArgsConstructor @AllArgsConstructor @Document("resume_preview") public class ResumePreview { /** * MongoDB中的ObjectId类型的_id */ private String id; /** * 城市 */ private String city; /** * 姓名 */ private String name; /** * 性别 * 0:男 * 1:女 */ private Integer gender; /** * 出生日期 */ private Date birthday; /** * 期望薪资 */ private Double expectSalary; } ``` - 创建持久层接口继承MongoRepository ```java package com.cll.prototype.mongodb.springboot.repository; import com.cll.prototype.mongodb.springboot.bean.ResumePreview; import org.springframework.data.mongodb.repository.MongoRepository; import java.util.List; /** * 描述信息: * * @author CLL * @version 1.0 * @date 2020/11/29 16:59 */ public interface ResumePreviewRepository extends MongoRepository { /** * 根据名称查询列表 * @param name 名称 * @return 列表 */ List findByNameEquals(String name); /** * 根据名称和期望薪资查询列表 * @param name 名称 * @param expectSalary 期望薪资 * @return 列表 */ List findByNameAndExpectSalary(String name, Double expectSalary); } ```