业务实战记录4:多维表插入数据任务丢失处理与思考

news2024/12/24 9:14:20

本文目录

  • 一、线程 bug
  • 二、解决方案
    • 2.1 加停顿
    • 2.2 单线程
    • 2.3 多 Token
  • 三、一点花絮

很久没有写业务实战记录了,实际工作过程中其实遇到了挺多问题的,但是要通过 CSDN 记录下来,还是比较难的,因为场景和目标比较难说清楚,为了降低业务壁垒和脱敏,通常需要花更多的时间进行整理,可能还需要反复修改。


一、线程 bug

今天讲一个多线程的东西,由于我之前对这个不是很理解,所以处理起来还是比较棘手,所以想着记录一下,可能你也会有同样的困惑,希望能够帮上忙。

不知道大家有没有用过或者听说过多维表,维格表简单讲就是一款多维表。
目前飞书表格也可以使用多维表,如果只是使用的话,还是停舒服的,但是如果涉及到数据传输,比如说数据入库,或者将一些数据同步到飞书表格上,会有一定的限制,首先需要企业版,再者需要企业管理员创建应用,或者个人创建应用给企业管理员审批。

维格表就好在这一点,数据处理来去自由,通过 API 接口可以轻松获取、更新、新增、删除数据。
可以比较自由地使用。【打住,这不是广告文】

说说最近遇到的一个问题:之前的同事写了一个 Python 脚本,用于往维格表更新和插入数据,之前跑得挺顺畅,但是最近一段时间发现同步任务经常出现了一定的数据缺失。之前跑一次就可以完成,现在需要跑几次才可以。

前阵子由于忙其他的项目,没有去修 bug,这些天得空了,挖一挖,顺便把它改一改适配 ODPS Python,把手工任务放到阿里云上自动调度,省得手工跑(虽然不是我负责跑,哈哈哈)。

之前没有问题,但是现在有问题了,有可能是多维表最近有更新导致,不过,看了更新日志,简单到一下子看完了三年的更新,没有什么有价值信息。

直接去看 API 手册,发现了一些比较有价值的信息点:

同一个用户对同一张表的 API 请求频率上限为 5 次/秒。
获取记录接口:一次最多获取 1000 行记录。
比如想批量获取 10000 行记录,至少需要调用 10 次获取记录接口。
创建记录接口:一次最多创建 10 行记录。
比如想批量创建 1000 行记录,至少需要调用 100 次创建记录接口。
更新记录接口:一次最多更新 10 行记录。
比如想批量更新 1000 行记录,至少需要调用 100 次更新记录接口。

image.png

结合源码,源码采用了多线程(开启 3 个线程)更新和写入的方式,基本可以定位到具体的问题,就是多线程在 1 秒内请求同一张表的频率超过了 5 次,导致 5 次内的任务没问题,超过 5 次的任务失败了。
简化之后的代码如下:

import concurrent.futures
import time
def task(index):
    # 执行任务的代码,这里是更新或新增数据的任务
    print(f"任务 {index} 开始")
    time.sleep(0.1)  # 模拟执行时间
    print(f"任务 {index} 完成")
    return F"result:任务{index} 完成"
# 创建线程池
executor = concurrent.futures.ThreadPoolExecutor(max_workers=3)
# 提交多个任务到线程池
tasks = [executor.submit(task, i) for i in range(5)]

# 输出任务执行结果
for future in tasks:
    print(future.result())

二、解决方案

2.1 加停顿

为了不改动源码太多内容,我减少了1个线程,并添加了停顿时间,每 0.5 秒跑一个任务,1 秒跑 4 个任务,结果是没有问题的,能够将所有的数据都完整更新或插入。新增第 4 行和第 16 行,修改第11行,max_workers 改为 2。

import concurrent.futures
import time
def task(index):
    time.sleep(0.5)  # 增加 0.5 秒的停顿
    # 执行任务的代码,这里是更新或新增数据的任务
    print(f"任务 {index} 开始")
    time.sleep(0.1)  # 模拟执行时间
    print(f"任务 {index} 完成")
    return F"result:任务{index} 完成"
# 创建线程池
executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
# 提交多个任务到线程池
tasks = [executor.submit(task, i) for i in range(10)]

# 等待每一批次所有任务完成,再开始下一批
concurrent.futures.wait(tasks)

# 输出任务执行结果
for future in tasks:
    print(future.result())

2.2 单线程

如果采用单线程,控制每 0.2 秒跑一次也是可以的,开启线程反而有点大材小用了, 反正都快不了,最快只能 5 次/秒,单线程也够用。这个代码就是将所有多线程相关的代码全部删掉或注释掉,然后,通过一个简单循环,并控制每个循环停顿 0.2 秒,将数据直接更新或插入多维表中即可。

2.3 多 Token

当然,也可以有更加骚的操作,搞多几个用户的 Token,交替使用,需要评估下速度,避免速度太快导致数据缺失。这个代码应该挺有意思的,就是将配置一个 Token 池,然后每次任务分别给不同的 Token 跑数,一个 Token 可以请求 5 次,示例使用 3 个 Token 便可请求 15 次。当然,这样是否会存在数据任务丢失,还是需要评估一下,如何还出现丢失,可以考虑加 Token 或者加停顿时间。

