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

MySQL 8.1.0 推出 InnoDB Cluster 只读副本

全面了解 8.1.0 版本新功能:InnoDB Cluster 只读副本的相关操作。

作者:Miguel Araújo 高级软件工程师 / Kenny Gryp MySQL 产品总监

本文来源:Oracle MySQL 官网博客

* 爱可生开源社区出品。

前言

MySQL 的第一个 Innovation 版本 8.1.0 已经发布,我们将推出 MySQL InnoDB Cluster 只读副本

在 MySQL InnoDB Cluster 中,副本(Secondray)节点的主要目的是在主(Primary)节点发生故障时做好切换替代(高可用性)。这是由 MySQL 组复制(MGR)插件配合完成的。副本节点的另一个用途是减少主节点的只读工作负载。

现在,可以向数据库拓扑结构中添加异步副本节点这些副本节点可以用于:

  1. 将读流量从主节点或者其他副本节点转移过来,分担它们的读压力。
  2. 设置专门用于读取的副本节点。
  3. 设置专门用于报表等特定目的的副本节点。
  4. 通过添加多个读取副本节点,实现超出其他副本节点处理能力范围的扩容。

MySQL InnoDB Cluster 会管理这些副本节点的操作,包括:

  • MySQL Router 会自动重新导向流量。
  • MySQL Shell 负责配置、初次预配(使用 InnoDB Clone 插件)。
  • 复制配置和任何想要进行的拓扑结构变更。

只读副本节点也可以与 MySQL InnoDB ClusterSet 配合使用,这个模式下,副本节点可以添加到主集群或副本集群中。

MySQL Router 会识别这些读取副本节点,并根据一些配置选项将读流量重新导向到它们。这些读取副本节点会从主节点或者其他副本节点进行复制,如果复制中断或成员变更(例如新主节点选举),它会自动重新连接到另一个成员。

创建只读副本

将读取副本节点添加到集群中和添加从节点很相似。Admin API 的外观和交互方式保持不变,这可以确保最佳的用户体验。

假设您已经有一个运行中的集群,可以使用新增的这个命令来添加读取副本节点:

<Cluster>.addReplicaInstance(instance[, options])

mysqlsh-js> cluster.addReplicaInstance("rome4:3306")Setting up 'rome4:3306' as a Read Replica of Cluster 'rome'.
Validating instance configuration at rome4:3306...
This instance reports its own address as rome4:3306
Instance configuration is suitable.
* Checking transaction state of the instance...省略……* Waiting for clone to finish...
NOTE: rome4:3306 is being cloned from rome1:3306
** Stage DROP DATA: Completed
** Clone Transfer  FILE COPY  ############################################################  100%  CompletedPAGE COPY  ############################################################  100%  CompletedREDO COPY  ############################################################  100%  CompletedNOTE: rome4:3306 is shutting down...* Waiting for server restart... ready 
* rome4:3306 has restarted, waiting for clone to finish...
** Stage RESTART: Completed
* Clone process has finished: 4.30 GB transferred in 4 sec (1.08 GB/s)
* Configuring Read-Replica managed replication channel...
** Changing replication source of rome4:3306 to rome1:3306
* Waiting for Read-Replica 'rome4:3306' to synchronize with Cluster...
** Transactions replicated  ############################################################  100% 'rome4:3306' successfully added as a Read-Replica of Cluster 'rome'.

如此简单,一个新的副本就添加到集群中了。和普通的集群成员一样,只读副本也支持 Clone 或者增量预配。

和往常一样,可以用 <Cluster>.status() 命令检查集群的状态:

mysqlsh-js> cluster.status()
{"clusterName": "rome", "defaultReplicaSet": {"name": "default", "primary": "rome1:3306", "ssl": "REQUIRED", "status": "OK", "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", "topology": {"rome1:3306": {"address": "rome1:3306", "memberRole": "PRIMARY", "mode": "R/W", "readReplicas": {"rome4:3306": {"address": "rome4:3306", "role": "READ_REPLICA", "status": "ONLINE", "version": "8.1.0"}}, "replicationLag": "applier_queue_applied", "role": "HA", "status": "ONLINE", "version": "8.1.0"}, "rome2:3306": {"address": "rome2:3306", "memberRole": "SECONDARY", "mode": "R/O", "readReplicas": {}, "replicationLag": "applier_queue_applied", "role": "HA", "status": "ONLINE", "version": "8.1.0"}, "rome3:3306": {"address": "rome3:3306", "memberRole": "SECONDARY", "mode": "R/O", "readReplicas": {}, "replicationLag": "applier_queue_applied", "role": "HA", "status": "ONLINE", "version": "8.1.0"}}, "topologyMode": "Single-Primary"}, "groupInformationSourceMember": "rome1:3306"
}

