Redis主从、哨兵、Redis Cluster集群架构

Redis主从、哨兵、Redis Cluster集群架构

Redis主从架构

Redis主从架构.png

Redis主从架构搭建

  • 主从搭建的问题
    • 如果同步数据失败,查看log日志
    • 报错无法连接,检查是否端口未开放
    • 出现”Error reply to PING from master:...“日志,修改参数protected-mode no

Redis主从复制原理

Redis主从复制原理.png

  • 详细流程
    • 如果你为master配置了一个slave,不管这个slave是否是第一次连接上master,它都会发送一个psync指令给master请求复制数据
    • master收到psync指令之后,会在后台进行数据持久化通过bgsave生成最新的rdb文件
    • 持久化期间,master会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存中
    • 当持久化完毕之后,master会把这份rdb文件数据集发送给slave,slave会把接收到的数据进行持久化生成rdb,然后再加载到内存中
    • 然后master再将之前缓存在内存中的命令发送给slave
    • 当master与slave之间的连接由于某些原因而断开的时候,slave能够自动重连master
    • 如果master收到了多个slave并发连接请求,它只会进行一次持久化,而不是一个连接一次,然后再把一份持久化的数据发送给多个并发连接的slave
  • 简概
    • 从节点每次都会向主节点发送psync同步指令,如果是首次连接,主节点会开启bgsave子线程进行全量数据复制并且生成rdb文件,并且在持久化期间会将从节点新的写命令缓存下来,当持久化结束后,主节点将rdb文件同步给从节点进行持久化,如果同步期间存在网络波动,从节点会进行重连,恢复连接后,主节点会将部分缺失的数据同步给从节点

数据部分复制(断点续传)

主从复制流程图.png

  • 当master和slave断开重连后,一般都会对整份数据进行复制。但从Redis 2.8之后,Redis开始改用支持部分数据复制的命令psync去master同步数据,slave和master能够在网络连接断开重连之后只进行部分数据复制(断点续传)
  • master会在其内存中创建一个复制数据用的缓存队列,缓存最近一段时间的数据,master和它所有的slave都维护了复制的数据下标offset和master的进程id,因此当网络连接断开后,slave会请求master继续进行未完成的复制,从所记录的数据下标开始。如果master进程id变化了,或者从节点数据下标offset太旧,已经不在master的缓存队列里了,那么将会进行一次全量数据的复杂

主从复制风暴

image.png

  • 如果有很多从节点,为了缓解主从复制风暴(多个节点同时复制主节点导致主节点压力过大),我们可以让部分从节点与从节点(与主节点同步)同步数据,也就是分层结构

Redis哨兵架构

Redis哨兵高可用架构.png

哨兵模式

  • 主从复制存在不能自动故障转移、达不到高可用的功能,哨兵模式解决了这些问题,通过哨兵机制可以自动切换主从节点,客户端连接Redis的时候,先连接哨兵,哨兵会告诉客户端Redis主节点的地址,然后客户端连接上Redis进行后续的操作,当主节点宕机的时候,哨兵监测到主节点宕机,会重新推选出过半选举后的从节点作为新的主节点,然后通过发布订阅模式通知其他从节点,让它们切换主机
  • 哨兵是特殊的Redis服务,不提供读写服务,主要是用来监控Redis实例节点

哨兵集群选举流程

  • 每个sentinel每秒钟向master节点进行ping,当master回复时间超过指定值会被标记为主观下线,如果master节点被标记为主观下线,那么正在监视这个master节点的所有sentinel都会ping去确认是否真的主观下线,当有足够数量的sentinel确认master节点主观下线,那么master会被标记为客观下线,反之解除标记

  • 每个发现master节点进入客观下线的sentinel都会要求其他sentinel将自己设置为局部leader选举是先到先得的,同时每个sentinel每次选举都会自增epoch,而每个纪元只会选择出一个sentinel作为局部leader,如果所有超过一半的sentinel选举某个sentinel作为局部leader,之后这个sentinel会进行故障转移,从存活的slave节点中选举出新的master节点,这个选举过程跟集群的master选举很类似的

  • 如果哨兵集群只有一个sentinel节点,Redis的主从节点也能正常运行以及选举master,如果master挂了,那唯一的sentinel节点就是局部leader

  • 注意情况

    • 哨兵集群虽然也是可以选举leader,但是哨兵架构配置复杂,只会提供一个master节点进行对外服务,还是不能解决线上并发问题,而且哨兵模式还会出现访问瞬断问题,基于以上情况,我们可以选择Redis集群架构,集群架构也能进行选举,而且是配置多主多从的,配置简单,性能上远远高于哨兵模式

