Redis持久化及集群

news2024/11/26 10:01:55

Redis可以通过将数据保存在磁盘里实现持久化功能, 以防止宕机导致的数据大量丢失.但是持久化只能保证在磁盘不损坏的情况下, 长时间保存数据, 如果一旦磁盘损坏, 数据仍然会丢失. 为了解决这个问题, 主从复制应允而生.

主从复制是Redis集群中的一总, 其中一个Redis做主, 其他Redis做从, 主对外能读能写, 并且会定期将数据复制到从节点, 而从节点对外只能被读. 这样, 就有多台主机保存相同的数据, 一旦主节点顺坏, 从节点的数据也不会受到影响, 而且从节点可以被外界读, 因此做到了读写分离, 也提高了并发能力. 但是如果主节点一旦宕机, 需要人手动将某个从节点升级为主节点, 因此系统的可用性不高.

哨兵模式则提高系统的可用性的, 当主节点宕机, 它可以自动将某个从节点升级为主节点, 不需要人工干预. 但是由于只有一个主节点, 主节点需要定时将数据复制到从节点, 如果从节点太多, 主节点的负载会很大, 因此横向扩展性不强.

Redis cluster集群则很好的解决了横向扩展性不强的问题. Redis cluster集群是去中心化的系统, 它有多个主节点, 每个主节点对应多个从节点. 主节点可读可写, 且写入的数据, 会被通过一定的算法分散到各个主节点中. 从节点则只是复制对应主节点的内容, 一旦某个主节点宕机, 对应的从节点中的一个就会自动升级为主节点.

一 Redis持久化

redis 的数据全部在内存中,如果突然宕机,数据就会全部丢失,因此需要持久化来保证 Redis 的数据不会因为故障而丢失,redis 重启的时候可以重新加载持久化文件来恢复数据;

redis有四种持久化的方式:aof,aof rewrite,rdb和混合持久化。默认配置下,只开启 rdb 持久化。

1 aof(append only file)
aof 日志存储的是 Redis 服务器的顺序指令序列,aof 日志只记录对内存修改的指令记录;

img

通过重放(replay)aof 日志中指令序列来恢复 Redis 当前实例的内存数据结构的状态;

刷盘的策略可以分为:

# 1. 每条命令刷盘
# appendfsync always
# 2. 每秒刷盘
# appendfsync everysec
# 3. 交由系统刷盘
# appendfsync no

这些可以在配置文件里配置

这种持久化方式的缺点:
随着时间越长,aof 日志会越来越长,如果 redis 重启,重放整个 aof 日志会非常耗时,导致redis 长时间无法对外提供服务。

2 aof rewrite

aof 持久化策略会持久化所有修改命令;里面的很多命令其实可以合并或者删除;aof rewrite 则是精简aof文件中的命令.

aof rewrite 在 aof 的基础上,满足一定策略则 fork 进程,根据当前内存状态以及现有的AOF文件,转换成一系列的 redis 命令,序列化成一个新的 aof 日志文件中,序列化完毕后再将操作期间发生的增量 aof 日志追加到新的 aof 日志文件中,追加完毕后替换旧的 aof 日志文件;以此达到对 aof 日志瘦身的目的。

note:aof rewrite 开启的前提是开启 aof。

img

配置方法:

# 开启 aof
appendonly yes
# 开启 aof复写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 关闭 混合持久化
aof-use-rdb-preamble no
# 关闭 rdb
save ""

策略:

# 1. redis 会记录上次aof复写时的size,如果之后累计超过了原来的size,则会发生aof复写;
auto-aof-rewrite-percentage 100
# 2. 为了避免策略1中,小数据量时产生多次发生aof复写,策略2在满足策略1的前提下需要超过 64mb
#才会发生aof复写;
auto-aof-rewrite-min-size 64mb

缺点:aof复写在 aof 基础上实现了瘦身,但是 aof 复写的数据量仍然很大;加载会非常慢

3 rdb

基于 aof 或 aof 复写文件大的缺点,rdb 是一种快照持久化, 它也是Redis的默认持久化方式。它通过 fork 主进程,在子进程中将内存当中的数据键值对按照存储方式持久化到 rdb 文件中。rdb 存储的是经过压缩的二进制数据。

img

配置:

# 关闭 aof 同时也关闭了 aof复写
appendonly no
# 关闭 aof复写
auto-aof-rewrite-percentage 0
# 关闭 混合持久化
aof-use-rdb-preamble no
# 开启 rdb 也就是注释 save ""
# save ""
# save 3600 1
# save 300 100
# save 60 10000

