《Redis设计与实现》阅读总结-4

第 17 章 集群

        Redis集群是Redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移的功能

一、命令

CLUSTER MEET命令:用来连接不同的开启集群支持的 Redis 节点,以进入工作集群。

CLUSTER MEET <ip> <port>

CLUSTER NODES命令:提供了当前连接节点所属集群的配置信息。

CLUSTER NODES

CLUSTER ADDSLOTS命令:把一组hash slots分配给接收命令的节点。

CLUSTER ADDSLOTS slot [slot ...]

MOVED错误 :当前节点(服务器)发现键所在的槽不是由自己负责,节点就会向客户端返回一个Moved错误,指引客户端转向正确节点

MOVED <slot> <host>:<ip>

ASK错误:在重新分片期间,客户端请求源节点槽的数据,发现数据不在源节点,数据已经迁移到目标节点时,源节点会向客户端返回一个ASK错误,指引客户端转向正确节点

ASK <slot> <host>:<ip>

CLUSTER REPLICATE命令:向一个节点发送该命令,让接受命令的节点称为node_id所指定节点的从节点,并开始对主节点进行复制:

CLUSTER REPLICATE <node_id>

二、节点

1. 集群如何添加节点:

  • 一开始,每个节点都是相互独立的,它们都处于一个只包含自己的集群当中,要组建一个真正可工作的集群,需要将各个独立的节点连接起来,构成一个包含多个节点的集群。
  • 向一个节点发送CLUSTER MEET命令,可以让节点与指定ip和port的节点进行握手(handshake),握手成功时,节点会把指定ip和port的节点添加到当前所在集群中。

2. 启动节点:

3. 集群数据结构:

  • ClusterNode结构保存了一个节点的当前状态,具体信息如下。ClusterNode结构的link属性是一个ClusterLink结构,该结构保存了链接节点的所有信息,具体如下:

  • 每个节点都保存着一个clusterState结构,这个结构记录了当前节点的视角下,集群目前所处的状态,具体如下:

4. 握手过程:

三、槽指派

        Redis集群通过分片来保存数据库中的键值对:集群的整个数据库被分为16384个槽(slot),集群中每个节点可以处于0~16384个槽位。

        当数据库中的16348个槽位都有节点在处理时,集群处于上线状态(ok),相反地,如果数据库中有任何一个槽位没有得到处理,那么集群处于下线状态(fail)。

1. 记录节点的槽位指派信息:

2. 传播节点的槽指派信息:

        一个节点(A节点)除了处理记录自己负责的槽记录,还会将自己的槽记录(A节点)通过消息发送给集群中的其他节点(B节点),其他节点(B节点)会在自己的clusterState.nodes字典中查找节点(A节点)对应的clusterNode结构,更新槽记录。

3. 记录集群所有槽的指派信息:

4. clusterState. slots数组与clusterNode.slots数组区别:

  • clusterState. slots记录了集群中所有槽的指派信息。
  • clusterNode.slots数组只记录了clusterNode结构所代表的节点的槽指派信息。

四、在集群中执行命令

1. 流程图:

2. 计算键属于哪个槽位:

3. 判断槽是否有当前节点负责处理:

计算出来键所属的槽 i 之后,节点就会检查自己在cluster.slots数组中的项i,判断键所在的槽是否由自己负责:

  • 如果clusterState.slots[i]等于clusterState.myself,那么说明槽i由当前节点负责,节点可以执行客户端发送的命令。
  • 如果clusterState.slots[i]不等于clusterState.myself,结构会根据clusterState.slots[i]指向的clusterNode结构记录的节点IP和端口号,向客户端返回MOVED错误,指引客户端专转向正在处理槽 i 的节点

4. MOVED错误:

5. 节点数据库的实现:

        集群节点保存键值对以及过期时间的方式,与单价Redis服务器完全相同。

五、重新分片

1. 概念:

        重启分片可以将任意数量已经指派给某个节点(源节点)的槽改为指派给另一个节点(目标节点),并且相关槽所属的键值对也会从源节点被移动到目标节点。

2. 实现原理:

        Redis集群的从新分片操作由Redis的集群管理软件redis-trib负责执行的,Redis提供进行重新分片的所需命令,而redis-trib则通过源节点和目标节点发送命令来进行重新分片操作。

六、ASK错误

1. 概念:

在重新分片期间,源节点向目标节点迁移一个槽的过程中,可能会出现这样一种情况:属于被迁移槽的一部分键值对保存在源节点里面,而另一部分键值对则保存在目标节点里面。

当客户端向源节点发送一个与数据库键有关的命令,并且命令要处理的数据库键恰好就属于正在被迁移的槽时:

  • 源节点会先在自己的数据库里面查找指定的键,如果找到的话,就直接执行客户端发送的命令。
  • 相反地,如果源节点没能在自己的数据库里面找到指定的键,那么这个键有可能已经被迁移到了目标节点,源节点将向客户端返回一个ASK错误,指引客户端转向正在导入槽的目标节点,并再次发送之前想要执行的命令。

2. 流程:

3. AKSING命令:

  • 作用:打开发送该命令的客户端的Redis_Asking标识。

4. ASK错误和MOVED错误的区别:

  • MOVED错误代表槽的负责权已经从一个节点转移到了另一个节点:在客户端收到关于槽i的MOVED错误之后,客户端每次遇到关于槽i的命令请求时,都可以直接将命令请求发送MOVED错误所指向的节点,因为该节点就是目前负责槽i的节点。
  • ASK错误只是两个节点在迁移槽的过程中使用的一种临时措施:
    • 在客户端收到关于槽 i 的ASK错误之后,客户端只会在接下来的一次命令请求中将关于槽 i 的命令请求发送至ASK错误所指示的节点,因为可能该槽位还有没迁移完的元素,所以只有全部迁移完之后才会把这个槽位标记成 target 节点的。
    • 所以这种转向不会对客户端今后发送关于槽 i 的命令请求产生任何影响,客户端仍然会将关于槽i的命令请求发送至目前负责处理槽i的节点,除非ASK错误再次出现。

七、复制与故障转移

1. 相关概念:

  • Redis集群中的节点为主节点(master)和从节点(slave),其中主节点处理槽,而从节点则用于复制某个节点,并在复制的主节点下线时,代替下线主节点继续处理命令请求。
  • 集群中的所有节点都会在代表主节点的clusterNode结构的slave属性和numslave属性中记录正在复制这个主节点的从节点名单。

2. 故障检测:

  • 集群中的每个节点都会定期地向集群中的其他节点发送PING消息,检测对方是否在线,如果接收PING消息的节点没有在规定的时间内,返回PONG消息,那么发送PING消息的节点就会将接收PING消息的节点标记为疑似下线(probable fail, PFAIL)。
  • 集群中各个节点会通过相互发送消息的方式来交换集群中各个节点的状态,如果半数以上复制处理槽的主节点都将某个主节点报告为疑似下线,那么这个主节点将被标记为已下线。

3. 故障转移:

  • 1) 下线主节点的所有从节点里面,会有一个从节点被选中。
  • 2) 被选中的从节点会执行 SLAVEOF no one命令,成为新的主节点。
  • 3) 新的主节点会撤销所有对已下线主节点的槽指派,并将这些槽全部指派给自己。
  • 4) 新的主节点向集群广播一条PONG消息,这条PONG消息可以让集群中的其他节点立即知道这个节点已经由从节点变成了主节点,并且这个主节点已经接管了原本由已下线节点负处理的槽。
  • 5) 新的主节点开始接收和自己负责处理的槽有关的命令请求,故障转移完成。

4. 选举新的主节点:

        基于Raft算法的领头选举方法(leader election)实现的,具体见P281

八、消息

1. 节点发送消息的种类(5种):

  • MEET消息:当发送者接到客户端发送的 CLUSTER MEET命令时,发送者会向接收者发送MEET消息,请求接收者加入到发送者当前所处的集群里面。
  • PING消息:集群里的每个节点默认每隔一秒钟就会从已知节点列表中随机选出五个节点,然后对这五个节点中最长时间没有发送过PING消息的节点发送PING消息,以此来检测被选中的节点是否在线。除此之外,如果节点A最后一次收到节点B发送的PONG消息的时间,距离当前时间已经超过了节点A的cluster-node-timeout选项设置时长的一半,那么节点A也会向节点B发PING消息,这可以防止节点A因为长时间没有随机选中节点B作为PING消息的发送对象而导致对节点B的信息更新滞后。
  • PONG消息:当接收者收到发送者发来的MEET消息或者PING消息时,为了向发送者确认这条MEET消息或者PING消息已到达,接收者会向发送者返回一条PONG消息。另外,一个节点也可以通过向集群广播自己的PONG消息来让集群中的其他节点立即刷新关于这个节点的认识。例如当一次故障转移操作成功执行之后,新的主节点会向集群广播一条PONG消息,以此来让集群中的其他节点立即知道这个节点已经变成了主节点,并且接管了已下线节点负责的槽。
  • FAIL消息:当一个主节点A判断另一个主节点B已经进入FAIL状态时,节点A会向集群广播一条关于节点B的FAIL消息,所有收到这条消息的节点都会立即将节点B标记为已下线。
  • PUBLISH消息:当节点接收到一个 PUBLISH命令时,节点会执行这个命令,并向集群广播一条PUBLISH消息,所有接收到这条 PUBLISH消息的节点都会执行相同的 PUBLISH命令。