Redis Cluster集群架构

哨兵模式的缺陷

  • 在Redis 3以前的版本要实现集群一般是借助哨兵SentInel工具来监控master节点的状态,如果master节点异常,就会做主从切换,将某一台slave作为master,哨兵的配置略微复杂,并且性能和高可用等各方面表现一般,特别是在主从切换的瞬间存在访问瞬断的情况,而且哨兵模式只有一个主节点对外提供服务,没法支持很高的并发,并且单个主节点内存页不适合设置得过大,否则会导致持久化文件过大,影响数据恢复或主从同步的效率
    • Sentinel模式的主从切换出现访问瞬断的问题,该怎么解决呢?
      • 集群架构已经包括了Sentinel模式

Redis Cluster集群模式

Redis高可用集群模式.png

  • Redis集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性
  • Redis集群不需要Sentinel哨兵,也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中心节点,可水平扩展,据官方文档称可以线性扩展到上万个节点,官方推荐不超过1k节点)
  • Redis集群的性能和高可用性均优于之前版本的哨兵模式,并且集群配置非常简单

Redis集群原理分析

  • Redis Cluster将所有数据划分为16384个slots(Redis集群没有使用一致性hash),每个节点负责其中一部分slots,slots的信息存储于每个节点中
    • 槽位定位算法
      • Redis集群默认会对key值使用CRC16算法进行hash得到一个整数值,然后用这个整数值对16384进行取模来得到具体槽位
      • HASH_SLOT = CRC16(key) mod 16384
  • Redis Cluster的客户端来连接集群时,它也会得到一份集群的slots配置信息并且将其缓存在客户端本地,这样当客户端要查找某个key的时候,可以直接定位到目标节点,同时因为slots的信息可能会存在客户端与服务器不一致的问题,还需要纠正机制来实现槽位信息的校验调整
    • 跳转重定位
      • 当客户端向一个错误的节点发出了指令,该节点会发现指令的key所在的槽位并不归自己管理,这时它会向客户端发送一个特殊的跳转指令携带目标操作的节点地址,告诉客户端去连这个节点去获取数据
      • 客户端收到指令后除了跳转到正确的节点上去操作,还会同步更新纠正本地的槽位映射表缓存,后续所有key将使用新的槽位映射表

Redis集群节点间的通信机制

  • 集中式(如zookeeper)

    • 优点在于元数据的更新和读取,时效性非常好,一旦数据出现变更立即就会更新到集中式的存储中吗,其他节点读取的时候立即就能感知到
    • 不足在于所有的元数据的更新压力全部集中在一个地方,可能导致元数据的存储压力
    • 很多中间件都会借助zookeeper集中式存储数据
  • gossip协议(默认)

    • ping:节点之间互相发送ping交换元数据信息
    • pong:对ping和meet消息的返回,包含自己的状态和其他信息,也可以用于信息广播和更新
    • meet: 某个节点发送meet给新加入的节点,让新节点加入集群中,然后新节点就会开始与其他节点进行通信
    • fail:某个节点判断另一个节点fail之后,就发送fail给其他节点,通知其他节点,指定的节点宕机了
    • gossip.gif
  • gossip协议优缺点

    • 优点:元数据的更新比较分散,不是集中在一个地方,更新请求会陆陆续续,打到所有节点上去更新,有一定的延时,降低了压力
    • 缺点:元数据更新有延时可能导致集群的一些操作会有一些滞后
  • 网络抖动

    • 问题: 假如不同的机房网络不太好的情况下,突然节点之间访问延迟不了的情况(过几秒又连接上了),为了避免因为这种场景而导致Cluster频繁切换(数据的重新赋值)造成性能消耗,该如何解决?
      • Redis Cluster提供cluster-node-timeout,表示如果超过这个时间,则认定节点出现故障,需要切换

