MongoDB笔记整理4 - 分布式 & 副本集

一、MongoDB的分布式部署

1、分片的概念

分片(sharding)是指根据片键,将数据进行拆分,使其落在不同的机器上的过程。如此一来,不需要功能,配置等强大的机器,也能储存大数据量,处理更高的负载。

2、分片的原理和思想

MongoDB分片的基本思想就是将集合切分成小块。这些块分散到若干片里面,每个片只负责总数据的一部分。
对于客户端来说,无需知道数据被拆分了,也无需知道服务端哪个分片对应哪些数据。数据在分片之前需要运行一个路由进程,进程名为mongos。这个路由器知道所有数据的存放位置,知道数据和片的对应关系。对客户端来说,它仅知道连接了一个普通的mongod,在请求数据的过程中,通过路由器上的数据和片的对应关系,路由到目标数据所在的片上,如果请求有了回应,路由器将其收集起来回送给客户端
在这里插入图片描述

3、分片的简单实现

(1)片键的概念

设置分片时,需要从集合里面选一个键,用该键的值作为数据拆分的依据。这个键称为片键(shard key)。
{department:“IT”,name:“zhangsan”},{department:“HR”,name:“lisi”},{department:“SUPPORT”,name:“zhaowu”}
以该数据为例,表示的是职员名字以及所在的部门,假若我们设置部门(department)为片键,那么第一片可能存放名称以字母A-F开头的部门,第二片存放名称以GP开头的部门,第三片存QZ,如此类推。随着添加或者删除片,MongoDB会重新平衡数据,使每片的流量都比较均衡,数据量也在合理范围内。

(2)本地模拟实现

a、首先mongod开启服务端3个节点,端口分别为8080,8081,8082
b、开启config服务器。mongos要把mongod之间的配置放到config服务器里面,所以首先开启它,这里就使用8083端口。
命令为:
mongod --dbpath E:\sharding\config_node --port 8083
c、开启mongos服务器 。端口8084,同时指定下config服务器。
命令为:
mongos --port 8084 --configdb=127.0.0.1:8083
d、 路由指定服务端节点。客户端直接跟mongos打交道,也就说明我们要连接mongos服务器,然后将8080,8081,8082的mongod交给mongos,添加分片也就是addshard()。需要进到路由节点的admin数据库进行配置。allowLocal表示该服务端节点,可被客户端直接连接而无需经过路由。
db.runCommand({“addshard”:“127.0.0.1:8080”,allowLocal:true})
db.runCommand({“addshard”:“127.0.0.1:8081”,allowLocal:true})
db.runCommand({“addshard”:“127.0.0.1:8082”,allowLocal:true})
e、 开启数据库分片功能,命令为enablesharding(),并指定数据库名称,如下指定每个mongod都有的test数据库
db.runCommand({“enablesharding”:“test”})
f、 指定集合中分片的片键,这里就指定为company.department键.
db.runCommand({“shardcollection”:“company.department”,“key”:{“depatment”:1}})
g、 通过向mongos节点插入100万条数据,查看各节点保存的数据。
h、 通过向mongos插入一条数据,查看数据被分配到哪个片

二、MongoDB的分布式-副本集

1、副本集概念

    什么是副本?可能第一印象想到的是游戏副本,游戏副本就是为了让每个玩家都有一个独立的游戏环境,这种环境的复制就是副本的一种体现。MongoDB也提供了对副本的支持,副本集中有多个副本保证数据库的容错性,即使一个副本挂掉了还是会存在很多副本;并且支持副本间的自动选举,切换,解决了上一篇博文讲到的主从复制的故障恢复得人工进行的问题。其实主从复制就是一个单副本,缺少扩展性,容错性。

2、副本集原理及图解

    应用服务器,也就是客户端,连接到MongoDB的整个副本集,副本集中有一台主服务器负责整个副本集的读写,副本节点定期同步主节点的数据和oplog,以保证数据的一致性,一旦主节点宕机或挂掉,副本节点会通过心跳机制检测到,并根据事先副本集创建时设置的节点优先级进行主节点的重新选举,从而保证高可用。如此,客户端完全不必关心副本集的健康状况,MongoDB集群也可以长期保持高可用。
    副本集提供了MongoDB集群故障的自动回复机制,扩展性高,容错性强,是MongoDB官方强烈推荐使用的集群解决方案。

在这里插入图片描述
在这里插入图片描述

3、副本集使用说明

