Kafka学习笔记之Kafka High Availability(下)

2023-05-16

0x00 摘要

  本文在上篇文章基础上,更加深入讲解了Kafka的HA机制,主要阐述了HA相关各种场景,如Broker failover,Controller failover,Topic创建/删除,Broker启动,Follower从Leader fetch数据等详细处理过程。同时介绍了Kafka提供的与Replication相关的工具,如重新分配Partition等。

 

0x01 Broker Failover过程

1.1 Controller对Broker Failure的处理过程

    1. Controller在Zookeeper的/brokers/ids节点上注册Watch。一旦有Broker宕机(本文用宕机代表任何让Kafka认为其Broker die的情景,包括但不限于机器断电,网络不可用,GC导致的Stop The World,进程crash等),其在Zookeeper对应的Znode会自动被删除,Zookeeper会fire Controller注册的Watch,Controller即可获取最新的幸存的Broker列表。
    2. Controller决定set_p,该集合包含了宕机的所有Broker上的所有Partition。
    3. 对set_p中的每一个Partition:
        3.1 从/brokers/topics/[topic]/partitions/[partition]/state读取该Partition当前的ISR。
        3.2 决定该Partition的新Leader。如果当前ISR中有至少一个Replica还幸存,则选择其中一个作为新Leader,新的ISR则包含当前ISR中所有幸存的Replica。否则选择该Partition中任意一个幸存的Replica作为新的Leader以及ISR(该场景下可能会有潜在的数据丢失)。如果该Partition的所有Replica都宕机了,则将新的Leader设置为-1。
        3.3 将新的Leader,ISR和新的leader_epochcontroller_epoch写入/brokers/topics/[topic]/partitions/[partition]/state。注意,该操作只有Controller版本在3.1至3.3的过程中无变化时才会执行,否则跳转到3.1。
    4. 直接通过RPC向set_p相关的Broker发送LeaderAndISRRequest命令。Controller可以在一个RPC操作中发送多个命令从而提高效率。
        Broker failover顺序图如下所示。

 

 LeaderAndIsrRequest结构如下

 

 LeaderAndIsrResponse结构如下

 

 

1.2 创建/删除topic

    1. Controller在Zookeeper的/brokers/topics节点上注册Watch,一旦某个Topic被创建或删除,则Controller会通过Watch得到新创建/删除的Topic的Partition/Replica分配。
    2. 对于删除Topic操作,Topic工具会将该Topic名字存于/admin/delete_topics。若delete.topic.enable为true,则Controller注册在/admin/delete_topics上的Watch被fire,Controller通过回调向对应的Broker发送StopReplicaRequest;若为false则Controller不会在/admin/delete_topics上注册Watch,也就不会对该事件作出反应,此时Topic操作只被记录而不会被执行。
    3. 对于创建Topic操作,Controller从/brokers/ids读取当前所有可用的Broker列表,对于set_p中的每一个Partition:
        3.1 从分配给该Partition的所有Replica(称为AR)中任选一个可用的Broker作为新的Leader,并将AR设置为新的ISR(因为该Topic是新创建的,所以AR中所有的Replica都没有数据,可认为它们都是同步的,也即都在ISR中,任意一个Replica都可作为Leader)
        3.2 将新的Leader和ISR写入/brokers/topics/[topic]/partitions/[partition]
    4. 直接通过RPC向相关的Broker发送LeaderAndISRRequest。
        创建Topic顺序图如下所示。

 

 

1.3 Broker响应请求流程

  Broker通过kafka.network.SocketServer及相关模块接受各种请求并作出响应。整个网络通信模块基于Java NIO开发,并采用Reactor模式,其中包含1个Acceptor负责接受客户请求,N个Processor负责读写数据,M个Handler处理业务逻辑。
  Acceptor的主要职责是监听并接受客户端(请求发起方,包括但不限于Producer,Consumer,Controller,Admin Tool)的连接请求,并建立和客户端的数据传输通道,然后为该客户端指定一个Processor,至此它对该客户端该次请求的任务就结束了,它可以去响应下一个客户端的连接请求了。其核心代码如下。

 

   Processor主要负责从客户端读取数据并将响应返回给客户端,它本身并不处理具体的业务逻辑,并且其内部维护了一个队列来保存分配给它的所有SocketChannel。Processor的run方法会循环从队列中取出新的SocketChannel并将其SelectionKey.OP_READ注册到selector上,然后循环处理已就绪的读(请求)和写(响应)。Processor读取完数据后,将其封装成Request对象并将其交给RequestChannel。
  RequestChannel是Processor和KafkaRequestHandler交换数据的地方,它包含一个队列requestQueue用来存放Processor加入的Request,KafkaRequestHandler会从里面取出Request来处理;同时它还包含一个respondQueue,用来存放KafkaRequestHandler处理完Request后返还给客户端的Response。
  Processor会通过processNewResponses方法依次将requestChannel中responseQueue保存的Response取出,并将对应的SelectionKey.OP_WRITE事件注册到selector上。当selector的select方法返回时,对检测到的可写通道,调用write方法将Response返回给客户端。
  KafkaRequestHandler循环从RequestChannel中取Request并交给kafka.server.KafkaApis处理具体的业务逻辑。

 