策略:

# redis 默认策略如下:
# 注意:写了多个 save 策略,只需要满足一个则开启rdb持久化
# 3600 秒内有以1次修改
save 3600 1
# 300 秒内有100次修改
save 300 100
# 60 秒内有10000次修改
save 60 10000

缺点:若采用 rdb 持久化,一旦 redis 宕机,redis 将丢失一段时间的数据。RDB 需要经常 fork 子进程来保存数据集到硬盘上,当数据集比较大的时候,fork 的过程是非常耗时的,可能会导致 Redis 在一些毫秒级内不能响应客户端的请求。如果数据集巨大并且 CPU 性能不是很好的情况下,这种情况会持续1秒,AOF 也需要 fork,但是你可以调节重写日志文件的频率来提高数据集的耐久度。

4 混合持久化

从上面知道,rdb 文件小且加载快但丢失多,aof文件大且加载慢但丢失少。混合持久化是吸取rdb 和 aof 两者优点的一种持久化方案。aof 复写的时候实际持久化的内容是 rdb,等持久化后,持久化期间修改的数据以 aof 的形式附加到文件的尾部。混合持久化实际上是在 aof rewrite 基础上进行优化。所以需要先开启 aof rewrite。

img

img

配置

# 开启 aof
appendonly yes
# 开启 aof复写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 开启 混合持久化
aof-use-rdb-preamble yes
# 关闭 rdb
save ""
# save 3600 1
# save 300 100
# save 60 10000

二 Redis主从复制

redis主从复制是集群的原理, 是为了提高数据的可靠性,和读写分离的。它是一种数据复制和同步机制,用于将一个 Redis 实例(主节点)的数据复制到其他 Redis 实例(从节点)。在主从复制中,主节点负责处理写操作,并将写操作的结果复制到一个或多个从节点,从节点则负责接收主节点发送的数据并将其复制到本地,从而保持与主节点数据的一致性。

主从复制的主要目的是实现数据的冗余备份、读写分离和横向扩展, 防止主 redis 所在磁盘损坏,造成数据永久丢失。主从之间采用异步复制的方式。从数据库有只读属性。

# redis.conf
replicaof 127.0.0.1 7002 #选择目标主节点

主从复制中的数据同步, 分为全量数据同步和增量数据同步, 它们分别是:

  • 全量数据同步: 全量数据同步是在主从复制建立时进行的初始数据同步阶段。在这个阶段,主节点会将自己的完整数据集发送给从节点,以确保从节点拥有与主节点一致的数据。全量数据同步可以通过以下方式实现:

    • 快照(Snapshot):主节点会生成一个快照文件,包含了当前的数据集,然后将快照文件发送给从节点。从节点接收到快照文件后,会加载文件并恢复数据。其优点是效率高, 缺点是延迟大, 对网络带宽和存储空间的要求高
    • 命令传播(Command Replication):主节点会将执行在自己上面的写操作命令记录下来,并发送给从节点。从节点接收到命令后,按照顺序执行这些命令来恢复数据。其优点是实时性好, 数据延迟小, 缺点是效率低, 复杂性高, 需要处理命令的并发和一致性等问题.

    选择哪种同步方式, 是通过配置文件进行设置的.

  • 增量数据同步(Incremental Sync):在完成全量数据同步之后,主从节点之间会进行增量数据同步。增量数据同步是指主节点将写操作命令发送给从节点,以使从节点实时更新自己的数据,以保持与主节点的一致性。增量数据同步是异步的,主节点会将命令发送给从节点,但从节点执行命令的速度可能会受到网络延迟等因素的影响。在增量数据同步期间,如果从节点与主节点之间的连接断开,从节点会尝试重新连接并继续同步丢失的数据。

全量数据同步的流程图:

img

增量数据同步的流程图:

img

服务器 RUN ID:无论主库还是从库都有自己的 RUN ID,RUN ID 启动时自动产生,RUN ID 由40个随机的十六进制字符组成。当从库对主库初次复制时,主库将自身的 RUN ID 传送给从库,从库会将 RUN ID 保存。

当从库断线重连主库时,从库将向主库发送之前保存的 RUN ID。

  • 从库 RUN ID 和主库 RUN ID 一致,说明从库断线前复制的就是当前的主库;主库尝试执行增量同步操作;
  • 若不一致,说明从库断线前复制的主库并不时当前的主库,则主库将对从库执行全量同步操作。