4个节点为例,ip,端口,日志以及数据存放路径如下      
        节点1
        地址:127.0.0.1:1001  # 在项目中,是实际的机器IP和端口,192.168.1.101:27017
        安装路径:D:\mongodb_cluster\MongoDB1
        日志存放路径:D:\mongodb_cluster\MongoDB1\log\mongodb.log
        数据存放路径:D:\mongodb_cluster\MongoDB1\data
        节点2
        地址:127.0.0.1:1002
        安装路径:D:\mongodb_cluster\MongoDB2
        日志存放路径:D:\mongodb_cluster\MongoDB2\log\mongodb.log
        数据存放路径:D:\mongodb_cluster\MongoDB2\data
        节点3
        地址:127.0.0.1:1003
        安装路径:D:\mongodb_cluster\MongoDB3
        日志存放路径:D:\mongodb_cluster\MongoDB3\log\mongodb.log
        数据存放路径:D:\mongodb_cluster\MongoDB3\data
        节点4
        地址:127.0.0.1:1004
        安装路径:D:\mongodb_cluster\MongoDB4
        日志存放路径:D:\mongodb_cluster\MongoDB4\log\mongodb.log
        数据存放路径:D:\mongodb_cluster\MongoDB4\data

        分别启动节点命令如下 
        启动节点1:
        mongod --dbpath D:\mongodb_cluster\MongoDB1\data  --logpath D:\mongodb_cluster\MongoDB1\log\mongodb.log --logappend --port 1001 --replSet guanghuan
        启动节点2:
        mongod --dbpath D:\mongodb_cluster\MongoDB2\data --logpath D:\mongodb_cluster\MongoDB2\log\mongodb.log --logappend --port 1002 --replSet guanghuan
        启动节点3:
    mongod --dbpath D:\mongodb_cluster\MongoDB3\data --logpath D:\mongodb_cluster\MongoDB3\log\mongodb.log --logappend --port 1003 --replSet guanghuan
        启动节点4:
    mongod --dbpath D:\mongodb_cluster\MongoDB4\data --logpath D:\mongodb_cluster\MongoDB4\log\mongodb.log --logappend --port 1004 --replSet guanghuan

        启动节点命令解释
        dbpath: 数据存放路径
        logpath:日志存放路径
        logappend : 日志拼接声明
        replSet:声明是副本集,后面格式为副本集名称/与之位于同一个副本集的节点地址(副本集要求至少要有两个节点,一个主,一个从)
        --fork:后台启动,这里为了效果没有添加此参数
        初始化节点(只能初始化一次,执行初始化之前,必须启动所有节点)
        mongo 127.0.0.1:1001
        use admin
       rs.initiate(
    {"_id" : "guanghuan",
     "members" : [
        {"_id" : 1, "host" : "127.0.0.1:1001", "priority":3},
        {"_id" : 2, "host" : "127.0.0.1:1002", "priority":2},
        {"_id" : 3, "host" : "127.0.0.1:1003", "priority":1},
        {"_id" : 4, "host" : "127.0.0.1:1004", "arbiterOnly" : true}
    ]
});        
初始化节点命令解释
        _id:副本集名称,与启动节点中的名称保持一致
        host:副本集成员地址
        priority:优先级,即选举成为新master的优先级,越大优先级越高
        arbiterOnly:仲裁节点

        
验证 :  rs.status()   # 查看副本集的状态


        登录主节点,即优先级最高的master节点,输入是否主节点的命令:rs.isMaster()
        相关指令:
        rs.remove(hostportstr) : 删除节点hostportstr:127.0.0.1:1003
        rs.add(hostportstr)  :增加节点

		登录所有副本集成员,设置:rs.slaveOk(),不然副本集不允许读取数据

	修改节点优先级:
		cfg = rs.conf()
		cfg.members[0].priority=10
		rs.reconfig(cfg)
		
        将该主节点关闭,登录优先级第二的从节点,输入是否主节点的命令: 发现在主节点宕机后,优先级较高的节点被选举为了master节点,继续负责读写的工作,从而持续地提供服务,保持集群高可用。
        
    四、仲裁者节点及其作用
        当集群中的节点数量为偶数个时,投票选举机制会根据数据最后操作,更新时间戳,优先级等来判定谁将成为master节点,如果出现以上条件都符合的情况,且票数相等,此投票环节需要等待若干分钟,这对于客户端来说是无法接受的。
        仲裁节点的出现打破了这个僵局,仲裁节点并不需要太多系统资源,也并不持有数据本身,而是参与投票并有效协调从节点争master的撕逼。
        集群中部署多仲裁节点时,需在初始化副本集时,添加属性arbiterOnly:true

4. 备注:

备注:
1. 整个副本集中的数据库,用户名和密码要统一
2. 增、删、改 操作只能在master机器上进行
3. 读取 操作 根据操作程序的配置,可以从不同的机器上读取
# conn = MongoClient('mongodb://127.0.0.1:1001,127.0.0.1:1002/')
conn = MongoClient(['127.0.0.1:1001,127.0.0.1:1002'])