Redis集群选举原理

  • 当slave发现自己的master变为FAIL状态时,便会尝试进行Failover,以期待成为新的master,由于挂掉的master可能会有多个slave,从而存在多个slave竞争成master节点的过程

    • slave发现自己的master变为FAIL
    • 将自己记录的集群currentEpoch加1,并广播FAILOVER_AUTH_REQUEST信息
    • 其他节点收到该信息(只有master响应),判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每一个epoch只发送一次ack
    • 尝试failover的slave收集master返回的FAILOVER_AUTH_ACK
    • slave收到超过半数master的ack后变为新master(这里解释了集群为什么至少需要三个主节点,如果只有两个,当其中一个节点挂了,只剩一个主节点是不能选举成功的)
    • slave广播pong消息通知其他集群节点
  • 问题: 如果重新选举时出现同一时刻多个slave发送请求给master节点进行选举,可能会出现选举失败,而且还可能会多次失败,如果避免此问题

    • 延迟每个节点发送重新选举的时间: DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms
      • SLAVE_RANK
        • 表示slave已经从master复制数据的总量的rank,rank越小代表已经复制的数据越新(理论上持有最新数据的slave将会首先发起选举)

Redis集群脑裂数据丢失问题

  • Redis集群没有过半机制会有脑裂问题

  • 网络分区导致脑裂后出现多个主节点对外提供写服务,一旦网络恢复,会将其中一个主节点变成从节点,(因为从节点初始化或启动时会删除本地的所有数据,然后再从主节点同步数据)这时会有大量数据丢失

  • 解决方案: min-replicas-to-write 1 ,写数据成功的前提是最少同步的slave节点数,这种机制类似zookeeperzab机制,比如集群共三个,加上master就是2个节点,超过半数

    • 注意:脑裂问题的解决方案有个弊端,如果需要至少一个slave节点同步数据成功才算成功的话,就可能引发另一个问题,Redis本就是AP机制(可以看CAP机制),如果改变这样的机制,使其成为CP机制,一旦slave节点写入失败,就会造成Redis返回失败,就牺牲了可用性,这样就违背了Redis的初衷

      • CAP含义
        • C表示一致性,访问所有的节点得到的数据应该是一样的
        • A表示可用性,所有的节点都保持高可用性
        • P表示分区容错性,这里的分区是指网络意义上的分区,由于网络是不可靠的,所有节点之间很可能出现无法通讯的情况,在节点不能通信时,要保证系统可以继续正常服务
        • image.png
    • 分析: Redis和Zookeeper的脑裂问题以及解决方案都很类似,都是需要半数或半数以上数据同步成功才能避免脑裂问题

  • 集群是否只有在完整的情况才能对外提供服务

    • 当Redis的配置文件中cluster-require-full-coverage no时,表示当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群仍然可用,如果为yes则集群不可用。
  • 问题: Redis集群为什么至少需要三个master节点,并且推荐节点数为奇数

    • 因为新master的选举需要大于半数的集群master节点同意才能选举成功,如果只有两个master节点,其中一个挂了,是达不到选举新的master的条件的

    • 3个master节点和4个master节点的场景

    • 奇数master节点可以在满足选举该条件的基础上节省一个节点

      • 3个或者4个master节点如果挂了一个节点,是可以重新选举新的master节点
      • 3个或4个master节点如果挂了两个节点,就都无法选举出新的master节点了(无法满足半数以及以上)
    • 所以奇数的master节点更多的是从节省机器资源角度出发的

  • Redis集群对大批量操作命令的支持

    • Redis集群支持将key落到同一个slots中

    • 解决方案: 数据分片时,hash计算的只会是大括号里的值,确保不同的key落到同一个slots中

    • 例子

      • **mset {user1}:1:name linc {user1}:1:age 18 **
  • Redis集群架构下的数据倾斜问题如何解决

    • 使用本地缓存

    • 使用分片算法的特性,对key进行打散处理

    • big key形成集群数据倾斜,对big key进行拆分