复制偏移量: 是一个用于标识复制进度的值。它表示主节点和从节点之间的数据同步位置。主从都会维护一个复制偏移量, 当从节点连接到主节点进行复制时,它会向主节点发送一个复制请求,并提供自己的复制偏移量。主节点会将从节点设置为该偏移量之后的数据进行同步。

其同步方式是:

  • 主库向从库发送N个字节的数据时,将自己的复制偏移量上加N。
  • 从库接收到主库发送的N个字节数据时,将自己的复制偏移量加上N。

通过比较主从偏移量得知主从之间数据是否一致;偏移量相同则数据一致;偏移量不同则数据不一致。

环形缓冲区(复制积压缓冲区):本质就是固定长度先进先出队列;
存储内容:当因某些原因(网络抖动或从库宕机)从库与主库断开连接,避免重新连接后开始全量同步,在主库设置了一个环形缓冲区;该缓冲区会在从库失联期间累计主库的写操作;当从库重连,会发送自身的复制偏移量到主库,主库会比较主从的复制偏移量:

  • 若从库offset还在复制积压缓冲区中,则进行增量同步;
  • 否则,主库将对从库执行全量同步;

三 Redis哨兵模式

Redis的哨兵模式, 主要是是为了解决Redis集群的高可用性问题. 和高可用性相比, 能够自动切换宕机的主节点.

哨兵模式是由一个或多个 sentinel 实例构成 sentinel 系统。sentinal和redis, 是两个相互独立的程序. 该系统可以监视任意多个主库以及这些主库所属的从库。当主库处于下线状态,自动将该主库所属的某个从库升级为新的主库。

客户端来连接集群时,会首先连接 sentinel,通过 sentinel 来查询主节点的地址,然后再连接主节点进行数据交互。当主节点发生故障时,客户端会重新向 sentinel 索要主库地址,sentinel 会将最新的主库地址告诉客户端。通过这样客户端无须重启即可自动完成节点切换。

哨兵模式当中涉及多个选举流程采用的是 Raft 算法的领头选举方法的实现;

原理图:

img

配置:

# sentinel.cnf
# sentinel 只需指定检测主节点就行了,通过主节点自动发现从节点
sentinel monitor mymaster 127.0.0.1 6379 2
# 判断主观下线时长
sentinel down-after-milliseconds mymaster 30000
# 指定可以有多少个Redis服务同步新的主机,一般而言,这个数字越小同步时间越长,而越大,则对网
# 络资源要求越高
sentinel parallel-syncs mymaster 1
# 指定故障切换允许的毫秒数,超过这个时间,就认为故障切换失败,默认为3分钟
sentinel failover-timeout mymaster 180000

异常检测:
主观下线:
sentinel 会以每秒一次的频率向所有节点(其他sentinel、主节点、以及从节点)发送 ping 消息,然后通过接收返回判断该节点是否下线;如果在配置指定 down-after-milliseconds 时间内则被判断为主观下线。

客观下线:
当一个 sentinel 节点将一个主节点判断为主观下线之后,为了确认这个主节点是否真的下线,它会向其他sentinel 节点进行询问,如果收到一定数量的已下线回复,sentinel 会将主节点判定为客观下线,并通过领头 sentinel 节点对主节点执行故障转移;

故障转移:
主节点被判定为客观下线后,开始领头 sentinel 选举,需要一半以上的 sentinel 支持,选举领头sentinel后,开始执行对主节点故障转移。

  • 从从节点中选举一个从节点作为新的主节点
  • 通知其他从节点复制连接新的主节点
  • 若故障主节点重新连接,将作为新的主节点的从节点

使用方式:

  1. 连接一个哨兵节点,并且获取主节点信息;
    SENTINEL GET-MASTER-ADDR-BY-NAME
  2. 验证当前获取的主节点。
    ROLE 或者 INFO REPLICATION
  3. 为当前连接的哨兵节点,添加发布订阅( PUB/SUB )连接,并且订阅 +switch-master 频道。

缺点:
redis 采用异步复制的方式,意味着当主节点挂掉时,从节点可能没有收到全部的同步消息,这部分未同步的消息将丢失。如果主从延迟特别大,那么丢失可能会特别多。sentinel 无法保证消息完全不丢失,但是可以通过配置来尽量保证少丢失。

# 主库必须有一个从节点在进行正常复制,否则主库就停止对外写服务,此时丧失了可用性
min-slaves-to-write 1
# 这个参数用来定义什么是正常复制,该参数表示如果在10s内没有收到从库反馈,就意味着从库同步不正常;
min-slaves-max-lag 10

