您当前的位置: 首页 >  mongodb

蔚1

暂无认证

  • 0浏览

    0关注

    4753博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

MongoDB故障点机制

蔚1 发布时间:2020-02-22 23:30:43 ,浏览量:0

本场 Chat 将会对 MongoDB 源码中的故障点机制进行一个简要介绍,方便对 MongoDB 源码感兴趣的同学了解 MongoDB 中的故障点机制,以便更好地学习 MongoDB 源码。

一个系统在运行的时候,可能会出现若干故障,我们产生故障的地方称为“故障点(FailPoint)”。这些故障可能并不是代码的逻辑错误(例如 1+1 是否等于 2),可能是一些其他故障,例如在网络异常(延迟、抖动、掉帧),磁盘异常(IO 延迟增加、IO 吞吐量过低)、服务调用异常(例如每个服务突然宕机)。这些非逻辑错误的故障,很难直接通过单元测试来发现。

为了便于对系统的稳健型进行测试,通过方便测试人员对故障点进行测试,MongoDB 提供了一种故障点机制,该机制提供了一种非侵入式的故障代码嵌入机制,使得开发人员可以在代码中嵌入一段自定义故障代码,并可由测试人员来控制是否激活这段“可控的”故障代码。

注意⚠️:这里的故障点,并不是指的数据库中的故障点,而是整个应用系统中产生错误的地方,例如一个分布系统中的网络故障。

常见的开源故障点方案有:

  • Etcd 的gofail
  • Pingcap 的failpoint

此外,FreeBSD 的内核也提供了故障点机制

MongoDB 中涉及故障点机制的源文件如下:

  • 故障点对象相关

  • src/mongo/until/fail_point.h

  • src/mongo/until/fail_point.cpp

  • 故障点定义(即在程序中配置若干个故障点)相关

  • src/mongo/until/fail_point_service.h

  • src/mongo/until/fail_point_service.cpp

  • src/mongo/until/fail_point_registry.h

  • src/mongo/until/fail_point_registry.cpp

  • src/mongo/until/fail_point_server_parameter.id

MongoDB 在fail_point.hfail_point.cpp文件中对故障点对象进行了定义和实现。

由于故障点是通过创建一个故障点对象的方式进行实现的,为了能够对故障点进行配置(例如,启用或禁用故障点,设置故障点所能被触发的最大次数,设置故障点随机触发的概率等等),我们提供一种方式来实现根据字符串获取指定的故障点。故 MongoDB 在fail_point_registry.hfail_point_registry.cpp文件中定义和实现了一个用于存放故障点的仓库。通过将定义好的故障点注册到故障点仓库(即在故障点仓库中添加一个的键值对),我们可以在程序启动时对故障点进行设置,以及在代码中访问另外一个地方定义的故障点。

故障点仓库(FailPointRegistry)提供以下方法来添加和访问故障点:

  • 添加故障点:Status addFailPoint(const std::string& name, FailPoint* failPoint)
  • 访问故障点:FailPoint* getFailPoint(const std::string& name) const

当我们定义故障点时,除了手动定义故障点+手动注册故障点的方式外,我们还可以使用 MongoDB 在`fail_point_service.h文件定义的宏MONGO_FAIL_POINT_DEFINE(fp):

/** * 工具宏:定义一个故障点. Convenience macro for defining a fail point. * NOTE: 必须在 mongo 名字空间内部使用该宏. Must be used at namespace scope. * NOTE: 不能在局部作用于或者类作用域中使用该宏,即只能在全局作用域中使用该宏(因为该宏需要使用到 MongoDB 中的初始化机制来向故障点注册表中添加该故障点). Never at local scope (inside functions) or class scope. * NOTE: 不要在头文件中使用该宏,这可能会造成重复定义同一个故障点. Never use in header files, only sources. */#define MONGO_FAIL_POINT_DEFINE(fp)                                                   \    ::mongo::FailPoint fp;                                                            \    MONGO_INITIALIZER_GENERAL(fp, ("FailPointRegistry"), ("AllFailPointsRegistered")) \    (::mongo::InitializerContext * context) {                                         \        /*在故障点注册表中添加该故障点*/                                                    \        return ::mongo::getGlobalFailPointRegistry()->addFailPoint(#fp, &fp);         \    }

我们还可以使用 MongoDB 在fail_point_service.h文件中定义的宏MONGO_FAIL_POINT_DECLARE(fp)来声明一个已经定义的故障点。

/** * 工具宏:声明一个已经定义的故障点. Convenience macro for declaring a fail point in a header. */#define MONGO_FAIL_POINT_DECLARE(fp) extern ::mongo::FailPoint fp;

当我们定义好故障点并注册故障点之后,我们可以通过调用故障点的shouldFail()方法来判断该故障点是否可以触发。示例代码如下:

//db.cpp 文件...//定义一个故障点MONGO_FAIL_POINT_DEFINE(shutdownAtStartup);...ExitCode _initAndListen(int listenPort) {  ...    if (MONGO_FAIL_POINT(shutdownAtStartup)) {//执行故障点的触发代码来程序一个程序故障。        //通过故障点完成启动过程中的退出        log() //告诉 mongod 中止接下来的两个网络操作> db.adminCommand( { configureFailPoint: "throwSockExcep", mode: {times: 2} } )2020-02-22T20:00:36.162-0400 trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed> db.collection.count()2020-02-22T20:01:40.162-0400 trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed> db.collection.count()2020-02-22T20:02:46.162-0400 trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed2020-02-22T20:03:28.162-0400 reconnect 127.0.0.1:27017 (127.0.0.1) ok

最后我们来了解一下故障点的触发模式。MongoDB 为故障点定义了 5 中触发模式:

  • off(禁用):故障点在程序运行中不触发,即shouldFail()方法总是返回 false。默认模式。
  • alwaysOn(总是激活):故障点在程序运行中总是可以被触发,即shouldFail()方法总是返回 true.
  • random(随机激活):故障点在程序运行中的触发次数是随机的。
  • nTimes(有限次激活):故障点在程序运行中的触发次数是有限的,触发一定次数后,不再触发。
  • skip(等待有限次再触发):当程序执行到特定故障点的次数超过一定次数后,故障点才触发,并且以后再执行到该故障点时都会触发。
其他故障点方案
  • Golang Failpoint 的设计与实现
  • Golang Failpoint 的设计与实现 视频分享
  • Uber JS Failpoint

阅读全文: http://gitbook.cn/gitchat/activity/5e5132f66f934d332782aadf

您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。

FtooAtPSkEJwnW-9xkCLqSTRpBKX

关注
打赏
1560489824
查看更多评论
立即登录/注册

微信扫码登录

0.0675s