1.4 LeaderAndIsrRequest响应过程

  对于收到的LeaderAndIsrRequest,Broker主要通过ReplicaManager的becomeLeaderOrFollower处理,流程如下:

  1. 若请求中controllerEpoch小于当前最新的controllerEpoch,则直接返回ErrorMapping.StaleControllerEpochCode。
  2. 对于请求中partitionStateInfos中的每一个元素,即((topic, partitionId), partitionStateInfo):
      2.1 若partitionStateInfo中的leader epoch大于当前ReplicManager中存储的(topic, partitionId)对应的partition的leader epoch,则:
        2.1.1 若当前brokerid(或者说replica id)在partitionStateInfo中,则将该partition及partitionStateInfo存入一个名为partitionState的HashMap中
        2.1.2否则说明该Broker不在该Partition分配的Replica list中,将该信息记录于log中
      2.2否则将相应的Error code(ErrorMapping.StaleLeaderEpochCode)存入Response中
  3. 筛选出partitionState中Leader与当前Broker ID相等的所有记录存入partitionsTobeLeader中,其它记录存入partitionsToBeFollower中。
  4. 若partitionsTobeLeader不为空,则对其执行makeLeaders方。
  5. 若partitionsToBeFollower不为空,则对其执行makeFollowers方法。
  6. 若highwatermak线程还未启动,则将其启动,并将hwThreadInitialized设为true。
  7. 关闭所有Idle状态的Fetcher。

  LeaderAndIsrRequest处理过程如下图所示

 

 

1.5 Broker启动过程

  Broker启动后首先根据其ID在Zookeeper的/brokers/idszonde下创建临时子节点(Ephemeral node),创建成功后Controller的ReplicaStateMachine注册其上的Broker Change Watch会被fire,从而通过回调KafkaController.onBrokerStartup方法完成以下步骤:

  1. 向所有新启动的Broker发送UpdateMetadataRequest,其定义如下。

 

  2. 将新启动的Broker上的所有Replica设置为OnlineReplica状态,同时这些Broker会为这些Partition启动high watermark线程。

  3. 通过partitionStateMachine触发OnlinePartitionStateChange。

 

1.6 Controller Failover

  Controller也需要Failover。每个Broker都会在Controller Path (/controller)上注册一个Watch。当前Controller失败时,对应的Controller Path会自动消失(因为它是Ephemeral Node),此时该Watch被fire,所有“活”着的Broker都会去竞选成为新的Controller(创建新的Controller Path),但是只会有一个竞选成功(这点由Zookeeper保证)。竞选成功者即为新的Leader,竞选失败者则重新在新的Controller Path上注册Watch。因为Zookeeper的Watch是一次性的,被fire一次之后即失效,所以需要重新注册。

Broker成功竞选为新Controller后会触发KafkaController.onControllerFailover方法,并在该方法中完成如下操作:

  1. 读取并增加Controller Epoch。
  2. 在ReassignedPartitions Path(/admin/reassign_partitions)上注册Watch。
  3. 在PreferredReplicaElection Path(/admin/preferred_replica_election)上注册Watch。
  4. 通过partitionStateMachine在Broker Topics Patch(/brokers/topics)上注册Watch。
  5. delete.topic.enable设置为true(默认值是false),则partitionStateMachine在Delete Topic Patch(/admin/delete_topics)上注册Watch。
  6. 通过replicaStateMachine在Broker Ids Patch(/brokers/ids)上注册Watch。
  7. 初始化ControllerContext对象,设置当前所有Topic,“活”着的Broker列表,所有Partition的Leader及ISR等。
  8. 启动replicaStateMachine和partitionStateMachine。
  9. 将brokerState状态设置为RunningAsController。
  10. 将每个Partition的Leadership信息发送给所有“活”着的Broker。
  11. auto.leader.rebalance.enable配置为true(默认值是true),则启动partition-rebalance线程。
  12. delete.topic.enable设置为true且Delete Topic Patch(/admin/delete_topics)中有值,则删除相应的Topic。

 

