使用 Feature Flags 与可观测工具实现数据库灰度迁移

场景描述

很多企业会遇到数据库升级、或数据库迁移的情况,尤其是在自建数据库服务向云数据库服务、自建机房向云机房、旧数据库向新数据库迁移等场景。
然而,我们需要在整个移植过程中保证其稳定性、避免数据遗失、服务宕机等情况,最常见的移植方法之一就是数据库双写移植操作

解决方案

如下图所示,这个双写移植的过程为:

  1. 原始阶段,程序只对一个旧数据库进行读写。
  2. 在现有的读写旧数据库的代码程序基础上,需要添加读写新数据库的代码。例如,在某个表中插入一条数据时,我们需要把这条数据同时插入到新旧两个数据库中。通常情况下,我们会并行执行这两个插入操作,以尽可能保持服务的原有调用处理时间。
  3. 当一个写数据库请求进来,我们将其写入旧数据库的同时,将一个很少的百分比流量写入新的数据库。
  4. 将写入新数据库的流量比缓慢提高,直到 100% 为止。在这个过程中如果出现问题,可以及时回滚,并在不影响生产环境服务的情况下进行修复。
  5. 写移植完成后,开始逐步放量从新的数据库中读取数据返回给服务,如先允许 10% 的流量在新数据库做读操作。在这个过程中测量性能的同时对比结果,如果在读操作中遇到问题,可以马上回滚新数据库的读流量,并在不影响生产环境服务的情况下进行修复。
  6. 直到在新数据库实现 100% 的读写操作一段时间没有问题后,就可以停止与旧数据库相关的代码服务了。

在实际操作过程中,不止新旧数据库的操作流量要逐渐开放,实际上新的数据库的读写代码也需要逐步的更新到生产环境服务中,以确保可迭代的稳定平滑移植。

实践方法与工具

整个过程中,除了自身系统架构的设计外,有两个特别的工具在其中起到重要环节:

  1. 负责可灵活、实时、稳定放量、回滚的 Feature Flags 服务 (FeatBit)。
  2. 在整个过程中全方位(支持无侵入和针对性埋点模式)的监测服务异常与及时报警的可观测服务 (观测云)。

使用 FeatBit 实现实时的数据库移植请求流量控制

如下代码所示,为某一个服务的数据库读取操作分流的示例伪代码:

  • 第 6 行代码,调用 _fbService.BoolVariation("read-sport-olddb") 方法获得流量控制返回值,如果为 true,则将读取旧数据库的 Query 函数添加到并行任务执行队列中。
  • 第 9 行代码,调用 _fbService.BoolVariation("read-sport-newdb")方法获得流量控制返回值,如果为 true,则将读取新数据库的 Query 函数添加到并行任务执行队列中。
  • 第 19 行代码,为使用 FeatBit Feature Flags SDK 同时运行两个数据库读取操作,并将结果进行对比验证,根据执行情况返回正确值,并向观测云发送相关异常数据。
public async Task<List<Sport>> GetSportsByCityAsync(int cityId, int pageIndex, int pageSize)
{
    var tasks = new List<Task<List<Sport>>>();

    // 当读取 Sport 相关业务的旧数据库开关返回 true 时,则添加读取任务到执行任务队列
    if (_fbService.BoolVariation("read-sport-olddb"))
    {
        tasks.Add(GetSportsByCityQueryAsync(_oldDbContext, cityId, pageIndex, pageSize));
    }

    // 当读取 Sport 相关业务的新数据库开关返回 true 时,则添加读取任务到执行任务队列
    if (_fbService.BoolVariation("read-sport-newdb"))
    {
        tasks.Add(GetSportsByCityQueryAsync(_newDbContext, cityId, pageIndex, pageSize));
    }

    // 同时执行两个读操作(为了避免新增数据读取增加请求时间),并将结果进行对比并返回
    // 如果结果不一致,则返回旧数据库读取结果,并进行记录
    return await _fbService.RunAndCompareDbTasksAsync(
                    tasks,
                    timeoutDelayForNewDB: 3000, // 设定新数据库的最长等待时间,避免不良体感
                    (timeoutInfo) => { }, // 当新数据库调用超时,发信息至观测云
                    (unMatchInfo) => { }, // 当返回结果不一致时,发信息至观测云
                    (exception) => { } // 当出现异常时,发信息至观测云
                );
}

在把类似于上述的代码逐步的集成到我们的项目中之后,就可以通过 FeatBit 提供的 Feature Flags 控制中心来控制每一个对应的数据库移植的双写双读放量工作了。例如我们先将 feature flag read-sport-from-newdb 放量调整到 5%,若在一段时间未在观测云中观察到异常状况,增大放量百分比至 10% (如下图)。

使用观测云观测移植全过程,及时发现潜在问题

