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

Redis主从复制集群的介绍及搭建

在现代的软件开发中,数据的可靠性和可用性是至关重要的。Redis,作为一个开源的、内存中的数据结构存储系统,以其出色的性能和灵活的数据结构,赢得了开发者们的广泛喜爱。而 Redis 的主从复制功能,更是为我们提供了一种简单有效的方式来提高数据的可靠性和可用性。今天,我们要探讨的是 Redis 的主从复制集群。

主从复制集群是一种常见的数据库集群架构,它包含一个主服务器和多个从服务器。主服务器负责处理写操作,所有的写操作会被复制到从服务器。从服务器主要用于处理读操作,分担读负载。通过这种方式,我们可以在多台服务器上读取相同的数据,提高读取性能,同时也可以防止数据丢失。

在接下来的文章中,我们将详细介绍 Redis 的主从复制集群,包括它的工作原理,如何搭建和配置,以及一些常见的使用场景。无论你是刚接触 Redis,还是已经有一定的使用经验,我相信你都能从这篇文章中学到一些新的知识。


文章目录

        • 1、Redis主从复制介绍
          • 1.1、Redis主从复制概述
          • 1.2、Redis主从复制作用
          • 1.3、Redis主从拓扑结构
          • 1.4、Redis主从的不足
        • 2、Redis主从复制原理
          • 2.1、Redis主从复制流程
          • 2.2、Redis主从复制同步数据集流程
          • 2.3、Redis主从复制的断线重连
        • 3、Redis主从复制数据同步方式
          • 3.1、Redis主从全量复制
          • 3.2、Redis主从部分复制
        • 4、Redis主从复制实现
          • 4.1、拉取Redis镜像
          • 4.2、创建所需文件夹
          • 4.3、运行容器
          • 4.4、实现主从同步-临时-查询主节点节点ip
          • 4.5、实现主从同步-临时-修改从节点配置
          • 4.6、实现主从同步-临时-查看主节点信息
          • 4.7、实现主从同步-临时-查看从节点信息
          • 4.8、实现主从同步-永久-相关配置修改
          • 4.9、实现主从同步-永久-重启查看


1、Redis主从复制介绍

1.1、Redis主从复制概述

Redis 主从复制是 Redis 数据备份和高可用性的重要机制之一。主从复制允许你有一个或多个从服务器复制主服务器的数据。这样,你可以在多个服务器上读取相同的数据,提高读取性能,同时也可以防止数据丢失。

以下是 Redis 主从复制的基本步骤:

  1. 配置从服务器:你可以通过在从服务器上执行 SLAVEOF <master-ip> <master-port> 命令来配置从服务器。这将使从服务器开始监听主服务器,准备复制数据。

  2. 数据同步:一旦从服务器接收到 SLAVEOF 命令,它将开始一个同步过程。在这个过程中,主服务器会创建一个当前数据的快照并将其发送给从服务器。

  3. 命令复制:数据同步完成后,主服务器会继续在接收到写命令时将其发送给所有从服务器。这样,所有的从服务器都能实时地保持和主服务器一致的数据。

  4. 读取数据:你可以配置应用程序从从服务器读取数据,以此来分担主服务器的读取负载。

  5. 故障转移:如果主服务器出现故障,你可以手动或通过 Sentinel 系统自动将一个从服务器提升为新的主服务器。

注意:在 Redis 4.0 以后,SLAVEOF 命令已经被 REPLICAOF 命令替代,但是为了向后兼容,SLAVEOF 命令仍然可以使用。

1.2、Redis主从复制作用

Redis 主从复制的主要作用有以下几点:

  • 数据冗余: 主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
  • 故障恢复: 当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复 (实际上是一种服务的冗余)。
  • 负载均衡: 在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务 (即写 Redis 数据时应用连接主节点,读 Redis 数据时应用连接从节点),分担服务器负载。尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高 Redis 服务器的并发量。
  • 高可用基石: 除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是 Redis 高可用的基础。
1.3、Redis主从拓扑结构

Redis 的复制拓扑结构可以支持单层或多层复制关系,根据拓扑复杂性可以分为以下三种:一主一从、一主多从、树状主从结构。

  • 一主一从结构:是最简单的复制拓扑结构,用于主节点出现宕机时从节点提供故障转移支持;
  • 一主多从结构(又称为星形拓扑结构):使得应用端可以利用多个从节点实现读写分离。对于读占比较大的场景,可以把读命令发送到从节点来分担主节点压力;
  • 树状主从结构(又称为树状拓扑结构):使得从节点不但可以复制主节点数据,同时可以作为其他从节点的主节点继续向下层复制。通过引入复制中间层,可以有效降低主节点负载和需要传送给从节点的数据量