import concurrent.futures
import time

def task(task_num, token):
    # time.sleep(0.5)       # 停顿 0.5 秒
    # 执行任务的代码,这里可以是你自己的任务逻辑
    print(f"任务 {task_num} 开始,使用{token}")
    time.sleep(0.1)     # 模拟执行时间,停顿 0.1 秒
    print(f"任务 {task_num} 完成,使用{token}")
    return F"result:任务{task_num} 完成"
# 创建线程池
executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)

# 假设有 3 个 token,10 组数据,需要循环 4 次
token_pool = ['token1','token2','token3']   # Token 池
groups_num = 10                             # 数据组数(任务数),用于多维表的更新或新增,每组上限10条
token_num = len(token_pool)                 # Token 数
loop_times = groups_num // token_num + 1    # 循环使用 Token 池次数
tasks = []
for times in range(loop_times):
    for index in range(token_num):
        task_num = token_num*times+index    # 任务数
        token = token_pool[index]
        # 最后一次循环跑完数据便停止,以免报错
        if task_num == groups_num:
            break
        # 提交多个任务到线程池
        tasks.append(executor.submit(task, task_num, token))

# 等待每一批次所有任务完成,再开始下一批
concurrent.futures.wait(tasks)

# 输出任务执行结果
for future in tasks:
    print(future.result())




三、一点花絮

聊点花絮(不喜勿喷):

在 debug 的过程中,还是比较艰难的,也经历过了好一段时间的探索。

一开始图方便,让国内知名大模型帮忙支招,但似乎它并不能理解【停顿时间】,还和超时时间混淆,还有一个明显的解释错误,就是submit()的第二个参数并不是设置超时时间的,而是传参用的。当然,也提了改进反馈给官方。


在这里插入图片描述

后面让国外知名大模型试试,停顿时间理解对了,也给了可行的解决办法。

在这里插入图片描述

这里没有贬低和抬高的意思,只是国内知名大模型仍需努力,毕竟国外的,有诸多限制,不仅仅是使用限制,还有安全层面的考量,这几年的断芯是前车之鉴,值得深思。可以依赖但不能过度依赖。

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

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

相关文章

【网络】HTTPHTTPS协议

文章目录 HTTP协议认识URLurlencode和urldecodeHTTP协议格式HTTP请求协议格式简单的小实验 HTTP响应协议格式关于封装解包分用 HTTP的方法关于GET和POST方法概念GET&POST对比(代码测试)测试POST和GET方法的区别 HTTP的状态码关于重定向的状态码临时重定向的代码演示: HTTP的…

【文献研究】轴辐式航线网络设计—Liner hub-and-spoke shipping network design

学习文献:轴辐式航线网络设计—Liner hub-and-spoke shipping network design 3. 模型建立 轴辐式航线网络设计 三级轴辐式网络:喂给港-二级枢纽港-一级枢纽港 主要考虑的限制条件:多种类型的集装箱船舶、转运时间、多种类型的集装箱 转运操…

Kangas:计算机视觉中的Pandas

介绍 在计算机视觉领域,Kangas是一种越来越受欢迎的工具,用于图像数据处理和分析。类似于Pandas如何改变数据分析人员处理表格数据的方式,Kangas对计算机视觉任务也起到了同样的作用。 Kangas是Comet ML开源的工具,用于探索、分析…

【Http协议①】认识http协议,学会使用fiddler抓包工具进行抓包.

前言: 大家好,我是良辰丫,今天我们一起来学习http协议,http协议是应用层的协议,应用层是最接近程序员的,那么,http协议到底是什么呢?我们往下看.💞💞 🧑个人主页:良辰针不戳 📖所属专栏:javaEE初阶 &#…

springboot+java养老院儿童福利院管理系统

安家儿童福利院管理系统包括儿童管理、申请领养管理、捐赠管理、楼栋管理、宿舍管理、分配信息管理、宿舍物品管理、报修管理、维修工管理、报修状态管理、留言管理、系统管理。通过对系统的实现得出安家儿童福利院管理系统具有安全稳定、操作简单、功能强大等特点,…

MySQL8.0卸载、安装和使用(二)

MySQL数据库的安装 注意: 必须用系统管理员身份运行mysql安装程序。安装目录切记不要用中文。 步骤一:双击mysql8的安装向导 步骤二:分为首次安装和再安装 1、首次安装 (1)如果是首次安装mysql系列的产品&#xff…

第06章_多表查询

第06章_多表查询 多表查询,也称为关联查询,指两个或更多个表一起完成查询操作。 前提条件:这些一起查询的表之间是有关系的(一对一、一对多),它们之间一定是有关联字段,这个关联字段可能建立了…

脑科学研究者的案头书(含下载资源)

脑科学研究者的案头书 <<< 回复关键词获取下载链接 >>> 《EEG Signal Processing and Machine Learning》&#xff08;Second Edition&#xff09; 简介&#xff1a; 《脑电信号处理与机器学习》书籍旨在描述脑电图(EEG)研究中的新技术和成果&#xff0c;主…