在整个的数据迁移过程中,自动化的、及时发现错误问题并回滚,是极为重要的。他可以最有效的帮我们避免诸多问题,如:

  • 新数据库操作带来巨大的系统资源消耗时,我们需要第一时间知道并通过 Feature Flags 系统立刻回滚。
  • 当某个写操作或读操出现时间操作超时数量超过预估阈值时,我们可以快速定位问题,回滚的同时进行快速的修复,提高移植的速度。
  • 当某个写操作或读操作出现信息错误时(如结果不一致、请求时间过长、程序异常等),我们可以根据观测系统具体定位错误信息,从而加速 debug 的速度。
  • 等等

实现这些,我们只需要:

  1. 根据《观测云文档:快速入门》,选择与自己业务相符的技术栈,进行小白式的在 15 分钟内完成配置和安装。
  2. 运行你已有的服务程序,开始你的数据库系统移植。
  3. 打开观测云控制台的「应用性能检测」页面,定位到链路,你将看到所有服务的运行情况。

通过「链路」与「错误追踪」快速定位移植错误

通过「链路」页面,我们发现在移植过程中,出现了一些红色项(即 Error),通过资源列可以轻松的看到我们在对新数据库的读取操作中出现了错误异常,如下所示:

点击对应的 Error,我们可以快速查看其对应的调用链路火焰图。如下图所示,根据火焰图的解释:

  1. 如下图 位置的 Span 所提示,在这个地方出现了数据库移植的 Timeout 错误,即新数据库的读取时间超出了我们可以接受的请求响应时间阈值。
  2. 如下图 位置中,指出错误发生在 Feature flag read-sport-newdb 为 true 的情况下面。也就是说我们可以快速定位可能需要回滚或关掉的 Feature Flags,从而避免移植风险。
  3. 而根据 位置 Span 可以快速定位出现超时现象的服务端 API 服务,并且根据捕捉到的 API 的参数与 Header,可以帮助我们后面去更好的调试解决问题。

通过 Feature Flags 实时将读操作回滚至无超时状态

根据上面的「链路」查找方式,我们快速定位到了出现异常的数据库读操作。那么,我们只需要回到 FeatBit 的后台界面,找到上面发现的开关 read-sport-newdb,并将其放量为 true 的百分比向后回滚即可。如下图所示,将 true 的百分比从 10% 回滚到之前未出现读数据异常的 5%的流量分配。

回滚后,下面代码所示的 _fbService.BoolVariation("read-sport-newdb") 返回值,只会将有 5% 的比率为 true。

// 当读取Sport相关业务的新数据库开关返回 true 时,则添加读取任务到执行任务队列
if (_fbService.BoolVariation("read-sport-newdb"))
{
    tasks.Add(GetSportsByCityQueryAsync(_newDbContext, cityId, pageIndex, pageSize));
}

总结与后续

这篇文章介绍了使用观测云与 FeatBit 通过双写双读的操作方式实现了降低数据库移植风险的基础方法。
在实际运行中,我们可能有大量的业务需要处理,人为的介入和操作会因为各种原因造成反应不及时的问题。在后续的文章中,我们将介绍更多的内容,如:

  • 使用观测云的指标服务与 FeatBit 的 Trigger 服务,实现移植时自动化实时回滚避灾与报警方案。
  • 使用观测云的指标服务与 FeatBit 的 Scheduler 服务 ,实现自动化的放量与回滚方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/84757.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

将eNSP Pro部署在华为云是什么体验

eNSP Pro简介 eNSP Pro 是华为公司数据通信产品线新推出的数通设备模拟器&#xff0c;主要应用在数据通信技能培训&#xff0c;为使用者提供华为数据通信产品设备命令行学习环境。 具备的能力 多产品模拟能力&#xff1a;支持数据通信产品线NE路由器、CE交换机、S交换机、AR…

实验二 Hdoop2.7.6+JDK1.8+SSH的安装部署与基本操作

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…

阿里云CDN加速器基本概念与购买开通

文章目录 1.CDN加速器的基本概念1.1.CDN加速器基本介绍1.2.网站引入CDN加速器的架构图1.3.CDN加速器的工作原理1.4.引入CDN后域名解析变成了CNAME&#xff1f; 2.开通阿里云CDN加速服务 1.CDN加速器的基本概念 CDN加速器官方文档&#xff1a;https://help.aliyun.com/product/…

Spring Clould 部署 - Docker

视频地址&#xff1a;微服务&#xff08;SpringCloudRabbitMQDockerRedis搜索分布式&#xff09; 初识Docker-什么是Docker&#xff08;P42&#xff0c;P43&#xff09; 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&…

Redis Lua脚本执行原理和语法示例

Redis Lua脚本语法示例 文章目录 Redis Lua脚本语法示例0. 前言参考资料 1. Redis 执行Lua脚本原理1.1. 对Redis源码中嵌入Lua解释器的简要解析&#xff1a;1.2. Redis Lua 脚本缓存机制 2. Redis Lua脚本示例1.1. 场景示例1. 请求限流2. 原子性地从一个list移动元素到另一个li…

计算机网络第2章(物理层)

计算机网络第2章&#xff08;物理层&#xff09; 2.1 物理层的基本概念2.2 物理层下面的传输媒体2.2.1 导引型传输媒体2.2.2 非导引型传输媒体 2.3 传输方式2.3.1 串行传输和并行传输2.3.2 同步传输和异步传输2.3.3 单向通信&#xff08;单工&#xff09;、双向交替通信&#x…