image-20230910142857199

1.4、Redis主从的不足

主从复制虽好,但也存在一些问题:

  • 一旦主节点出现故障,需要手动将一个从节点晋升为主节点,同时需要修改应用方的主节点地址,还需要命令其他从节点去复制新的主节点,整个过程都需要人工干预;
  • 主节点的写能力和存储能力受到单机的限制

2、Redis主从复制原理

2.1、Redis主从复制流程

Redis主从复制的工作流程大概可以分为如下几步:

  1. 保存主节点(master)信息:这一步只是保存主节点信息,保存主节点的 ip 和 port;
  2. 主从建立连接:从节点(slave)发现新的主节点后,从节点会向主节点发送一个同步命令(SYNC)来尝试和主节点建立连接;
  3. 发送 pin g命令:连接建立成功后从节点发送ping请求进行首次通信,主要是检测主从之间网络套接字是否可用、主节点当前是否可接受处理命令。

image-20230910141411664

  1. 权限验证:如果主节点要求密码验证,从节点必须正确的密码才能通过验证;
  2. 同步数据集:主从复制连接正常通信后,主节点会把持有的数据全部发送给从节点;
  3. 命令持续复制 接下来主节点会持续地把写命令发送给从节点,保证主从数据一致性。
2.2、Redis主从复制同步数据集流程

(全量复制)Redis 同步数据集的主要步骤就是发送和加载数据快照。具体来说,包括以下步骤:

  1. 主服务器生成数据快照:当主服务器接收到从服务器的同步请求后,会开始在后台生成一个数据快照(RDB 文件)。这个数据快照包含了主服务器在接收到同步请求时的所有数据。

  2. 主服务器发送数据快照:数据快照生成后,主服务器会将这个快照文件发送给从服务器。同时,主服务器还会将生成数据快照期间接收到的所有写命令缓存起来。

  3. 从服务器加载数据快照:从服务器接收到数据快照后,会清空旧数据,然后加载这个数据快照。这样,从服务器的数据就和主服务器在生成数据快照时的数据一致了。

  4. 主服务器发送缓存的写命令:数据快照发送完毕后,主服务器会将生成数据快照期间缓存的写命令发送给从服务器。从服务器执行这些写命令后,就和主服务器的当前数据状态一致了。

以上就是 Redis 同步数据集的主要步骤。需要注意的是,从 Redis 2.8 版本开始,Redis 使用了一种叫做部分重同步(PSYNC)的机制,可以使得在网络连接断开后,从服务器只需要复制断开期间主服务器上发生变化的部分,而不需要重新复制所有数据,大大提高了复制的效率。

2.3、Redis主从复制的断线重连

(部分复制)在 Redis 主从复制过程中,如果主从服务器之间的连接断开,从服务器会尝试重新连接主服务器,并重新开始同步过程。具体来说,包括以下步骤:

  1. 检测连接断开:从服务器会定期检测与主服务器的连接状态。如果检测到连接已经断开,从服务器会尝试重新连接主服务器。

  2. 重新连接主服务器:从服务器会尝试重新连接主服务器。如果连接失败,从服务器会在一段时间后再次尝试,直到连接成功。

  3. 请求同步:一旦重新连接成功,从服务器会向主服务器发送一个同步请求。这个请求会告诉主服务器,从服务器需要的数据的起始位置。

  4. 部分重同步:如果可能,主服务器会进行部分重同步。也就是说,主服务器只会发送从服务器缺失的数据,而不是所有数据。这是通过在主服务器上维护一个缓冲区实现的,这个缓冲区保存了最近的写命令。如果从服务器请求的数据都在这个缓冲区内,主服务器就可以进行部分重同步。

  5. 全量重同步:如果部分重同步无法进行,例如缓冲区的数据已经被覆盖,或者从服务器是第一次进行同步,主服务器就会进行全量重同步。也就是说,主服务器会发送所有数据给从服务器。

以上就是 Redis 主从复制进行断线重连的主要步骤。通过这种机制,Redis 可以在网络连接不稳定的情况下,保证数据的一致性。


3、Redis主从复制数据同步方式

Redis 在 2.8 及以上版本使用 psync 命令完成主从数据同步,同步过程分为:全量复制和部分复制。

