Mongodb学习(9)集群搭建以及错误处理

来源:互联网 发布:android 源码添加apk 编辑:程序博客网 时间:2024/06/05 04:40

mongodb 这种NoSQL(非关系型数据库),有其自身的特点和有点。

本文来说一下Mongodb的三种集群方式的搭建:Replica Set / Sharding / Master-Slaver


Replica Set

       中文翻译叫做副本集

其实简单来说就是集群当中包含了多份数据,保证主节点挂掉了,备节点能继续提供数据服务,提供的前提就是数据需要和主节点一致。如下图:

       Mongodb(M)表示主节点,Mongodb(S)表示备节点,Mongodb(A)表示仲裁节点。主备节点存储数据,仲裁节点不存储数据。客户端同时连接主节点与备节点,不连接仲裁节点。

       默认设置下,主节点提供所有增删查改服务,备节点不提供任何服务,作为一个备份。但是可以通过设置使备节点提供查询服务,这样就可以减少主节点的压力,当客户端进行数据查询时,请求自动转到备节点上。这个设置叫做Read Preference Modes,同时Java客户端提供了简单的配置方式,可以不必直接对数据库进行操作

当主节点挂掉的时候,其余节点根据投票选出一个新的主节点,提供读写功能

       仲裁节点是一种特殊的节点,它本身并不存储数据,主要的作用是决定哪一个备节点在主节点挂掉之后提升为主节点,所以客户端不需要连接此节点。这里虽然只有一个备节点,但是仍然需要一个仲裁节点来提升备节点级别。

介绍完了集群方案,那么现在就开始搭建了。



1.创建数据文件夹

一般情况下,默认是把数据目录放在根节点下的, 但是这里为了省事(不用每次执行都加sudo), 因此建立在用户目录下吧

$:mkdir -p ~/data/mongodb/data/master$:mkdir -p ~/data/mongodb/data/slaver$:mkdir -p ~/data/mongodb/data/arbiter这三个目录分别是主节点,备用节点, 仲裁节点

$:mkdir -p ~/data/mongodb/log/$:touch ~/data/mongodb/log/master.log$:touch ~/data/mongodb/log/slaver.log$:touch ~/data/mongodb/log/artiber.log创建log文件


好了~, 到此我们的第一步准备工作就做好了



2.建立配置文件

配置文件的内容比较多, 这里就直接写到文件中去。

配置文件说明

#dbpath:数据存放目录#logpath:日志存放路径#pidfilepath:进程文件,方便停止mongodb, 存贮进程号#directoryperdb:为每一个数据库按照数据库名建立文件夹存放#logappend:以追加的方式记录日志#replSet:replica set的名字#bind_ip:mongodb所绑定的ip地址#port:mongodb进程所使用的端口号,默认为27017#fork:以后台方式运行进程#oplogSize:mongodb操作日志文件的最大大小。单位为Mb,默认为硬盘剩余空间的5%#noprealloc:不预先分配存储


文件路径:~/data/mongodb/

#mastdbpath=/home/jm/data/mongodb/data/master/logpath=/home/jm/data/mongodb/log/master.logpidfilepath=/home/jm/data/mongodb/master.piddirectoryperdb=truelogappend=truereplSet=testrs bind_ip=127.0.0.1port=27017fork=trueoplogSize=10000noprealloc=true
#slaver.confdbpath=/home/jm/data/mongodb/data/slaver/logpath=/home/jm/data/mongodb/log/slaver.logpidfilepath=/home/jm/data/mongodb/slaver.piddirectoryperdb=truelogappend=truereplSet=testrs bind_ip=127.0.0.2port=27017fork=trueoplogSize=10000noprealloc=true
#artiber.confdbpath=/home/jm/data/mongodb/data/arbiter/logpath=/home/jm/data/mongodb/log/arbiter.logpidfilepath=/home/jm/data/mongodb/arbiter.piddirectoryperdb=truelogappend=truereplSet=testrs bind_ip=127.0.0.3port=27017fork=trueoplogSize=10000noprealloc=true