你可能注意到,新增的只读副本运行在 rome4:3306 端口,它被放置在集群主节点 rome1:3306 下面,这表示它会将 rome1:3306 当作源节点进行数据同步,即它会从 rome1:3306 节点复制数据。

从主节点复制数据有一些优点,如可以减少潜在的复制延迟。但是,它也可能增加主节点的负载。为了提供灵活性以及根据不同场景选择,我们改进让这个配置成为可配置项。

运行原理:源节点识别

如上所示,只读副本默认会从主节点进行同步,如果主从切换或故障转移发生,它会自动重新连接到集群新的主节点。换句话说,它总是会跟踪主节点,保持与集群的同步。

这是通过 MySQL 复制技术里的异步复制连接故障转移特性实现的。副本会检查组复制状态,存储一份潜在源服务列表。如果当前源服务下线,它会从列表中选择一个新的源。

这个源列表可以手动或自动维护,后者支持集群复制拓扑。在这种情况下,故障转移机制可以监控成员变更,相应添加或删除候选源。此外,它也能区分主从节点。这与 MySQL InnoDB Cluster 中副本集复制主集群的方式一致。

有了这样灵活的架构,Admin API 可以根据每个用户的需求管理和配置读取副本。

运行原理:配置只读副本

选择故障恢复候选项

从主节点复制有降低延迟的优点,但也可能增加主节点压力。

我们了解自动故障转移机制工作原理,理解不同配置选项:

  • 优先从主节点复制
  • 优先从副本节点中选择一个复制
  • 设置候选列表

可以在添加副本时定义,或随时改变现有副本的配置。下图显示,Rome 地区副本选择从节点作为源,Brussels 副本选择主节点作为源。

作为一个例子,让我们使用指定实例作为源,同时预定义故障恢复候选列表,来向集群添加一个新的副本:

mysqlsh-js> cluster.addReplicaInstance("rome5:3306", {replicationSources: ["rome2:3306", "rome3:3306"]})
Setting up 'rome5:3306' as a Read Replica of Cluster 'rome'.Validating instance configuration at rome5:3306...This instance reports its own address as rome5:3306Instance configuration is suitable.
* Checking transaction state of the instance...
NOTE: A GTID set check of the MySQL instance at 'rome5:3306' determined that it is missing transactions that were purged from all cluster members.
NOTE: The target instance 'rome5:3306' has not been pre-provisioned (GTID set is empty). The Shell is unable to determine whether the instance has pre-existing data that would be overwritten with clone based recovery.
The safest and most convenient way to provision a new instance is through automatic clone provisioning, which will completely overwrite the state of 'rome5:3306' with a physical snapshot from an existing cluster member. To use this method by default, set the 'recoveryMethod' option to 'clone'.Please select a recovery method [C]lone/[A]bort (default Clone): c
* Waiting for the donor to synchronize with PRIMARY...
** Transactions replicated  ############################################################  100% Monitoring Clone based state recovery of the new member. Press ^C to abort the operation.
Clone based state recovery is now in progress.NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.* Waiting for clone to finish...
NOTE: rome5:3306 is being cloned from rome2:3306
** Stage DROP DATA: Completed
** Clone Transfer  FILE COPY  ############################################################  100%  CompletedPAGE COPY  ############################################################  100%  CompletedREDO COPY  ############################################################  100%  CompletedNOTE: rome5:3306 is shutting down...* Waiting for server restart... ready 
* rome5:3306 has restarted, waiting for clone to finish...
** Stage RESTART: Completed
* Clone process has finished: 4.30 GB transferred in 6 sec (717.27 MB/s)* Configuring Read-Replica managed replication channel...
** Changing replication source of rome5:3306 to rome2:3306* Waiting for Read-Replica 'rome5:3306' to synchronize with Cluster...
** Transactions replicated  ############################################################  100% 'rome5:3306' successfully added as a Read-Replica of Cluster 'rome'.

此次就是完成向集群添加运行在 rome5:3306 上的新的读取副本。