3.1、Redis主从全量复制

一般用于初次复制场景,Redis 早期支持的复制功能只有全量复制,它会把主节点全部数据一次性发送给从节点,当数据量较大时,会对主从节点和网络造成很大的开销。

全量复制的完整运行流程如下:

  1. 发送 psync 命令进行数据同步,由于是第一次进行复制,从节点没有复制偏移量和主节点的运行ID,所以发送 psync-1
  2. 主节点根据 psync-1 解析出当前为全量复制,回复 +FULLRESYNC 响应;
  3. 从节点接收主节点的响应数据保存运行 ID 和偏移量 offset;
  4. 主节点执行 bgsave 保存 RDB 文件到本地;

image-20230910143735212

  1. 主节点发送 RDB 文件给从节点,从节点把接收的 RDB 文件保存在本地并直接作为从节点的数据文件;
  2. 对于从节点开始接收 RDB 快照到接收完成期间,主节点仍然响应读写命令,因此主节点会把这期间写命令数据保存在复制客户端缓冲区内,当从节点加载完 RDB 文件后,主节点再把缓冲区内的数据发送给从节点,保证主从之间数据一致性;
  3. 从节点接收完主节点传送来的全部数据后会清空自身旧数据;
  4. 从节点清空数据后开始加载 RDB 文件;
  5. 从节点成功加载完 RDB 后,如果当前节点开启了 AOF 持久化功能,它会立刻做 bgrewriteaof (异步 AOF 重写命令)操作,为了保证全量复制后 AOF 持久化文件立刻可用。
3.2、Redis主从部分复制

部分复制主要是 Redis 针对全量复制的过高开销做出的一种优化措施,使用 psync{runId}{offset} 命令实现。当从节点(slave)正在复制主节点(master)时,如果出现网络闪断或者命令丢失等异常情况时,从节点会向主节点要求补发丢失的命令数据,如果主节点的复制积压缓冲区内存在这部分数据则直接发送给从节点,这样就可以保持主从节点复制的一致性。

全量复制的完整运行流程如下:

  1. 当主从节点之间网络出现中断时,如果超过 repl-timeout 时间,主节点会认为从节点故障并中断复制连接;
  2. 主从连接中断期间主节点依然响应命令,但因复制连接中断命令无法发送给从节点,不过主节点内部存在的复制积压缓冲区,依然可以保存最近一段时间的写命令数据,默认最大缓存 1MB;
  3. 当主从节点网络恢复后,从节点会再次连上主节点;

image-20230910144246393

  1. 当主从连接恢复后,由于从节点之前保存了自身已复制的偏移量和主节点的运行 ID。因此会把它们当作 psync 参数发送给主节点,要求进行部分复制操作;
  2. 主节点接到 psync 命令后首先核对参数 runId 是否与自身一致,如果一致,说明之前复制的是当前主节点;之后根据参数 offset 在自身复制积压缓冲区查找,如果偏移量之后的数据存在缓冲区中,则对从节点发送 +CONTINUE 响应,表示可以进行部分复制;
  3. 主节点根据偏移量把复制积压缓冲区里的数据发送给从节点,保证主从复制进入正常状态。

4、Redis主从复制实现

这里我们基于 Docker 搭建一个 Redis 主从模式集群

4.1、拉取Redis镜像

拉取 Redis 镜像:

docker pull redis

image-20230910145808068

4.2、创建所需文件夹

创建所需文件夹,用于映射容器相应文件路径:

mkdir -p ~/data/redis/master/data                                  
touch ~/data/redis/master/redis.confmkdir                       
touch ~/data/redis/master/redis.conf 
mkdir -p ~/data/redis/slave-1/data       
touch ~/data/redis/slave-1/redis.confmkdir
touch ~/data/redis/slave-1/redis.conf
mkdir -p ~/data/redis/slave-2/data       
touch ~/data/redis/slave-2/redis.confmkdir
touch ~/data/redis/slave-2/redis.conf 

image-20230910150833947

4.3、运行容器

运行容器并指定挂载路径:

docker run -p 16379:6379  --name redis-master -v ~/data/redis/master/data/:/data -v ~/data/redis/master/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf --appendonly yes
---
docker run -p 26379:6379  --name redis-slave-1 -v ~/data/redis/slave-1/data/:/data -v ~/data/redis/slave-1/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf --appendonly yes
---
docker run  -p 36379:6379  --name redis-slave-2 -v ~/data/redis/slave-2/data/:/data -v ~/data/redis/slave-2/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf --appendonly yes