3.通过配置文件,启动mongodb

进入mongodb的安装目录下,启动


$:cd ~/mongodb-linux-x86_64-ubuntu1404-3.4.4/bin/$:./mongod -f ~/data/mongodb/master.conf$:./mongod -f ~/data/mongodb/slaver.conf$:./mongod -f ~/data/mongodb/arbiter.conf


如果能够正常启动, 那么应该会有如下信息显示:

note: noprealloc may hurt performance in many applicationsabout to fork child process, waiting until server is ready for connections.forked process: 9771child process started successfully, parent exiting

这样每次启动成功就会这样显示, 进程以子进程的方式在后台运行,log也存贮在指定的目录中


4.错误处理

这里最常见的几个错误以及解决方式:

4.1 error number 1 

ERROR: child process failed, exited with error number 1


这种错误,真的是好烦人, 在网上少了老半天, 无果, 最后在一个角落里看到了一个解决方法:

报了这个 number 1 的错误, 是因为我们指定的 log路径或者是其他文件路径不正确, 造成了文件不可读

尝试用下面的命令就能看到这样的提示了:

$: ./mongod -f --repair ~/data/mongodb/master.conf Error reading config file: No such file or directory

解决方案其实也很简单, 一般情况下是我们的文件路径定义错误

如果是文件是放在用目录下, 一定要写清楚 绝对路径

应该是这样  /home/jm/data/mongodb/log/master.conf,   不能是~/data/mongodb/log/master.conf


4.2 error number 100


ERROR: child process failed, exited with error number 100


这算是一个Mongod 启动的一个常见错误,非法关闭的时候,lock 文件没有干掉,第二次启动的时候检查到有lock 文件的时候,就报这个错误了。

解决方法:进入 mongod 上一次启动的时候指定的 data 目录  --dbpath=~/data/mongodb/data/

删除掉该文件:

rm ~/data/mongodb/data/mongo.lock 

再使用 下面的命令修复一下,之后再次启动应该就ok了

$: ./mongod --repair


5.配置三个节点

可以通过客户端连接mongodb,也可以直接在三个节点中选择一个连接mongodb。

./mongo 127.0.0.1:27017   #ip和port是某个节点的地址  >use admin  cfg={ _id:"testrs", members:[ {_id:0,host:'127.0.0.1:27017',priority:2}, {_id:1,host:'127.0.0.2:27017',priority:1},   {_id:2,host:'127.0.0.3:27017',arbiterOnly:true}] };  


cfg是可以任意的名字,当然最好不要是mongodb的关键字,conf,config都可以。最外层的_id表示replica set的名字,members里包含的是所有节点的地址以及优先级。优先级最高的即成为主节点,即这里的127.0.0.1:27017。
特别注意的是,对于仲裁节点,需要有个特别的配置——arbiterOnly:true。这个千万不能少了,不然主备模式就不能生效。
配置的生效时间根据不同的机器配置会有长有短,配置不错的话基本上十几秒内就能生效,有的配置需要一两分钟。
如果生效了,执行rs.status()命令会看到如下信息:

{"set" : "testrs","date" : ISODate("2017-06-09T02:46:39.036Z"),"myState" : 1,"term" : NumberLong(2),"heartbeatIntervalMillis" : NumberLong(2000),"optimes" : {"lastCommittedOpTime" : {"ts" : Timestamp(1496976389, 1),"t" : NumberLong(2)},"appliedOpTime" : {"ts" : Timestamp(1496976389, 1),"t" : NumberLong(2)},"durableOpTime" : {"ts" : Timestamp(1496976389, 1),"t" : NumberLong(2)}},"members" : [{"_id" : 0,"name" : "127.0.0.1:27017","health" : 1,"state" : 1,"stateStr" : "PRIMARY","uptime" : 73,"optime" : {"ts" : Timestamp(1496976389, 1),"t" : NumberLong(2)},"optimeDate" : ISODate("2017-06-09T02:46:29Z"),"electionTime" : Timestamp(1496976337, 1),"electionDate" : ISODate("2017-06-09T02:45:37Z"),"configVersion" : 1,"self" : true},{"_id" : 1,"name" : "127.0.0.2:27017","health" : 1,"state" : 2,"stateStr" : "SECONDARY","uptime" : 61,"optime" : {"ts" : Timestamp(1496976389, 1),"t" : NumberLong(2)},"optimeDurable" : {"ts" : Timestamp(1496976389, 1),"t" : NumberLong(2)},"optimeDate" : ISODate("2017-06-09T02:46:29Z"),"optimeDurableDate" : ISODate("2017-06-09T02:46:29Z"),"lastHeartbeat" : ISODate("2017-06-09T02:46:37.701Z"),"lastHeartbeatRecv" : ISODate("2017-06-09T02:46:37.506Z"),"pingMs" : NumberLong(0),"syncingTo" : "127.0.0.1:27017","configVersion" : 1},{"_id" : 2,"name" : "127.0.0.3:27017","health" : 1,"state" : 7,"stateStr" : "ARBITER","uptime" : 55,"lastHeartbeat" : ISODate("2017-06-09T02:46:37.709Z"),"lastHeartbeatRecv" : ISODate("2017-06-09T02:46:38.444Z"),"pingMs" : NumberLong(0),"configVersion" : 1}],"ok" : 1}

如果配置正在生效,其中会包含如下信息:

"stateStr" : "RECOVERING"  



至此, 基本的搭建工作就完成了。 下面就可以再自己调试一下

#coding:utf-8from pymongo import MongoClientmaster_client=MongoClient('127.0.0.1',27017)#连接主节点slaver_client=MongoClient('127.0.0.2',27017)#连接从节点#利用主节点插入数据master_db=master_client.testmaster_table=master_db.persondict_data={'Jimy':20}dict_list=[{'Bob':22},{'Cindy':66}]master_table.insert_one(dict_data)print 'insert  a  data  success'master_table.insert(dict_list)print 'insert   datas  success'#利用从节点查询数据for data in slaver_client.test.person.find():print data#结果是在从节点上查到了主节点插入的数据




插入一个启动数据库的程序

#!/usr/bin/python#-*-coding:utf-8-*-"""    This file is for initiate mongodb situation        When you want to save book file in file system,then you don't need sharding cluster,that the database design is:    database:books_fs    collections:book_detail    fields:        book_detail:            book_name            alias_name:vector            author:vector            book_description:string            book_covor_image_path:string            book_covor_image_url:string            book_download:vector            book_file_url:string            book_file:string            original_url:string            update_time:datetime    index:        book_name        alias_name        author    So what this do is to delete books_fs is it has existed,and create index for it."""import typesfrom pymongo import MongoClientfrom pymongo import ASCENDING, DESCENDINGDATABASE_NAME = "books_fs"client = NoneDATABASE_HOST = "localhost"DATABASE_PORT = 27017INDEX = {\            #collection            'book_detail':\                {\                    (('book_name',ASCENDING),('author',ASCENDING)):{'name':'book_name_author','unique':True},                    'book_name':{'name':'book_name'},                    'author':{'name':'author'},                    'alias_name':{'name':'alias_name'},                }\        }def drop_database(name_or_database):    if name_or_database and client:        client.drop_database(name_or_database)def create_index():    """        create index for books_fs.book_detail    """    for k,v in INDEX.items():        for key,kwargs in v.items():            client[DATABASE_NAME][k].ensure_index(list(key) if type(key)==types.TupleType else key,**kwargs)if __name__ == "__main__":    client = MongoClient(DATABASE_HOST,DATABASE_PORT)     drop_database(DATABASE_NAME)    create_index()







原创粉丝点击