这个副本使用一个固定的候选失败列表,包含 rome2:3306rome3:3306,其中 rome2:3306 是当前运行中的源服务。列表中的其他成员是潜在的失败转移候选,他们的顺序决定权重,靠前的权重高,靠后的权重低。

让我们查看集群描述,以更直观地了解当前的拓扑结构:

mysqlsh-js> cluster.describe()
{"clusterName": "rome", "defaultReplicaSet": {"name": "default", "topology": [{"address": "rome1:3306", "label": "rome1:3306", "role": "HA"}, {"address": "rome2:3306", "label": "rome2:3306", "role": "HA"}, {"address": "rome3:3306", "label": "rome3:3306", "role": "HA"}, {"address": "rome4:3306", "label": "rome4:3306", "replicationSources": ["PRIMARY"], "role": "READ_REPLICA"}, {"address": "rome5:3306", "label": "rome5:3306", "replicationSources": ["rome2:3306", "rome3:3306"], "role": "READ_REPLICA"}], "topologyMode": "Single-Primary"}
}

同样,使用扩展状态,我们可以查看当前拓扑结构的更多信息:

mysqlsh-js> cluster.status({extended:1})
{"clusterName": "rome", "defaultReplicaSet": {"GRProtocolVersion": "8.0.27", "communicationStack": "MYSQL", "groupName": "33cfdab9-3469-11ee-9f3b-d08e7912e4ee", "groupViewChangeUuid": "33cfe2b0-3469-11ee-9f3b-d08e7912e4ee", "groupViewId": "16913336945761559:7", "name": "default", "paxosSingleLeader": "OFF", "primary": "rome1:3306", "ssl": "REQUIRED", "status": "OK", "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", "topology": {"rome1:3306": {"address": "rome1:3306", "applierWorkerThreads": 4, "fenceSysVars": [], "memberId": "e304af5d-3466-11ee-8d97-d08e7912e4ee", "memberRole": "PRIMARY", "memberState": "ONLINE", "mode": "R/W", "readReplicas": {"rome4:3306": {"address": "rome4:3306", "applierStatus": "APPLIED_ALL", "applierThreadState": "Waiting for an event from Coordinator", "applierWorkerThreads": 4, "receiverStatus": "ON", "receiverThreadState": "Waiting for source to send event", "replicationLag": null, "replicationSources": ["PRIMARY"], "replicationSsl": "TLS_AES_256_GCM_SHA384 TLSv1.3", "role": "READ_REPLICA", "status": "ONLINE", "version": "8.1.0"}}, "replicationLag": "applier_queue_applied", "role": "HA", "status": "ONLINE", "version": "8.1.0"}, "rome2:3306": {"address": "rome2:3306", "applierWorkerThreads": 4, "fenceSysVars": ["read_only", "super_read_only"], "memberId": "e6eb91c6-3466-11ee-aca6-d08e7912e4ee", "memberRole": "SECONDARY", "memberState": "ONLINE", "mode": "R/O", "readReplicas": {"rome5:3306": {"address": "rome5:3306", "applierStatus": "APPLIED_ALL", "applierThreadState": "Waiting for an event from Coordinator", "applierWorkerThreads": 4, "receiverStatus": "ON", "receiverThreadState": "Waiting for source to send event", "replicationLag": null, "replicationSources": ["rome2:3306", "rome3:3306"], "role": "READ_REPLICA", "status": "ONLINE", "version": "8.1.0"}}, "replicationLag": "applier_queue_applied", "role": "HA", "status": "ONLINE", "version": "8.1.0"}, "rome3:3306": {"address": "rome3:3306", "applierWorkerThreads": 4, "fenceSysVars": ["read_only", "super_read_only"], "memberId": "ea08833f-3466-11ee-b87c-d08e7912e4ee", "memberRole": "SECONDARY", "memberState": "ONLINE", "mode": "R/O", "readReplicas": {}, "replicationLag": "applier_queue_applied", "role": "HA", "status": "ONLINE", "version": "8.1.0"}}, "topologyMode": "Single-Primary"}, "groupInformationSourceMember": "rome1:3306", "metadataVersion": "2.2.0"
}

改变故障候选项

改变源配置就像改变实例选项一样简单。Cluster.setInstanceOption() 增强了一个新的选项 replicationSources,允许执行这个操作:

让我们修改第一个读取副本的配置,优先从第二实例而不是主实例进行同步。

