MongoDB 搭建符合本集

单个redis实例无论是存储容量还是要处理能力最终都见面受限于单机的特性,随着数据量和请求量的加强,必然使谋求redis集群的化解方案。在redis推出首,redis自身并不曾集群的方案,但是业界在用redis的当儿发生无数集群方案。到了redis
3.0,redis内盖了集群方案,称之为redis
cluster。集群规划为主是将众多的key分散存放到多单不等的实例上去,另外要考虑的问题即是赛可用以及可扩大。

称本集(Replica
Set)是同组MongoDB实例组成的集群,由一个预示(Primary)服务器和多只备份(Secondary)服务器构成。通过Replication,将数据的创新由Primary推送及任何实例上,在必然的推移之后,每个MongoDB实例维护相同之数集副本。通过维护冗余的数据库副本,能够实现数量的异乡备份,读写分离及电动故障转移。

以实现集群的作用,从服务端、客户端的角度来拘禁,可以分为以下三近似:

一致,MongoDB版本及条件

  • 客户端实现: 典型的凡永葆一致性哈希的客户端
  • 代理层实现: 典型代表twemproxy、codis
  • redis服务端实现: redis cluster

每当Windows上创立包含三个节点的入本集,使用的环境:

客户端实现redis集群

在客户端实现redis集群,通常的采取状况是管redis单纯当简单的休养存来采取,就如以memcache那样使用redis。一般的策略是动一致性哈希。实际运用被,在客户端实现redis集群功能并无是一个好方案,它存在保障管理困难的题材,当需要这样做时恳求考虑当代理层做。

  • 数据库:MongoDB 版本 3.2.9
  • Server 环境:Windows Server 2012 R2
  • 可视化编程环境:Robomongo 版本 0.08.4
  • 三台Windows Server:srv1,srv2,srv3

代理层实现redis集群

以redis 3.0推出redis
cluster之前,代理层实现redis集群是首选方案,twemproxy和codis是极致广泛的有限个代理。

其次,拓扑结构分析

twemproxy实现redis集群

twemproxy实现redis集群的方案主要通过twemproxy配置里之distribution来决定的,不同的distribution可以适用于不同之景象,比较如下:

项目 ketama modula random
KEY分布 一致性哈希方式将key分布到不同的redis实例上 通过对key的哈希值求模分布到相应的redis实例上 随机分布key
高可用 可以通过开启自动屏蔽失效节点来自动更新一致性哈希环,从而实现依赖一致性哈希的高可用 内建没有对高可用的支持,可以通过外部控制在有节点失效时更新配置并重启 开启自动屏蔽失效节点功能,或同modula
可扩展 直接添加redis节点重启代理即可 只能双倍扩容,数据同步过程中需要重启twemproxy,重启过程中可能丢失一点最新的数据,扩容后各redis实例里会残留垃圾数据,如果未设置超时时间的话需要手工清理 直接添加redis节点重启代理即可
适用场景 缓存使用 缓存或存储使用 队列使用,较少使用
问题 一致性哈希虽然既可以实现高可用也可以实现可扩展,但实际上这两点做的都不够好,在一致性哈希环改变的时候会造成短期的缓存命中率下降,在大量请求的情况下这可能是不可接受的,有可能瞬间把后端数据库击垮;在网络抖动情况下,哈希环可能持续多次改变,这可能会带来脏数据的问题;在有多个代理的时候,还可能因为种种原因导致各代理上哈希环不一致的问题。 高可用需要额外依赖其它组件来实现,可扩展问题上面已提出 较少使用

创造一个Replica Set,包含三只分子:一个Primary 成员及片独Secondary
成员,Primary用于拍卖客户端请求,Secondary用于保存Primary的数量副本。客户端Application
在 Primary
节点上拓展读写操作,通过Replication的异步同步机制,将数据操作并到
Secondary 成员,在早晚之延迟之后,三单成员有相同的多少集。

codis实现redis集群

同twemproxy不一样,codis不单纯是平慢性代理软件,它包括了某些单零件,不过以此我们无密切讲,只介绍那实现redis集群的基本原理。两个重大的零部件是codis-server(redis修改版)和codis-proxy,codis在逻辑上分出1024只slot,每个codis-server实例可以具有多独slot,而key则透过测算哈希值来求模分布到当时1024单slot中,codis-proxy知道每个slot位于哪个codis-server里。对愈可用的支持codis依赖redis-sentinel,而针对性可扩大的支撑是经过迁移slot到新的codis-server实例上来贯彻的。