2. 消息的组成(两部分):消息头和消息正文

3. 消息头结构:

4. 消息正文结构:

5. MEET、PING、PONG消息的实现

  • Redis集群中各个节点通过Gossip协议来交互各自关于不同节点的状态信息,其中Gossip协议由MEET、PING、PONG三种消息实现,这三种消息的正文都由两个cluster.h/clusterMsgDataGossip机构组成,其他资料见P285

 

6. FAIL消息的实现:

在集群的节点数量比较大的情况下,单纯使用Gossip协议来传播节点的下线信息会有些延迟。FALL消息的正文由cluster.h/clusterMsgDataFail结构表示,这个机构只包括弄得那么属性:

7. PUBLISH消息的实现:

        当客户端向集群中某个节点发送命令的时候,接受命令的节点不仅向channel频道发送消息message,它还会向集群广播一条publish消息,所以接收到这条publish消息的节点都会向channel频道发送message消息。

九、重点回顾

  • 节点通过握手来将其他节点添加到自己所处的集群当中。
  • 集群中的16384个槽可以分别指派给集群中的各个节点,每个节点都会记录哪些槽指派给了自己,而哪些槽又被指派给了其他节点。
  • 节点在接到一个命令请求时,会先检查这个命令请求要处理的键所在的槽是否由自己负责,如果不是的话,节点将向客户端返回一个 MOVED错误,MOVED错误携带的信息可以指引客户端转向至正在负责相关槽的节点。
  • 对 Redis集群的重新分片工作是由redis-trib负责执行的,重新分片的关键是将属于某个槽的所有键值对从一个节点转移至另一个节点。
  • 如果节点A正在迁移槽 i 至节点B,当节点A没能在自己的数据库中找到命令指定的数据库键时,节点A会向客户端返回一个ASK错误,指引客户端到节点B继续查找指定的数据库键。
  • MOVED错误表示槽的负责权已经从一个节点转移到了另一个节点,而ASK错误只是两个节点在迁移槽的过程中使用的一种临时措施。
  • 集群里的从节点用于复制主节点,并在主节点下线时,代替主节点继续处理命令请求。
  • 集群中的节点通过发送和接收消息来进行通信,常见的消息包括MEET、PING、PONG、FAIL、 PUBLISH五种。

第 18 章 发布与订阅

一、命令

Publish命令:用于将信息发送到指定的频道

PUBLISH channel_name message

Subscribe命令:用于客户端订阅给定的一个或多个频道的信息

SUBSCRIBE channel_name [channel_name ...]

Unsubscribe命令: 用于客户端退订给定的一个或多个频道的信息

UNSUBSCRIBE channel_name [channel_name ...]

Psubscribe命令:用于客户端订阅一个或多个符合给定模式的频道

PSUBSCRIBE pattern_name [pattern_name ...]

Punsubscribe命令: 用于客户端退订所有给定模式的频道

PUNSUBSCRIBE pattern_name [pattern_name ...]

Pubsub命令:用于查看订阅与发布系统状态,它由数个不同格式的子命令组成,详情见《五、查看订阅信息》

PUBSUB <subcommand> [argument [argument ...]]

二、频道的订阅与退订

1. 频道的存储位置与数据结构:

        Redis将所有频道的订阅关系都保存在服务状态的pubsub_channels字典里面,这个字典的键存储的是频道,值是一个链表,链表里记录了所有订阅这个频道的客户端。

2. 频道订阅步骤:

  • 如果频道已经有其他订阅者,将客户端添加到订阅者链表的末尾。
  • 如果频道没有任何订阅者,首先为频道创建一个键,并将这个键的值设置为空链表,然后将客户端添加到链表,成为链表的第一个元素。