总结

  • 问题: Redis的主从复制原理

    • 从节点每次都会向主节点发送psync同步指令,如果是首次连接,主节点会开启bgsave子线程进行全量数据复制并且生成rdb文件,并且在持久化期间会将从节点新的写命令缓存下来,当持久化结束后,主节点将rdb文件同步给从节点进行持久化,如果同步期间存在网络波动,从节点会进行重连,恢复连接后,主节点会将部分缺失的数据同步给从节点

    • 问题: 主从复制会有什么问题

      • 主从复制会带来主从复制风暴问题
        • 如果有很多从节点,为了缓解主从复制风暴(多个节点同时复制主节点导致主节点压力过大),我们可以让部分从节点与从节点(与主节点同步)同步数据,也就是分层结构
  • 问题: 哨兵模式的缺陷

    • 哨兵模式不适合线上高并发场景,主从切换会导致访问瞬断,以及只是监控master节点,并不做转发,最终还是单节点master提供访问,性能并没有提升多少
    • 高可用集群模式不仅很好的弥补了哨兵模式的缺点,而且还具备了哨兵模式的选举机制,所以推荐在生产环境使用
  • 问题: Redis集群的数据是怎么存储的

    • Redis集群的所有数据被划分到16384个槽位中,并且每个节点管理一部分的槽位,而到客户端连接集群的时候会去缓存一份槽位信息方便定位到目标节点,但是缓存的槽位信息可能会存在数据不一致的问题,所以Redis集群提供了纠错机制,当客户端通过槽位信息去定位目标节点的时候发现异常,集群会帮忙纠错并且重定位到目标节点以及缓存一份新的槽位信息给客户端
    • 定位是通过CRC算法进行位运算的
  • 问题: ZK和Redis的通信机制

    • ZK是集中式存储数据的,时效性好,但是会有数据存储压力,Redis是gossip协议的,数据存储被分散开了,时效性稍微滞后
  • 问题: Redis集群选举原理

    • 当slave发现自己的master挂掉了,就会尝试进行故障转移,期待自己成为新的master,首先会将自己记录集群的epoch进行加1,并且广播通知给其他存活的master节点,让他们来判断请求者是否合法,如果合法,就只会给每一个epoch发送一次ack,尝试故障转移的slave收到超过一半的master节点的同意的ack信息,就会成为新的master,然后广播通知其他集群的节点自己成为新的master了
    • 注意: 建议设置3个以上的奇数master节点
      • 问题: Redis集群为什么至少需要三个master节点,并且推荐节点数为奇数
        • 因为新master的选举需要大于半数的集群master节点同意才能选举成功,如果只有两个master节点,其中一个挂了,是达不到选举新的master的条件的
        • 例子
          • 3个master节点和4个master节点的场景
            • 奇数master节点可以在满足选举该条件的基础上节省一个节点
            • 3个或者4个master节点如果挂了一个节点,是可以重新选举新的master节点
            • 3个或4个master节点如果挂了两个节点,就都无法选举出新的master节点了(无法满足半数以及以上)
        • 所以奇数的master节点更多的是从节省机器资源角度出发的
      • 问题: 如果重新选举时出现同一时刻多个slave发送请求给master节点进行选举,可能会出现选举失败,而且还可能会多次失败,如果避免此问题
        • 集群选举并不一定是一次就能成功的,假如同一时刻有多个slave节点发送信息给maste节点,master节点可能会同时发送到所有slave节点,如果slave节点收到的结果都是各自持有一票,这样就会再次重新选举,我们可以通过参数设置slave发送信息给master的时间,避免让所有slave同一时刻发送信息
  • 问题: Redis集群的脑裂问题

    • Redis集群没有过半机制会有脑裂问题
    • 网络分区导致出现多个master节点,一旦网络恢复了,会将其中一个master变成slave,而变成从节点后会将从节点本地数据清空,同步master节点的rdb快照数据
    • 如果变成slave节点的,服务数据是最新的,而另外一个master节点不是最新的,这样直接从master同步数据,就会出现数据丢失问题
    • Redis也有解决脑裂问题的方案,但是是牺牲性能换来的,可以通过设置参数,让半数节点数据同步成功之后才能响应客户端,避免脑裂问题,但是性能却大大降低了,这个其实就违背了Redis的AP机制
    • Redis和ZK的脑裂问题以及解决方案都很类似,都是需要半数或半数以上数据同步成功才能避免脑裂问题
      • 问题: CAP理论
        • CAP理论是分布式领域⾮常重要的⼀个理论,很多分布式中间件在实现时都需要遵守这个理论
          • C表示⼀致性:指的的是分布式系统中的数据的⼀致性
          • A表示可⽤性:表示分布式系统是否正常可⽤
          • P表示分区容错性:表示分布式系统出现⽹络问题时的容错性
        • CAP理论是指在分布式系统中不能同时保证C和A,也就是说在分布式系统中要么保证CP,要么保证 AP,也就是⼀致性和可⽤性只能取其⼀,如果想要数据的⼀致性,那么就需要损失系统的可⽤性,如果需要系统⾼可⽤,那么就要损失系统的数据⼀致性,特指强⼀致性
        • CAP理论太过严格,在实际⽣产环境中更多的是使⽤BASE理论,BASE理论是指分布式系统不需要保证数据的强⼀致,只要做到最终⼀致,也不需要保证⼀直可⽤,保证基本可⽤即可
  • 问题: Redis集群架构下的数据倾斜问题如何解决

    • 使用本地缓存

    • 使用分片算法的特性,对key进行打散处理

    • big key形成集群数据倾斜,对big key进行拆分

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

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