mysqlsh-js> cluster.setInstanceOption("rome4:3306", "replicationSources", "secondary")
Setting the value of 'replicationSources' to 'secondary' in the instance: 'rome4:3306' ...WARNING: To update the replication channel with the changes the Read-Replica must be reconfigured using Cluster.rejoinInstance().
Successfully set the value of 'replicationSources' to 'secondary' in the cluster member: 'rome4:3306'.

为让新的设置立即生效,我们需要使用 Admin API 非常有名的命令 Cluster.rejoinInstance() 强制实例重新加入集群:

mysqlsh-js> cluster.rejoinInstance("rome4:3306")
Rejoining Read-Replica 'rome4:3306' to Cluster 'rome'...* Checking transaction state of the instance...
The safest and most convenient way to provision a new instance is through automatic clone provisioning, which will completely overwrite the state of 'rome4:3306' with a physical snapshot from an existing cluster member. To use this method by default, set the 'recoveryMethod' option to 'clone'.The incremental state recovery may be safely used if you are sure all updates ever executed in the cluster were done with GTIDs enabled, there are no purged transactions and the new instance contains the same GTID set as the cluster or a subset of it. To use this method by default, set the 'recoveryMethod' option to 'incremental'.Incremental state recovery was selected because it seems to be safely usable.NOTE: User 'mysql_innodb_replica_2506922964'@'%' already existed at instance 'rome1:3306'. It will be deleted and created again with a new password.
** Changing replication source of rome4:3306 to rome2:3306* Waiting for Read-Replica 'rome4:3306' to synchronize with Cluster...
** Transactions replicated  ############################################################  100% <strong>Read-Replica 'rome4:3306' successfully rejoined to the Cluster 'rome'.

说明:和普通实例一样,使用 Cluster.removeInstance() 可以从集群中删除读取副本。

路由读请求到副本

MySQL Router 在 InnoDB Cluster 中扮演着至关重要的角色,所以现在它完全知晓只读副本的存在。Router 位于应用和集群之间,将客户端流量定向到正确的目标。它可以为只读请求使用只读副本。但是从节点也可以,那么它如何选择?

配置 Router 目标池

默认情况下,Router 的行为不变,即读流量定向到集群的从节点。但是,现在是可配置的。

read_only_targets 模式接受以下可能的行为:

  • secondaries:只将目标集群的副本成员用作只读流量(默认)
  • read_replicas:只将目标集群的读取副本用于只读流量
  • all:将目标集群的所有读取副本以及其他副本成员一起用于只读流量

该模式可以通过另一个常见的命令 .setRoutingOption() 进行配置,该命令可以在 Router、Cluster 或 ClusterSet 级别进行配置。

例如:

mysqlsh-js> cluster.setRoutingOption("read_only_targets", "all")
Routing option 'read_only_targets' successfully updated.
mysqlsh-js> cluster.routingOptions()
{"clusterName": "rome", "global": {"read_only_targets": "all", "stats_updates_frequency": null, "tags": {}}, "routers": {"domus::": {}}
}

下图显示了更复杂的拓扑,其中 ClusterSet 由主集群(Rome)和部署了多个路由器的副本集群(Brussels)组成。

主要集群是包含 3 个主要成员和 3 个只读副本的 3 个成员集群。读取副本使用 sourcesList:"secondary ,因此它们从集群的次要成员进行复制。

部署在该数据中心的两个路由器使用主要集群作为目标集群,并且被配置为使用所有读取目标,即 read_only_targets:all

另一个数据中心的副本集群也是一个 3 个成员的集群,包含 3 个只读副本,它们被配置为从主集群主成员进行复制。两个路由器有不同的配置:第一个路由器被配置为使用主要集群作为目标集群,并且只将读取副本用于只读目标,即 read_only_targets: read_replicas。另一个路由器被配置为使用 Brussels 作为目标集群,并且只将次要成员用于只读目标,即 read_only_targets:secondaries

健康检查和隔离

MySQL Router 作为无状态服务,因此它依赖于 InnoDB Cluster 成员信息进行准确的路由。MGR 基于 Paxos 实现提供集群成员服务,定义哪些服务器在线并参与组。通过利用该信息,Router 避免连接到每个成员检查其状态。

然而,当只读副本也是集群的一部分时,该信息在组成员信息中不可用,Router 无法依赖于该机制。同时,集群成员间看到的可用性不同于 Router 视角,成员信息可能不准确。

为解决这些挑战,Router 实现了内置的隔离机制。

