MongoD副本集(一)

副本集的目的? 

1.提供冗余备份,因为一份数据会复制多份放在不同的服务器上

2.避免单点故障,一旦副本集中主服务器挂掉,其余成员会迅速选举出新的primary,对外提供服务。

3.实现读写分离。可以设置在主服务器上进行写操作,在剩余从服务器上进行读操作,大大减轻主服务器的负担。但是这样可能会存在数据不实时的问题。 

副本集中成员类别? 

1.primary:

副本集中的主服务器,只有它才能进行写操作,其他成员都只能从它进行数据同步

2.普通secondary

副本集中的从服务器,从服务器同步数据,可以接受读操作,在一定条件下可以成为primary

3.Priority 0,优先级设为0的服务器。可以同步数据,接受读操作,但是永远不会变成primary,一般仅仅用于数据备份。

4.Hidden Replica Set Members,这种服务器和上面的priority 0 服务器类似,但是有一点不同的是,客户端无法对它进行读操作。

db.isMaster()命令也看不到它。

sh1:PRIMARY> db.isMaster()

{

        "setName" : "sh1",

        "ismaster" : true,

        "secondary" : false,

        "hosts" : [

                "192.168.69.41:10001",

                "192.168.69.42:10001",

                "192.168.69.40:10001"

        ],

        "primary" : "192.168.69.41:10001",

        "me" : "192.168.69.41:10001",

        "maxBsonObjectSize" : 16777216,

        "maxMessageSizeBytes" : 48000000,

        "localTime" : ISODate("2013-07-16T08:01:37.145Z"),

        "ok" : 1

}

5.Delayed members,和上面的隐藏节点有相同属性,不过,延迟节点会延迟同步数据。

6.Arbiter,仲裁节点。上面几种类型的成员都会从主节点同步数据,仲裁节不会同步数据,他也参与投票,但是不会成为primary。如果集群里有多台服务器,而且数据冗余已经足够,为了增强容差,可以在副本集中添加多个仲裁节点。 

最大成员数目: 

副本集一般最多可以有12个成员,同时投票的成员数最多为7个。添加副本集成员或者是为了分担读压力,或者是为了增加冗余。但是要注意添加后成员数量是否是奇数,否则需要添加仲裁节点。以后的版本应该会取消这些限制。

由于投票成员最多为7个,可以设置剩余的为非投票成员,这些成员不参与投票,但是他可以否决投票,从而成为primary 

影响primary选举的因素

影响选举的因素有4个:

心跳:

副本集成员之间每两秒相互发送一次心跳,心跳包含状态映射表,例如,优先级信息,是否有新节点加入,是否有节点宕机。如果心跳发出后十秒,对方没有返回,节点会认为对方已经宕机,把他标记为不可达,同时通过心跳向其他节点发送这个重要信息。 

优先级:

优先级不言自明。副本集中的成员收到心跳后,将会投票给优先级最高的成员。没有设置优先级时,默认是1。如果设置优先级是0,那么这个成员参与投票,同步数据,但是不可能成为primary 

Optime:

optime代表成员上次从primary应用日志的时间戳。在优先级相同的情况下,没有最新的optime则无法成为primary。所以,优先级相同情况下,一般谁的optime最新,谁就最可能成为primary。也是是说,谁最先启动,谁就是primary 

sh0:SECONDARY> rs.status().members

[

        {

                "_id" : 1,

                "name" : "192.168.69.40:10000",

                "health" : 1,

                "state" : 1,

                "stateStr" : "PRIMARY",

                "uptime" : 422043,

                "optime" : {

"t" : 1373954309,

"i" : 139

                },

                "optimeDate" : ISODate("2013-07-16T05:58:29Z"),

                "lastHeartbeat" : ISODate("2013-07-16T07:14:20Z"),

                "lastHeartbeatRecv" : ISODate("2013-07-16T07:14:21Z"),

                "pingMs" : 0

        },

网络连接:

如果一个加点不能和一半以上的节点进行通信,他无法成为primary。所以,在三个成员的情况下,如果坏掉两个(都是secondly),原来的primary将会变成secondary。这个时候,副本集就变成只读的了。这点尤其需要注意。副本集成员个数与容错性(fault tolerance)如下:

 

所以,设置了三个成员(一主二副)的情况下,如果还有别的机器,可以在其他机器上添加几个仲裁节点,保证是奇数个即可。对于一个副本集,仲裁节点一般不建议配置在已经是primary或者secondary的机器上。 

网络分割:如果成员被分立,但是配置未改变,这会造成投票量不能过半的问题,导致无法选举出primary,副本集变成只读。

例如:有个副本集有7个成员,现在由于物理原因分成了两部分,分别包含4个和3个成员。那么,第二个副本集由于投票成员是3,不到47的一半),这个副本集就会变成只读。 

什么时候发生选举:

1.副本集初始化

2.Primary宕机或者用命令把他剔除出副本集。

3.副本集中一个Secondary无法与primary通信的情况下,将会触发选举。

选举期间,由于没有primary,副本集无法提供写服务,但是可以提供读服务。 

6 具备选举资格的成员

PRIMARY, SECONDARY, RECOVERING, ARBITER, and ROLLBACK.,不要通过修改vote来禁掉其选举资格。

选举过程 

上面谈到选举发生的条件,下面介绍选举的具体过程:

各节点每两秒向其他节点发送心跳,每个节点收到心跳后会更新自己的状态映射表,包括:各节点优先级,各节点的optime,是否有新节点加入,是否有老节点宕机等等

sh0:PRIMARY> rs.status()

{

        "set" : "sh0",

        "date" : ISODate("2013-07-16T09:31:04Z"),

        "myState" : 1,

        "members" : [

                {

                        "_id" : 1,

                        "name" : "192.168.69.40:10000",

                        "health" : 1,

                        "state" : 1,

                        "stateStr" : "PRIMARY",

                        "uptime" : 503001,

                        "optime" : {

                                "t" : 1373954309,

                                "i" : 139

                        },

                        "optimeDate" : ISODate("2013-07-16T05:58:29Z"),

                        "self" : true

                },

如果primary节点状态映射表发生变化则会通过心跳做以下判断:

自己是否能和其他大多数节点(一半以上的节点)进行通信,如果不能则自动降级为secondary

是否有更高优先级的成员,如果有,自己降级,同时准备投票给他。


如果secondary节点状态表发生变化则会检测自己是否需要成为primary,它会进行三项检测,如果任意一个是否定的则不会成为primary

是否集群中有其它节点认为自己是 primary

自己是否有资格成为 primary


其他节点收到想要成为primary节点的信息包后会进行三项检测,如果任意一个满足都会投否定票

他们自己的数据是否比发送节点更新

是否有其它节点的数据比发送节点更新

集群中是否已经有primary,他们的优先级是否比已经有的primary低


如果确认后则节点宣布自己为primary并向其他节点发布,其余节点进行最终一致性确认。也就是说,要成为primary,必须要自己得到票数多余总票数的一半,然后向其他成员确认。 

什么时候primary降级

1. 执行replSetStepDown()命令

2. 当前一个sescondary更有成为primary的资格和更高优先级。(手动切换,修改在主服务器上修改优先级,然后reconfig)

3. Primary无法与一半以上的机器通信

posted @ 2021-05-02 18:48  hexel  阅读(92)  评论(0编辑  收藏  举报