相关文章

《乱弹篇(十八)天灾人祸》

昨天午后笔者发表《贵州山火频发,令人扼腕痛惜》一文后,昨晚和今日上午又见社交网站上媒体发表的最新消息报道《南京一小区火灾已造成15死44伤,市长鞠躬道歉》《南京“223”火灾15死44伤:为啥1楼起火烧到了30层?除了电…

C/C++文件操作

一、文本文件操作 1、写文件操作 代码 #include<fstream> #include<iostream>int main() {ofstream outfile("Student.txt", ios::out);if (!outfile) {cout << "文件写入失败" << endl;exit(0); //程序终止}cout << &qu…

k8s-kubeapps部署 20

部署kubeapps应用&#xff0c;为Helm提供web UI界面管理&#xff1a; 下载最新版本的kubeapps并修改其values.yaml文件 下载并拉取所需镜像&#xff1a; 部署应用 添加解析 修改svc暴露方式为LoadBalancer 得到分配地址 访问http://192.168.182.102 授权并获取token 1.24前的…

LeetCode 1038.从二叉搜索树到更大和树

给定一个二叉搜索树 root (BST)&#xff0c;请将它的每个节点的值替换成树中大于或者等于该节点值的所有节点值之和。 提醒一下&#xff0c; 二叉搜索树 满足下列约束条件&#xff1a; 节点的左子树仅包含键 小于 节点键的节点。 节点的右子树仅包含键 大于 节点键的节点。 左…

Orange3数据预处理(列选择组件)数据角色及类型描述

在Orange3的文件组件中&#xff0c;datetime、categorical、numeric以及text代表不同种类的数据类型&#xff0c;具体如下&#xff1a; datetime&#xff1a;代表日期和时间类型的数据。通常用于时间序列分析、生存分析和其他需要考虑时间因素的机器学习任务中。例如&#xff0…

【Linux】部署前后端分离项目---(Nginx自启,负载均衡)

目录 前言 一 Nginx&#xff08;自启动&#xff09; 2.1 Nginx的安装 2.2 设置自启动Nginx 二 Nginx负载均衡tomcat 2.1 准备两个tomcat 2.1.1 复制tomcat 2.1.2 修改server.xml文件 2.1.3 开放端口 2.2 Nginx配置 2.2.1 修改nginx.conf文件 2.2.2 重启Nginx服务 2…

【动态规划题目讲解】AGC026D - Histogram Coloring

[ A G C 026 D ] H i s t o g r a m C o l o r i n g \mathrm{[AGC026D] Histogram\ Coloring} [AGC026D]Histogram Coloring D e s c r i p t i o n \mathrm{Description} Description 给定 N N N 列的网格&#xff0c;每列高为 h i h_i hi​&#xff0c;将每个格子染色成红…

鸿蒙开发【WebGL】简单了解

WebGL的全称为Web Graphic Library(网页图形库)&#xff0c;主要用于交互式渲染2D图形和3D图形。目前HarmonyOS中使用的WebGL是基于OpenGL裁剪的OpenGL ES&#xff0c;可以在HTML5的canvas元素对象中使用&#xff0c;无需使用插件&#xff0c;支持跨平台。WebGL程序是由JavaScr…

什么是抖音视频下载软件|视频批量下载|爬虫工具