image-20230910151527347

通过 Docker Desktop 查看:

image-20230910151550537

4.4、实现主从同步-临时-查询主节点节点ip

这种搭建模式在重启容器之后将被重置,看个人情况考虑搭建

可以通过以下命令查看节点IP

docker inspect [CONTAINER ID]

docker inspect [CONTAINER ID] 是一个 Docker 命令,用于获取 Docker 对象的详细信息。这个 Docker 对象可以是一个容器、镜像、网络或者卷。

这个命令的各个部分的含义如下:

  • docker inspect:这是 Docker 的一个命令,用于获取 Docker 对象的详细信息。
  • [CONTAINER ID]:这是你要获取信息的 Docker 对象的 ID。你需要将其替换为实际的对象 ID。

所以,docker inspect [CONTAINER ID] 命令的作用就是获取指定容器的详细信息,包括容器的配置、网络设置、挂载的卷等等。这个命令返回的是一个 JSON 格式的数据,你可以通过这个数据来查看容器的各种详细信息。

4.5、实现主从同步-临时-修改从节点配置

分别进入 slave-1,slave-2 从节点,将该节点设置为主节点的从属节点:

# 进入从节点服务
docker exec -it [CONTAINER ID] redis-cli

docker exec -it [CONTAINER ID] redis-cli 是一个 Docker 命令,用于在运行的 Redis 容器中启动一个 redis-cli 客户端。

这个命令的各个部分的含义如下:

  • docker exec:这是 Docker 的一个命令,用于在运行的容器中执行一个命令。
  • -it:这是 docker exec 命令的两个选项,-i(或 --interactive)表示保持 STDIN 打开,-t(或 --tty)表示分配一个伪终端。这两个选项通常一起使用,可以让你交互地运行命令。
  • [CONTAINER ID]:这是你要在其中运行命令的容器的 ID。你需要将其替换为实际的容器 ID。
  • redis-cli:这是你要在容器中运行的命令,也就是启动 redis-cli 客户端。
# 将该节点设置为主节点的从属节点,
slaveof 172.17.0.2 6379

image-20230910153037618

4.6、实现主从同步-临时-查看主节点信息

此时再次查看主节点的角色信息和主从复制信息:

# 查看角色信息
role
# 查看主从复制信息
info replication

image-20230910153421366

4.7、实现主从同步-临时-查看从节点信息

此时再次查看从节点的角色信息和主从复制信息:

# 查看角色信息
role
# 查看主从复制信息
info replication

image-20230910153300067

4.8、实现主从同步-永久-相关配置修改

这种搭建模式在重启容器之后不会被重置,看个人情况考虑搭建。

修改 redis-master 配置文件:

# 修改之前挂载的 redis 的配置文件
vim ~/data/redis/master/redis.conf

在 redis.conf 里加入以下内容:

# 允许所有ip地址访问
bind 0.0.0.0# 以守护进程的方式运行,就是关闭了远程连接窗口,redis依然运行,使用容器时必须注释,否则启动容器失败
# daemonize yes# 设置需要密码才能访问
requirepass root# 设置redis持久化,默认是no
appendonly yes# 设置主节点的密码(当主节点设置了requirepass配置时需要配置该项或者需要搭建哨兵模式的时候也需要配置该项,因为如果主节宕机重启之后就会#  # 装换为slave节点,这个时候需要去连接sentinel选举出来的新的master节点)
# masterauth root

修改 redis-slave-1 配置文件:

#修改之前挂载的redis的配置文件
vim ~/data/redis/slave-1/redis.conf# 允许所有ip地址访问
bind 0.0.0.0# 以守护进程的方式运行,就是关闭了远程连接窗口,redis依然运行,使用容器时必须注释,否则启动容器失败
# daemonize yes# 设置需要密码才能访问
requirepass root# 设置redis持久化,默认是no
appendonly yes# 设置主节点的密码(当主节点设置了requirepass配置时需要配置该项)
masterauth root# 主从模式下主节点的IP和PORT(这里要根据实际情况来定,我这里使用的是容器内部的IP和端口)
#容器内部ip和端口可以使用 docker inspect 镜像id来查看
# 这里也可以使用容器的名称,使用容器名称的时候在构建容器的时候就需要使用--link参数
# 这里也可以使用物理地址,使用物理地址的时候在构建容器的时候就需要使用--net参数
replicaof 172.17.0.3 6379

