使用 Feature Flags 实现数据库灰度迁移的监控与可观测性

news2024/11/17 3:29:16

作者:观测云与胡博

场景描述

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

解决方案

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

  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.coloradmin.cn/o/1018752.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows 安装 chromedriver 和 Python 调试

下载 chromedriver 从官方网站上下载 chromedriver 的版本&#xff0c;这个版本需要和你 Chrome 的版本对应上。 下载的地址为&#xff1a;ChromeDriver - WebDriver for Chrome - Downloads 这个地方&#xff0c;将会打开一个新的浏览器界面&#xff0c;Chrome for Testing …

9参数化重采样时频变换,基于MATLAB平台,程序已调通,可直接替换数据进行分析。

参数化重采样时频变换&#xff0c;基于MATLAB平台&#xff0c;程序已调通&#xff0c;可直接替换数据进行分析。 9matlab参数化重采样时频变换 (xiaohongshu.com)

Debian 12安装Docker

1.更新系统包 #apt update 2.安装依赖包 #apt install apt-transport-https ca-certificates curl gnupg lsb-release 3.添加Docker源 &#xff08;1&#xff09;添加Docker 官方GPG密钥 #curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/s…

OPENCV实现DNN图像分类

使用步骤1 使用步骤2 使用步骤3 使用步骤4 使用步骤5 使用步骤6 完整代码如下: import numpy as np

lv5 嵌入式开发-1 进程的创建和回收

目录 1 进程概念 2 进程内容 3 进程类型 4 进程状态 5 查看进程信息 5.1 相关命令ps top /proc 5.2 相关命令 nice renice 5.3 相关命令job bg fg 6 子进程概念 7 子进程创建 – fork 8 父子进程 9 思考 10 进程结束 – exit/_exit 11 进程的回收 11.1 进程回…

opencv形状目标检测

1.圆形检测 OpenCV图像处理中“找圆技术”的使用-图像处理-双翌视觉OpenCV图像处理中“找圆技术”的使用,图像处理,双翌视觉https://www.shuangyi-tech.com/news_224.htmlopencv 找圆心得&#xff0c;模板匹配比霍夫圆心好用 - 知乎1 相比较霍夫找直线算法&#xff0c; 霍夫找…

RK3568平台开发系列讲解(调试篇)系统运行相关频率设置

🚀返回专栏总目录 文章目录 一、CPU 频率设置二、DDR 频率设置三、NPU 频率设置沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 CPU 默认是 interactive 状态,它会根据 CPU 使用率和目标负载来动态地调整 CPU 频率。为获得更高运行速度或者性能评估,我们需要手动固…

红外成像技术

针对GI S设备红外检测目前未被大众认可的原因&#xff1a; 1 、 目前对GI S带电检测的意义认识不够&#xff0c; 许多单位认为GI S测温发现不了什么&#xff0c; 对其测温仅仅检测接头。 2、 GI S外壳温度异常的原因多种&#xff0c; 出现外壳温度异常大家不会分析&#xff0c;…

stringBuffer.append(analyze);使用这个拼接时候如何在字符串参数字符串参数整数参数字符串数组参数内容之间添加空格

stringBuffer.append(analyze);使用这个拼接时候如何在字符串参数字符串参数整数参数字符串数组参数内容之间添加空格&#xff1f; 在添加参数到 StringBuffer 时&#xff0c;你可以在每次添加参数之后都添加一个空格&#xff0c;如下所示&#xff1a; StringBuffer stringBu…

【Linux入门】---Linux权限管理详解

文章目录 1.shell命令以及运行原理2.linux用户分类su指令切换用户 3.Linux权限管理3.1Linux文件访问者3.2文件类型和访问权限3.3文件权限值的表示方法3.4文件访问权限的相关设置方法chmod指令--权限修改方法①chmod指令--权限修改方法②chown指令chgrp指令umask指令file指令 4.…

按键点亮led灯