from pymongo import ReadPreference

test = conn.get_database('test', read_preference=ReadPreference.SECONDARY_PREFERRED)


'PRIMARY',  : 在主节点上读取
'PRIMARY_PREFERRED', : 主节点优先
'SECONDARY', : 只在 从节点 上读取
'SECONDARY_PREFERRED', :从节点 优先
'NEAREST', : 自动选择最空闲的节点读取

三、笔记

1、索引


1、索引
    提高检索速度
    降低增、删、改的速度

    索引不是越多越好!只在必要的字段上建立索引
    什么字段建立索引?
    根据你的业务需求,需要频繁作为条件进行查询的字段

    不建议建立索引的字段:
    需要频繁修改的字段

    索引是有顺序的,升序和降序

2、缩写

2、缩写
    ns  大概率是 namespace, 命名空间

    pasword:  pass、 pwd
    internationalization:  i18n

3、复合索引

3、复合索引
    建立复合索引:db.inventory.createIndex({'item':1, 'qty':-1})

    以下各种情况是否应用到了上面这个索引:
    db.inventory.find({'item': 'test'})  索引起效
    db.inventory.find({'qty': 5})     索引不起效
    db.inventory.find({'item': 'test', 'qty': 5})  起效
    db.inventory.find({'qty': 5, 'item': 'test'})  起效

    条件中:
    包含了符合索引的 字段的从第一个按顺序来的, 那么就会起效的
    如果中间有某个字段 中断 了的,那么就不会起效

    譬如: 索引字段的顺序是:col1、col2、col3、col4、col5
    索引起作用的 字段查询:
    col1
    col1、col2
    col1、col2、col3
    col1、col2、col3、col4
    col1、col2、col3、col4、col5
    索引不起作用的 查询:
    col2、col3、col4、col5
    col1、col2、col4、col5

4、斜杠

4、斜杠
/  :  斜杠
    \  :  反斜杠


5、条件操作符


5、条件操作符
    select * from table_name where age < 18
    db.table_name.find({'age'< 18})  不允许出现   <
    db.table_name.find({'age': {$lt: 18}})

6、 nor

6、 nor
    使用逻辑NOR连接查询子句将返回所有与两个子句不匹配的文档。
    db.inventory.find({$nor: [{item:'journal'}, {qty:25}]})
    等同于:
    db.inventory.find({$and: [{item: {$ne: 'journal'}}, {qty: {$ne: 25}}]})

7、 exsits

7、 exsits
    字段是否存在
    db.inventory.find({item:{$exists: true}})
    即使  item: null  也算存在!

8、 参数个数错误

8、 参数个数错误
    mongodb:  Expression $subtract takes exactly 2 arguments. 3 were passed in.
    python:   TypeError: test_func() takes 2 positional arguments but 3 were given

    只要2个参数,但是你提供了3

9、avg 取平均值

9、avg 取平均值
    mysql:
    select item as _id, avg(price*quantity) as avgAmount,
        avg(quantity) as avgAquantity from sales group by item

    mongodb:
        db.sales.aggregate(
           [
             {
               $group:
                 {
                   _id: "$item",
                   avgAmount: { $avg: { $multiply: [ "$price", "$quantity" ] } },
                   avgQuantity: { $avg: "$quantity" }
                 }
             }
           ]
        )

10、json

10、json,只关注4个方法:
    load : 从文件中反序列化为 字典对象
    dump : 将 字典对象 序列化到 文件当中
    loads: 将一个符合 json 格式的 字符串 反序列化 为 字典对象
    dumps: 将 字典对象 序列化为 一个 json字符串

备份与恢复

1、 备份

备份与恢复
1、	备份:
mongodump -h dbhost -d dbname -o dbdirectory
-h:
MongDB所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017
-d:
需要备份的数据库实例,例如:test
-o:
备份的数据存放位置,例如:c:\data\dump,当然该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据。

mongodump -h 127.0.0.1 -d test -o d:\
mongodump -h 127.0.0.1:27017 -d test -o d:\
mongodump -h 127.0.0.1:27017 -d test –-collection counters -o d:\

2、 恢复

2、	恢复
mongorestore -h <hostname><:port> -d dbname <path>
--host <:port>, -h <:port>:
MongoDB所在服务器地址,默认为: localhost:27017
--db , -d :
需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2
--drop:
恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用哦!
<path>:
mongorestore 最后的一个参数,设置备份数据所在位置,例如:c:\data\dump\test。

你不能同时指定 <path>--dir 选项,--dir也可以设置备份目录。

--dir:
指定备份的目录

你不能同时指定 <path>--dir 选项。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值