同时,它的致命缺点是不能进行横向扩展, 因为, 所有的写操作都需要通过组节点完成, Redis节点过多, 会导致master负载过高.

四 Redis cluster集群

Redis cluster 将所有数据划分为 16384(2^14)个槽位,每个 redis 节点负责其中一部分槽位。cluster 集群是一种去中心化的集群方式。

如图,该集群由三个 redis 节点组成,每个节点负责整个集群的一部分数据,每个节点负责的数据多少可能不一样。这三个节点相互连接组成一个对等的集群,它们之间通过一种特殊的二进制协议交互集群信息。

当 redis cluster 的客户端来连接集群时,会得到一份集群的槽位配置信息。这样当客户端要查找某个 key时,可以直接定位到目标节点。

客户端为了可以直接定位(对 key 通过 crc16 进行 hash 再对2^14取余)某个具体的 key 所在节点,需要缓存槽位相关信息,这样才可以准确快速地定位到相应的节点。同时因为可能会存在客户端与服务器存储槽位的信息不一致的情况,还需要纠正机制(通过返回 -MOVED 3999127.0.0.1:6479 ,客户端收到后需要立即纠正本地的槽位映射表)来实现槽位信息的校验调整。

另外,redis cluster 的每个节点会将集群的

配置信息持久化到配置文件中,这就要求确保配置文件是可写的,而且尽量不要依靠人工修改配置文件。

img

数据迁移
redis cluster 提供了工具 redis-trib 可以让运维人员手动调整槽位的分配情况,它采用 ruby 语言开发,通过组合原生的 redis cluster 指令来实现。图中:A 为待迁移的源节点,B 为待迁移的目标节点。

img

过程:
如上图:redis 迁移的单位是槽,redis 是一个槽一个槽地进行迁移,当一个槽位正在迁移时,这个槽就处于中间过渡状态。这个槽在源节点的状态为 migrating ,在目标节点的状态为importing ,表示此时数据正在从源节点流向目标节点。

迁移工具 redis-trib 首先在源节点和目标节点设置好中间过渡状态,然后一次性获取源节点槽位的所有或者部分的 key 列表,再依次将 key 进行迁移。源节点对当前的 key 执行 dump 指令得到序列化内容,然后向目标节点发送 restore 指令,目标节点将源节点的序列化内容进行反序列化并将内容应用到目标节点的内容中,然后返回 +ok 给源节点,源节点收到后删除该 key;按照这些步骤将所有待迁移的 key 进行迁移。

note:迁移过程是同步的,迁移过程中源节点的主线程处于阻塞状态,直到key被删除。如果迁移过程中源节点出现网络故障,这两个节点依然处于中间状态,重启后,redis-trib可继续迁移。

所以,redis-trib 迁移的过程是一个一个 key 来进行,如果这个 key 对应 val 内容很大,将会影响到客户端的正常访问。

复制以及故障转移
cluster 集群中节点分为主节点和从节点,其中主节点用于处理槽,而从节点则用于复制该主节点,并在主节点下线时,代替主节点继续处理命令请求。

故障检测
集群中每个节点都会定期地向集群中的其他节点发送 ping 消息,如果接收 ping 消息的节点没有在规定时间内回复 pong 消息,那么这个没有回复 pong 消息的节点会被标记为 PFAIL(probablefail)。

集群中各个节点会通过互相发送消息的方式来交换集群中各个节点的状态信息;如果在一个集群中,半数以上负责处理槽的主节点都将某个主节点 A 报告为疑似下线,那么这个主节点A将被标记为下(FAIL);标记主节点 A 为下线状态的主节点会广播这条消息,其他节点(包括A节点的从节点)也会将A节点标识为 FAIL;

故障转移
当从节点发现自己的主节点进入FAIL状态,从节点将开始对下线主节点进行故障转移;

  1. 从数据最新的从节点中选举为主节点;
  2. 该从节点会执行 replica no one 命令,称为新的主节点;
  3. 新的主节点会撤销所有对已下线主节点的槽指派,并将这些槽全部指派给自己;
  4. 新的主节点向集群广播一条 pong 消息,这条 pong 消息可以让集群中的其他节点立即知道
  5. 这个节点已经由从节点变成主节点,并且这个主节点已经接管了之前下线的主节点;
  6. 新的主节点开始接收和自己负责处理的槽有关的命令请求,故障转移结束;