1.7 Partition重新分配

管理工具发出重新分配Partition请求后,会将相应信息写到/admin/reassign_partitions上,而该操作会触发ReassignedPartitionsIsrChangeListener,从而通过执行回调函数KafkaController.onPartitionReassignment来完成以下操作:

    1. 将Zookeeper中的AR(Current Assigned Replicas)更新为OAR(Original list of replicas for partition) + RAR(Reassigned replicas)。
    2. 强制更新Zookeeper中的leader epoch,向AR中的每个Replica发送LeaderAndIsrRequest。
    3. 将RAR - OAR中的Replica设置为NewReplica状态。
    4. 等待直到RAR中所有的Replica都与其Leader同步。
    5. 将RAR中所有的Replica都设置为OnlineReplica状态。
    6. 将Cache中的AR设置为RAR。
    7. 若Leader不在RAR中,则从RAR中重新选举出一个新的Leader并发送LeaderAndIsrRequest。若新的Leader不是从RAR中选举而出,则还要增加Zookeeper中的leader epoch。
    8. 将OAR - RAR中的所有Replica设置为OfflineReplica状态,该过程包含两部分。第一,将Zookeeper上ISR中的OAR - RAR移除并向Leader发送LeaderAndIsrRequest从而通知这些Replica已经从ISR中移除;第二,向OAR - RAR中的Replica发送StopReplicaRequest从而停止不再分配给该Partition的Replica。
    9. 将OAR - RAR中的所有Replica设置为NonExistentReplica状态从而将其从磁盘上删除。
    10. 将Zookeeper中的AR设置为RAR。
    11. 删除/admin/reassign_partition
        
      注意:最后一步才将Zookeeper中的AR更新,因为这是唯一一个持久存储AR的地方,如果Controller在这一步之前crash,新的Controller仍然能够继续完成该过程。
        以下是Partition重新分配的案例,OAR = {1,2,3},RAR = {4,5,6},Partition重新分配过程中Zookeeper中的AR和Leader/ISR路径如下

 

 

1.8 Follower从Leader Fetch数据

  Follower通过向Leader发送FetchRequest获取消息,FetchRequest结构如下

 

   从FetchRequest的结构可以看出,每个Fetch请求都要指定最大等待时间和最小获取字节数,以及由TopicAndPartition和PartitionFetchInfo构成的Map。实际上,Follower从Leader数据和Consumer从Broker Fetch数据,都是通过FetchRequest请求完成,所以在FetchRequest结构中,其中一个字段是clientID,并且其默认值是ConsumerConfig.DefaultClientId。

   Leader收到Fetch请求后,Kafka通过KafkaApis.handleFetchRequest响应该请求,响应过程如下:

  1. replicaManager根据请求读出数据存入dataRead中。
  2. 如果该请求来自Follower则更新其相应的LEO(log end offset)以及相应Partition的High Watermark
  3. 根据dataRead算出可读消息长度(单位为字节)并存入bytesReadable中。
  4. 满足下面4个条件中的1个,则立即将相应的数据返回
  • Fetch请求不希望等待,即fetchRequest.macWait <= 0
  • Fetch请求不要求一定能取到消息,即fetchRequest.numPartitions <= 0,也即requestInfo为空
  • 有足够的数据可供返回,即bytesReadable >= fetchRequest.minBytes
  • 读取数据时发生异常
  1. 若不满足以上4个条件,FetchRequest将不会立即返回,并将该请求封装成DelayedFetch。检查该DeplayedFetch是否满足,若满足则返回请求,否则将该请求加入Watch列表

  Leader通过以FetchResponse的形式将消息返回给Follower,FetchResponse结构如下

 

 

0x02 Replication工具

2.1 Topic Tool

  $KAFKA_HOME/bin/kafka-topics.sh,该工具可用于创建、删除、修改、查看某个Topic,也可用于列出所有Topic。另外,该工具还可修改以下配置。


