MongoDB开发系列复制集对程序开发的影响

42次阅读

共计 2669 个字符,预计需要花费 7 分钟才能阅读完成。

本篇文章主要从以下几个方面说明复制集架构对程序开发的影响

笔者把基于 MongoDb 的应用开发分为软件运维和 软件开发两个阶段

本篇会侧重后一阶段的实践经验分享

  1. 理解复制集与主从结构
  2. 关注数据库连接字符串

复制集的基本概念

谈到复制集,它是副本的集合,分布式系统的基本属性之一。

副本(Replica)

副本是分布式系统最常见的概念之一,指分布式系统对数据和服务提供的一种冗余方式。在常见的分布式系统中,为了对外提供高可用的服务,我们往往会对数据和服务进行副本处理。有副本的概念,就会关联到副本数据一致性问题。

MongoDb 环境下,我们很容易从公开资料查询到复制集的基本你含义

MongoDB 复制(副本集)MongoDB 复制是将数据同步在多个服务器的过程。

复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性,并可以保证数据的安全性。

复制还允许您从硬件故障和服务中断中恢复数据

副本集角色

MongoDB 副本集是一组 mongod 进程的集合,它通过一系列机制实现了高可用。

mongod is the primary daemon process for the MongoDB system. It handles data requests, manages data access, and performs background management operations.

副本集角色主要包括主节点,从节点,和仲裁节点。主节点负责所有的写操作。

复制集与主从结构的关系

两者属于不同的 MongoDb 数据库结构,主从结构已经不被官方推荐

Deprecated since version 3.6: MongoDB 3.6 deprecates the use of
master-slave replication.Master-slave replication has been deprecated
for components of sharded clusters since MongoDB 3.2.

主从结构与复制集最主要的区别是前者有真正的主服务器的概念,复制集没有主服务器的概念,通过选举选出主要的主节点 Primary

Do not run an arbiter on systems that also host the primary or the secondary members of the replica set

仲裁者一定要部署在独立的服务器上,避免与主节点和复制节点部署在一起

传统的主从部署

复制集

这是 Mongo 官方更推荐的部署结构

复制集

关注数据库连接字符串

复制集属于 MongoDb 高可用架构的一种部署方式,对于使用数据库的应用者来说应该是极度透明的,内部主从实例切换应该做到无感切换,也就是说应用并不关心具体的一次数据库操作,是由哪个实例来处理的。

我们可以在程序中指定如何连接复制集,正确的连接方式可以避免当主节点宕机或者故障时,应用程序无感知正常切换,借用网络的一张图来说明

这张图的左边部分实际上是有问题的,直连一个实例,并且标明 Primary,对于连接 Db 数据库的 Driver 来说,它应该不用关心哪个实例是主,并且哪个实例是主也是会变化的。

试想运维给到开发的数据库连接串是一组配置,那我们如何集成到应用程序中?

基础设置

对于 PHP 应用来讲,框架使用 YII2,驱动使用 yii2-mongodb

https://www.yiiframework.com/…

Github 地址

https://github.com/yiisoft/yi…

  1. 安装
Either run

php composer.phar require --prefer-dist yiisoft/yii2-mongodb

or add

"yiisoft/yii2-mongodb": "~2.1.0"
  1. 连接字符串

直连方式

return [

    'class' => '\yii\mongodb\Connection',

    'dsn'  => 'mongodb://username:password@s1.test.mongodb.domain.cn:10000/databasename',

    'options'=>['socketTimeoutMS' => 1000]

];

复制集连接

return [

'class' => '\yii\mongodb\Connection',

'dsn' => 'mongodb://user:pqssword@s1._test.mongodb.domain.cn:30000,s2.mongodb.domain.cn:30000,s3._test.mongodb.domain.cn:30000/databasename',

];

问题来了

1 应该都连接,还是只连接一台数据库实例即可?

生产环境下,复制集合实例有 3 个,我们都配到了连接串中。是否应该只连接一台,我个人也没有很好的解释,理论上应用只需要一个入口即可,后续都交给数据库处理。

2 连接超时设置是否应该显示设置?

https://docs.mongodb.com/manu… 官方有针对连接串的参考说明。

谈到超时问题,我们来看数据库连接周期

一次完整的请求包括三个阶段:1、建立连接 2、数据传输 3、断开连接。

通常我们谈到的超时分为两种,connectTimeout 和 socketTimeout,前者是网络连接超时,后者是执行超时。

如果与数据库服务器请求建立连接的时间超过 ConnectionTimeOut,就会抛 ConnectionTimeOutException,即服务器连接超时,没有在规定的时间内建立连接。如果服务器处理数据用时过长,超过了 SocketTimeOut,就会抛 SocketTimeOutExceptin,即服务器响应超时,服务器没有在规定的时间内返回给客户端数据。(这里的异常是 java 驱动返回的异常)

这两个参数,官方给出的是 connectTimeoutMS 和 socketTimeoutMS

生产环境下关于 options 参数

我们在生产环境下,参数 replicaSet,connectTimeoutMS,socketTimeoutMS 都没有配置。

官方文档

https://docs.mongodb.com/manu…

https://docs.mongodb.com/manu…

https://docs.mongodb.com/manu…


文章中的观点有不严谨之处,欢迎评论沟通,关于副本集,笔者也是在不断探索中。

抱着不确定性思维,学习 MongoDb 数据库的基本态度:边学习,边实践,边参考,边改进,在问题中成长。

欢迎关注公众号《图南科技》

正文完
 0