浅析 Apache Kafka 分区重分配的实现原理

kafka集群磁盘满警告,新增kafka节点,重新分配partition 本文参考了网上部分文章,并进行了说明和归纳,详情请查看参考。 官方文档参考:https://cwiki.apache.org/confluence/display/KAFKA/Replication+tools kafka环境中机器磁盘告警很容易出现,原因可能是某一个topic的partition为1(或者partition不足导致的),只往一台机器上写数据,造成kafka集群空间使用不均。 下面主要使用kafka-topics.sh和kafka-reassign-partitions.s... 阅读详情

本文作者为中国移动云能力中心大数据团队软件开发工程师孙大鹏,本文结合 2.0.0 版本的 Kafka 源码,详细介绍了 Kafka 分区副本重分配的流程和逻辑,供大家参考。

一、前言

Kafka 是由 Apache 软件基金会开发的一个开源流处理平台,旨在提供一个统一的、高吞吐、低延迟的实时数据处理平台。其持久化层本质上是一个“按照分布式事务日志架构的大规模发布/订阅消息队列”,这使它作为企业级基础设施来处理流式数据非常有价值。

在 Kafka 中,用 topic 来对消息进行分类,每个进入到 Kafka 的信息都会被放到一个 topic 下,同时每个 topic 中的消息又可以分为若干 partition 以此来提高消息的处理效率。存储消息数据的主机服务器被命名为 broker。通常为了保证数据的可靠性,数据是以多副本的形式保存在不同 broker 的不同磁盘上的。对于每一个 topic 的每一个 partition,如果多个副本之间完成了数据同步,保证了数据的一致性,则此时的多个副本所在的 broker 的集合称为 Isr。同一时间,某个 topic 的某个 partition 的多个副本中仅有一个对外提供服务,此时对外提供服务的 broker 被认定为该 partition 的 leader,客户端的请求都集中到 leader 上。

对于 2 副本 3 分区的 topic 其描述信息及存储状态如下所示:

test的描述信息:
Topic:test PartitionCount:3 ReplicationFactor:2 Configs:min.insync.replic
as=1
Topic: test Partition: 0 Leader: 0 Replicas: 0,1 Isr: 0,1
Topic: test Partition: 1 Leader: 2 Replicas: 2,0 Isr: 2,0
Topic: test Partition: 2 Leader: 1 Replicas: 1,2 Isr: 1,2

test的副本分布

健康状态的 Kafka 集群,对于每个 topic 的每个 partition,其 Isr 都应该等于预期的副本集合(后面均已 Replicas 表示),但在实际场景中,不可避免的存在磁盘/主机故障,或者 由于某些原因需要将部分 broker 节点下线的情况,此时就需要将故障/要下线的 broker 从 Replicas 中移除。对此 Kafka 提供了 kafka-reassign-partitions 工具来进行手动的分区副本迁移。

二、工具的使用

在 Kafka 的根路径下,通过执行如下命令,来完成分区副本的重分配:

./bin/kafka‐reassign‐partitions.sh ‐‐zookeeper localhost:2181/kafka ‐‐reassignment‐json‐file reassign‐topic.json ‐‐execute

其中:reassign‐topic.json 文件指定了分区副本的分布情况,示例如下:

