Kafka - 3.x 分区分配策略及再平衡不完全指北

news2024/9/23 0:35:05

文章目录

  • 生产经验——分区分配策略及再平衡
    • 生产者分区分配之Range及再平衡
      • Range分区策略原理
      • Range分区分配策略及再平衡案例
    • 生产者分区分配之RoundRobin策略及再平衡
      • RoundRobin分区策略原理
      • RoundRobin分区分配策略及再平衡案例
    • 生产者分区分配之Sticky及再平衡
      • Sticky分区策略原理
      • Sticky分区分配策略及再平衡案例

在这里插入图片描述


生产经验——分区分配策略及再平衡

在Apache Kafka中,确定哪个Consumer消费哪个Partition的数据是由Kafka的Group Coordinator和Partition Assignment策略来管理的。以下是一些关于这个过程的详细解释:

  1. Consumer Group:Consumer Group是一组Consumer的集合,它们协作地消费一个或多个Kafka Topic中的数据。Consumer Group通常用于实现消息处理的负载均衡,确保每个消息被处理一次,而不被重复处理。

  2. Topic和Partition:Kafka Topic可以分成多个Partition,每个Partition是数据的一个子集。分割Topic成多个Partition有助于实现数据并行处理和提高吞吐量。

  3. Group Coordinator:Kafka集群中有一个Group Coordinator,它负责管理Consumer Group的活动。Consumer Group的成员定期与Group Coordinator通信,以确保它们的状态和分配情况。

  4. Partition Assignment策略:在Consumer Group启动时,Group Coordinator负责为Consumer Group的每个成员分配要消费的Partition。这个分配是根据Partition Assignment策略来完成的,Kafka提供了不同的策略来实现不同的分配方式,例如Round Robin、Range、或自定义分配策略。

  • Round Robin:这是一种简单的策略,每个Consumer依次分配一个Partition,然后再循环。这样可以均匀分配Partition,但可能会导致不均衡,因为某些Partition可能比其他Partition更大或更活跃。

  • Range:Range策略尝试将相邻的Partition分配给相同的Consumer,以最大程度地减少网络传输。

  • 自定义策略:你也可以编写自定义的Partition Assignment策略来满足特定需求。

最终,每个Consumer会被分配一组Partition,它们将负责从这些Partition中消费数据。这个分配过程是动态的,因此如果Consumer Group的成员数目变化,或者有新的Partition被添加到Topic中,分配策略将会重新计算并分配Partition。

需要注意的是,Kafka的分配策略和Consumer Group的协调机制使得数据的消费和负载均衡变得相对容易管理,同时允许水平扩展,以适应不同规模的工作负载。

在这里插入图片描述

参数名称描述
heartbeat.interval.msKafka消费者和coordinator之间的心跳时间,默认3秒。必须小于session.timeout.ms,且不应该高于session.timeout.ms的1/3。
session.timeout.msKafka消费者和coordinator之间连接的超时时间,默认45秒。超过该值,消费者被移除,消费者组执行再平衡。
max.poll.interval.ms消费者处理消息的最大时长,默认是5分钟。超过该值,消费者被移除,消费者组执行再平衡。
partition.assignment.strategy消费者分区分配策略,默认策略是Range + CooperativeSticky。Kafka可以同时使用多个分区分配策略。可选策略包括:Range、RoundRobin、Sticky、CooperativeSticky。

生产者分区分配之Range及再平衡

Range分区策略原理

Range分区分配策略是Kafka中一种用于分配分区给消费者的策略。它的基本原理是将一组连续的分区分配给每个消费者,这样每个消费者负责一定范围内的连续分区。这种分配方式有助于减少网络传输和提高局部性,因为相邻的分区通常在相同的Broker上,并且减少了Leader的切换。