3. 频道退订步骤:

  • 根据退订频道的名字,从字典中找到该频道对应订阅链表,再从链表中删除。
  • 如果删除订阅客户端后,链表为空,则从字典中删除频道对应的键。

三、模式的订阅与退订

1. 模式的存储位置与数据结构:

        Redis将所有模式的订阅关系都保存在服务器状态的pubsub_patterns属性里面,pubsub_patterns属性是一个链表,链表中包含一个pubsubPattern结构。

2. 模式的订阅步骤:

  • 1)新建一个pubsubPattern结构,将结构的pattern属性设置为被订阅的模式,client属性设置为订阅模式的客户端。
  • 2)将pubsubPattern结构添加到pubsub_patterns链表的表尾。

3. 模式的退订步骤:

  • 从链表中查找并删除节点。

四、消息发送

服务器执行消息发送的两个动作:

  • 将消息发送给频道的所有订阅者。
  • 如果有一个或多个模式与频道匹配,将消息发送给模式的订阅者。

五、查看订阅信息

1. Pubsub命令:查看频道或模式相关信息。

2. Pubsub Channels子命令:

PUBSUB CHANNLES [pattern]
  • 作用:返回服务器当前被订阅的频道,其中pattern参数时可选的:
  • 如果不给定pattern参数,那么命令返回服务器当前被订阅的所有频道。
  • 如果给定pattern参数,那么命令返回服务器当前被订阅的频道中那些与pattern模式相匹配的频道。

3. Pubsub Numsub子命令:

PUBSUB NUMSUB [channel-1 channel-2 ... channel-n]
  • 作用:接受任意多个频道作为输入参数,并返回这些频道的订阅者数量。

3. Pubsub Numpat子命令:

PUBSUB NUMPAT
  • 作用:返回服务器当前被订阅,模式的数量。

六、重点回顾

  • 服务器状态在 pubsub channels字典保存了所有频道的订阅关系:SUBSCRIBE命令负责将客户端和被订阅的频道关联到这个字典里面,而 UNSUBSCRIBE命令则负责解除客户端和被退订频道之间的关联。
  • 服务器状态在pubsub patterns链表保存了所有模式的订阅关系:PSUBSCRIBE命令负责将客户端和被订阅的模式记录到这个链表中,而 PUNSUBSCRIBE命令则负责移除客户端和被退订模式在链表中的记录。
  • PUBLISH命令通过访问 pubsub channels字典来向频道的所有订阅者发送消息,通过访问pubsub patterns链表来向所有匹配频道的模式的订阅者发送消息。
  • PUBSUB命令的三个子命令都是通过读取 pubsub channels字典和 pubsub patterns链表中的信息来实现的。

第 19 章 事务

        事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而改变去执行其他客户端的命令请求,它会将事务中所有命令都执行完毕,然后才去处理其他客户端的命令请求。

一、命令

Multi命令:用于标记一个事务块的开始。

Multi

Exec命令:用于执行所有事务块内的命令。

Exec

Watch命令:用于监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

WATCH key [key ...]

二、事务的实现

1. 事务的阶段:

        事务开始、命令入队、事务执行。

2. 事务开始:

  • Multi命令开启事务。
  • 客户端从非事务状态切换成事务状态:是通过在客户端状态的flags属性中打开REDIS_MULTL标识完成的。

3. 命令入队:

        客户端切换成事务状态后,服务器判断不同命令之后,需要执行的操作流程图

4. 事务队列:

  • 每个Redis客户端都有自己的事务状态,这个事务状态保存在客户端的mstate属性里面:

  • 事务状态包含一个事务队列,以及一个已入队命令的计数器:

  • 事务队列是一个mutilCmd类型的数组,数组中的每一个multiCmd结构都保存了一个已入队列的相关信息,包括指向命令实现函数的指针,命令的参数,以及参数的数量。

  • 事务队列以FIFO(先进先出)的方式保存入队命令。
  • 事务状态的数据结构:

5. 执行事务:

  • 处于事务装的客户端向服务器发送EXEC命令时,这个EXEC命令将立即被服务器执行。
  • 执行EXEC命令时,服务器会遍历这个客户端的事务队列,执行队列中保存的所有命令,最后将执行命令所得的结果全部返回给客户端。

三、WATCH命令的实现