修改 redis-slave-2 配置文件:

#修改之前挂载的redis的配置文件
vim ~/data/redis/slave-2/redis.conf# 允许所有ip地址访问
bind 0.0.0.0# 以守护进程的方式运行,就是关闭了远程连接窗口,redis依然运行,使用容器时必须注释,否则启动容器失败
# daemonize yes# 设置需要密码才能访问
requirepass root# 设置redis持久化,默认是no
appendonly yes# 设置主节点的密码(当主节点设置了requirepass配置时需要配置该项)
masterauth root# 主从模式下主节点的IP和PORT(这里要根据实际情况来定,我这里使用的是容器内部的IP和端口)
#容器内部ip和端口可以使用 docker inspect 镜像id来查看
# 这里也可以使用容器的名称,使用容器名称的时候在构建容器的时候就需要使用--link参数
# 这里也可以使用物理地址,使用物理地址的时候在构建容器的时候就需要使用--net参数
replicaof 172.17.0.3 6379
4.9、实现主从同步-永久-重启查看

重启 Redis 主节点和从节点容器

docker restart redis-master redis-slave-1 redis-slave-2

验证是否搭建成功,这里我们看一下主节点

#进入redis-master主节点
docker exec -it redis-master redis-cli
#输入密码验证root
auth root
#查看实例所属角色
role
查看主从复制信息
info replication

image-20230910153421366

相关文章:

Redis主从复制集群的介绍及搭建

在现代的软件开发中&#xff0c;数据的可靠性和可用性是至关重要的。Redis&#xff0c;作为一个开源的、内存中的数据结构存储系统&#xff0c;以其出色的性能和灵活的数据结构&#xff0c;赢得了开发者们的广泛喜爱。而 Redis 的主从复制功能&#xff0c;更是为我们提供了一种…...

MAC M1芯片安装mounty读写移动硬盘中的文件

因为移动硬盘中的文件是微软公司NTFS格式&#xff0c;MAC只支持自己的APFS或者HFS&#xff0c;与微软的NTFS不兼容&#xff0c;所以需要第三方的软件来支持读写硬盘中的文件&#xff0c;经过一上午的折腾&#xff0c;最终选择安装mounty这个免费的第三方软件 工具网址连接&am…...

原生Js Canvas去除视频绿幕背景

Js去除视频背景 注&#xff1a; 这里的去除视频背景并不是对视频文件进行操作去除背景 如果需要对视频扣除背景并导出可以使用ffmpeg等库&#xff0c;这里仅作播放用所以采用这种方法 由于uniapp中的canvas经过封装&#xff0c;且 uniapp 的 drawImage 无法绘制视频帧画面&…...

Vue知识系列(1)每天10个小知识点

目录 系列文章目录知识点**1. Vue修饰符**的概念、作用、原理、特性、优点、缺点、区别、使用场景**2. 双向数据绑定**的概念、作用、原理、特性、优点、缺点、区别、使用场景**3. MVVM、MVC、MVP** 的概念、作用、原理、特性、优点、缺点、区别、使用场景**4. slot** 的概念、…...

Elasticsearch(三)聚合基本使用

基础概念 bucket 数据分组&#xff0c;一些数据按照某个字段进行bucket划分&#xff0c;这个字段值相同的数据放到一个bucket中。可以理解成Java中的Map<String, List>结构&#xff0c;类似于Mysql中的group by后的查询结果。 metric&#xff1a; 对一个数据分组执行…...

单片机C语言实例:14、音频输出

一、喇叭发声原理 程序实例1&#xff1a; #include<reg52.h> //包含头文件&#xff0c;一般情况不需要改动&#xff0c;头文件包含特殊功能寄存器的定义sbit SPK P1^2; //定义喇叭端口 /*------------------------------------------------函数声明 --------------…...

docker 和 podman的区别

Podman 和 Docker 都是用于容器化应用程序的工具&#xff0c;它们在很多方面非常相似&#xff0c;但也有一些关键区别&#xff1a; 1. 架构和权限&#xff1a; - Docker&#xff1a;Docker 使用守护进程&#xff08;dockerd&#xff09;来管理容器&#xff0c;它需要在操作…...

苹果手机远程控制安卓手机,为什么不能发起控制?

这位用户想要用iOS设备远程控制安卓设备&#xff0c;在被控端安装好AirDroid之后&#xff0c;就在控制端的苹果手机上也安装了AirDroid&#xff0c;然而打开控制端的软件&#xff0c;却没有在手机界面上看到【远程控制】按钮&#xff0c;于是提出了以上疑问。 解答 想要让iOS设…...