图片 1

redis cluster

redis cluster原理及跟codis差不多,同样是引入了slot的定义,不过redis
cluster有16384个slot。redis
cluster自身集成了大可用的效力,可扩大为是经过迁移slot来兑现之。但是对客户端的话,redis
cluster和单个redis实例相比其以求响应上带来了MOVE/ASK语义,也便表示之前的redis客户端无法直接获得周集群效应,需要充实对MOVE/ASK响应的支撑才方可看整个集群。

以为客户端透明的拜会redis
cluster,可以当中等加同叠代理,predixy是一个不错的选

辩论及,每个成员好分布于不同之数主导机房内,这些数量主导或相距甚远,实现多少的异乡备份;可以装Primary
节点只担负写入操作,而要Secondary节点负责读取操作,实现数据集的读写分离;如果Primary
连接中断过10s,其他节点会自行选举出一个Primary
节点,负责响应客户端Application的请求,实现多少的机动故障转移。

方案选

因客户端的方案外时刻还如慎重考虑,在斯我们反对推荐。

根据twemproxy的方案则看起功能特别到,但是其实用受到是的题材同多,具体表现上述,目前为无推荐还就此twemproxy的方案。

codis在redis
cluster出来前应是无与伦比优秀的相同种redis集群解决方案,但是codis需要利用该自修改版的redis,因此就与redis社区版本会起异样,因此无法马上和进redis社区版本更新,而对那些自己对redis有所改动的用户来讲,那还不方便使用codis。同时codis-proxy是go语言编写,在性能方面,尤其是耗时表现损耗较多。

redis cluster自redis
3.0推出以来,目前早就于不少产条件及获得了用,目前来讲,构建redis集群,推荐使用redis
cluster搭配一款支持redis cluster的代办方案。

图片 2

其三,技术原理说明

1,以Replica Set模式启动MongoDB实例

MongoDB
Instance有少数种不同的启动方式:单机模式(Standalone)和副本集模式(Replica
Set),在起步mongod时,如果设置 replSet 参数,那么MongoDB
实例以合本集模式启动;如果无安装replSet
参数,那么MongoDB以单机模式启动。

单机实例是因运行于服务器上的一个mongod 进程,该过程不是其它一个Replica
Set的分子,因此,单机实例不能自动故障转移,在产品环境中,风险非常高,如果服务器崩溃了,客户端App至少在一段时间内不足看,如果硬件出现问题,可能会见促成数据的永丢失。建议,使用Replica
Set,至少保留少数卖数据集副本。

2,选举Primary成员

每当Replica Set中生出个别种植成员:Primary成员和Secondary成员,一个Replica
Set只能有一个Primary成员,但得出多独Secondary成员。Primary用于拍卖客户端请求,Secondary用于保存Primary的数量副本。如果Primary崩溃了,Replica
Set探测到Primary不可访问,将启动自动故障转移过程,从剩下的Secondary成员中,投票选举出一个分子作Primary,接收和拍卖客户端的伸手。

推选Primary成员时,使用“大多数”和“一票否决”原则。在Replica
Set中,每个成员只能要求自己被选举为Primary节点。当一个Secondary成员无法和Primary成员连通时,该成员就是会见倡导选举,请求其他成员将好选出为Primary成员,只来收获“大多数”成员的支撑,该成员才会被推举为Primary成员;只要发生一个成员否决,选举就见面取消。

不是各级一个分子都产生投票选举的权利,在一个Replica
Set中,最多有7个分子用于投票选举的权利,Primary成员是由当时7单分子选举出的。有投票权利的成员,其性:”votes”
是1;若为0,表示该成员没有投票权利。

3,操作日志