1. 概念:

        Watch命令是一个乐观锁,它可以在EXEC命令执行之前,监视任意数量的数据库键,并在Exec命令执行时,检查监视的键是否至少有一个已经被修改过了,如果被修改,则拒绝执行事务,并向客户端返回代表事务执行失败的空回复。

2. watch_keys字典:

每个Redis数据库都保存着一个watch_keys字典,这个字典的键是某个被Watch命令监视的数据库键,值则是一个链表,链表中记录了所有监视相应数据库键的客户端:

3. 监视机制的触发:

        所有对数据库进行修改的命令,在执行之后都会调用mutil.c/touchWatchKey函数对watch_keys字典进行检查,查看是否有客户端正在监视刚刚被命令修改的数据库键。如果有修改,那么touchWatchKey函数会将监视被修改键的客户端的REDIS_DIRTY_CAS标识打开,标识该客户端的事务安全性已经被破坏。

4. 判断事务是否安全:

        当服务器接收到一个客户端发来的Exec命令时,服务器会根据这个客户端是否打开了REDIS_DIRTY_CAS标识来决定是否执行事务。

四、事务的ACID性质

        在Redis中,事务总是具有原子性(Atomicity)、一致性(Consistency)和隔离性(Isolation),并且当Redis运行在某种特定的持久化模式下,事务也具有耐久性(Durability)

1. Redis的事务和传统关系型数据库事务的区别:

        Redis不支持事务回滚机制(rollback),即事务队列中的某个命令在执行期间出现了错误,整个事务也会继续执行下去,直到将事务队列中的所有命令都执行完毕为止。

2. Redis事务可能出错的三个地方:

  • 入队错误:

        命令不存在,或者命令的格式不正确(此时会提示错误),Redis将决绝执行这个事务。

  • 执行错误:

        不能再入队时被服务器发现的错误,这些错误只会在命令实际执行时被触发。

        即使在事务的执行过程中发生了错误,服务器也不会中断事务的执行,它会继续执行事务中余下的命令,并且已执行的命令(包括执行命令产生的结果)不会被出错的命令影响。

        出错的命令会被服务器识别出来,并进行响应的错误处理,这些出错的命令不会对数据库作出任何修改,也不会对事务的一致性产生任何影响。

  • 服务器停机:

        执行事务的过程中停机,那么根据服务器使用的持久化模式,可能有以下情况出现:

        如果服务器运行在无持久化的内存模式下,那么重启之后的数据库将是空白的,因此数据总是一致的。

        如果服务器运行在RDB模式下,那么在事务中途停机不会导致不一致性,因为服务器可以根据现有的RDB文件来恢复数据,从而将数据库还原到一个一致的状态。如果找不到可供使用的RDB文件,那么重启之后的数据库将是空白的,而空白数据库总是一致的。

        如果服务器运行在AOF模式下,那么在事务中途停机不会导致不一致性,因为服务器可以根据现有的AOF文件来恢复数据,从而将数据库还原到一个一致的状态。如果找不到可供使用的AOF文件,那么重启之后的数据库将是空白的,而空白数据库总是一致的。

3. Redis事务的耐久性由Redis所使用的持久化模式决定:

  • 当服务器在无持久化的内存模式下运作时,事务不具有耐久性:一旦服务器停机,包括事务数据在内的所有服务器数据都将丢失。
  • 当服务器在RDB持久化模式下运作时,服务器只会在特定的保存条件被满足时,才会执行 BGSAVE命令,对数据库进行保存操作,并且异步执行的 BGSAE不能保证事务数据被第一时间保存到硬盘里面,因此RDB持久化模式下的事务也不具有耐久性。
  • 当服务器运行在AOF持久化模式下,并且appendfsync选项的值为always时,程序总会在执行命令之后调用同步(syne)函数,将命令数据真正地保存到硬盘里面,因此这种配置下的事务是具有耐久性。
  • 当服务器运行在AOF持久化模式下,并且appendfsync选项的值为everysec时,程序会每秒同步一次命令数据到硬盘。因为停机可能会恰好发生在等待同步的那一秒钟之内,这可能会造成事务数据丢失,所以这种配置下的事务不具有耐久性。