以下是Range分区分配策略的详细原理和工作流程:

  1. 确定可用分区:首先,消费者组需要确定可用的分区。这通常涉及到订阅一个或多个Kafka Topic,然后获取每个Topic的所有分区列表。

  2. 排序分区:接下来,消费者组对分区进行排序。这是为了确保所有消费者在分配分区时都能按照相同的顺序进行操作。通常,分区按照它们的分区号(Partition ID)进行升序排序。

  3. 确定消费者数目:消费者组需要知道有多少个消费者成员。这可以通过与Group Coordinator通信来获取成员列表,然后计算消费者的数量。

  4. 分配分区:现在,Range分区分配策略开始分配分区给消费者。它通过如下步骤完成:

    a. 将排序后的分区列表均匀地分割成若干区块,区块的数量等于消费者的数量。

    b. 然后,每个消费者被分配一个区块,这个区块包含一组连续的分区。

    c. 每个消费者被分配的区块是按照均匀分布的原则进行分配的,确保每个消费者的分区负载大致相等。

    d. 如果分区数量无法被整除地分配给消费者数目,最后一个消费者可能会获得稍多于其他消费者的分区,以确保所有分区都分配出去。

  5. 分配完成:一旦分配完成,每个消费者就知道它需要消费哪些分区,以及如何访问这些分区。消费者会开始从这些分区中拉取数据,进行处理。

在这里插入图片描述

总的来说,Range分区分配策略通过将一组连续的分区分配给每个消费者来实现负载均衡。这有助于减少网络开销,并提高数据局部性,因为相邻的分区通常位于相同的Broker上,从而减少了Leader的切换次数,提高了整体性能。这是Kafka的默认分区分配策略之一,但你也可以选择其他策略来满足特定需求。


Range分区分配策略及再平衡案例

1)准备
① 修改主题groupTest01的分区为7个分区

[xxx@hadoop102 kafka]$ bin/kafka-topics.sh --bootstrap-server hadoop102:9092 --alter --topic groupTest01--partitions 7

② 创建3个消费者,并组成消费者组group02,消费主题groupTest01
③ 观察分区分配情况

启动第一个消费者,观察分区分配情况
// consumer01
Successfully synced group in generation Generation{generationId=1, memberId='consumer-group02-1-4b019db6-948a-40d2-9d8d-8bbd79f59b14', protocol='range'}
Notifying assignor about the new Assignment(partitions=[groupTest01-0, groupTest01-1, groupTest01-2, groupTest01-3, groupTest01-4, groupTest01-5, groupTest01-6])
Adding newly assigned partitions: groupTest01-3, groupTest01-2, groupTest01-1, groupTest01-0, groupTest01-6, groupTest01-5, groupTest01-4
启动第二个消费者,观察分区分配情况
// consumer01
Successfully synced group in generation Generation{generationId=2, memberId='consumer-group02-1-4b019db6-948a-40d2-9d8d-8bbd79f59b14', protocol='range'}
Notifying assignor about the new Assignment(partitions=[groupTest01-0, groupTest01-1, groupTest01-2, groupTest01-3])
Adding newly assigned partitions: groupTest01-3, groupTest01-2, groupTest01-1, groupTest01-0
// consumer02
Successfully synced group in generation Generation{generationId=2, memberId='consumer-group02-1-60afd984-6916-4101-8e72-ae52fa8ded6c', protocol='range'}
Notifying assignor about the new Assignment(partitions=[groupTest01-4, groupTest01-5, groupTest01-6])
Adding newly assigned partitions: groupTest01-6, groupTest01-5, groupTest01-4
启动第三个消费者,观察分区分配情况
// consumer01
Successfully synced group in generation Generation{generationId=3, memberId='consumer-group02-1-4b019db6-948a-40d2-9d8d-8bbd79f59b14', protocol='range'}
Notifying assignor about the new Assignment(partitions=[groupTest01-0, groupTest01-1, groupTest01-2])
Adding newly assigned partitions: groupTest01-2, groupTest01-1, groupTest01-0
// consumer02
Successfully synced group in generation Generation{generationId=3, memberId='consumer-group02-1-60afd984-6916-4101-8e72-ae52fa8ded6c', protocol='range'}
Notifying assignor about the new Assignment(partitions=[groupTest01-3, groupTest01-4])
Adding newly assigned partitions: groupTest01-3, groupTest01-4
// consumer03
Successfully synced group in generation Generation{generationId=3, memberId='consumer-group02-1-fd15f50f-0a33-4e3a-8b8c-237252a41f4d', protocol='range'}
Notifying assignor about the new Assignment(partitions=[groupTest01-5, groupTest01-6])
Adding newly assigned partitions: groupTest01-6, groupTest01-5

思考:如果有消费者退出,分区分配会是什么样子?


生产者分区分配之RoundRobin策略及再平衡

RoundRobin分区策略原理

RoundRobin分区分配策略是Kafka中一种常用的消费者分区分配策略,它的原理非常简单:每个消费者依次轮流分配Topic的分区,以确保分区分配是均匀的。这意味着每个消费者将依次处理不同分区的数据,然后再重新开始。

