前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >012.MongoDB读写分离

012.MongoDB读写分离

作者头像
木二
发布2019-07-01 14:15:54
2.2K0
发布2019-07-01 14:15:54
举报
文章被收录于专栏:木二天空木二天空

一 读写分离概述

1.1 读写分离描述

从应用程序角度来看,使用Replica Set 和使用单台mongo很像。默认的驱动程序会连接primary节点,并且将所有读写请求都路由到主节点。但也可以通过设置驱动程序的Read Preferences 配置其他选项,将读请求路由到其他节点。

通常官网中建议不使用向从节点取数据。原因如下:

  1. 所有的从节点拥有与主节点一样的写入负载,读的加入会增加其负载;
  2. 对于分片的集合,在平衡器的关系下,数据的返回结果可能会缺失或者重复某部分数据;
  3. 相对而言,官方建议使用shard来分散读写请;
  4. 一致性的考虑,对一致性要求比较高的应用程序是不应该从备份节点读取数据,备份节点通常由于加载问题,网络等原因,而落后于主节点几毫秒,几秒,几分钟甚至更多。如果应用程序需要读取它自己的写操作(比如,先插入一个文档,再去查询它),那么不应该从备份节点去读取数据,除非针对写操作,使用Write Concern定义w数值,在复制到所有备份节点之后,再返回执行成功与否。总之,如果从一个落后的备份节点读取数据,就要牺牲一致性。如果希望写入操作返回之前被复制到所有的副本集成员,就要牺牲写入速度。
  5. 如果路由到的备份节点,其中一台挂了,那么其他节点将承担其相应的压力,需要注意此时在线节点的负载压力。

因此一般是不建议做读写分离,通常对于写操作很少,大量的读请求的业务,实现读写分离来分担服务器压力,然后逐步过度到分片模式。

注意:副本集不是为了提高读性能存在的,在进行oplog的时候,读操作是被阻塞的;

提高读取性能应该使用分片和索引,它的存在更多是作为数据冗余,备份;

尤其当主库本来就面临着大量的写入压力,对于副本集的节点,也同样会面临写的压力。

1.2 使用的场景

通常官方不推荐使用从节点实现读写分离,但可能存在以下场景需要使用读写分离:

  • 异地的分布式部署
  • 故障切换,在紧急情况下向从节点读数据

1.3 延伸读写分离思考

该思考来源:https://github.com/smallnewer/bugs/issues/22

个人总结如下:

主从的写压力基本一样;

  • MongoDB从不会受到主写锁的影响,可通过mongotop 或者 mongostat查看写锁状态;
  • MongoDB从会在主写锁后,在恢复oplog时,进行写锁;
  • 从优先读,而且读太多会影响写;
  • 从节点读的权限比写锁优先级高(注:主节点反之,应该是写贪婪的),建议当从节点的读太高从而影响了oplog的恢复时,改用分片方案。

因此在以下情景下适合使用读写分离:

读写比例要大,即读多写少。如果写多读少,从库也会有大量写锁,阻塞读。

读多写少,从库虽然有写锁,但由于优先读的原因,读不受写锁阻塞,读的速度会加快。

不过从库读压力大的时候,只是暂时把写滞后,如果写滞后的很多,超过了主的oplog上限,会触发整体同步,造成主库压力过大,产生雪崩。

在从能轻松顶住读压力的时候,且读写比例是读多写少,可以考虑读写分离,提高读的速度。

若从节点不能顶住读压力,最好放弃读写分离,换用分片,将热数据分散到不同的机器上。

二 读写分离部署

2.1 正常部署副本集

参考《006.MongoDB复制(副本集)》。

2.2 开启Sencondary可读状态

代码语言:javascript
复制
  1 [root@mongodb02 ~]# mongo --host 172.24.8.72 -u clusteradmin -p clusteradmin
  2 my_rep:SECONDARY> db.getMongo().setSlaveOk()
  3 [root@mongodb02 ~]# mongo --host 172.24.8.73 -u clusteradmin -p clusteradmin
  4 my_rep:SECONDARY> db.getMongo().setSlaveOk()        #分别连接两个Sencondary节点服务器,设置为可读状态

2.3 客户端设置读取方式

通过修改客户端读取方式实现从节点的读,具体方式包括:

Read Preference模式

中文解释

primary

默认,只从主节点读取数据

primaryPreferred

在主节点不可用时,从副节点读取数据

secondary

所有的读操作,从副节点读取数据

secondaryPreferred

在副节点不可用时,从主节点读取数据

nearest

从网络延迟最小的节点获取数据 该模式不关注成员的类型,不管是primary还是secondary成员。

客户端演示:略。

参考链接:

https://docs.mongodb.com/manual/applications/replication/

https://www.cnblogs.com/magialmoon/p/3268963.html

http://www.gaozhy.cn/blog/2018/01/18/%E5%9F%BA%E4%BA%8E%E5%89%AF%E6%9C%AC%E9%9B%86%E7%9A%84%E8%AF%BB%E5%86%99%E5%88%86%E7%A6%BB/

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-06-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 读写分离概述
    • 1.1 读写分离描述
      • 1.2 使用的场景
        • 1.3 延伸读写分离思考
        • 二 读写分离部署
          • 2.1 正常部署副本集
            • 2.2 开启Sencondary可读状态
              • 2.3 客户端设置读取方式
              相关产品与服务
              云数据库 MongoDB
              腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档