MongoDB使用操作日志(oplog)来兑现复制(Replication)功能,oplog包含了Primary成员的各一个翻新操作,通过以oplog传递及外Secondary成员中,在其它成员中还做(redo)已经交付的操作,实现多少的异步同步。Replica
Set中之每个成员还维护在友好的oplog,记录着各国一个自Primary成员复制操作的多寡。复制操作的长河是先行复制数据,再以操作写副到oplog中。如果某一个分子以推行操作时失败,当该成员又开之后,自动从oplog中最终一个操作进行共同。由于复制操作的进程是先行复制数据,再写副oplog,该成员或会见以都联手的数据及再实施复制操作,MongoDB在计划oplog时,就考虑到这种情形:将oplog中的与一个操作实践多次,与实践同一次的结果是一模一样的。

oplog保存之是对每个doc的更新操作日志,如果一个命令就更新一个doc,那么Replication进程向oplog插入一漫漫日志;如果一个命更新多单doc,那么Replication进程向oplog插入多条日志,每一样条日志只更新一个doc。

oplog的尺寸是固定的,只能保留特定数量之操作日志,如果Primary成员更新的数据量特别酷,oplog很快即为填满,Secondary来不及同步数据,Primary成员就拿oplog中之日记,这样,Secondary成员就会成陈旧的(Stale)。建议,让Primary成员使用于特别之oplog,保存足够多的操作日志。

季,创建布局文档

1,创建mongod 启动之部署文件

每当各个台server上创立布局文件,将部署文件存放于目录C:\data\面临。在同一个Replica
Set中的装有成员必须出平等之Replica Set Name,这里装也“rs0”。

--srv1    config_file_name:rs0_1.conf
dbpath=C:\data\db\db_rs0
logpath=C:\data\db\db_rs0\rs0_1.log
port=40001
replSet=rs0

--srv2   config_file_name:rs0_2.conf
dbpath=C:\data\db\db_rs0
logpath=C:\data\db\db_rs0\rs0_2.log
port=40002
replSet=rs0

--srv3  config_file_name:rs0_3.conf
dbpath=C:\data\db\db_rs0
logpath=C:\data\db\db_rs0\rs0_3.log
port=40003
replSet=rs0

部署参数含义:

  • replSet:设置Replica
    Set的name,在逐一配置文件中,其值必须同。
  • dbpath:MongoDB用于存储数据的目,默认值是C:\data\db
  • logpath:用于记录mongod的日志数据
  • port:指定MongoDB监听的端口,默认值是27017

2,以安排文件方式启动mongod

诚如景象下,mongod的参数值是休更换的,将这些参数写副到布置文件被,能够简化MongoDB的保管。

mongod 命令有参数:–config 或 -f,用于引用配置文件。

--srv1
mongod -f C:\data\rs0_1.conf

--srv2
mongod -f C:\data\rs0_2.conf

--srv3
mongod -f C:\data\rs0_3.conf

3,启动mongo shell

每当肆意一大Server上打开三单mongo shell,使用参数 –host 指定Server
Name,使用 –port 指定端口号。由于mongod没有用默认的监听端口
27017,因此,必须运用 在mongo shell中运用 –port参数显式指定监听的Port。

--connect srv1
mongo --host srv1 --port 40001

--connect srv2
mongo --host srv2 --port 40002

--connect srv3 
mongo --host srv3 --port 40003

五,配置Replica Set

于不同之Server上运行不同之MongoDB Instance,但是,每个mongod
都不掌握其他mongod的留存,为了为每个mongod能够感知彼此的存在,需要配备Replica
set,增加成员。

1,使用安排文档为Replica Set 增加成员

每当srv1的mongo
shell中,创建布局文档,调用rs.initiate()函数,按照安排文档来初始化Replica
Set。

conf=
{
    "_id" : "rs0",
    "members" : [
        { "_id" : 0,  "host" : "srv1:40001"  },
        { "_id" : 1,  "host" : "srv2:40002"  },
        { "_id" : 2,  "host" : "srv3:40003"  }
    ]
}

rs.initiate(conf)

在配置doc中,使用”_id” : “rs0” 指定Replica Set的name,members数组指定
Replica Set的分子的ID 和
host(“host:port”)。等交独具成员配置好以后,Replica Set
会自动选举出一个Primary 节点,两个Secondary 节点。在Primary
节点上拓展创新操作,就能够共同到Secondary 节点了。

2,修改Replica Set

而盖rs.initiate()方式初始化Replica
Set,那么MongoDB以默认配置文档初始化Replica
Set,可以由此add()函数增加成员。