unclean.leader.election.enable
delete.retention.ms
segment.jitter.ms
retention.ms
flush.ms
segment.bytes
flush.messages
segment.ms
retention.bytes
cleanup.policy
segment.index.bytes
min.cleanable.dirty.ratio
max.message.bytes
file.delete.delay.ms
min.insync.replicas
index.interval.bytes  

 

2.2 Replica Verification Tool

$KAFKA_HOME/bin/kafka-replica-verification.sh,该工具用来验证所指定的一个或多个Topic下每个Partition对应的所有Replica是否都同步。可通过topic-white-list这一参数指定所需要验证的所有Topic,支持正则表达式。

 

2.3 Preferred Replica Leader Election Tool

用途
  有了Replication机制后,每个Partition可能有多个备份。某个Partition的Replica列表叫作AR(Assigned Replicas),AR中的第一个Replica即为“Preferred Replica”。创建一个新的Topic或者给已有Topic增加Partition时,Kafka保证Preferred Replica被均匀分布到集群中的所有Broker上。理想情况下,Preferred Replica会被选为Leader。以上两点保证了所有Partition的Leader被均匀分布到了集群当中,这一点非常重要,因为所有的读写操作都由Leader完成,若Leader分布过于集中,会造成集群负载不均衡。但是,随着集群的运行,该平衡可能会因为Broker的宕机而被打破,该工具就是用来帮助恢复Leader分配的平衡。
  事实上,每个Topic从失败中恢复过来后,它默认会被设置为Follower角色,除非某个Partition的Replica全部宕机,而当前Broker是该Partition的AR中第一个恢复回来的Replica。因此,某个Partition的Leader(Preferred Replica)宕机并恢复后,它很可能不再是该Partition的Leader,但仍然是Preferred Replica。
  
原理

  1. 在Zookeeper上创建/admin/preferred_replica_election节点,并存入需要调整Preferred Replica的Partition信息。
  2. Controller一直Watch该节点,一旦该节点被创建,Controller会收到通知,并获取该内容。
  3. Controller读取Preferred Replica,如果发现该Replica当前并非是Leader并且它在该Partition的ISR中,Controller向该Replica发送LeaderAndIsrRequest,使该Replica成为Leader。如果该Replica当前并非是Leader,且不在ISR中,Controller为了保证没有数据丢失,并不会将其设置为Leader。  

用法


$KAFKA_HOME/bin/kafka-preferred-replica-election.sh --zookeeper localhost:2181  

  在包含8个Broker的Kafka集群上,创建1个名为topic1,replication-factor为3,Partition数为8的Topic,使用$KAFKA_HOME/bin/kafka-topics.sh --describe --topic topic1 --zookeeper localhost:2181命令查看其Partition/Replica分布。

  查询结果如下图所示,从图中可以看到,Kafka将所有Replica均匀分布到了整个集群,并且Leader也均匀分布。

 

   手动停止部分Broker,topic1的Partition/Replica分布如下图所示。从图中可以看到,由于Broker 1/2/4都被停止,Partition 0的Leader由原来的1变为3,Partition 1的Leader由原来的2变为5,Partition 2的Leader由原来的3变为6,Partition 3的Leader由原来的4变为7。

 

   再重新启动ID为1的Broker,topic1的Partition/Replica分布如下。可以看到,虽然Broker 1已经启动(Partition 0和Partition5的ISR中有1),但是1并不是任何一个Parititon的Leader,而Broker 5/6/7都是2个Partition的Leader,即Leader的分布不均衡——一个Broker最多是2个Partition的Leader,而最少是0个Partition的Leader。

 

   运行该工具后,topic1的Partition/Replica分布如下图所示。由图可见,除了Partition 1和Partition 3由于Broker 2和Broker 4还未启动,所以其Leader不是其Preferred Repliac外,其它所有Partition的Leader都是其Preferred Replica。同时,与运行该工具前相比,Leader的分配更均匀——一个Broker最多是2个Parittion的Leader,最少是1个Partition的Leader。

 

   启动Broker 2和Broker 4,Leader分布与上一步相比并未变化,如下图所示。

 

   再次运行该工具,所有Partition的Leader都由其Preferred Replica承担,Leader分布更均匀——每个Broker承担1个Partition的Leader角色。
  
  除了手动运行该工具使Leader分配均匀外,Kafka还提供了自动平衡Leader分配的功能,该功能可通过将auto.leader.rebalance.enable设置为true开启,它将周期性检查Leader分配是否平衡,若不平衡度超过一定阈值则自动由Controller尝试将各Partition的Leader设置为其Preferred Replica。检查周期由leader.imbalance.check.interval.seconds指定,不平衡度阈值由leader.imbalance.per.broker.percentage指定。

 