原理图: K0这个按键按下时&#xff0c;开发板D1这个灯亮&#xff0c;松开&#xff0c;灯灭 代码如下: #include "stm32f4xx.h" void LED_Init(void) {//1.定义一个GPIO外设的结构体变量 GPIO_InitTypeDef GPIO_InitStructure;//RCC_AHB1PeriphClockCmd(RCC_AHB1Pe…

【自学开发之旅】Flask-前后端联调-异常标准化返回(六)

注册联调&#xff1a; 前端修改&#xff1a; 1.修改请求向后端的url地址 文件&#xff1a;env.development修改成VITE_API_TARGET_URL http://127.0.0.1:9000/v1 登录&#xff1a;token验证 校验forms/user.py from werkzeug.security import check_password_hash# 登录校验…

目标检测前言,RCNN,Fast RCNN,Faster RCNN

一、RCNN&#xff1a; 找到概率最高的目标之后&#xff0c;与其他目标进行IOU交并比计算&#xff0c;若高于一定值&#xff0c;则说明这两张图片预测的是同一个目标&#xff0c;则把概率低的目标删掉 二、Fast RCNN 因为是直接得到特征图之后进行映射&#xff0c;所以不限制输入…

AXMB-GY v2.0: 全新开源的爱希彩虹易支付模板,简洁轻量级设计

AXMB-GYv2.0&#xff1a;全新发布的开源爱希彩虹易支付模板。该模板对用户中心、登录、注册、找回密码和支付页面进行了美化&#xff0c;采用了简洁轻量级的设计风格。作为全开源模板&#xff0c;它提供了灵活且自由的定制和二次开发选项。同时&#xff0c;该模板具有出色的兼容…

Typora偏好设置中图床的配置文件点击打开没有反应

Typora偏好设置中图床的配置文件点击打开没有反应 突然发现Typora偏好设置中图床打开配置文件点击没有反应&#xff0c;如下按钮所示 可能是因为系统不知道用什么软件打开json&#xff0c;直接进入配置文件json目录&#xff0c;一般位置在C:\Users\<your_user_name>\.pi…

CSS选择器笔记

A plate #id #fancy A B plate apple #id A #fancy pickle .classname .small A.className orange.small #id.className #big.wide A,B both plate,bento * all A * plate * AB 紧跟在盘子后的苹果 plate apple A~B 跟在盘子后面所有的泡菜 plate~b…

Mybatis学习笔记5 面向接口CRUD练习

新建项目 大致目录结构 核心配置文件 日志配置文件,只需要引入logback依赖 配置文件名为logback.xml即可 <?xml version"1.0" encoding"UTF-8"?> <configuration debug"false"><!--定义⽇志⽂件的存储地址--><propert…

8.全配置自动生成模块前后端

文章目录 学习资料配置式开发全新的模块&#xff08;快速实现&#xff09;字典管理代码生成器详细属性设置全智能模块开发查询调整-多表连接药品模块-生产厂家下拉框 学习资料 https://www.bilibili.com/video/BV13g411Y7GS/?p19&spm_id_frompageDriver&vd_sourceed0…

Qt ffmpeg音视频转换工具

Qt ffmpeg音视频转换工具&#xff0c;QProcess方式调用ffmpeg&#xff0c;对音视频文件进行格式转换&#xff0c;支持常见的音视频格式&#xff0c;主要在于QProcess的输出处理以及转换的文件名和后缀的处理&#xff0c;可以进一步加上音视频剪切合并和音视频文件属性查询修改的…

GraphQL基础知识与Spring for GraphQL使用教程

文章目录 1、数据类型1.1、标量类型1.2. 高级数据类型 基本操作2、Spring for GraphQL实例2.1、项目目录2.2、数据库表2.3、GraphQL的schema.graphql2.4、Java代码 3、运行效果3.1、添加用户3.2、添加日志3.3、查询所有日志3.4、查询指定用户日志3.5、数据订阅 4、总结 GraphQL…