{   
"version": 1,   
"partitions": [       
{         
"topic": "test",         
"partition": 2,         
"replicas": [            
2,             
1         
],         
"log_dirs": [             
"any",             
"any"         
]        
} 
}

文件中指明了将 topic=test,partition=2 的分区的两副本分别移动到 brokerId=2 和 brokerId=1 的节点的任意磁盘路径上。

下面将结合 2.0.0 版本的 Kafka 源码简单的介绍下 Kafka 分区副本重分配的流程和逻辑。

三、元数据管理及协调器

在开始之前先简单介绍下在 Kafka 分区副本重分配中涉及到的两个概念:ZooKeeper 和 Kafka Controller。

3.1 ZooKeeper

Kafka 的元数据,是存储在 ZooKeeper  中的。Apache ZooKeeper  是一个提供高可靠性的分布式协调服务框架。它使用的数据模型类似于文件系统的树形结构,根目录也是以“/”开始。该结构上的每个节点被称为 znode,用来保存一些元数据协调信息。同时 ZooKeeper 赋予客户端监控 znode 变更的能力,即所谓的 Watch 通知功能。一旦 znode 节点被创建、删除,子节点数量发生变化,或是 znode 所存的数据本身变更, ZooKeeper 会通过节点变更监听器 (ChangeHandler) 的方式显式通知客户端以便客户端 触发对应的处理操作。

3.2 Kafka Controller

Kafka Controller 是 Apache Kafka 的核心组件,它的主要作用是在 Apache ZooKeeper 的帮助下管理和协调整个 Kafka 集群。集群中任意一台 Broker 都能充当控制器的角色,但是,在运行过程中,只能有一个 Broker 成为控制器,行使其管理和协调的职责。

四、分区重分配流程分析

Kafka 的分区重分配就是在 client、broker 和 controller 的协同运行下完成的。即:

1. 客户端发起分区重分配任务,在 ZooKeeper  中创建/admin/reassign_partitions 节点,然 后向涉及的 broker 发送 alterReplicaLogDirs 请求 2. controller 监测到 ZooKeeper  中/admin/reassign_partitions 的变化,触发 Kafka 分区元 数据的变更维护操作 3. broker 接收到客户端发送的 alterReplicaLogDirs 请求,根据具体任务内容在服务端实际完成分区副本移动

流程总结如下图所示:

下面将针对这三部分分别展开介绍:

4.1 kafka-reassign-partitions 客户端

分区重分配任务是由客户端发起的,其入口主类为 ReassignPartitionsCommand.scala 中,调用 executeAssignment 方法。客户端的 executeAssignment 方法主要完成了如下操作:

1. 解析 json 文件并进行相关校验 • 读取 json 文件内容,校验“partitions”的“version”,仅为 1 时,继续执行副本重分 配 • 校验分区副本数和副本数据路径数是否一致 • 校验 partition/replica 是否为空/重复 2. 检查待重分配的分区在集群中是否存在(根据 zk 中的/brokers/topics/${topic}) 3. 检查确认所有目标 broker 均在线(zk 中/brokers/ids 的子 znode 列表) 4. 检查是否已存在分区副本重分配任务,如果已存在相关任务,则退出 5. 将分区重分配任务记录到 zk 中,即在 zk 中创建/admin/reassign_partitions,以便 controller 可以发现并协调 broker 进行相关操作 6. 根据解析的 json 内容,逐个 topic 向相关的 broker 发送 alterReplicaLogDirs 请求

客户端的处理逻辑可总结为如下流程图:

4.2 controller 维护分区的元数据信息

在 controller 启动时会创建 partitionReassignmentHandler,kafkaController 主线程回调 onControllerFailover 时,检测到/admin/reassign_partitions 发生变化时,触发分区副本重分配操作,在 maybeTriggerPartitionReassignment 中通过调用 onPartitionReassignment 真正执行分区副本重分配。在 onPartitionReassignment 中定 义了三个概念:

• RAR:指定的分区副本放置策略 • OAR:原始的分区副本放置策略 • AR:当前的分区副本放置策略

onPartitionReassignment 的执行过程可以总结为如下步骤:

检查指定的分区副本是否处在 isr 中,如果不在则执行以下前 3 步,否则直接执行第 4 步

1. 在 zk 中将 AR 更新为 RAR+OAR (/broker/topics/${topicName}) 2. 向所有副本(RAR+OAR)中发送 LeaderAndIsr 请求 3. 将 RAR-OAR 的副本状态置为 NewReplica,等待 NewReplica 中的数据与 leader 中的数据 完成同步 4. 等待直到所有 RAR 中的副本完成与 leader 的同步 5. 将所有 RAR 的副本置为 OnlineReplica 状态 6. 将 RAR 作为 AR 7. 如果当前的 leader 不在 RAR 中,发送 LeaderAndIsr Request 从 RAR 中选出一个新的 leader;如果当前 leader 在 RAR 中,检查 leader 状态,如果 leader 健康则更新 LeaderEpoch,否则重新选择 leader 8. 将 OAR-RAR 的副本置为 Offline 状态 9. 将 OAR-RAR 的副本置为 NonExistentReplica 状态(真实删除对应的分区副本) 10. 将 zk 中的 AR 置为 RAR(/brokers/topics/${topicName}数据格式:{"version":1,"partitions":{"0":[${brokerId}]}}) 11. 更新 zk 中/admin/reassign_partitions 的值,将完成迁移的分区删除 12. 同步所有 broker,更新元数据信息

逻辑流程图如下:

4.3 broker 端数据跨路径迁移

底层数据跨路径迁移,是由 broker 端完成的,broker 接收到客户端发来的 ALTER_REPLICA_LOG_DIRS 请求后,调用 alterReplicaLogDirs 方法,相关流程如下:

1. 确保目的路径/待移动分区在线 2. 如果当前分区副本的 log 路径不存在给定的目的路径并且 futureLogs(用于跨路径数据迁移的中间过程)也不包含目的路径,则在内存中记录当前分区副本和目的 logDir,即标记那些需要进行迁移的分区副本路径 3. 对于需要移动的分区副本,目的 broker 的路径中创建 future Log 4. 停止当前 Log 的清理工作,等待 future Log 同步完再清理 5. 创建 ReplicaAlterLogDirsThread,逐个 topic 逐个 partition 获取 fetchOffset、 logStartOffset 、fetchSize 等数据构造 Fetch 请求 6. 通过 ReplicaManager.fetchMessages 从分区副本 leader 获取数据,完成数据同步

更详细的处理流程如下图所示:

五、总结

Kafka 分区重分配,通过 kafka-reassign-partitions 启动任务,将任务记录在元数据管理器 ZooKeeper  中,Kafka controller 通过对 ZooKeeper  的监测,发现相关任务通过和 broker 的交互按序处理相关的迁移任务,同时 controller 实时维护 ZooKeeper  中的元数据信息并进行相关变化的记录,保证在重分配过程中,不影响 topic 分区的正常使用,在任务完成后,再由 controller 负责 ZooKeeper  中重分配任务标记的清理,以便客户端验证重分配任务的结果。

ZYNQ PS-PL数据交互方式总结 一,中断 二,IO方式:MIO EMIO GPIO 三,BRAM或FIFO或EMIF (1)通过BRAM实现PL/PS之间交互 PS 的配置如下图所示。使能 M_AXI_GP0 口,将 FCLK_CLK0 设为 100MHz,使能 PL 至 PS 的中断。 AXI BRAM Controller IP 核连接 PS 的 M_AXI_GP0 口和 BRAM,完成 AXI 接口至 BRAM 接口的转换。 添加BRAM,将BRAM设置为双口RAM,将PORTA与AXI B... 阅读详情

相关推荐

保姆级教程:在RK3568 Debian系统上搞定AIC8800 WiFi与蓝牙驱动(含固件路径与开机自启脚本)

本文提供在RK3568 Debian系统上配置AIC8800 WiFi与蓝牙驱动的保姆级教程,涵盖驱动移植、固件部署、开机自启脚本等关键步骤。通过详细的硬件连接指南、内核配置示例和常见问题解决方案,帮助开发者快速实现无线模块的全功能配置,特别适合嵌入式Linux开发者参考。

weixin_28684825的博客 380

kafka分区重分配详解

​ 当集群中的一个节点突然宕机下线时,如果节点上的分区是单副本的,那么这些分区就变得不可用,在节点恢复前,相应的数据也就处于丢失状态;如果节点上的分区是多副本的,那么位于这个节点上的leader副本的角色会转交到集群中的其他follower副本中。总而言之,这个节点上的分区副本都已经处于功能失效状态。kafka并不会将这些失效的副本自动地迁移到集群中剩余的可用broker节点上。如果放任不管则不仅影响整个集群的均衡负载,还会影响整体服务的可用性和可靠性。 ​ 当要对集群中的一个节点进行有计划的下线操作时

徐海兴的专栏 4808

Mac---安装Navicat

把这个填充好的字符串放入刚才打开的RSA在线加解密的网站中的第二个框框(替换之前的请求码),第一个框框不动(还是之前第10步骤中的私钥),点击RSA私钥加密,这时会得到一个加密的字符串,这个就是激活码。{“K”:“你的K值”, “N”:“52pojie”, “O”:“52pojie.cn”, “DI”:“你的DI值”, “T”:你的时间戳}链接: https://pan.baidu.com/s/1mEVY4hnKdktg-p7DBIfD7A 提取码: twwg。Navicat会弹出一个对话框,点击“注册”

weixin_53970868的博客 1万+

Kafka 原理以及分区分配策略剖析

一、简介 Apache Kafka 是一个分布式的流处理平台(分布式的基于发布/订阅模式的消息队列【Message Queue】)。 流处理平台有以下3个特性: 可以让你发布和订阅流式的记录。这一方面与消息队列或者企业消息系统类似。 可以储存流式的记录,并且有较好的容错性。 可以在流式记录产生时就进行处理。 1.1 消息队列的两种模式 1.1.1 点对点模式 生产者将消息发送到queue中,然后消费者从queue中取出并且消费消息。消息被消费以后,queue中不再存储.

Java搜索工程技术栈 2659

基于立创EDA的8口全千兆POE交换机设计详解:RTL8370N芯片与90W大功率供电方案

本文详细解析了基于立创EDA设计的8口全千兆POE交换机方案,核心采用RTL8370N交换芯片与支持90W大功率供电的IEEE 802.3bt标准PD芯片。文章深入探讨了PSE/PD供电管理、电源架构设计、电路细节及关键散热方案,为DIY或学习POE交换机硬件设计提供了完整的开源实践指南。

weixin_29050829的博客 1万+

从平衡车到寻迹小车:IMU963RA九轴陀螺仪实战避坑与四元数融合指南

本文详细解析了IMU963RA九轴陀螺仪在机器人姿态控制中的应用,重点探讨了从六轴升级到九轴系统的技术路径及四元数融合算法。通过实战案例,揭示了如何利用地磁计补偿陀螺积分漂移,并提供硬件集成、传感器校准及算法实现的完整解决方案,有效将8小时漂移控制在2度以内。

weixin_27219587的博客 255

大数据-64 Kafka 深入理解 Kafka 分区与重分配机制:高并发与高可用的核心 实机测试

Kafka 分区是实现高并发与高可用的核心机制。每个主题可被划分为多个分区,分布在不同 Broker 上,以实现水平扩展和并行处理。生产者可并发写入不同分区,消费者组内多个消费者可并行消费数据,从而显著提升吞吐量。分区配合副本机制(Leader 与 Follower)提供容错能力,即使某个 Broker 宕机,仍可在秒级切换 Leader 保证服务可用。分区重新分配(Partition Reassignment)用于在扩容、缩容或负载不均时调整分区分布,确保资源利用均衡和机架容灾。执行重分配。

谢谢你的喜欢 我们一起无限进步 2979

基于STM32L4XX的环境光传感器(AS7343-DLGMN)应用程序设计

define AS7343_STATUS_SPECTRAL_INT (1 << 3) /* 光谱数据就绪 */#define AS7343_SYS_CFG_SPECTRAL_EN (1 << 1) /* 光谱测量使能 */#define AS7343_SYS_CFG_ALS_EN (1 << 0) /* ALS使能 */#define AS7343_SYS_CFG_INT_EN (1 << 4) /* 中断使能 *//* 切换通道组 (0=组1 F1-F6, 1=组2 F7-F12) */

myron6688的博客 258

Kafka重平衡与分区策略解析

Kafka 的重平衡与分区策略如同隐藏在数据洪流中的精密齿轮,既支撑着千万级消息的高效流转,也暗藏着消费停顿、数据重复等潜在陷阱。你是否好奇:当消费者节点增减时,Kafka 如何在毫秒级内完成分区的重新洗牌?默认的 Range 分配策略为何会导致分区负载不均?又该如何驯服重平衡这头 "猛兽",让数据处理链路始终保持丝滑

日拱一卒无有尽,功不唐捐终入海 1万+

北斗导航 | 基于LSTM-KF融合的北斗卫星定位算法研究框架

针对北斗卫星导航系统在复杂环境下存在的多路径效应、非视距传播等问题,提出一种基于长短期记忆网络(LSTM)与卡尔曼滤波(KF)的组合定位算法。通过LSTM网络建模定位误差的非线性特征,结合卡尔曼滤波实现动态噪声抑制,构建"粗定位-LSTM校正-卡尔曼滤波优化"的三级处理架构。实验表明,融合算法较传统方法定位精度提升42.7%,均方根误差降低至1.2米。

尘世冰封的专栏 923

BLDC&PMSM电机控制器硬件设计工程(八)72V 10kW电机控制器原理图工程及库文件

电机控制器基本需求:接口类型;MCU平台;通信接口;供电;信号采集;信号输出;功率;EMC或者认证需求。

小幽余生不加糖 375

kylin streaming原理介绍与特点浅析

文章目录前言kylin streaming设计和原理架构介绍streaming coordinatorstreaming receiver clusterkylin streaming数据构建流程kylin streaming查询流程kylin streaming实现细节kylin streaming segment存储实现重平衡/重分配故障恢复kylin streaming优化总结 前言 最近搭了Kylin Streaming并初步测试了下,觉得这个东西虽然有些限制,但还是蛮好用的,所以系统写篇文章总结下

zzzzMing -大数据/数据分析/数据挖掘 465

【ARM AMBA5 CHI 2 -- CHI 链路层详细介绍 】

目前有六个版本的 CHI 协议,CHI-A 是 CHI 协议的第一个版本。它提供了一个传输层,具有减少拥塞的功能。新通道、CHI 术语和组件命名的定义;请求、监听过滤器和缓存状态转换的示例;事务排序、独占访问和分布式虚拟内存(DVM)操作的规则;CHI-B 问题扩展了 CHI-A,但不能直接向后兼容 CHI-A。更大的物理地址宽度;原子事务;DVM 的 VMID 扩展;通道字段、事务结构和可靠性、可用性和可维护性(RAS)特性的描述;

CodingCos的博客 2536

Kafka的Rebalance机制与分区分配策略详解

Kafka 中的 Rebalance(重平衡)机制是在消费者组的成员发生变化时,重新分配分区以确保每个消费者都能处理适当数量的分区。这种机制对于保证数据消费的平衡性和系统的高可用性至关重要。有新的消费者加入消费者组时,需要重新分配分区,以便新的消费者也能接收到数据。消费者退出或崩溃时,组内的分区需要重新分配给剩余的消费者。主题的分区数量增加或减少时,也会触发 Rebalance。如果消费者组的协调器发生变化,也会触发 Rebalance。

RLCRAFT的博客 1511

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

kafka-重新分区

kafka 重新分区 为什么要重新分区? kafka 不会因为 broker 的增加或者减少而重新对原有的分区进行扩展 重新分区命令 –generate 生成分区重分配计划 –execute 执行分区重分配计划 –verify 验证分区充重配计划 准备 现集群: $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS

面朝大海,春暖花开 1659

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

二、kafka分区副本重分配-限流

这一篇我们主要来看看分区副本重分配限流是如何实现的,此源码分析基于kafka2.5版本。在开始之前我们先来回顾一下分区重分配的流程,如图一所示。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 执行分区重分配脚本,这里相当于起了个kafka客户端,执行完脚本将重分配数据写入zk即返回了。 kafkaController监听到zk分区重分配节点数据变动,会调相应的handler来处理数据,这里相当于kafka服务端大脑的角色,控制了分区重分配主要处理的流程,并发送命令给其他节点执行,描

Coding fly的博客 2239

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Kafka Partition重分配流程简析

节日快乐~ 今天是属于广大程序员的节日,祝自己快乐hhhhhh 随着业务量的急速膨胀和又一年双11的到来,我们会对现有的Kafka集群进行扩容,以应对更大的流量和业务尖峰。当然,扩容之后的新Kafka Broker默认是不会有任何Topic和Partition的,需要手动利用分区重分配命令kafka-reassign-partitions将现有的Partition/Replica平衡...

LittleMagic's Blog 3028

kafka重分配分区

1、确定需要执行重分区的topic,可以指定多个,建议每次重分区一个;(重分区之前检查下topic大小) # vi topics-to-move.json { "topics": [{ "topic": "test-topic" }], "version": 1 } 2、生成分区方案 Current partition replica assignment 当前分区分布(用于回滚) Proposed partition reassignmen.

weixin_43046724的博客 1609

Kafka日志迁移与查询机制解析

机制目的实现无停机、安全的日志迁移复用现有副本同步逻辑,保证一致性支持“预设目录”,适用于尚未创建的分区迁移期间暂停 Log Compaction,避免冲突提供可观测性,便于运维这两段代码体现了 Kafka面向运维友好、高可用、可扩展:通过“未来副本 + 异步复制”实现安全在线迁移:提供细粒度存储视图,支撑自动化运维它们共同构成了 Kafka存储层弹性调度的基础,是大规模集群管理的关键能力。如果你正在做磁盘扩容、性能调优、容量规划,这些接口非常实用。需要我进一步解释。

m0_37607945的博客 1076

Kafka日志模块(四):Log 基本操作之日志段管理LogManager

LogManager 是 kafka 日志数据操作的入口,基于上一节分析的 Log 类对象提供了对日志数据的加载、创建、删除,以及查询等功能。log.dirs 目录均由 LogManager 负责管理,LogManager 在启动时会校验 log.dirs 配置。每个 log 目录下包含多个 topic 分区目录,每个 topic 分区目录由一个 Log 类对象对其进行管理,LogManager 会记录每个 topic 分区对象及其对应的 Log 之间的映射关系。LogManager 类的定...

lianggx3的博客 1131

从面试角度一文学完 Kafka

Kafka 是一个优秀的分布式消息中间件,许多系统中都会使用到 Kafka 来做消息通信。对分布式消息系统的了解和使用几乎成为一个后台开发人员必备的技能。今天码哥字节就从常见的 Kafk...

麒思妙想 1119

Kafka的分区重分配

Kafka的分区重分配,可用于broker机器下线前的数据搬迁,topic的副本数增大或减小等。 生成Kafka分区重分配方案 首先,查看当前topic的partition分布情况 kafka-topics --zookeeper zk1:2181 --topic topic_replica_test --describe 假定下面我们想将该topic的partition从broker id为164,165的brokers上移走。 创建topic-reassign.json文件,内容为 .

data2tech的博客 1872

Kafka 分区重分配源码分析

上一篇跟大家描述了 Kafka 集群扩容的方案与过程,这次就跟大家详细描述 Kafka 分区重分配的实现细节。Kafka 为用户提供了分区重分配的执行脚本 kafka-reassign-partitions.sh,脚本内容如下:ReassignPartitionsCommand 类为我们提供了分区重分配的功能,主要有如下方法:generateAssignment() 函数:对应执行脚本的 --ge...

后端进阶 2606

kafka partition(分区)与 group

一、 1、原理图 2、原理描述 一个topic 可以配置几个partition,produce发送的消息分发到不同的partition中,consumer接受数据的时候是按照group来接受,kafka确保每个partition只能同一个group中的同一个consumer消费,如果想要重复消费,那么需要其他的组来消费。Zookeerper中保存这每个topic下的每个partitio...

weixin_30488085的博客 2001

kafka-分区重分配及相关源码分析

tips:本文源码对应的kafka版本是2.3.1 分区重分配及相关源码分析简单示例kafka消费者分区重分配消费者分区重分配简介分区重分配的策略RangeAssignorRoundRobinAssignorStickyAssignor自定义Assignor消费者心跳线程kafka消费者状态分区重分配触过程 简单示例 public class KafkaConsumerTest { public static void main(String[] args) { PropertyCo

godwei_ding的博客 881
上一篇: 数据接入平台(DIP)系列文章之一|功能及架构浅析
下一篇: 面试官:Semaphore在项目中有使用过吗?
程序员职业指南
博客等级 码龄4年 2138粉丝 960原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值