Gradle 配置国内镜像

我们在使用gradle构建项目的时候&#xff0c;每当需要build或者刷新依赖的时候&#xff0c;由于gradle需要从服务器下载各种依赖包&#xff0c;速度非常慢&#xff0c;根本原因是由于gradle服务器在国外&#xff0c;而国内有些一些大厂和高校(比如阿里&#xff0c;华为&#xf…...

Spring AOP使用指南: 强大的面向切面编程技术

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

Spring Boot集成Elasticsearch实战

文章目录 一、简介二、安装与配置Elasticsearch三、集成Spring Boot与Elasticsearch1. 添加依赖与配置文件2. 创建Elasticsearch数据模型3. 定义Elasticsearch仓库接口4. 实现Elasticsearch数据操作 四、基本查询与索引操作1. 插入与更新数据2. 删除数据与索引3. 条件查询与分页…...

【python零基础入门学习】python基础篇之文件对象open、模块以及函数的使用(三)

本站以分享各种运维经验和运维所需要的技能为主 《python》&#xff1a;python零基础入门学习 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8》暂未更新 《docker学习》暂未更新 《ceph学习》ceph日常问题解…...

【JavaEE】_CSS常用属性值

目录 1. 字体属性 1.1 设置字体家族 font-family 1.2 设置字体大小 font-size 1.3 设置字体粗细 font-weight 1.4 设置字体倾斜 font-style 2. 文本属性 2.1 设置文本颜色 color 2.2 文本对齐 text-align 2.3 文本装饰 text-decoration 2.4 文本缩进 text-indent 2.…...

vue组件库开发,webpack打包,发布npm

做一个像elment-ui一样的vue组件库 那多好啊&#xff01;这是我前几年就想做的 但webpack真的太难用&#xff0c;也许是我功力不够 今天看到一个视频&#xff0c;早上6-13点&#xff0c;终于实现了&#xff0c;呜呜 感谢视频的分享-来龙去脉-大家可以看这个视频&#xff1a;htt…...

Java中快速排序的优化技巧:随机取样、三数取中和插入排序

目录 快速排序基础 优化1&#xff1a;随机取样 优化2&#xff1a;三数取中 优化3&#xff1a;插入排序 总结&#xff1a; 快速排序&#xff08;Quick Sort&#xff09;是一种高效的排序算法&#xff0c;它的平均时间复杂度为O(n log n)。然而&#xff0c;在某些情况下&…...

【leetcode 力扣刷题】删除字符串中的子串or字符以满足要求

删除字符串中的子串或者字符以满足题意要求 1234. 替换子串得到平衡字符串680. 验证回文串917. 仅仅反转字母 1234. 替换子串得到平衡字符串 题目链接&#xff1a;1234. 替换子串得到平衡字符串 题目内容&#xff1a; 题目中给出了平衡字符串的定义——只有’Q’&#xff0c;…...

【Unity基础】3.脚本控制物体运动天空盒

【Unity基础】3.脚本控制物体运动&天空盒 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity基础系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;搭建开发环境 &#xff08;1&#xff09;下载visual studio 在我们下载unity编译器的时候&…...

Spring MVC拦截器

拦截器&#xff08;Interceptor&#xff09;是 Spring MVC 提供的一种强大的功能组件。它可以对用户请求进行拦截&#xff0c;并在请求进入控制器&#xff08;Controller&#xff09;之前、控制器处理完请求后、甚至是渲染视图后&#xff0c;执行一些指定的操作。 在 Spring MV…...

ClickHouse的Join算法

ClickHouse的Join算法 ClickHouse是一款开源的列式分析型数据库&#xff08;OLAP&#xff09;&#xff0c;专为需要超低延迟分析查询大量数据的场景而生。为了实现分析应用可能达到的最佳性能&#xff0c;分析型数据库&#xff08;OLAP&#xff09;通常将表组合在一起形成一个…...

java面试题-RabbitMQ面试题

RabbitMQ面试题 面试官&#xff1a;RabbitMQ-如何保证消息不丢失 候选人&#xff1a; 嗯&#xff01;我们当时MYSQL和Redis的数据双写一致性就是采用RabbitMQ实现同步的&#xff0c;这里面就要求了消息的高可用性&#xff0c;我们要保证消息的不丢失。主要从三个层面考虑 第一…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...