五、重点回顾

  • 事务提供了一种将多个命令打包,然后一次性、有序地执行的机制。
  • 多个命令会被入列到事务队列中,然后按FIFO的顺序执行。
  • 事务咋执行过程中不会被中断,当事务队列中的所有命令都被执行完毕之后,事务才会结束。
  • 带有Watch命令的事务会将客户端和被监视的键在数据库的watched_keys字典中进行关联,当键被修改时,程序会将所有监视被修改键的客户端的Redis_DIRTY_CAS标识打开。
  • 只有在客户端的Redis_DIRTY_CAS标识未被打开是,服务器才会执行客户端提交的事务,否则,服务器拒绝执行客户端提交的事务。
  • Redis的事务总是具体ACID中原子性,一致性和隔离性,当服务器运行在AOF持久化模式下,并且appendfsync选项的值为always时,事务也具有耐久性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

dataX同步SQLserver到MySQL数据

引用datax官方描述&#xff1a; DataX 是阿里云 DataWorks数据集成 的开源版本&#xff0c;在阿里巴巴集团内被广泛使用的离线数据同步工具/平台。DataX 实现了包括 MySQL、Oracle、OceanBase、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS…

易用且免费的在线3D交互编辑器?

目前市面上的在线3D交互编辑器&#xff0c;有收费、免费、永久免费的。 1、博维数孪&#xff1a;永久免费的在线3D数字孪生应用平台&#xff0c;用户可以轻松创作和分享多种应用类型&#xff0c;包括3D交互展示、3D产品目录、交互式动画、3D产品配置器、交互式演示文稿、在线商…

webstorm无法识别tsconfig.json引用项目配置文件中的路径别名

问题 vite项目模板中&#xff0c;应用的ts配置内容写在tsconfig.app.json文件中&#xff0c;并在tsconfig.json通过项目引用的方式导入 {"files": [],"references": [{"path": "./tsconfig.app.json"},{"path": "./t…

Dominate_一个用于生成和操作 HTML 文档的 Python 库

目录 01初识 Dominate 什么是 Dominate&#xff1f; 为什么选择 Dominate&#xff1f; 安装与配置 02Dominate 的基本使用 创建简单的 HTML 文档 添加表格 嵌套结构 03Dominate 的高级功能 动态内容生成 使用…

【自动化测试】Selenium自动化测试框架 | 相关介绍 | Selenium + Java环境搭建 | 常用API的使用

文章目录 自动化测试一、selenium1.相关介绍1.Selenium IDE2.Webdriverwebdriver的工作原理&#xff1a; 3.selenium Grid 2.Selenium Java环境搭建3.常用API的使用1.定位元素2.操作测试对象3.添加等待4.打印信息5.浏览器的操作6.键盘事件7.鼠标事件8.定位一组元素9.多层框架定…

CO-DETR利用coco数据集训练和推理过程

CO-DETR利用coco数据集训练和推理过程&#xff0c;参考链接 Co-DETR训练自己的数据集 文章目录 前言训练过程推理过程总结 前言 环境&#xff1a;PyTorch 1.11.0 Python 3.8(ubuntu20.04) Cuda 11.3 先是在github上下载CO-DETR模型 !git clone https://github.com/Sense-X/Co…

新手教程系列 -- SQLAlchemy对同一张表联表两次

在开发过程中,我们经常会遇到对同一张表进行多次联表查询的需求。比如在查询航线时,我们希望将起飞和降落的机场名称代入结果中。为了实现这一目标,机场名称统一存放在 AirPort 表中。下面,我们将介绍如何通过 SQLAlchemy 实现这一需求。 问题描述 一般情况我们第一时间会…

针对VMWare无法使用鼠标功能键问题

在使用 VMWare 虚拟机的Ubuntu系统时发现无法使用许多鼠标带有额外的功能键&#xff0c;比如常用的前进后退&#xff0c;但是双系统中的Ubuntu没有问题&#xff0c;后来一搜发现是&#xff0c;虚拟系统中不支持这些功能键。因此我们对这个问题进行了解决。 解决方案 1.找到自…

Jenkins容器的部署

本文主要是记录如何在Centos7上安装docker,以及在docker里面配置tomcat、mysql、jenkins等环境。 一、安装docker 1.1 准备工作 centos7、VMware17Pro 1.2 通过yum在线安装dokcer yum -y install docker1.3 启动docker服务 systemctl start docker.service1.4 查看docke…

【AUTOSAR 基础软件】DEM模块详解(诊断故障管理)

文章包含了AUTOSAR基础软件&#xff08;BSW&#xff09;中DEM模块相关的内容详解。本文从ISO标准&#xff0c;AUTOSAR规范解析&#xff0c;ISOLAR-AB配置以及模块相关代码分析四个维度来帮读者清晰的认识和了解DEM这一基础软件模块。文中涉及的ISOLAR-AB配置以及模块相关代码都…