简而言之,当 Router 由于新用户连接尝试连接目标端点失败时,它会将该目标置于隔离状态。但目标不会永远停留在隔离状态,在超时后,Router 会对该服务器执行健康检查,以确定是否可以从隔离池中移除它。

隔离机制在两个方面是可配置的:

  • 隔离阈值:接受失败连接尝试的次数,直到服务器被隔离。
  • 隔离服务器应该多频繁进行健康检查。

默认情况下,这两个设置的值都是 1,即失败连接会导致目标实例被隔离,每秒对隔离实例进行健康检查,以查看是否可以从隔离池中移除。

复制延迟

同步复制会导致复制延迟是常见问题,需要考虑。如果实例延迟严重,DBA 可能希望隐藏它,等待它恢复同步,然后再将它曝光给应用。

此外,DBA 也可能希望隐藏读取副本:

  • 进行不断升级而不影响流入流量
  • 进行维护操作或配置更改而无需停止 MySQL
  • 在备份或生成报表时排除它以免影响其他查询
  • 将其配置为备份服务器,排除任何读流量

与常规集群成员一样,这可以通过指导 Router 不使用其标签来实现。

隐藏副本

要将实例从 Router 流量中隐藏,可以使用内置的 _hidden 标签,通过 .setInstanceOption() 命令很容易设置:

mysqlsh-js> cluster.setInstanceOption("rome5:3306", "tag:_hidden", true)

该功能不限于副本,次要实例也可以标记为隐藏。

总结

只读副本可以扩展读密集型工作负载的规模,减轻其他集群成员的压力,并提供更多的数据冗余。

感谢您使用 MySQL!

更多技术文章,请访问:https://opensource.actionsky.com/

关于 SQLE

爱可生开源社区的 SQLE 是一款面向数据库使用者和管理者,支持多场景审核,支持标准化上线流程,原生支持 MySQL 审核且数据库类型可扩展的 SQL 审核工具。

SQLE 获取

类型地址
版本库https://github.com/actiontech/sqle
文档https://actiontech.github.io/sqle-docs/
发布信息https://github.com/actiontech/sqle/releases
数据审核插件开发文档https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse

相关文章:

MySQL 8.1.0 推出 InnoDB Cluster 只读副本

全面了解 8.1.0 版本新功能&#xff1a;InnoDB Cluster 只读副本的相关操作。 作者&#xff1a;Miguel Arajo 高级软件工程师 / Kenny Gryp MySQL 产品总监 本文来源&#xff1a;Oracle MySQL 官网博客 * 爱可生开源社区出品。 前言 MySQL 的第一个 Innovation 版本 8.1.0 已…...

java并发编程 PriorityBlockingQueue详解

文章目录 1 PriorityBlockingQueue是什么2 核心属性详解3 核心方法详解3.1 offer(E e)3.2 poll()3.3 take()3.4 peek() 4 总结 1 PriorityBlockingQueue是什么 PriorityBlockingQueue类上的注释描述&#xff1a;一个无界阻塞队列&#xff0c;它使用与类PriorityQueue相同的排序…...

SpringMVC_基本使用

一、JavaWEB 1.回顾 JavaWEB 1.1新建项目结构 新建 javaweb 项目目录结构 1.2导入依赖 依赖 <dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>…...

大屏开发,浏览器的可视区域和设备的分辨率

在线屏幕检测 - 显示器检测 - 显示器坏点检测工具...

【微服务部署】06-日志集成

文章目录 1. EFK日志三件套集成1.1 核心组件1.2 部署 2. Exceptionless日志系统2.1 Exceptionless核心特性2.2 Exceptionless部署文件2.3 K8s中使用Exceptionless 1. EFK日志三件套集成 1.1 核心组件 Elasticsearch&#xff08;存储&#xff09;Fluentd&#xff08;收集器&am…...

【Python】python使用docxtpl生成word模板

python使用docxtpl生成word模板 python-docxtpl包简单使用和实战&#xff0c;Python处理word&#xff0c;docx文件。 最近需要处理一些爬虫得到的数据来进行一些自动化报告的操作&#xff0c;因为需要生成的是word的报告&#xff0c;所以估选用docxtpl库来直接生成模板 docxt…...

C++学习笔记总结练习:多态与虚函数