2.4 Kafka Reassign Partitions Tool

用途
  该工具的设计目标与Preferred Replica Leader Election Tool有些类似,都旨在促进Kafka集群的负载均衡。不同的是,Preferred Replica Leader Election只能在Partition的AR范围内调整其Leader,使Leader分布均匀,而该工具还可以调整Partition的AR。
  Follower需要从Leader Fetch数据以保持与Leader同步,所以仅仅保持Leader分布的平衡对整个集群的负载均衡来说是不够的。另外,生产环境下,随着负载的增大,可能需要给Kafka集群扩容。向Kafka集群中增加Broker非常简单方便,但是对于已有的Topic,并不会自动将其Partition迁移到新加入的Broker上,此时可用该工具达到此目的。某些场景下,实际负载可能远小于最初预期负载,此时可用该工具将分布在整个集群上的Partition重装分配到某些机器上,然后可以停止不需要的Broker从而实现节约资源的目的。
  需要说明的是,该工具不仅可以调整Partition的AR位置,还可调整其AR数量,即改变该Topic的replication factor。
  
原理
  该工具只负责将所需信息存入Zookeeper中相应节点,然后退出,不负责相关的具体操作,所有调整都由Controller完成。

  1. 在Zookeeper上创建/admin/reassign_partitions节点,并存入目标Partition列表及其对应的目标AR列表。
  2. Controller注册在/admin/reassign_partitions上的Watch被fire,Controller获取该列表。
  3. 对列表中的所有Partition,Controller会做如下操作:
  • 启动RAR - AR中的Replica,即新分配的Replica。(RAR = Reassigned Replicas, AR = Assigned Replicas)
  • 等待新的Replica与Leader同步
  • 如果Leader不在RAR中,从RAR中选出新的Leader
  • 停止并删除AR - RAR中的Replica,即不再需要的Replica
  • 删除/admin/reassign_partitions节点

用法
  该工具有三种使用模式

  • generate模式,给定需要重新分配的Topic,自动生成reassign plan(并不执行)
  • execute模式,根据指定的reassign plan重新分配Partition
  • verify模式,验证重新分配Partition是否成功

  下面这个例子将使用该工具将Topic的所有Partition重新分配到Broker 4/5/6/7上,步骤如下:

    1. 使用generate模式,生成reassign plan。指定需要重新分配的Topic ({“topics”:[{“topic”:”topic1”}],”version”:1}),并存入/tmp/topics-to-move.json文件中,然后执行

$KAFKA_HOME/bin/kafka-reassign-partitions.sh 
    --zookeeper localhost:2181 
    --topics-to-move-json-file /tmp/topics-to-move.json  
    --broker-list "4,5,6,7" --generate  

结果如下图所示

 

     2. 使用execute模式,执行reassign plan
      将上一步生成的reassignment plan存入/tmp/reassign-plan.json文件中,并执行


$KAFKA_HOME/bin/kafka-reassign-partitions.sh 
--zookeeper localhost:2181     
--reassignment-json-file /tmp/reassign-plan.json --execute  

 

 此时,Zookeeper上/admin/reassign_partitions节点被创建,且其值与/tmp/reassign-plan.json文件的内容一致。

 

     3. 使用verify模式,验证reassign是否完成。执行verify命令


$KAFKA_HOME/bin/kafka-reassign-partitions.sh 
--zookeeper localhost:2181 --verify
--reassignment-json-file /tmp/reassign-plan.json  

结果如下所示,从图中可看出topic1的所有Partititon都重新分配成功。

 

   接下来用Topic Tool再次验证。


bin/kafka-topics.sh --zookeeper localhost:2181 --describe --topic topic1  

  结果如下图所示,从图中可看出topic1的所有Partition都被重新分配到Broker 4/5/6/7,且每个Partition的AR与reassign plan一致。

 

   需要说明的是,在使用execute之前,并不一定要使用generate模式自动生成reassign plan,使用generate模式只是为了方便。事实上,某些场景下,generate模式生成的reassign plan并不一定能满足需求,此时用户可以自己设置reassign plan。 

 

2.5 State Change Log Merge Tool