chatgpt赋能Python-python3捕获异常

Python3异常处理技术详解 在Python3中&#xff0c;异常处理技术是一项非常重要的工具。它能够帮助程序员避免不可预见的错误&#xff0c;减少不必要的程序崩溃&#xff0c;保证程序的稳定性。 什么是异常&#xff1f; 异常就是程序在执行过程中发生的错误或异常情况。不同的…

Redis+LUA脚本实现限流

文章目录 1、demo结构2、自定义接口3、编写写LUA脚本4、通过AOP切面识别需要限流的接口编写切面AOP通知类型 5、Redis限流自定义异常构建Redis限流自定义异常声明这个类为全局异常处理器专属日志 6、流量限制器RateLimiterRateLimitAlgApiLimitRateLimitRuleRuleConfig 7、Guav…

Win11系统不兼容怎么回退到Win10系统使用?

Win11系统不兼容怎么回退到Win10系统使用&#xff1f;有用户将自己的电脑系统升级到了Win11之后&#xff0c;发现使用起来非常的卡顿&#xff0c;自己的电脑配置不足。那么这个情况怎么去进行问题的解决呢&#xff1f;来看看以下详细的解决方法分享吧。 准备工作&#xff1a; 1…

Golang每日一练(leetDay0071) 同构字符串、反转链表

目录 205. 同构字符串 Isomorphic Strings &#x1f31f; 206. 反转链表 Reverse Linked-list &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日一练 专栏 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 205. 同…

Debezium系列之:Debezium镜像仓库Quay.io,使用Debezium镜像仓库的方法和案例

Debezium系列之:Debezium镜像仓库Quay.io,使用Debezium镜像仓库的方法和案例 一、Debezium镜像仓库变动二、镜像仓库[Quay.io](https://quay.io/organization/debezium)三、使用镜像仓库Quay.io方法四、使用镜像仓库下载Debezium UI一、Debezium镜像仓库变动 Debezium2.2版本…

Linux RTC 驱动实验

RTC 也就是实时时钟&#xff0c;用于记录当前系统时间&#xff0c;对于 Linux 系统而言时间是非常重要的&#xff0c; 就和我们使用 Windows 电脑或手机查看时间一样&#xff0c;我们在使用 Linux 设备的时候也需要查看时 间。 一、Linux 内核 RTC 驱动简介 RTC 设备驱动是标准…

verdaccio + docker搭建私有npm仓库(有手就行)

一、环境准备 docker 二、步骤 运行verdaccio docker run -d --name verdaccio -p 4873:4873 --restartalways该命令执行完&#xff0c;一个本地的npm仓库就基本搭建好了&#xff0c;可以浏览器访问http://localhost:4873/ 查看&#xff0c;效果如下&#xff1a; 效果出是…

教你接入Midjourney,不用梯子也能玩

1、效果 话不多说&#xff0c;先上最终出图效果&#xff0c; 我给的关键词是一只白色的猫 2、接入流程 API文档可以来这里查&#xff08;可以白嫖100次midjourney出图和10次gpt4体验&#xff09;&#xff0c;我这里精简一下接入流程&#xff0c;方便大家快速接入 2.1、文字生…

JDK源码怎么学?看这篇文章就够了!

最近后台收到很多粉丝私信&#xff0c;说的是程序员究竟要不要去读源码&#xff1f;当下行情&#xff0c;面试什么样的薪资/岗位才会被问到源码&#xff1f; 对此&#xff0c;我的回答是&#xff1a;一定要去读&#xff0c;并且要提到日程上来&#xff01; 据不完全统计&…

远程访问群晖Drive并挂载为电脑磁盘同步备份文件「无需公网IP」

文章目录 前言视频教程1.群晖Synology Drive套件的安装1.1 安装Synology Drive套件1.2 设置Synology Drive套件1.3 局域网内电脑测试和使用 2.使用cpolar远程访问内网Synology Drive2.1 Cpolar云端设置2.2 Cpolar本地设置2.3 测试和使用 3. 结语 转发自CSDN远程穿透的文章&…

ARM的数据处理指令、跳转指令与储存器访问指令

最开始在此介绍一下CPSR寄存器中 N、Z、C、V 4位的作用&#xff1a; Bit[28]&#xff08;V&#xff09;&#xff1a; 当运算器中进行加法运算且产生符号位进位时该位自动置1&#xff0c;否则为0 当运算器中进行减法运算且产生符号位借位时该位自动置0&#xff0c;否则为1 …

头歌计算机组成原理实验—运算器设计(6)第6关:5位无符号阵列乘法器设计

第6关&#xff1a;5位无符号阵列乘法器设计 实验目的 帮助学生掌握阵列乘法器的实现原理&#xff0c;能够分析阵列乘法器的性能&#xff0c;能在 Logisim 中绘制阵列乘法器电路。 视频讲解 实验内容 在 Logisim 中打开 alu.circ 文件&#xff0c;在5位阵列乘法器中实现斜向…