以下是RoundRobin分区分配策略的详细原理:

  1. 消费者加入Group:当一个新的消费者加入Consumer Group时,或者已经存在的消费者需要重新平衡分区,Group Coordinator(Kafka集群中的一个组协调器)会触发分区分配过程。

  2. 计算分区分配:在RoundRobin策略下,Group Coordinator会遍历Topic的所有分区,并将它们按顺序分配给消费者。假设有3个分区(Partition 0、Partition 1、Partition 2)和2个消费者(Consumer A和Consumer B),分配可能如下:

    • Consumer A: Partition 0
    • Consumer B: Partition 1
    • Consumer A: Partition 2
    • Consumer B: Partition 0
    • Consumer A: Partition 1
    • Consumer B: Partition 2
  3. 分区分配循环:这个过程会持续下去,循环分配分区,确保每个消费者都有机会消费所有分区。这也有助于实现负载均衡,因为每个消费者都会处理不同的分区,从而分散了负载。

  4. 动态负载均衡:如果新的消费者加入Consumer Group或有现有消费者离开,分区分配将会重新计算,以确保适应消费者的数量变化。

在这里插入图片描述

RoundRobin分区分配策略的优点是简单且公平,每个消费者都有相同的机会消费每个分区。然而,它可能不适用于所有情况,特别是当分区的大小或活跃度不均匀时。在这种情况下,其他分区分配策略如Range或Sticky可能更适合,它们会更精细地考虑分区的特性来实现更好的负载均衡。


RoundRobin分区分配策略及再平衡案例

  • 修改消费者代码,消费者组都是group03。
  • 修改分区分配策略为roundrobin
properties.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG, RoundRobinAssignor.class.getName());

依次启动3个消费者,观察控制台输出

启动消费者CustomConsumer01,观察控制台输出
// customConsumer01
Successfully synced group in generation Generation{generationId=1, memberId='consumer-group03-1-2d38c78b-b17d-4d43-93f5-4b676f703177', protocol='roundrobin'}
Notifying assignor about the new Assignment(partitions=[groupTest01-0, groupTest01-1, groupTest01-2, groupTest01-3, groupTest01-4, groupTest01-5, groupTest01-6])
Adding newly assigned partitions: groupTest01-3, groupTest01-2, groupTest01-1, groupTest01-0, groupTest01-6, groupTest01-5, groupTest01-4
启动消费者CustomConsumer02,观察控制台输出
// customConsumer01
Successfully synced group in generation Generation{generationId=2, memberId='consumer-group03-1-2d38c78b-b17d-4d43-93f5-4b676f703177', protocol='roundrobin'}
Notifying assignor about the new Assignment(partitions=[groupTest01-0, groupTest01-2, groupTest01-4, groupTest01-6])
Adding newly assigned partitions: groupTest01-2, groupTest01-0, groupTest01-6, groupTest01-4
// customConsumter02
Successfully synced group in generation Generation{generationId=2, memberId='consumer-group03-1-5771a594-4e99-47e8-9df6-ca820af6698b', protocol='roundrobin'}
Notifying assignor about the new Assignment(partitions=[groupTest01-1, groupTest01-3, groupTest01-5])
Adding newly assigned partitions: groupTest01-3, groupTest01-1, groupTest01-5
启动消费者CustomConsumer03,观察控制台输出
// customConsumer01
Successfully synced group in generation Generation{generationId=3, memberId='consumer-group03-1-2d38c78b-b17d-4d43-93f5-4b676f703177', protocol='roundrobin'}
Notifying assignor about the new Assignment(partitions=[groupTest01-0, groupTest01-3, groupTest01-6])
Adding newly assigned partitions: groupTest01-3, groupTest01-0, groupTest01-6
// customConsumter02
Successfully synced group in generation Generation{generationId=3, memberId='consumer-group03-1-5771a594-4e99-47e8-9df6-ca820af6698b', protocol='roundrobin'}
Notifying assignor about the new Assignment(partitions=[groupTest01-1, groupTest01-4])
Adding newly assigned partitions: groupTest01-1, groupTest01-4
// customConsumter03
Successfully synced group in generation Generation{generationId=3, memberId='consumer-group03-1-d493b011-d6ea-4c36-8ae5-3597db635219', protocol='roundrobin'}
Notifying assignor about the new Assignment(partitions=[groupTest01-2, groupTest01-5])
Adding newly assigned partitions: groupTest01-2, groupTest01-5

