当前位置: 首页 > news >正文

对OceanBase中的配置项与系统变量,合法性检查实践

在“OceanBase 配置项&系统变量实现及应用详解”的系列文章中,我们已经对配置项和系统变量的源码进行了解析。当涉及到新增配置项或系统变量时,通常会为其指定一个明确的取值范围或定义一个专门的合法性检查函数。本文将详细阐述在不同情境下,应如何对配置项和系统变量进行合法性检查。

配置项的合法性检查

配置项通常可以直接设定其取值范围,或者根据需要自定义合法性检查函数。此外,在某些情况下,还需要通过访问特定的配置项甚至系统变量,才能确定是否满足修改条件

常规检查

在定义配置项时,对于基础类型的数据,一般会指定一个“取值范围”。比如[0,100]"表示0到100之间的整数,方括号表示包含0和100;"[0M,)"表示范围从0到无穷大,"M"是数据的单位,它还可以是"K"、"G"等。

DEF_INT(cpu_count, OB_CLUSTER_PARAMETER, "0", "[0,]","the number of CPU\\'s in the system. ""If this parameter is set to zero, the number will be set according to sysconf; ""otherwise, this parameter is used. Range: [0,+∞) in integer",ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));

cpu_count 合法性检查示例:

对于有的配置项,无法用一个简单的字符串来描述它的取值范围,就需要定义一个专门的检查函数。

DEF_STR_WITH_CHECKER(default_compress_func, OB_CLUSTER_PARAMETER, "zstd_1.3.8",common::ObConfigCompressFuncChecker,"default compress function name for create new table, ""values: none, lz4_1.0, snappy_1.0, zlib_1.0, zstd_1.0, zstd_1.3.8",ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));

合法性检查类有固定的模板可以使用,只需模仿已有的结构定义即可。关键在于check函数的功能,比如 ObConfigCompressFuncChecker::check 函数,会去检查传入的值是否在指定的 compress_funcs 数组中,如果不是则返回 is_valid = false,表示参数不合法,那么最终就会修改失败。

bool ObConfigCompressFuncChecker::check(const ObConfigItem &t) const
{bool is_valid = false;for (int i = 0; i < ARRAYSIZEOF(common::compress_funcs) && !is_valid; ++i) {if (0 == ObString::make_string(compress_funcs[i]).case_compare(t.str())) {is_valid = true;}}return is_valid;
}// 在某个头文件中定义
const char *const compress_funcs[] =
{"lz4_1.0","none","snappy_1.0","zstd_1.0","zstd_1.3.8","lz4_1.9.1",
};

default_compress_func 合法性检查示例:

特殊检查

检查集群配置项

有的配置项可能会依赖其他配置项的值,比如A必须大于B、A*B要小于C等要求,这时候就需要在检查函数中访问其他配置项的值,从而判断当前传入的新值是否符合要求。

例如租户配置项 max_stale_time_for_weak_consistency,不能小于集群配置项 weak_read_version_refresh_interval(超时时间必须大于刷新时间,不然来不及刷新很可能会超时),那么在它的 check 函数中,可以通过全局的 GCONF 对象访问集群配置项的值。

bool ObConfigStaleTimeChecker::check(const ObConfigItem &t) const
{bool is_valid = false;int64_t stale_time = ObConfigTimeParser::get(t.str(), is_valid);if (is_valid) {is_valid = (stale_time >= GCONF.weak_read_version_refresh_interval);if (!is_valid) {LOG_USER_ERROR(OB_NOT_SUPPORTED, "max_stale_time_for_weak_consistency violate"" weak_read_version_refresh_interval,");}}return is_valid;
}

max_stale_time_for_weak_consistency 合法性检查示例:

检查租户配置项

对于某些配置项,可能需要跟另一个租户配置项进行对比,而租户配置项存在多个实例,显然无法直接通过 GCONF 访问。

