复制集的好处:
<1> 数据备份。每一个从节点都是一个备份
<2> 数据恢复。当主节点机器死掉后,可以让从节点成为主节点,保证程序正常运行
<3> 读写分离。即主节点写、从节点读。如果所有的读写操作全部放在主节点,那么对于主节点的压力太大,所有写入往主节点写,读取时在从节点这里读(不要在从节点写,在主节点读,因为从节点会检测主节点的更新,但是主节点不会检测子节点更新,那么子节点写数据,主节点不会更新操作,那么数据就不统一(自己猜的))
复制集操作,真是生产环境中,应该在不同机器上创建配置文件,但是环境有限,目前在同一个机器操作
具体步骤如下:
1、在电脑的任何位置创建一个.config文件,如27018.config
config文件内容示例如下:
dbpath=D:\Program Files\MongoDB\data\db\27018 #数据库路径
logpath=D:\Program Files\MongoDB\data\db\27018\log\mongodb27018.log#日志输出文件路径
logappend=true #错误日志采用追加模式,配置这个选项后mongodb的日志会追加到现有的日志文件,而不是从新创建一个新文件
journal=true #启用日志文件,默认启用
quiet=false #这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false
port=27018 #端口号默认为27017
pidfilepath=D:\Program Files\MongoDB\data\db\27018\27018.pid
#fork=true 后台启动(dos中启动实例时,不会卡在那里,但是只有linux系统才有效)
oplogSize=512 #
replSet=QHIT #复制集名称,所有节点的复制集名称必须要相同
(这里还有一个bind_ip的属性可以配置,目前还没了解怎么用)
2、在.config文件同目录(也可以不是同一目录,可以随便放在哪个磁盘都行,这里为了方便,放在同一目录),创建一个文件夹(如27018这个文件夹),文件夹里创建一个.pid的文件(如27018.pid,文件里面不用写内容)和一个文件夹(文件夹名称如:log),并在log文件夹里创建一个.log文件(如mongodb27018.log,文件里面不用写内容)
3、把第二步操作执行几次,比如重复操作3次,那么相当于创建了3个复制集,但是需要注意,所有的名称要换(比如把所有文件、文件夹、配置文件内容的27018换成27019)
4、使用cmd打开dos窗口
1)cd进入mongodb安装目录的bin目录
2)输入mongod -f"D:\Program Files\MongoDB\data\db\27018.config"命令创建一个数据库实例,(因为当前环境是在windows下操作,所以启动实例后会卡在这里,但是实例是正常启动了)
3)重复执行上面1、2操作,打开多个dos窗口开启27019和27020的数据库实例
4、上面启动了三个实例,相当于启动了三个不同的mongodb数据库的服务,下面就要对配置的复制集进行初始化操作
1)那么现在再重新打开一个dos窗口,cd进入mongodb安装目录的bin目录,使用mongolocalhost:27018(这里的端口号就是刚才自己配置实例的端口号,随便连接三个实例的哪个实例都可以)
2)在上面1步骤连接成功的dos窗口中输入如下示例配置:
config={"_id":"QHIT","menbers":[{"_id":0,"host":"127.0.0.1:27018"},{"_id":1,"host":"127.0.0.1:27019"},{"_id":2,"host":"127.0.0.1:27020","arbiterOnly":true}]}
config相当于是一个变量
值是所有配置复制集的信息
arbiterOnly代表当前实例是一个选举节点,选举节点作用是当主节点死掉后,选举节点负责挑选一个从节点来充当主节点(选举节点只需要配置这个属性即可,无需其他配置,在进行配置复制集是,应该也可以不用指定选举节点)
3)执行rs.initiate(config)进行初始化复制集
4)注意的几个事项以及自己犯的错误:
l 上面config变量的值,外层的那个_id必须与config文件中配置的replSet名称一致,否则会出错
l 不能去启动mongodb之间创建的那个服务,使用dos窗口连接默认27017的这个服务实例来执行初始化复制集操作,因为以前的服务27017并没有指定replSet名称
5、验证复制集同步
1)开启三个dos窗口,分别连接三个mongodb数据库实例
2)观察每个连接成功后,前面的标识,不是仅仅一个”>”符号,如:
QHIT : SECONDARY>
QHIT : ARBITER>
QHIT : PRIMARY>
前面的QHIT是在config文件中配置的replSet名称,后面的SECONDARY代表当前连接的实例是一个从节点,ARBITER代表连接的实例是一个选举节点,PRIMARY代表连接的实例是一个主节点
注:如果没有找到PRIMARY的窗口,那么exit先退出来,再重新连接试试
3)那么我们在主节点的dos窗口上,使用use选择一个数据库中的表,进行insert插入操作
4)在其他从节点上也选择刚才的那个数据库中的那个表,查询数据,会发现在主节点插入的数据,在从节点中也同样存在(这就是复制集的作用,当在主节点上插入数据,会生成日志文件,那么所有的从节点会不断检测主节点是否有数据改变,如果有就立即在从节点上进行更新同步操作)
注意,在从节点查询时,会出错,因为SECONDARY这种从节点是不允许读写的,如果非要解决,需要先在当前从节点中执行rs.slaveOk();让从节点支持读写操作
5)也可以尝试,把主节点的启动实例窗口关闭掉,那么再使用不同dos窗口连接不同实例,本来之前的从节点,因为主节点死掉,所以会提升成为主节点(这样就可以放在有一个机器的硬盘问题或其他原因,导致主节点数据库无法使用,那么就可以让从节点成为主节点,保证程序的正常运行)
5、连接复制集
URI 格式:
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
说明:
mongodb:// 前缀,代表这是一个Connection String
username:password@ 如果启用了鉴权,需要指定用户密码
hostX:portX 复制集成员的ip:port信息,多个成员以逗号分割
/database 鉴权时,用户帐号所属的数据库
?options 指定额外的连接选项
6、java程序连接复制集(没有尝试过)
MongoClientURI connectionString = new
MongoClientURI("mongodb://root:****@localhost:27018, localhost:27019,localhost:27020/admin?replicaSet=QHIT"); // ****替换为root密码
MongoClient client = new MongoClient(connectionString);
MongoDatabase database = client.getDatabase("mydb");
MongoCollection collection =database.getCollection("mycoll");
7、读写分离(没有尝试过)
在options里添加readPreference=secondaryPreferred即可实现,读请求优先到Secondary节点,从而实现读写分离的功能
网上的其他说法:
第一种方法:在java代码中调用dbFactory.getDb().slaveOk();
第二种方法:在java代码中调用
dbFactory.getDb().setReadPreference(ReadPreference.secondaryPreferred());//在复制集中优先读secondary,如果secondary访问不了的时候就从master中读
或
dbFactory.getDb().setReadPreference(ReadPreference.secondary());//只从secondary中读,如果secondary访问不了的时候就不能进行查询
第三种方法:在配置mongo的时候增加slave-ok="true"也支持直接从secondary中读
<mongo:mongo id="mongo"host="${mongodb.host}" port="${mongodb.port}">
<mongo:optionsslave-ok="true"/>
</mongo:mongo>
7、限制连接数(没有尝试过)
在options里添加maxPoolSize=xx即可将客户端连接池限制在xx以内