思考:如果有消费者退出,分区分配会是什么样子?


生产者分区分配之Sticky及再平衡

Sticky分区策略原理

可以理解为分配的结果带有“粘性的”。即在执行一次新的分配之前,考虑上一次分配的结果,尽量少的调整分配的变动,可以节省大量的开销。粘性分区是Kafka从0.11.x版本开始引入这种分配策略,首先会尽量均衡的放置分区到消费者上面,在出现同一消费者组内消费者出现问题的时候,会尽量保持原有分配的分区不变化

"Sticky"分区分配策略是Kafka中的一种分区分配策略,用于将分区分配给消费者。它的主要目标是尽量减少分区再分配(rebalancing)的频率,以提高消费者组的稳定性。

Sticky分区分配策略的原理如下:

  1. 初始化分配:初始时,Kafka将分区均匀分配给消费者。每个消费者按顺序获取一个或多个分区,以确保尽可能平均地分配负载。

  2. 粘性分区分配:一旦分区被分配给某个消费者,该分区将尽量保持分配给同一消费者。这是策略名称"Sticky"的来源,因为它试图将分区"粘"在已经处理它的消费者上。

  3. 分区重新平衡:如果有新的消费者加入消费者组,或者有消费者离开,系统需要执行分区再分配。但是,Sticky策略会尽量减小重新平衡的频率。它不会立刻重新分配所有分区,而是尽量将已分配的分区保持不变,并只分配新增的分区。

  4. 重新平衡的触发:重新平衡可以由以下几种情况触发:

    • 消费者加入或退出消费者组。
    • 消费者心跳超时。
    • 某个分区失去联系的情况下,可能会重新分配。
  5. 维持粘性:Sticky策略会尽力保持分区分配的稳定性,以减少分区再分配的次数,从而降低了整个消费者组的不稳定性。这有助于提高系统的可用性和性能。

Sticky策略的主要优点是减少了分区再分配的频率,减轻了系统的不稳定性,降低了重新平衡的成本。这对于大规模的Kafka集群和高吞吐量的消费者组特别有用。然而,它不一定适用于所有情况,因为在某些情况下,需要更频繁的重新平衡以确保公平的负载分配。因此,在选择分区分配策略时,需要根据具体的使用情况和需求来权衡。


Sticky分区分配策略及再平衡案例

  1. 修改分区分配策略,修改消费者组为groupTest03
// 修改分区分配策略
properties.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG, StickyAssignor.class.getName());
  1. 分别启动三个消费者后,查看第三次分配如下
启动消费者CustomConsumer01,观察控制台输出
// customConsumer01
Successfully synced group in generation Generation{generationId=1, memberId='consumer-group06-1-19e1e6a4-e2ca-467d-909f-3769dc527d34', protocol='sticky'}
Notifying assignor about the new Assignment(partitions=[groupTest01-0, groupTest01-1, groupTest01-2, groupTest01-3, groupTest01-4, groupTest01-5, groupTest01-6])
Adding newly assigned partitions: groupTest01-3, groupTest01-2, groupTest01-1, groupTest01-0, groupTest01-6, groupTest01-5, groupTest01-4
启动消费者CustomConsumer02,观察控制台输出
// customConsumer01
Successfully synced group in generation Generation{generationId=2, memberId='consumer-group06-1-19e1e6a4-e2ca-467d-909f-3769dc527d34', protocol='sticky'}
Notifying assignor about the new Assignment(partitions=[groupTest01-0, groupTest01-1, groupTest01-2, groupTest01-3])
Adding newly assigned partitions: groupTest01-3, groupTest01-2, groupTest01-1, groupTest01-0
// customConsumer02
Successfully synced group in generation Generation{generationId=2, memberId='consumer-group06-1-6ea3622c-bbe8-4e13-8803-d5431a224671', protocol='sticky'}
Notifying assignor about the new Assignment(partitions=[groupTest01-4, groupTest01-5, groupTest01-6])
Adding newly assigned partitions: groupTest01-6, groupTest01-5, groupTest01-4
启动消费者CustomConsumer03,观察控制台输出
// customConsumer01
Successfully synced group in generation Generation{generationId=3, memberId='consumer-group06-1-19e1e6a4-e2ca-467d-909f-3769dc527d34', protocol='sticky'}
Notifying assignor about the new Assignment(partitions=[groupTest01-0, groupTest01-1, groupTest01-2])
Adding newly assigned partitions: groupTest01-2, groupTest01-1, groupTest01-0
// customConsumer02
Successfully synced group in generation Generation{generationId=3, memberId='consumer-group06-1-6ea3622c-bbe8-4e13-8803-d5431a224671', protocol='sticky'}
Notifying assignor about the new Assignment(partitions=[groupTest01-4, groupTest01-5])
Adding newly assigned partitions: groupTest01-5, groupTest01-4
// customConsumer03
Successfully synced group in generation Generation{generationId=3, memberId='consumer-group06-1-eb0ac20c-5d94-43a7-b7c1-96a561513995', protocol='sticky'}
Notifying assignor about the new Assignment(partitions=[groupTest01-3, groupTest01-6])
Adding newly assigned partitions: groupTest01-3, groupTest01-6
3) 杀死消费者CustomConsumer01后,观察控制台输出
// customConsumer02
Successfully synced group in generation Generation{generationId=4, memberId='consumer-group06-1-6ea3622c-bbe8-4e13-8803-d5431a224671', protocol='sticky'}
Notifying assignor about the new Assignment(partitions=[groupTest01-4, groupTest01-5, groupTest01-0, groupTest01-2])
Adding newly assigned partitions: groupTest01-2, groupTest01-0, groupTest01-5, groupTest01-4
// customConsumer03
Successfully synced group in generation Generation{generationId=4, memberId='consumer-group06-1-eb0ac20c-5d94-43a7-b7c1-96a561513995', protocol='sticky'}
Notifying assignor about the new Assignment(partitions=[groupTest01-3, groupTest01-6, groupTest01-1])
Adding newly assigned partitions: groupTest01-3, groupTest01-1, groupTest01-6