1 多态 多态分类 静态多态&#xff0c;是只在编译期间确定的多态。静态多态在编译期间&#xff0c;根据函数参数的个数和类型推断出调用的函数。静态多态有两种实现的方式 重载。&#xff08;函数重载&#xff09;模板。 动态多态&#xff0c;是运行时多态。通过虚函数机制实…...

linux 批量更改指定后辍文件的可执行权限

要在Linux上批量更改指定后缀文件的可执行权限&#xff0c;您可以使用find命令来查找这些文件&#xff0c;然后使用chmod命令来更改它们的权限。以下是一些步骤&#xff1a; 1. 打开终端。 2. 使用 find 命令查找要更改权限的文件&#xff0c;例如&#xff0c;如果您想要更…...

数据结构(Java实现)-Map和Set

搜索树 概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值 它的左右子树也…...

C++进程、线程、内存管理

目录 进程和线程区别 进程和线程切换的区别 系统调用流程 系统调用是否会引起线程切换 为什么需要使用虚拟内存 进程和线程区别 本质区别&#xff1a; 进程是资源分配的基本单元。 线程是操作系统调度的基本单元。 地址空间&#xff1a; 进程具有独立的虚拟地址空间。 线程…...

打车系统网约车系统开发支持APP公众号H5小程序版本源码

一、操作流程 二、业务模式 三、用户端 用户注册登录&#xff1a;未注册的手机号将自动创建账号 通过好友的邀请链接进行注册&#xff0c;将会绑定上下级关系 也可以注册的时候输入好友的邀请码&#xff0c;也可以绑定关系 用户充值&#xff1a; 用户下单支付时&#xff0c;可以…...

HTTP/1.1协议的状态码

2023年8月30日&#xff0c;周三下午 HTTP/1.1协议定义了一组状态码&#xff0c;用于表示请求的处理结果。 每个状态码都有特定的含义&#xff0c;它们以三位数字的形式出现在响应的状态行中。 下面是一些常见的HTTP/1.1协议的状态码及其含义&#xff1a; 1xx&#xff08;信息…...

SpringCloud(十)——ElasticSearch简单了解(一)初识ElasticSearch和RestClient

文章目录 1. 初始ElasticSearch1.1 ElasticSearch介绍1.2 安装并运行ElasticSearch1.3 运行kibana1.4 安装IK分词器 2. 操作索引库和文档2.1 mapping属性2.2 创建索引库2.3 对索引库的查、删、改2.4 操作文档 3. RestClient3.1 初始化RestClient3.2 操作索引库3.3 操作文档 1. …...

CAD文字显示?问号解决

背景 从别人哪儿发过来的CAD文件&#xff0c;打开后发现有些文字显示为&#xff1f; 问题排查 通过点击文字特性得知 该文字的样式是 SF和仿宋通过命令行执行st 得知&#xff0c;两种样式关联的字体都是仿宋GB_2312&#xff0c;但当前操作系统无此字体&#xff0c;故显示为&…...

Calico切换网络模式无效

Calico切换网络模式无效 Calico由原先的BGP模式切换为IP IP模式发现未生效&#xff0c;使用的模式还是BGP模式&#xff0c;Calico卸载后查询Etcd发现存在很多Calico数据 [rootk8s-master-1 ~]# etcdctl get / --prefix --keys-only | grep calico /calico/ipam/v2/assignment…...

数据生成 | MATLAB实现GAN生成对抗网络结合SVM支持向量机的数据生成

数据生成 | MATLAB实现GAN生成对抗网络结合SVM支持向量机的数据生成 目录 数据生成 | MATLAB实现GAN生成对抗网络结合SVM支持向量机的数据生成生成效果基本描述程序设计参考资料 生成效果 基本描述 数据生成 | MATLAB实现GAN生成对抗网络结合SVM支持向量机的数据生成。 生成对抗…...

iOS - 资源按需加载 - ODR

一、瘦身技术大图 二、On-Demand Resources 简介 将其保存管理在苹果的服务器&#xff0c;按需使用资源、优化包体积&#xff0c;实现更小的应用程序。ODR 的好处&#xff1a; 应用体积更小&#xff0c;下载更快&#xff0c;提升初次启动速度资源会在后台下载操作系统将会在磁…...

arduino仿真 SimulIDE1.0仿真器

SimulIDE 是一个开源的电子电路模拟器&#xff0c;支持模拟各种电子元器件的行为&#xff0c;可以帮助电子工程师和爱好者进行电路设计和测试。以下是 SimulIDE 的安装和使用说明&#xff1a; 安装 SimulIDE SimulIDE 可以在 Windows、Linux 和 Mac OS X 等操作系统上安装。您…...