抖音视频抓取软件是一款方便用户获取抖音平台上视频内容的工具。它具备以下主要功能&#xff1a; 批量视频提取&#xff1a;用户可以输入关键词&#xff0c;软件将自动搜索抖音平台上与关键词相关的视频&#xff0c;并将它们列出供用户选择和下载。用户可以随时停止搜索和下载过…

【数电】一文带你轻松搞定奇偶校验原理与规则(案例演示)

前言 大家好吖&#xff0c;欢迎来到 YY 滴单片机系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的…

STM32 HAL库移植MPU6050 DMP库(跟着做就能成功)

STM32移植MPU6050 DMP库&#xff08;跟着做就能成功&#xff09; 0.前言一、使用CubeMX建立工程二、移植DMP库修改&#xff1a;注意&#xff1a; 使用 三、总结 0.前言 最近捣鼓FreeRTOS时需要使用一个MPU6050姿态传感器&#xff0c;到处扒拉例程时发现各式各样的教程都不太满意…

游戏 CP 专访| InOutPath 技术干货分享!

“ 编辑语&#xff1a;STEAM 上的 3D 解密游戏《InOutPath》以其清新的画面&#xff0c;独特的玩法&#xff0c;受到了广大 STEAM 玩家&#xff0c;以及 Cocos 开发者们的关注。今天有幸邀请到了这款游戏的开发商&#xff0c;为大家做一次技术分享。希望能够对在用 Cocos Creat…

【数据结构与算法】(14)基础算法 之AVL 树相关示例 详细代码讲解

目录 3.4 红黑树概述历史红黑树特性 实现插入情况删除情况完整代码小结 3.4 红黑树 概述 历史 红黑树是一种自平衡二叉查找树&#xff0c;最早由一位名叫Rudolf Bayer的德国计算机科学家于1972年发明。然而&#xff0c;最初的树形结构不是现在的红黑树&#xff0c;而是一种称…

关于js [GDOUCTF 2023]hate eat snake

查看页面源代码 发现snake.js文件 打开js文件 第7行定义了游戏的速度this.speed this.oldSpeed speed || 10 ; 全文搜索speed&#xff0c;在第237行发现自增代码this.speed; 注释或者删除自增代码 回到游戏页面 重玩游戏&#xff0c;等待60s即可 得到flag

Swift Combine 使用 handleEvents 操作符调试管道 从入门到精通二十五

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三Swift Combine 发布者publisher的生命周期 从入门到精通四Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五Swift Com…

【微服务】mybatis typehandler使用详解

目录 一、前言 二、TypeHandler简介 2.1 什么是TypeHandler 2.1.1 TypeHandler特点 2.2 TypeHandler原理 2.3 mybatis自带的TypeHandler 三、环境准备 3.1 准备一张数据表 3.2 搭建一个springboot工程 3.2.1 基础依赖如下 3.2.2 核心配置文件 3.2.3 测试接口 四、T…

d3dcompiler_47.dll是什么,电脑出现d3dcompiler_47.dll丢失如何解决

当打开软件时提示“d3dcompiler_47.dll丢失”时&#xff0c;用户通常会看到类似于以下的错误消息&#xff1a; “无法启动此程序&#xff0c;因为计算机中丢失了d3dcompiler_47.dll。尝试重新安装该程序以解决此问题。” “找不到d3dcompiler_47.dll文件&#xff0c;因此应用…

破译一致性难题:Raft日志复制技术及成员变更问题详解

一、日志复制 Raft 算法是一种用于实现分布式系统中一致性状态机复制的共识算法。在 Raft 中&#xff0c;日志复制是保证集群数据一致性的关键机制。每个节点&#xff08;服务器&#xff09;都维护着一个日志&#xff0c;其中包含一系列的日志条目&#xff08;Log Entry&#x…

在 where子句中使用子查询(二)

目录 ANY ANY &#xff1a;功能上与 IN 是没有任何区别的 >ANY &#xff1a;比子查询返回的最小值要大 ALL >AL &#xff1a;比子查询返回的最大值要大 EXISTS() 判断 NOT EXISTS Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209…

Open3D 点云法向量计算与可视化 (25)

Open3D 点云法向量计算与可视化 (25) 一、算法原理二、算法实现三、可视化显示和长度调节一、算法原理 通常计算点云的法向量可以使用以下两种常见的方法: 最小二乘法(Least Squares Method):该方法通过拟合局部表面的平面来计算法向量。对于给定点周围的邻域,可以通过…