在这里插入图片描述

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

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

相关文章

网络协议--TCP的超时与重传

21.1 引言 TCP提供可靠的运输层。它使用的方法之一就是确认从另一端收到的数据。但数据和确认都有可能会丢失。TCP通过在发送时设置一个定时器来解决这种问题。如果当定时器溢出时还没有收到确认,它就重传该数据。对任何实现而言,关键之处就在于超时和重…

Android NDK开发详解之Android.mk探秘

Android NDK开发详解之Android.mk探秘 概览基础知识变量和宏NDK 定义的 include 变量CLEAR_VARSBUILD_EXECUTABLEBUILD_SHARED_LIBRARYBUILD_STATIC_LIBRARYPREBUILT_SHARED_LIBRARYPREBUILT_STATIC_LIBRARY 目标信息变量TARGET_ARCHTARGET_PLATFORMTARGET_ABI 模块描述变量LOC…

ubuntu下英伟达显卡驱动及cuda安装

一、查看显卡需要安装的cuda版本及需要的驱动版本 进入官网查看: CUDA 12.3 Release Notes 比如需要装cuda12.2GA需要驱动版本至少为535.54.03 二、下载显卡驱动 2.1 进入官网下载界面: Official Drivers | NVIDIA,点击Beta and older dr…

系列三十三、代理(三)动态代理

一、概述 在实际开发过程中,往往我们自己不会去创建代理类,而是通过JDK提供的Proxy类在程序运行时,运用反射机制动态创建而成,这就是所谓的动态代理。 1.1、动态代理 vs 静态代理 静态代理需要程序员自己写代理类,动态…

软件测试面试百问:如何测试App性能?

APP性能测试几乎是客户端面试必问。 为什么要做App性能测试 如果APP总是出现卡顿或网络延迟的情况,降低了用户的好感,用户可能会抛弃该App,换同类型的其他应用。如果APP的性能较好,用户体验高,使用起来丝滑顺畅&…

干货:传统软文和新媒体软文的区别在哪儿

其实早在古代就有软文的影子,不管是“借问酒家何处有,牧童遥指杏花村”,还是“日啖荔枝三百颗,不辞长作岭南人。”都有软文的影子。今天媒介盒子就来和大家聊聊,传统软文和新媒体软文的区别在哪儿? 一、 渠道不同 在…

UWB智能制造

(一)无人值守的人、车、物出入监控 (二)人、车、物授权区域进出监控 (三)固定资产区域盘点及移动盘点 (四)人、车、物作业现场网格化管理 (五)作业现场人车、…

万兆光模块是否能够应对未来网络的需求?