PyCharm PyQt5 开发环境搭建

环境 python&#xff1a;3.6.x PyCharm&#xff1a;PyCharm 2019.3.5 (Community Edition) 安装PyQT5 pip install PyQt5 -i https://pypi.douban.com/simplepip install PyQt5-tools -i https://pypi.douban.com/simple配置PyCharm PyQtUIC Program &#xff1a;D:\Pytho…

sql数据导出到excel

一、打开Navicat Premium 12 二、导出

SpringBoot 配置优先级

一般而言&#xff0c;SpringBoot支持配置文件进行配置&#xff0c;即在resources下的application.properties或application.yml。 关于配置优先级而言&#xff0c; application.properties>application.yml>application.yaml 另外JAVA程序程序还支持java系统配置和命令行…

Python-主线程控制子线程结束-2

需求&#xff1a;主线程创建工作子线程和键盘输入监听子线程。 当用户输入 0 后&#xff0c; 工作子线程会收到停止信号并退出&#xff0c;此时键盘输入监听线程仍然运行&#xff1b; 当用户输入 1 后&#xff0c;会建立新的工作子线程&#xff1b; …

计网第三章(数据链路层)(五)

目录 一、以太网交换机自学习和转发帧的过程 1.两层交换机和三层交换机 2.以太网交换机的基本原理 3.具体实现过程 一、以太网交换机自学习和转发帧的过程 1.两层交换机和三层交换机 大家可能注意到平常做题时有叫两层交换机&#xff0c;或者三层交换机的。 两层交换机就…

html表格中加入斜线,使用css给table表格表头单元格添加斜线

背景&#xff1a;业务给了90张word电子表格&#xff0c;需要用html设计出来。 如图所示&#xff0c;红色区域的下斜线如何实现&#xff1f; 先说结论&#xff1a;html中table没有直接的斜线表头标签&#xff0c;但结合css、svg之类的可以实现。 #lineTd{ background:#FFFFFF u…

UG\NX二次开发 创建中心线

文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,C\C++,Qt-CSDN博客 简介: 下面是在制图模块创建中心线的例子,用的是ufun函数。 效果: 代码: #include "me.hpp"#include <stdio.h> #include <string.h> #include <uf.h>…

Qt关于hex转double,或者QByteArray转double

正常的00 ae 02 33这种类型的hex数据类型可以直接通过以下代码进行转换 double QDataConversion::hexToDouble(QByteArray p_buf) {double retValue 0;if(p_buf.size()>4){QString str1 byteArrayToHexStr(p_buf.mid(0,1));QString str2 byteArrayToHexStr(p_buf.mid(1,…

如何使用CSS实现一个响应式视频播放器?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用CSS实现响应式视频播放器⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴趣…

数字孪生流域共建共享相关政策解读

当前数字孪生技术在水利方面的应用刚起步&#xff0c;2021年水利部首次提出“数字孪生流域”概念&#xff0c;即以物理流域为单元、时空数据为底座、数学模型为核心、水利知识为驱动&#xff0c;对物理流域全要素和水利治理管理活动全过程的数字映射、智能模拟、前瞻预演&#…

志凌海纳 SmartX 携手灵雀云推出全栈云原生联合解决方案

近日&#xff0c;北京志凌海纳科技有限公司&#xff08;以下简称“SmartX”&#xff09;与北京凌云雀科技有限公司&#xff08;以下简称“灵雀云”&#xff09;联合推出全栈云原生联合解决方案&#xff0c;为客户提供从基础设施到容器云平台的一站式服务&#xff0c;加速客户云…

七夕情侣飞行棋游戏限定版本源码/解锁版

七夕情侣飞行棋限定版本源码已经发布&#xff01;这是一款专为情侣打造的桌游&#xff0c;让您与您的另一半一起感受浪漫的体验。 更为重要的是&#xff0c;这个版本已经移除了路由器限制&#xff0c;解锁了全部功能&#xff0c;而且没有任何加密措施&#xff0c;您只需将源码…

英伟达™(NVIDIA®)535.98 Linux 图形驱动程序发布

导读英伟达™&#xff08;NVIDIA&#xff09;公司近日发布了适用于 Linux、FreeBSD 和 Solaris 系统的 NVIDIA 535.98 图形驱动程序&#xff0c;作为其生产分支的维护更新&#xff0c;解决了各种错误和问题。 在英伟达™&#xff08;NVIDIA&#xff09;535.86.05 版本发布仅三周…

阿里云100元预算可选的云服务器配置2核2G3M带宽

阿里云服务器100元可以买到哪些配置&#xff1f;如果是一年时长&#xff0c;轻量应用服务器2核2G3M带宽一年108元&#xff0c;系统盘为50GB高效云盘。以前阿里云服务器ECS卖过35元一年、69元、88元、89元和99元的都有过&#xff0c;但是现在整体费用上涨&#xff0c;入门级云服…
最新文章