用途
  该工具旨在从整个集群的Broker上收集状态改变日志,并生成一个集中的格式化的日志以帮助诊断状态改变相关的故障。每个Broker都会将其收到的状态改变相关的的指令存于名为state-change.log的日志文件中。某些情况下,Partition的Leader Election可能会出现问题,此时我们需要对整个集群的状态改变有个全局的了解从而诊断故障并解决问题。该工具将集群中相关的state-change.log日志按时间顺序合并,同时支持用户输入时间范围和目标Topic及Partition作为过滤条件,最终将格式化的结果输出。
  
用法


bin/kafka-run-class.sh kafka.tools.StateChangeLogMerger
--logs /opt/kafka_2.11-0.8.2.1/logs/state-change.log
--topic topic1 --partitions 0,1,2,3,4,5,6,7  

 

0x03 转载

 

转载于:https://www.cnblogs.com/JetpropelledSnake/p/11611404.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Kafka学习笔记之Kafka High Availability(下) 的相关文章

  • VideoStream流媒体(VOD视频点播)系统平台

    软件介绍 xff1a VideoStream是集流媒体视频服务和流媒体应用管理为一体的综合流媒体服务系统 xff0c 本产品通过宽带IP网络为教育系统 各类运营商 政府企业等用户提供音视频服务的应用 系统特点 xff1a 1 采用WEB端口
  • c语言实现模拟FTP服务器项目

    下载源码后 xff0c 直接可以在ubuntu中编译运行 xff1a FTP服务器程序功能 xff1a 客户端 xff1a 1 输入命令 xff1a help 查看FTP服务器所支持的所有命令 2 输入名 xff1a ls 查看服务器上可以
  • 基于ArUco的视觉定位

    参考如下 博客 基于ArUco的视觉定位 1 3 https www freesion com article 4265319144 基于ArUco的视觉定位 4 https www pianshen com article 2491452
  • 伺服电机和步进电机的区别

    硬件型号 xff1a 三菱伺服电机HG KR43J 系统版本 xff1a 电机系统 1 控制的方式不同 步进电机 xff1a 通过控制脉冲的个数控制转动角度的 xff0c 一个脉冲对应一个步距角 伺服电机 xff1a 通过控制脉冲时间的长短
  • ubutnu更换国内源后,更新一直出现404,Not Found的问题

    1 问题 题主系统是ubuntu16 04 64位系统 尝试更换国内各种源 连ubuntu官方源都尝试了 sudo vim etc apt sources list修改为 deb https mirrors tuna tsinghua ed
  • Python+Flask实现股价查询系统。Python绘制股票k线走势

    文章目录 一 实现效果图二 实现思路1 获取数据 2 可视化数据三 源码获取 一 实现效果图 打开默认显示半年线 xff0c 可以通过可视化类型选择可视化k线图 高低点等 xff08 目前只完成了初版 xff0c 当查询的股票数据返回为空时
  • Failed to fetch http://mirrors.tuna.tsinghua.edu.cn/ubuntu/pool/main/g/gcc-5/g++-5_5.4.0-6ubuntu1~16

    今天在ubutun中在安装redis过程中 xff0c 安装gcc时遇到了Failed to fetch http mirrors tuna tsinghua edu cn ubuntu pool main g gcc 5 g 43 43
  • 切换日语输入法找不到MicrosoftIME键盘选项了

    去微软官方下载一个 Microsoft IME office 2010后 xff0c 安装解决 转载于 https www cnblogs com tupx p 3816026 html
  • msgid 属性

    Android源码中的String xml文件 xff0c msgid这个属性是干嘛的 xff1f 全局资源 xff0c 方便引用 比如在布局的text和activity中用到 转载于 https www cnblogs com Ph on
  • 2017年09月23日普级组 数列

    Description 小S今天给你出了一道找规律题 xff0c 题目如下 xff1a 有如下的数列1 xff0c 11 xff0c 21 xff0c 1211 xff0c 111221 xff0c 312211 xff0c 小S问你这个数
  • python 机器学习实战:信用卡欺诈异常值检测

    今晚又实战了一个小案例 xff0c 把它总结出来 xff1a 有些人利用信用卡进行诈骗等活动 xff0c 如何根据用户的行为 xff0c 来判断该用户的信用卡账单涉嫌欺诈呢 xff1f 数据集见及链接 xff1a 在这个数据集中 xff0c
  • Virtual Serial Port Driver 虚拟串口工具软件 使用介绍

    一般来说 xff0c 电脑的外部设备可以用过各种端口和电脑连接 常见的有USB xff0c VGA xff0c DVI等等 在工业领域或者是软件开发领域 xff0c 我们常常需要用简单低成本快捷的方式 xff0c 完成电脑和设备的连接 那么
  • Freertos 源码分析 队列queue

    队列queue xff08 零 xff09 队列的基础概念和形态 xff08 一 xff09 Freertos 队列 queue c FreeRTOS Kernel 10 4 6 include queue h Freertos队列模块包含
  • Freertos 任务TASK(一) 任务创建

    任务的创建 Freertos 的任务创建难点 1 xff09 堆栈生长的方向 2 xff09 64字节的对齐 3 xff09 任务堆栈初始化 Freertos 的任务使用任务控制块来进行管理 xff0c 是对任务的抽象 任务本身就是一段可执
  • Freertos Cortex-M3上下文切换

    上下文切换是操作系统实现虚拟化的核心功能 xff0c 操作系统对任务的管理通过上下文切换完成 Freertos 在STM32F103上的上下文切换是本文介绍的内容 STM32F103 采用 Cortex M3 内核 上下文切换的本质是对现场
  • STM32CubeMX配置freertos配置任务(一)

    使用STM32CubeMX 配置Freertos 生成一个任务点亮LED stm32cubemx STM32CubeMX 是 ST 意法半导体近几年来大力推荐的STM32 芯片图形化配置工具 xff0c 允许用户使用图形化向导生成C 初始化
  • STM32 精准采集ADC电压,误差分析

    ADC模块采集电压流程 数字世界和模拟世界的桥梁 xff0c 对于嵌入式软件而言 xff0c 大家止于采集功能的实现 本文目的在于深入理解ADC xff0c 积累技术做出更加稳定优秀的产品 STM32 大部分系列都是使用SAR 逐次逼近型电
  • STM32 编码器驱动/旋转编码器旋钮encoder

    本文已比较纯粹的方式介绍编码器和驱动的编写 编码器最少有两个输出信号 xff0c 一种典型的结构如上图所示 AB是编码器的输出引脚 当触点和黄色的金属片接触的时候信号发生跳变沿 xff0c 可以上上升沿也可以是下降沿 xff0c 具体根据A
  • UTC 转 LocalTime

    使用unsigned const char 纯碎是为了配合项目 xff0c 改成char 会比较通用些 BOOL CDllSuiteEngine Time StrToType unsigned const char lpszValue SY
  • CubeMX 图形配置工具 (UART) H743

    本文分两部分 1 图形操作步骤 2 自动生成代码结构分析 3 自动代码生成的坑 一 xff1a 使用CubeMX 配STM32H743 串口模块LPUSART 1 使能调试口 xff0c 以免使用SWD下载需要手动复位 2 配置 时钟树 x