2.1 向Replica Set中长一个分子

rs.add("host:port")

2.2 从Replica Set中去一个成员

rs.remove("host")

2.3 查看Replica Set的配置

rs.conf()

2.4 重新配置Replica Set

var conf=rs.conf()
conf.members[1].priority =5

--at primary member
rs.reconf(conf)

--at secondary member
rs.reconf(conf,{force:true})

2.5 查看Replica Set的状态

rs.status()

六,维护Replica Set

1,查看Replica Set的布信息

rs.conf()

部署文档主要分为三块:Replica Set 的ID和 Version,Members数组 和
Settings,下面是透过简化的配置信息。

{
    "_id" : "rs0",
    "version" : 202997,
    "members" : [ 
        {
            "_id" : 1,
            "host" : "srv1:40001",
            "arbiterOnly" : false,
            "hidden" : false,
            "priority" : 5,
            "votes" : 1
        }, {...}
    ],
    "settings" : {  .....  }
}

Replica Set的ID字段唯一标识一个Replica Set,每一个Replica
Set都发一个自增的版号,由Version字段标识,标识Replica
Set的两样版本。version字段的初始值是1,每次修改Replica
Set的布置时,version字段都见面自增。

Settings 字段的价是使用至Replica Set中持有成员的安排信息。

最为紧要的凡members数组的字段,标识每个成员的布局信息。

  • arbiterOnly:0或1,标识一个核定(arbiter),Arbiter的绝无仅有作用是介入Primary的推,Arbiter不保存数据,不会见也client提供劳务,它在的意思就是是为着推举Primary。
  • hidden:0或1,表示该成员是休是藏匿成员,Hidden成员的首要意图是备份数据,可以使用性能于差之服务器作为Hidden成员。Hidden成员不见面接收Client的呼吁,也未会见成Primary。在安Hidden成员经常,必须设置members[n].priorty属性为0;
  • priority数值类,用于安装成员成为Primary的预先级。priority越强的积极分子,越有会变成Primary。如果priority=0,那么该成员永远不见面化Primary。
  • votes:1或0,表示该成员的投票的数据,在每个Replica
    Set中,最多来7单成员,其votes属性值是1。votes 属性是1底积极分子(voting
    members)拥有选举Primary的权利。一个分子要想变成一个Primary,那么得取得voting
    members的几近成员的支撑。

以Replica Set中,如果voting
members的数是5,那么一个分子成为Primary的原则是:获得超过2个voting
members的支撑,并且没有另外voting members 反对。只要发生自由一个voting
member 反对该成员成为Primary,那么该成员即使无能够成Primary。

2,强制一个成员成为Primary

倘拿一个成员的priority属性在Replica
Set的具备成员中是最高的,那么该成员太有或变成Primary。

拿成员0的priority设置5,其他成员的priority设置为1,这样,成员0成为Primary的优先级是高的。

cfg = rs.conf()
cfg.members[0].priority = 5
cfg.members[1].priority = 1
cfg.members[2].priority = 1
rs.reconfig(cfg)

七,测试数据

1,在Primary上宣读写多少

db.users.insert({_id:1,name:"a",age:24})

2,在Secondary上读取数据

默认情况下,客户端不能够从Secondary成员中读取数据。在Secondary成员上显式执行setSlaveOk之后,才能够由Secondary节点读取数据。

rs.setSalveOk()

db.users.find({_id:1})

八,查看mongod 服务器的授命执行参数

db.serverCmdLineOpts()

/* 0 */
{
    "argv" : [ 
        "mongod", 
        "-f", 
        "C:\\data\\rs0_1.conf"
    ],
    "parsed" : {
        "config" : "C:\\data\\rs0_1.conf",
        "net" : {
            "port" : 40001
        },
        "replication" : {
            "replSet" : "rs0"
        },
        "storage" : {
            "dbPath" : "C:\\data\\db\\db_rs0"
        },
        "systemLog" : {
            "destination" : "file",
            "path" : "C:\\data\\db\\db_rs0\\rs0_1.log"
        }
    },
    "ok" : 1
}

参考doc:

Replication

Replica Set
Tutorials

MongoDB –
Replication

Replica Set
Configuration

Force a Member to Become
Primary

发表评论

电子邮件地址不会被公开。 必填项已用*标注