万兆光模块目前已经是数据中心等高性能计算场景中的标配之一,其传输速率可以满足大量的数据传输需求。随着网络的发展,光模块的传输速率也在不断提升。目前一些厂商已经推出了400G和800G光模块,同时更高速率光模块也在加速研发中。可以预见&a…

原型和原型链的理解

记住一句话:万物皆对象 对于原型和原型链,我们要知道一下几个:函数对象,实例对象、原型对象 1)函数对象——就是平时称的对象; 2)实例对象——new出的对象或者{ }; 3)原型…

医疗安全不良事件管理系统源码(PHP+ vue+laravel)

医疗安全不良事件管理系统全套源码 不良事件上报系统源码 不良事件管理系统帮助医院梳理建立不良事件上报与管理的一体化解决方案,包含上报内容、归口科室、上报流程及管理办法。提供面向医院的不良事件全过程管理平台,包含事件上报、事件处理、事件追踪…

线性代数 第一章 行列式

一、概念 不同行不同列元素乘积的代数和(共n!项) 二、性质 经转置行列式的值不变,即; 某行有公因数k,可把k提到行列式外。特别地,某行元素全为0,则行列式的值为0; 两行互换行列式…

goland setup go env

go env -w设置的变量,在goland中不生效,需要额外配置。 点击goland->preference,在go module里,设置go环境变量即可。

Istio实战(九)-Envoy 流量劫持

前言 Envoy 是一款面向 Service Mesh 的高性能网络代理服务。它与应用程序并行运行,通过以平台无关的方式提供通用功能来抽象网络。当基础架构中的所有服务流量都通过 Envoy 网格时,通过一致的可观测性,很容易地查看问题区域,调整整体性能。 Envoy也是istio的核心组件之一…

JS获取阿里云oss私有图片需要通过SDK加签名访问问题

文章目录 一、问题背景二、了解一些概念1. 防盗链2. 公有和私有两种链接的区别 三、下载SDK的地址四、js的SDK对url加签名实现方法实现示例 五、另外1. 跨域问题 六、文章用到的官方文档链接 一、问题背景 我们项目中平时需求都是上传一张原始图片到阿里云OSS公共空间&#xf…

利用OSG和GLSL实现彩色图转为灰度图

目录 1. 前言 2. 开发环境说明 3. 预备知识 4. 功能实现 4.1. 代码 4.2. 代码说明 5. 附加说明 1. 前言 灰色图片其rgb值是一样的,比如(0.5, 0.5, 0.5)就是一张灰度图。彩色转黑白算法有很多种。因此由彩色转黑白关键就是由彩色的rgb算出灰度gray&#xff0…

7+共病思路。WGCNA+多机器学习+实验简单验证,易操作

今天给同学们分享一篇共病WGCNA多机器学习实验的生信文章“Shared diagnostic genes and potential mechanism between PCOS and recurrent implantation failure revealed by integrated transcriptomic analysis and machine learning”,这篇文章于2023年5月16日发…

数据结构与算法解析(C语言版)--搭建项目环境

本栏目致力于从0开始使用纯C语言将经典算法转换成能够直接上机运行的程序,以项目的形式详细描述数据存储结构、算法实现和程序运行过程。 参考书目如下: 《数据结构C语言版-严蔚敏》 《数据结构算法解析第2版-高一凡》 软件工具: dev-cpp 搭…

调试AOSP源码的官方神器-Android Studio for Platform(ASfP)

文章目录 下载安装启动AOSP导入调试不足 欢迎关注微信公众号ZZH的Android 下载 下载地址平台版 Android Studio 由于该工具在调试源码时需要对AOSP进行编译,所以目前只有Ubuntu版本,后续应该也只会有Ubuntu版本。 Ubuntu环境下显示可下载 Windows系统…

【Redis】认识Redis-特点特性应用场景对比MySQL重要文件及作用

文章目录 认识redisredis的主要特点redis的特性(优点)redis是单线程模型,为什么效率这么高,访问速度这么快redis应用场景redis不可以做什么MySQL和Redis对比启动RedisRedis客户端Redis重要文件及作用 认识redis redis里面相关的小…

SHCTF2023 山河CTF Reverse Week3 --- ststst easyre WP详解

文章目录 [WEEK3]ststst[WEEK3]easyre [WEEK3]ststst 64 bit 的 ELF 文件 sub_400763点进去看看 mprotect ,这个 这一题是SMC TEA的考察,我写过一篇关于 SMC学习网鼎杯jocker 可以使用idapython写脚本自动修复,也可以使用动态调试&#x…