hive零基础入门

1、hive简介 hive&#xff1a;由facebook开源用于解决海量结构化数据的统计工具。 hive是基于Hadoop的数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张表&#xff0c;并提供sql查询功能。 2、hive本质 hive的本质是HQL&#xff08;HiveSQL&#xff09;转化成MapR…

【人工智能】—XGBoost、CatBoost、LightGBM算法构建信用卡欺骗识别模型

引言 在金融领域&#xff0c;信用卡欺诈行为一直是银行和金融机构面临的一大挑战。随着电子商务的快速发展&#xff0c;信用卡欺诈事件的数量和复杂性都在不断增加。据统计&#xff0c;全球每年因信用卡欺诈造成的损失高达数十亿美元。因此&#xff0c;开发有效的欺诈检测系统…

检索增强生成 (RAG):揭开这一术语的神秘面纱并解释其带来的价值

一、介绍 如今&#xff0c;数据已成为新的黄金&#xff0c;而高效筛选这些丰富信息的能力则是成功企业脱颖而出的关键。Retrieval Augmented Generation&#xff08;RAG&#xff09;是创新的标杆&#xff0c;尤其是在知识管理领域。它不再只是为了存储信息&#xff0c;而是为了…

半小时速通Python爬虫!GitHub开源的Python爬虫入门教程

今天给小伙伴们带来了一篇详细介绍 Python 爬虫入门的教程&#xff0c;从实战出发&#xff0c;适合初学者。 小伙伴们只需在阅读过程紧跟文章思路&#xff0c;理清相应的实现代码&#xff0c;30 分钟即可学会编写简单的 Python 爬虫。 这篇 Python 爬虫教程主要讲解以下 5 部…

爆款短视频素材库有哪些?分享几个容易火的视频素材网站

当今自媒体时代&#xff0c;每位内容创作者都渴望制作出下一个爆款短视频。你是否在寻找那些能让你的视频迅速蹭热度的顶级素材库&#xff1f;本文将为你介绍几个视频素材库&#xff0c;它们或许能成为你成功的秘密武器。首先要提的&#xff0c;自然是著名的国内素材库——蛙学…

信创加密沙箱,是如何应对国产化系统加密下的场景的?

SDC信创加密沙箱作为一款基于国产操作系统&#xff08;如麒麟、统信等&#xff09;设计的安全防护工具&#xff0c;以安全沙箱为核心概念&#xff0c;对沙箱内的数据和应用进行全面保护&#xff0c;保障业务系统和核心资料的安全。 信创加密沙箱的背景与意义 在当前复杂的网络…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【15】异步_线程池

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【15】异步_线程池 初始化线程的 4 种方式开发中为什么使用线程池线程池七大参数线程池工作原理常见的 4 种线程池生产中如何使用线程池&#xff1f;CompletableFuture 异步编排—简介业务…

SpringBoot防抖方案(防止表单重复提交)

SpringBoot防抖方案&#xff08;防止表单重复提交&#xff09; 1.应用场景&#xff08;什么是防抖&#xff09; 所谓防抖&#xff0c;一是防用户手抖&#xff0c;二是防网络抖动。在Web系统中&#xff0c;表单提交是一个非常常见的功能&#xff0c;如果不加控制&#xff0c;容…

最新AIGC系统源码-ChatGPT商业版系统源码,自定义ChatGPT指令Promp提示词,AI绘画系统,AI换脸、多模态识图理解文档分析

目录 一、前言 系统文档 二、系统演示 核心AI能力 系统快速体验 三、系统功能模块 3.1 AI全模型支持/插件系统 AI模型提问 文档分析 ​识图理解能力 3.2 GPts应用 3.2.1 GPTs应用 3.2.2 GPTs工作台 3.2.3 自定义创建Promp指令预设应用 3.3 AI专业绘画 3.3.1 文…

Linux——echo命令,管道符,vi/vim 文本编辑器

1.echo 命令 作用 向终端设备上输出字符串或变量的存储数据 格式 echo " 字符串 " echo $ 变 量名 [rootserver ~] # echo $SHELL # 输出变量的值必须加 $ /bin/bash [rootserver ~] # str1" 我爱中国 " # 自定义变量 echo 重定向输出到文件 ec…