随机推荐

  • LWIP (1.1) ETH Module以太网模块

    STM32 以太网 ETH模块说明 1 overview 2 ETH module in stm32h743 STM32H743 为例 开局一张图 ETHER 模块 红框所示 以STM32H743为例 32 BIt AHB为内部高速总线 D
  • UML(二)component 组件图

    组件图即是用来描述组件与组件之间关系的一种UML图 组件图在宏观层面上显示了构成系统某一个特定方面的实现结构 组件图适用于基于组件的开发模式 xff08 Component Based Development CBD xff09 xff0c
  • xilinx ZYNQ 7000 AXI GPIO

    0AXI GPIO 第一部分 PS 和 PL之间的通讯有一个接口称为AXI AXI总线具体的内容这边不去深究 xff0c 可以理解为一种特殊协议的通讯方式 AXI GPIO是什么意思 xff1f PL是FPGA它可以做成任何你想要的东西 x
  • xilinx ZYNQ 7000 XADC 片上模拟转数字模块

    上图所示 xff0c XADC 属于 PL部分的资源 XADC是一种硬逻辑实现 xff0c 位于PL功率域 PS xadc接口是PS的一部分 xff0c 可以被PS APU访问 xff0c 而不需要对PL进行编程 PL必须上电才能配置PS
  • XILINX FPGA OV5640 摄像头驱动(一)

    影像行业是一个值得深耕的方向 xff0c 废话不多说 先看输入和输出 输入是光照 xff0c 输出是光照的数字信号 image area xff1a 说的是感光矩阵 xff0c CMOS图像传感器的最核心部分 xff0c 接收光照产生电信号
  • Xilinx ZYNQ 7000 HDMI

    High Definition Multimedia Interface HDMI 参考xilinx application note XAPP460 HDMI来自High Definition Multimedia Interface 高
  • CAN协议与CANOpen协议

    这里详细介绍了CAN协议中数据通信帧每位的含义 xff0c 有图片 xff0c 值得一看 xff1a https www cnblogs com pejoicen p 3986587 html 这里介绍了CanOpen协议 xff0c ht
  • 标准的 C++ 由三个重要部分组成

    标准的 C 43 43 由三个重要部分组成 xff1a 核心语言 xff0c 提供了所有构件块 xff0c 包括变量 数据类型和常量 xff0c 等等 C 43 43 标准库 xff0c 提供了大量的函数 xff0c 用于操作文件 字符串等
  • 【转】每个程序员应该阅读的10本经典书籍

    如果你是一个程序员 xff0c 除了编码之外 xff0c 你还需要大量的阅读 今天我要为大家介绍几本值得一读的书 xff0c 包括 The Pragmatic Programmer xff0c The Mythical Man month
  • 解决Sqlite Developer过期的最简单办法(转自百度经验)

    第一种方法是 xff1a 打开注册表 开始 gt 运行 gt 输入regedit 依次打开目录 HKEY CURRENT USER SharpPlus SqliteDev 找到右侧的StartDate项 xff0c 删除 第二种方法更简单
  • 使用PhpOffice的PhpWord生成Word文件损坏,提示:很抱歉,无法开test.docx,因为内容有问题The file is corrupt and cannot be opened

    先说一下我的环境 xff1a 客户端 xff1a 操作系统 xff1a Windows 10 专业版20H2 64 位 内部版本 xff1a 19042 870 浏览器 xff1a Microsoft Edge版本 89 0 774 75
  • Prometheus.yml配置文件示例

    my global config global scrape interval 15s Set the scrape interval to every 15 seconds Default is every 1 minute evalua
  • 如何查看chrome浏览器已保存的密码

    该方法是针对在chrome中已经存储了登陆密码的情况 chrome版本是 66 0 3359 139 xff08 正式版本 xff09 xff08 64 位 xff09 xff0c 不知道哪天会改了这个bug 一般来说 xff0c 我们登陆
  • SNMP学习笔记之iReasoning MIB Browser

    0x00 MIB Browser iReasoning MIB浏览器是一个强大和易于使用的工具由iReasoning SNMP API提供支持 MIB浏览器是工程师管理启用SNMP的网络设备和应用程序不可或缺的工具 它允许用户加载标准的 x
  • K8S学习笔记之将Google的gcr.io、k8s.gcr.io 换为国内镜像

    0x00 添加docker官方的国内镜像 sudo tee etc docker daemon json lt lt 39 EOF 39 34 registry mirrors 34 34 https registry docker cn
  • Docker学习笔记之常见 Dockerfile 使用技巧

    0x00 概述 在掌握 Dockerfile 的基本使用方法后 xff0c 我们再来了解一些在开发中使用 Dockerfile 的技巧 这一小节的展现方式与之前的略有不同 xff0c 其主要来自阅读收集和我自身在使用中的最佳实践 也许这里面
  • Docker学习笔记之通过 Dockerfile 创建镜像

    0x00 概述 由于 Docker 镜像的结构优势 xff0c 使它的占用空间远小于普通的虚拟机镜像 xff0c 而这就大幅减少了 Docker 镜像在网络或者其他介质中转移所花费的时间 xff0c 进而提高了我们进行迁移部署的效率 不过
  • K8S学习笔记之ETCD启动失败注意事项

    最近搭建K8S集群遇到ETCD的报错 xff0c 报错信息如下 xff0c 一定要关闭防火墙 iptables和SELINUX xff0c 三个都要关闭 xff01 xff01 Mar 26 20 39 24 k8s m1 etcd 643
  • 硬件笔记之Thinkpad T470P更换2K屏幕

    0x00 前言 手上的Thinkpad T470P屏幕是1920x1080的屏幕 xff0c 色域范围NTSC 45 xff0c 作为一块办公用屏是正常配置 xff0c 但是考虑到色彩显示和色域范围 xff0c 计划升级到2K屏幕 2k屏幕
  • Kafka学习笔记之Kafka High Availability(下)

    0x00 摘要 本文在上篇文章基础上 xff0c 更加深入讲解了Kafka的HA机制 xff0c 主要阐述了HA相关各种场景 xff0c 如Broker failover xff0c Controller failover xff0c To