以 partition_balance_schedule_interval 为例,首先定义一个常量字符串 PARTITION_BALANCE_SCHEDULE_INTERVAL 来表示该配置项,在配置项预检查函数 set_config_pre_hook 中,如果 strcmp 匹配到该配置项,则可以进行后续的检查。遍历本次更新涉及到的所有 tenant_id(注意不是所有租户,只是当前修改命令涉及的租户),依次获取每个租户的 tenant_config,从中取出配置项 balancer_idle_time,然后与传入的值进行对比,若所有租户全部检查通过则可以修改。

	} else if (0 == STRCMP(item->name_.ptr(), PARTITION_BALANCE_SCHEDULE_INTERVAL)) {const int64_t DEFAULT_BALANCER_IDLE_TIME = 10 * 1000 * 1000L; // 10sfor (int i = 0; i < item->tenant_ids_.count() && valid; i++) {const uint64_t tenant_id = item->tenant_ids_.at(i);omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));int64_t balancer_idle_time = tenant_config.is_valid() ? tenant_config->balancer_idle_time : DEFAULT_BALANCER_IDLE_TIME;int64_t interval = ObConfigTimeParser::get(item->value_.ptr(), valid);if (valid) {if (0 == interval) {valid = true;} else if (interval >= balancer_idle_time) {valid = true;} else {valid = false;char err_msg[DEFAULT_BUF_LENGTH];(void)snprintf(err_msg, sizeof(err_msg), "partition_balance_schedule_interval of tenant %ld, ""it should not be less than balancer_idle_time", tenant_id);LOG_USER_ERROR(OB_INVALID_ARGUMENT, err_msg);}}if (!valid) {ret = OB_INVALID_ARGUMENT;LOG_WARN("config invalid", KR(ret), K(*item), K(balancer_idle_time), K(tenant_id));}}

partition_balance_schedule_interval 合法性检查示例:

  1. 修改所有租户的 partition_balance_schedule_interval = 1800s 失败,因为其中一个租户 perf 的 balancer_idle_time = 2000s,而 partition_balance_schedule_interval 不能小于 balancer_idle_time,所以 perf 租户无法修改,导致整个修改操作失败;
  2. 修改 test 租户的 partition_balance_schedule_interval = 1800s 成功,因为 test 租户的 balancer_idle_time = 10s,满足要求;
  3. 修改 perf 租户的 partition_balance_schedule_interval = 1800s 失败,因为 perf 租户的 balancer_idle_time = 2000s,不满足要求;
  4. 修改 sys 租户(当前租户为sys租户)的 partition_balance_schedule_interval = 1800s 成功,因为 sys 租户的 balancer_idle_time = 10s,满足要求;

1702260734

检查全局系统变量

配置项还可能受到系统变量的影响,有时也需要检查全局系统变量的值,这就要从schema中获取系统变量进行比较。

以 max_stale_time_for_weak_consistency为例,同样地,首先为目标配置项定义一个常量字符串 WEAK_READ_VERSION_REFRESH_INTERVAL。在配置项预检查函数 set_config_pre_hook 中,如果 strcmp 匹配到该配置项,则可以进行后续的检查,代码较多的情况下可以封装一个函数(check_weak_read_version_refresh_interval)用于检查合法性。

const char* const WEAK_READ_VERSION_REFRESH_INTERVAL = "weak_read_version_refresh_interval";int ObRootService::set_config_pre_hook(obrpc::ObAdminSetConfigArg &arg)
{} else if (0 == STRCMP(item->name_.ptr(), WEAK_READ_VERSION_REFRESH_INTERVAL)) {int64_t refresh_interval = ObConfigTimeParser::get(item->value_.ptr(), valid);if (valid && OB_FAIL(check_weak_read_version_refresh_interval(refresh_interval, valid))) {LOG_WARN("check refresh interval failed ", KR(ret), K(*item));} else if (!valid) {ret = OB_INVALID_ARGUMENT;LOG_WARN("config invalid", KR(ret), K(*item));}

check_weak_read_version_refresh_interval 函数先从 schema_service_中获取所有租户的 id,然后对于每个租户,依次从 schema_service_中获取 ob_max_read_stale_time 的值,再与当前传入的值进行对比,如果不合法则返回 false,所以租户都检查通过则返回 true。

int ObRootService::check_weak_read_version_refresh_interval(int64_t refresh_interval, bool &valid)
{......if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, sys_schema_guard))) {LOG_WARN("get sys schema guard failed", KR(ret));} else if (OB_FAIL(sys_schema_guard.get_tenant_ids(tenant_ids))) {LOG_WARN("get tenant ids failed", KR(ret));} else {......for (int64_t i = 0; OB_SUCC(ret) && valid && i < tenant_ids.count(); i++) {tenant_id = tenant_ids[i];if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(tenant_id, schema_guard))) {LOG_WARN("get schema guard failed", KR(ret), K(tenant_id));} else if (OB_FAIL(schema_guard.get_tenant_system_variable(tenant_id,OB_SV_MAX_READ_STALE_TIME, var_schema))) {LOG_WARN("get tenant system variable failed", KR(ret), K(tenant_id));} else if (OB_FAIL(var_schema->get_value(NULL, NULL, obj))) {LOG_WARN("get value failed", KR(ret), K(tenant_id), K(obj));} else if (OB_FAIL(obj.get_int(session_max_stale_time))) {LOG_WARN("get int failed", KR(ret), K(tenant_id), K(obj));} else if (session_max_stale_time != share::ObSysVarFactory::INVALID_MAX_READ_STALE_TIME&& refresh_interval > session_max_stale_time) {valid = false;LOG_USER_ERROR(OB_INVALID_ARGUMENT,"weak_read_version_refresh_interval is larger than ob_max_read_stale_time");}}}