vue实现导出excel的多种方式

在Vue中实现导出Excel有多种方式&#xff0c;可以通过前端实现&#xff0c;也可以通过前后端配合实现。下面将详细介绍几种常用的实现方式。 1. 前端实现方式&#xff1a; 使用xlsx库&#xff1a;使用xlsx库可以在前端将数据导出为Excel文件。首先需要安装xlsx库&#xff0c;…...

redis实战-实现优惠券秒杀解决超卖问题

全局唯一ID 唯一ID的必要性 每个店铺都可以发布优惠券&#xff1a; 当用户抢购时&#xff0c;就会生成订单并保存到tb_voucher_order这张表中&#xff0c;而订单表如果使用数据库自增ID就存在一些问题&#xff1a; id的规律性太明显&#xff0c;容易被用户根据id的间隔来猜测…...

C语言:截断+整型提升+算数转换练习

详情关于整型提升、算数转换与截断见文章&#xff1a; 《C语言&#xff1a;整型提升》 《C语言&#xff1a;算数转换》 一、代码一 int main() { char a -1; signed char b -1; unsigned char c -1; printf("%d %d %d", a, b, c); return 0; } 求…...

Java后端开发面试题——多线程

创建线程的方式有哪些&#xff1f; 继承Thread类 public class MyThread extends Thread {Overridepublic void run() {System.out.println("MyThread...run...");}public static void main(String[] args) {// 创建MyThread对象MyThread t1 new MyThread() ;MyTh…...

Redis 学习笔记

文章目录 一、简介二、下载三、安装四、启动和关闭五、配置文件六、常用指令七、安全加固 版权声明&#xff1a;本文为CSDN博主「杨群」的原创文章&#xff0c;遵循 CC 4.0 BY-SA版权协议&#xff0c;于2023年9月3日首发于CSDN&#xff0c;转载请附上原文出处链接及本声明。 原…...

华为云新生代开发者招募

开发者您好&#xff0c;我们是华为2012UCD的研究团队 为了解年轻开发者的开发现状和趋势 正在邀请各位先锋开发者&#xff0c;与我们进行2小时的线上交流&#xff08;江浙沪附近可线下交流&#xff09; 聊聊您日常开发工作中的产品使用需求 成功参与访谈者将获得至少300元京…...

DockerFile简明教程

需求 由于在测试环境中使用了docker官网的centos 镜像&#xff0c;但是该镜像里面默认没有安装ssh服务&#xff0c;在做测试时又需要开启ssh。所以上网也查了查资料。下面详细的纪录下。在centos 容器内安装ssh后&#xff0c;转成新的镜像用于后期测试使用。 镜像定制 第一种…...

Cygwin是什么?是Windows还是Linux?

原文作者&#xff1a;gentle_zhou 原文链接&#xff1a;https://bbs.huaweicloud.com/blogs/408674 最近在和客户交流的时候&#xff0c;一直以为客户的研发环境就是windows 7&#xff0c;直到和对面的研发团队交流的时候&#xff0c;得到的反馈是在windows 7系统上安装了Cygw…...

成集云 | 多维表格自动化管理jira Server项目 | 解决方案

源系统成集云目标系统 方案介绍 基于成集云集成平台&#xff0c;在多维表格中的需求任务信息自动创建、更新同步至 Jira Server 的指定项目中&#xff0c;实现多维表格中一表管理 Jira Server 中的项目进度。 维格表是一种新一代的团队数据协作和项目管理工具&…...

数据结构(Java实现)-排序

排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#xff0c;若经过排序&#xff…...

C++------vector【STL】

文章目录 vector的介绍及使用vector的介绍vector的使用 vector的模拟实现 vector的介绍及使用 vector的介绍 1、vector是表示可变大小数组的序列容器。 2、就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问和数…...

Matlab(变量与文本读取)

目录 1.变量&#xff08;数据&#xff09;类型转换 1.1 字符 1.2 字符串 1.3 逻辑操作与赋值 2.Struct结构体数组 2.1函数的详细介绍&#xff1a; 2.1.1 cell2struct 2.1.1.1 垂直维度转换 2.1.1.2 水平维度转换 2.1.1.3 部分进行转换 2.1.2 rmfield 2.1.3 fieldnames(查…...