集群配置方法:
创建文件夹:

# 创建 6 个文件夹
mkdir -p 7001 7002 7003 7004 7005 7006
cd 7001
vi 7001.conf
# 7001.conf 中的内容如下

集群中单个Redis的配置方式:

pidfile "/home/chengjun/redis-data/7001/7001.pid"
logfile "/home/chengjun/redis-data/7001/7001.log"
dir /home/chengjun/redis-data/7001/
port 7001
daemonize yes
cluster-enabled yes
cluster-config-file nodes-7001.conf
cluster-node-timeout 15000

将配置复制多份, 并启动多个Redis进程.

手动创建集群:

# 节点会面
cluster meet ip port
# 分配槽位
cluster addslots slot
# 分配主从
cluster replicate node-id

智能创建集群:

redis-cli --cluster help
# --cluster-replicas 后面对应的参数 为 一主对应几个从数据库
redis-cli --cluster create host1:port1 ... hostN:portN --cluster-replicas
<arg>
redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluster-replicas 1

文章参考与<零声教育>的C/C++linux服务期高级架构系统教程学习:链接

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

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

相关文章

C++数据结构:线性顺序表(数组)

文章目录 前言一、vector简介二、泛型编程自定义数组结构1、定义类2、删除、读取元素和首尾指针3、修改元素、获取元素数量、和插入 总结 前言 将一个线性表存储到计算机中&#xff0c;把线性表的结点按逻辑顺序依次存放到一组地址连续的存储单元里&#xff0c;用这种方法存储…

nodejs+vue+elementui个人心情日志博客网站系统5ht83

语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;VScode 前端vueelementui,博客管理系统模块 该模块是博客管理系统中的重要模块&#xff0c;它也是博客管理系统的主模块&#xff0c;该模块的…

从 WebKit 看浏览器内核架构

浏览器常见的浏览器内核有&#xff1a;Blink、WebKit、Gecko、Trident 等&#xff0c;目前 WebKit 内核占据了非常大的的市场&#xff0c;包括 Chrome、Safari、安卓浏览器等市面上的主流浏览器&#xff0c;都使用了 WebKit 内核。 从 WebKit 看浏览器内核架构 既然 WebKit 这么…

lwip的arp协议的意义和更新时机

ARP协议存在的目的 ARP&#xff08;Address Resolution Protocol&#xff09;协议是 TCP/IP 协议族中的一个协议&#xff0c;它的主要目的是将 IP 地址解析为 MAC&#xff08;Media Access Control&#xff09;地址&#xff0c;以便在局域网中进行通信。 具体而言&#xff0c…

## 如何顺序处理设备上报的数据

1. 引言 随着智能技术的发展&#xff0c;市场上出现了很多的智能设备&#xff0c;其具有连接网络的能力。用户可以实现远程控制&#xff0c;并且设备也可上报自己的状态&#xff0c;实现云端对设备的运行情况分析。在某些情况下需要保证设备上报状态的有序性&#xff0c;例如传…

Unity之ShaderGraph 节点介绍 Input输入节点

目录 Input&#xff08;输入&#xff09;  1、Basic&#xff08;基本&#xff09;   1) Boolean&#xff08;布尔&#xff09;   2) Color&#xff08;颜色&#xff09;   3) Constant&#xff08;常量&#xff09;   4) Integer&#xff08;整型&#xff09;   5)…

weblogic CVE-2023-21839 复现

影响版本 Weblogic 12.2.1.3.0 Weblogic 12.2.1.4.0 Weblogic 14.1.1.0.0 这里是用的docker下载的vulhub的CVE-2023-21839 靶机和攻击机都是192.168.85.131 docker 启动环境 ocker-compose up -d 然后看一下说明书 vim README.zh-cn.md 让你访问ip:7001/console 好&a…

chatgpt赋能python:PythonWoody:网站优化工具的首选

Python Woody: 网站优化工具的首选 在当今数字化时代&#xff0c;网站被认为是企业的门面。 然而&#xff0c;这只是建立网络存在的起点。 在许多情况下&#xff0c;优化网站并提高其排名对于企业的成功至关重要。 在这里&#xff0c;Python Woody成为了网站优化工具的首选。 …

LVGL-最新版本及其版本定义标准

lvgl的最新版本是9.0.0&#xff0c;处于开发分支中。 稳定版本是8.3.0. 建议一般开发使用稳定版8.3.0. .\lvgl.h定义了当前版本 /*************************** CURRENT VERSION OF LVGL ***************************/ #define LVGL_VERSION_MAJOR 8 #define LVGL_VERSION_MINO…