weak_read_version_refresh_interval 合法性检查示例:

  1. 修改 session 变量 ob_max_read_stale_time = 2s,然后修改 weak_read_version_refresh_interval = 3s 成功,因为session变量不影响配置项的修改;
  2. 修改 global 变量 ob_max_read_stale_time = 2s 失败,因为 ob_max_read_stale_time(系统变量)需要大于等于 weak_read_version_refresh_interval(配置项);
  3. 修改 global 变量 ob_max_read_stale_time = 3s,然后修改 weak_read_version_refresh_interval = 4s 失败,因为global变量的值可以影响配置项的修改;

系统变量的合法性检查

系统变量同样支持多种合法性检查方式,以便应对不同场景的需求。

常规检查

与配置项类似,在定义系统变量时也可以指定取值范围。

例如 connect_timeout,设置了"min_val"和"max_val"字段,取值范围就是[2, 31536000],不需要自己增加额外的代码,现有的框架会自动进行范围检查。

"connect_timeout": {"id": 22,"name": "connect_timeout","default_value": "10","base_value": "10","data_type": "int","info": " ","flags": "GLOBAL","min_val": "2","max_val": "31536000","publish_version": "","info_cn": "","background_cn": "","ref_url": ""},

connect_timeout 范围检查示例:

有的系统变量是字符串类型,无法用简单的数值表示取值范围,可以在 update_global_variables 函数中增加额外的检查代码。例如 ob_log_level,调用 OB_LOGGER.parse_check 函数进行检查,返回 OB_SUCCESS 表示检查通过。

	} else if (set_var.var_name_ == OB_SV_LOG_LEVEL) {ObString log_level;if (OB_FAIL(val.get_varchar(log_level))) {LOG_WARN("fail get varchar", K(val), K(ret));} else if (0 == log_level.case_compare("disabled")) {//allowed for variables} else if (OB_FAIL(OB_LOGGER.parse_check(log_level.ptr(), log_level.length()))) {LOG_WARN("Log level parse check error", K(log_level), K(ret));}

ob_log_level 合法性检查示例:

特殊检查

同样的,系统变量也需要访问其他的配置项或者变量,从而判断传入值的合法性。

检查集群配置项

以 ob_max_read_stale_time 为例,如果是global变量,可以在 update_global_variables 函数中,通过 GCONF 获取其他集群级别配置项的值,对比当前传入的值是否合法,不合法则返回 OB_INVALID_ARGUMENT。

int ObVariableSetExecutor::update_global_variables(
{......} else if (set_var.var_name_ == OB_SV_MAX_READ_STALE_TIME) {int64_t max_read_stale_time = 0;if (OB_FAIL(val.get_int(max_read_stale_time))) {LOG_WARN("fail to get int value", K(ret), K(val));} else if (max_read_stale_time != ObSysVarFactory::INVALID_MAX_READ_STALE_TIME &&max_read_stale_time < GCONF.weak_read_version_refresh_interval) {ret = OB_INVALID_ARGUMENT;LOG_USER_ERROR(OB_INVALID_ARGUMENT,"max_read_stale_time is smaller than weak_read_version_refresh_interval");}

ob_max_read_stale_time 合法性检查示例:

如果是session变量,则可以在 process_session_variable 函数中调用相应的处理函数,相关的判断逻辑与global变量一致即可。

OB_INLINE int ObBasicSessionInfo::process_session_variable(ObSysVarClassType var, const ObObj &val,const bool check_timezone_valid/*true*/, const bool is_update_sys_var/*false*/)
{int ret = OB_SUCCESS;switch (var) {case SYS_VAR_OB_LOG_LEVEL: {OZ (process_session_log_level(val), val);break;}

检查租户配置项

目前代码中没有这样的例子,如果需要在更新系统变量时检查租户配置项,可以参考更新配置项时的做法。而且,系统变量只涉及当前租户,所以也只需要获取当前租户的配置项进行合法性检查。

检查系统变量

对于global变量,可以在 update_global_variables 函数中,先获取当前租户的 schema,然后取得需要的系统变量的值。获取的方式与“更新配置项时检查全局系统变量”类似,不再赘述。

对于session变量,在 process_session_variable 函数中,通过 sys_vars_cache_.get_xxx() 的方式获取其缓存值,检查通过后直接调用 sys_vars_cache_.set_xxx() 函数更新变量值即可。

小结

通过自定义的合法性检查手段,对配置项和系统变量的值进行检查,可以有效避免用户设置无效的、超出正常边界的值,进而影响系统稳定性和可用性。

至此,关于配置项和系统变量的使用方法和源码分析已经介绍完了,接下来还会有一些应用和问题排查相关的文章,感兴趣的同学可以关注下。

参考文档

如何新增配置项?

如何新增系统变量?

OceanBase 里的 schema 是什么?

相关文章:

对OceanBase中的配置项与系统变量,合法性检查实践

在“OceanBase 配置项&系统变量实现及应用详解”的系列文章中&#xff0c;我们已经对配置项和系统变量的源码进行了解析。当涉及到新增配置项或系统变量时&#xff0c;通常会为其指定一个明确的取值范围或定义一个专门的合法性检查函数。本文将详细阐述在不同情境下&#x…...

YOLOv8绝缘子边缘破损检测系统(可以从图片、视频和摄像头三种方式检测)

可检测图片和视频当中出现的绝缘子和绝缘子边缘是否出现破损&#xff0c;以及自动开启摄像头&#xff0c;进行绝缘子检测。基于最新的YOLO-v8训练的绝缘子检测模型和完整的python代码以及绝缘子的训练数据&#xff0c;下载后即可运行。&#xff08;效果视频&#xff1a;YOLOv8绝…...

【vim 学习系列文章 18 -- 选中行前后增加两行】

请阅读【嵌入式开发学习必备专栏 之 Vim】 文章目录 选中行前后增加两行1. 定义函数2. 创建快捷键映射3. 保存并重新加载 .vimrc使用方法 重新选中实现步骤 1: 定义函数步骤 2: 绑定快捷键保存并重新加载 .vimrc使用方法 选中行前后增加两行 为了在 Vim 中实现这个功能&#x…...

分布式系统接口限流方案

Git地址&#xff1a;https://gitee.com/deepjava/test-api-limit.git 方案一、 Guava工具包 实现单机版限流 具体代码见git 方案二、Redis lua脚本 实现分布式系统的接口限流 具体代码见git...

Flutter仿Boss-6.底部tab切换

效果 实现 图片资源采用boss包中的动画webp资源。Flutter采用Image加载webp动画。 遇到的问题 问题&#xff1a;Flutter加载webp再次加载无法再次播放动画问题 看如下代码&#xff1a; Image.asset(assets/images/xxx.webp,width: 40.w,height: 30.w, )运行的效果&#xf…...

深入理解机器学习:用Python构建您的第一个预测模型

在这个数据驱动的时代&#xff0c;机器学习技术正在成为各行各业的变革力量。无论是金融、医疗、零售还是教育&#xff0c;机器学习都在为业务决策提供支持&#xff0c;优化用户体验&#xff0c;并创造出全新的服务方式。今天&#xff0c;我们将一起走进机器学习的世界&#xf…...

redisson与redis集群检测心跳机制原理

redisson与redis集群检测心跳机制原理 1、ClusterConnectionManager.scheduleClusterChangeCheck 创建延时定时调度任务 2、monitorFuture group.schedule(new Runnable() { EventExecutorGroup 是 Netty 中用于管理一组 EventExecutor 的组件&#xff0c;它类似于 EventLoo…...

部署Redis

部署Redis过程简要记录 在家目录创建存放各类软件源码、安装文件、数据、日志、依赖等目录 cd /home/liqiang mkdir sourcecode software app log data lib tmp在 sourcecode 中下载Redis并解压 cd sourcecode wget http://download.redis.io/releases/redis-5.0.4.tar.gz t…...

性能测试-数据库优化二(SQL的优化、数据库拆表、分表分区,读写分离、redis)

数据库优化 explain select 重点&#xff1a; type类型&#xff0c;rows行数&#xff0c;extra SQL的优化 在写on语句时&#xff0c;将数据量小的表放左边&#xff0c;大表写右边where后面的条件尽可能用索引字段&#xff0c;复合索引时&#xff0c;最好按复合索引顺序写wh…...

44.基于SpringBoot + Vue实现的前后端分离-汽车租赁管理系统(项目 + 论文PPT)

项目介绍 本站是一个B/S模式系统&#xff0c;采用SpringBoot Vue框架&#xff0c;MYSQL数据库设计开发&#xff0c;充分保证系统的稳定性。系统具有界面清晰、操作简单&#xff0c;功能齐全的特点&#xff0c;使得基于SpringBoot Vue技术的汽车租赁管理系统设计与实现管理工作…...

2024届数字IC秋招-华为机试-数字芯片-笔试真题和答案(五)(含2022年和2023年)

文章目录 前言1、多比特信号A,时钟域clk_a存在从4’d11到4’d12的变化过程中,若时钟域clk_b直接采用D触发器采样,可能采样到数据是2、Bod由1变成0,Arb会如何变化3、减少片外DRAM的访问,而代之以片内SRAM访问,这样可以降低访问功耗,降低片外DRAM,同时加大片内SRAM能节省…...

Lua语法(四)——协程

参考链接: 系列链接: Lua语法(一) 系列链接: Lua语法(二)——闭包/日期和时间 系列链接: Lua语法(三)——元表与元方法 系列链接: Lua语法(四)——协程 系列链接: Lua语法(五)——垃圾回收 系列链接: Lua语法(六)——面相对象编程 Lua语法 四——协程 简介正文协程coroutine.c…...

LangChain-15 Manage Prompt Size 管理上下文大小,用Agent的方式询问问题,并去百科检索内容,总结后返回

背景描述 这一节内容比较复杂&#xff1a; 涉及到使用工具进行百科的检索&#xff08;有现成的插件&#xff09;有AgentExecutor来帮助我们执行后续由于上下文过大&#xff0c; 我们通过计算num_tokens&#xff0c;来控制我们的上下文 安装依赖 pip install --upgrade --qu…...

OR-TOOL 背包算法

起因&#xff1a;最近公司要发票自动匹配&#xff0c; 比如财务输入10000W块&#xff0c;找到发票中能凑10000的。然后可以快速核销。 废话不多&#xff0c; 一 官方文档 https://developers.google.cn/optimization/pack/knapsack?hlzh-cn 二 POM文件 <!--google 算法包…...

前端h5录音

时隔差不多半个月&#xff0c; 现在才来写这编博客。由于某些原因&#xff0c;我一直没有写&#xff0c;请大家原谅。前段时间开发了一个小模块。模块的主要功能就是有一个录音的功能。也就是说&#xff0c;模仿微信发送语音的功能一样。不多说&#xff0c;直接来一段代码 //自…...

Android Studio 使用Flutter开发第一个Web页面(进行中)

附上Flutter官方文档 1、新建Flutter项目&#xff08;需要勾选web选项&#xff09; 新建项目构成为&#xff1a; 2、配置 Flutter 使用 path 策略 官方文档 在main.dart中&#xff0c;需要导入flutter_web_plugins/url_strategy.dart包&#xff0c;并在main(){}函数中usePath…...

Vue.js组件精讲 第2章 基础:Vue.js组件的三个API:prop、event、slot

如果您已经对 Vue.js 组件的基础用法了如指掌&#xff0c;可以跳过本小节&#xff0c;不过当做复习稍读一下也无妨。 组件的构成 一个再复杂的组件&#xff0c;都是由三部分组成的&#xff1a;prop、event、slot&#xff0c;它们构成了 Vue.js 组件的 API。如果你开发的是一个…...

npm install 报 ERESOLVE unable to resolve dependency tree 异常解决方法

问题 在安装项目依赖时&#xff0c;很大可能会遇到安装不成功的问题&#xff0c;其中有一个很大的原因&#xff0c;可能就是因为你的npm版本导致的。 1.npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree 2.ERESOLVE unable to resolve dependenc…...

RPC还是HTTP

RPC是一个远程调用的通讯协议 RPC要比HTTP快一些 1. HTTP体积大 原因是HTTP协议会带着一堆无用信息 HTTP由三部分组成 请求头 请求行 请求体 这三部分只有请求体是需要的 2. HTTP支持的序列化协议比较少 RPC支持更多轻量级的通讯协议 3. RPC协议支持定制...

Conda 常用命令总结

创建虚拟环境 conda create -n name python[your_version] 激活环境 conda activate name 退出环境 conda deactivate 查看虚拟环境 conda info --envs 删除虚拟环境 conda remove -n name --all 删除所有的安装包及cache(索引缓存、锁定文件、未使用过的包和tar包) …...

Spring MVC 文件上传和下载

文章目录 Spring MVC 中文件上传利用 commons-fileupload 文件上传使用 Servlet 3.1 内置的文件上传功能 Spring MVC 中文件下载 Spring MVC 中文件上传 为了能上传文件&#xff0c;必须将 from 表单的 method 设置为 POST&#xff0c;并将 enctype 设置为 multipart/form-data…...

WSL访问adb usb device

1.Windows上用PowerShell运行&#xff1a; winget install --interactive --exact dorssel.usbipd-win 2.在WSLUbuntu上终端运行&#xff1a; sudo apt install linux-tools-generic hwdata sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-too…...

CDF与PDF(描述随机变量的分布情况)

一、概念解释 CDF(Cumulative Distribution Function)和PDF(Probability Density Function)是概率论和统计学中常用的两个评价指标,用于描述随机变量的分布情况。 1. CDF(累积分布函数): - CDF是描述随机变量在某个取值及其之前所有可能取值的概率的函数。它表示了累…...

react项目中需要条形码功能,安装react-barcode使用时报错

react项目中需要条形码功能&#xff0c;用yarn add安装react-barcode后&#xff0c;在项目中使用import Barcode from ‘react-barcode’&#xff0c;页面中一直白屏&#xff0c;加载中 查看控制台报以下错误 load component failed Error: Module "./react-barcode"…...

ES6基础(JavaScript基础)

本文用于检验学习效果&#xff0c;忘记知识就去文末的链接复习 1. ECMAScript介绍 ECMAScript是一种由Ecma国际&#xff08;前身为欧洲计算机制造商协会&#xff0c;英文名称是European Computer Manufacturers Association&#xff09;通过ECMA-262标准化的脚本程序设计语言…...

[蓝桥杯] 纸张尺寸(C语言)

题目链接 蓝桥杯2022年第十三届省赛真题-纸张尺寸 - C语言网 题目理解 输入一行包含一个字符串表示纸张的名称&#xff0c;该名称一定是 A0、A1、A2、A3、A4、A5、A6、A7、A8、A9 之一&#xff0c;输出两行&#xff0c;每行包含一个整数&#xff0c;依次表示长边和短边的长度…...

AI推介-多模态视觉语言模型VLMs论文速览(arXiv方向):2024.04.05-2024.04.10

文章目录~ 1.BRAVE: Broadening the visual encoding of vision-language models2.ORacle: Large Vision-Language Models for Knowledge-Guided Holistic OR Domain Modeling3.MedRG: Medical Report Grounding with Multi-modal Large Language Model4.InternLM-XComposer2-4…...

【golang】动态生成微信小程序二维码实战下:golang 生成 小程序二维码图片 并通过s3协议上传到对象存储桶 | 腾讯云 cos

项目背景 在自研的系统&#xff0c;需要实现类似草料二维码的功能 将我们自己的小程序&#xff0c;通过代码生成相想要的小程序二维码 代码已经上传到 Github 需要的朋友可以自取 https://github.com/ctra-wang/wechat-mini-qrcode 一、生成Qrcode并提交到对象存储 通过源生A…...

kubeadm k8s 1.24之后版本安装,带cri-dockerd

最后编辑时间&#xff1a;2024/3/26 适用于1.24之后的版本 单节点配置 检查是否已经安装kubectl, kubelet, kubeadm直接输入命令确定&#xff0c;如果提示没有该指令则正确 kubectl kubelet kubeadm如果之前安装&#xff0c;首先reset&#xff0c;然后使用apt remove和snap r…...

13-pyspark的共享变量用法总结

目录 前言广播变量广播变量的作用 广播变量的使用方式 累加器累加器的作用累加器的优缺点累加器的使用方式 PySpark实战笔记系列第四篇 10-用PySpark建立第一个Spark RDD(PySpark实战笔记系列第一篇)11-pyspark的RDD的变换与动作算子总结(PySpark实战笔记系列第二篇))12-pysp…...