《JavaEE》HTTPS

文章目录 HTTPS起源HTTPS对称加密非对称加密两者的区别 HTTPS的安全问题使用对称加密正常交互黑客入侵解决方案 非对称加密引入非对称加密后的流程 中间人攻击黑客的入侵方案加入后的流程解决方案黑客再次加注解决方案 ​&#x1f451;作者主页&#xff1a;Java冰激凌 &#x1…

ChatGPT突然上线APP!iPhone可用、速度更快,GPT-4用量限制疑似取消

新建了一个网站 ChatGPT人工智能中文站 - ChatGPT人工智能中文站http://ai.weoknow.com 每天给大家更新可用的国内可用chatGPT免费镜像站 OpenAIChatGPT正式推出iOS应用程序的官方公告突然发布。 立即在苹果商店的免费列表中排名第二&#xff0c;在效率列表中排名第一。 &am…

VScode+LaTeX 配置时遇到的一些问题

文章目录 VScodeLaTeX 配置时遇到的一些问题1. json 配置文件总览2. 使用 SumatraPDF 作为 pdf 阅读器时的双向跳转3. 选择使用 VScode 内置的 tab 打开 pdf 或者使用外部 SumatraPDF 打开4. 关于 LaTeX Workshop 插件的安装 VScodeLaTeX 配置时遇到的一些问题 1. json 配置文…

『MySQL 实战 45 讲』17 - 如何正确地显示随机消息?(随机抽取 3 个词)

如何正确地显示随机消息&#xff1f;&#xff08;随机抽取 3 个词&#xff09; 需求&#xff1a;从用户的英语单词表中&#xff0c;随机选择三个单词&#xff0c;创表和插入数据如下&#xff1a; # 建表 CREATE TABLE words (id INT(11) NOT NULL AUTO_INCREMENT,word VARCHA…

Chatgpt版本的opencv安装教程

文章目录 前言一、安装opencv方法一二、安装opencv方法二 前言 最近刚买了台RTX 3070的电脑&#xff0c;顺手刷了个ubuntu系统专门玩Carla&#xff0c;为了方便查资料&#xff0c;也顺手搭了浏览chatgpt的环境&#xff0c;用的clash&#xff0c;还挺好用的。然后刚好在看Carla…

(转载)MATLAB智能算法30个案例分析(4)——基于遗传算法的TSP算法

1 理论基础 TSP(traveling salesman problem,旅行商问题)是典型的NP完全问题&#xff0c;即其最坏情况下的时间复杂度随着问题规模的增大按指数方式增长&#xff0c;到目前为止还未找到一个多项式时间的有效算法。 TSP问题可描述为&#xff1a;已知n个城市相互之间的距离&…

chatgpt赋能python:PythonUrwid:一个优秀的控制台UI工具

Python Urwid&#xff1a;一个优秀的控制台UI工具 在开发控制台应用程序时&#xff0c;通常需要一种轻而易举的方法来创建用户界面。Python Urwid是一个高效&#xff0c;可定制的控制台UI工具&#xff0c;它可以帮助你创建强大的用户界面&#xff0c;同时获取出色的响应时间。…

SpringCloudAlibaba:继解决登录问题之后,Sentinel持久化没有效果问题

说实话好麻烦&#xff0c;每次使用关于Nacos的时候&#xff0c;bootstrap.yaml中都得配置username和password。 我后悔了。。。 哪位大哥有好办法啊&#xff01;&#xff01;&#xff01; 因为之前开启登录鉴权&#xff0c;导致使用Nacos就得配username和password&#xff0c…

day2 - 使用OpenCV进行图像的读取与展示

本期将使用OpenCV对图像进行一些基本的了解和操作&#xff1a;主要包含图像的读取、展示和保存&#xff0c;以及查看图像的基本属性&#xff0c;让我们充分的了解图像&#xff0c;为后续图像处理做准备。 完成本期内容&#xff0c;你可以&#xff1a; 会使用OpenCV对图像进行读…

Redis常用命令详解

Redis 是Remote Dictionary Service 的简称&#xff1b;也是远程字典服务。它是内存数据库&#xff0c;KV 数据库&#xff0c;数据结构数据库。它是一个单线程的单reactor模型。其交互方式是请求响应方式。在正常情况下&#xff0c;如果向redis发出请求&#xff0c;则一定会有响…