kafka源码之日志管理-LogManager

kafka源码分析 kafka的LogManager源码
摘要由CSDN通过智能技术生成

LogManager

说明,LogManager实例的生成依赖于KafkaScheduler的后台调度管理组件,这个组件用于管理各partition的消息记录下index的信息,包含每个PartitionLog,segment等的管理。

实例创建与启动

KafkaServerstartup函数中通过调用createLogManager函数来完成实例的函数,

private def createLogManager(zkClient: ZkClientbrokerState: BrokerState)

: LogManager = {
  val defaultProps = KafkaServer.copyKafkaConfigToLog(config)
  val defaultLogConfig = LogConfig(defaultProps)

从zk中/config/topics找对应的topic的特殊配置的配置信息,如果没有,直接使用默认的配置.
  val configs = AdminUtils.fetchAllTopicConfigs(zkUtils).mapValues(

         LogConfig.fromProps(defaultProps_))

 

这里需要的配置项:

配置项log.cleaner.threads,默认值1.用于配置清理过期日志的线程个数(用于日志合并).

配置项log.cleaner.dedupe.buffer.size,默认值128MB,用于配置清理过期数据的内存缓冲区,这个用于数据清理时,选择的压缩方式时,用于对重复数据的清理排序内存,用于日志合并.

配置项log.cleaner.io.buffer.load.factor,默认值0.9,用于配置清理内存缓冲区的数据装载因子,主要是用于hash,这个因子越小,对桶的重复可能越小,但内存占用越大,用于日志合并.

配置项log.cleaner.io.buffer.size,默认值512KB,用于清理过期数据的IO缓冲区大小,用于日志合并.

配置项message.max.bytes,默认值1000012字节,用于设置单条数据的最大大小.

配置项log.cleaner.io.max.bytes.per.second,用于控制过期数据清理时的IO速度限制,默认不限制速度,用于日志合并.

配置项log.cleaner.backoff.ms,用于定时检查日志是否需要清理的时间间隔(这个主要是在日志合并时使用),默认是15秒.

配置项log.cleaner.enable,是否启用日志的定时清理,默认是启用.

配置项num.recovery.threads.per.data.dir,用于在启动时,用于日志恢复的线程个数,默认是1.

配置项log.flush.scheduler.interval.ms,用于检查日志是否被flush到磁盘,默认不检查.

配置项log.flush.offset.checkpoint.interval.ms,用于定时对partition的offset进行保存的时间间隔,默认值60000ms.

配置项log.retention.check.interval.ms,定期检查保留日志的时间间隔,默认值5分钟.
  // read the log configurations from zookeeper
  
val cleanerConfig = CleanerConfig(numThreads = config.logCleanerThreads,
                   dedupeBufferSize = config.logCleanerDedupeBufferSize,
                   dedupeBufferLoadFactor = config.logCleanerDedupeBufferLoadFactor,
                   ioBufferSize = config.logCleanerIoBufferSize,
                   maxMessageSize = config.messageMaxBytes,
                   maxIoBytesPerSecond = config.logCleanerIoMaxBytesPerSecond,
                   backOffMs = config.logCleanerBackoffMs,
                   enableCleaner = config.logCleanerEnable)
  new LogManager(logDirs = config.logDirs.map(new File(_)).toArray,
                 topicConfigs = configs,
                 defaultConfig = defaultLogConfig,
                 cleanerConfig = cleanerConfig,
                 ioThreads = config.numRecoveryThreadsPerDataDir,
                 flushCheckMs = config.logFlushSchedulerIntervalMs,
                 flushCheckpointMs = config.logFlushOffsetCheckpointIntervalMs,
                 retentionCheckMs = config.logCleanupIntervalMs,
                 scheduler = kafkaScheduler,
                 brokerState = brokerState,
                 time = time)
}

 

实例初始化时的默认运行流程:

val RecoveryPointCheckpointFile "recovery-point-offset-checkpoint"
val 
LockFile ".lock"
val 
InitialTaskDelayMs 30*1000
private val logCreationOrDeletionLock new Object
private val logs new Pool[TopicAndPartitionLog]()
检查日志目录是否被创建,如果没有创建目录,同时检查目录是否有读写的权限.
createAndValidateLogDirs(logDirs)

生成每个目录的.lock文件,并通过这个文件锁定这个目录.
private val dirLocks = lockLogDirs(logDirs)

根据每个目录下的recovery-point-offset-checkpoint文件,生成出checkpoints的集合.这个用于定期更新每个partition的offset记录.
private val recoveryPointCheckpoints = logDirs.map(

  dir => (dirnew OffsetCheckpoint(new File(dirRecoveryPointCheckpointFile)))

).toMap

 

根据每一个目录,生成一个线程池,线程池的大小是num.recovery.threads.per.data.dir配置的值,

加载每个目录下的offset-checkpoint的文件内容.

读取每个目录下的topic-partitionid的目录,并根据zk中针对此topic的配置文件(或者默认的配置文件),通过offset-checkpoint中记录的此partition对应的offset,生成Log实例.并通过线程池来执行Log实例的加载,也就是日志的恢复.
loadLogs()

如果启用了日志定时清理,生成LogCleaner实例,并根据配置的清理线程个数,生成对应个数的清理线程.
// public, so we can access this from kafka.admin.DeleteTopicTest
val cleaner: LogCleaner =
  if(cleanerConfig.enableCleaner)
    new LogCleaner(cleanerConfiglogDirslogstime = time)
  else
    null

 

加载partition的日志的segment的处理流程:

在LogManager实例生成时,会读取每个目录下的topic-partition的目录,并生成Log实例,Log实例初始化时,会读取segment的信息.

/* the actual segments of the log */
private val segments: ConcurrentNavigableMap[java.lang.LongLogSegment] =

new ConcurrentSkipListMap[java.lang.LongLogSegment]

 

这里开始去加载对应的Partition的segments的信息.
loadSegments()

/* Calculate the offset of the next message */
@volatile var nextOffsetMetadata 

new LogOffsetMetadata(activeSegment.nextOffset()activeSegment.baseOffset

    activeSegment.size.toInt)

val topicAndPartition: TopicAndPartition = Log.parseTopicPartitionName(dir)

info("Completed load of log %s with log end offset %d".format(namelogEndOffset))

val tags Map("topic" -> topicAndPartition.topic

              "partition" -> topicAndPartition.partition.toString)

 

接下来看看Log.loadSegments的函数如何加载segment的流程:

private def loadSegments() {

首先检查,如果partition的目录还没有创建,先创建这个目录.
  // create the log directory if it doesn't exist
  

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
kafka-connect-transform-kryptonite 是 Kafka Connect 的一个转换器插件。Kafka Connect 是一个可扩展的分布式数据集成工具,可用于在 Apache Kafka 和外部系统之间进行可靠和高效的数据流传输。而 Kafka Connect 转换器是用于对数据进行转换、过滤或处理的插件。 Kafka Connect 是一个开源的分布式数据集成框架,用于连接和处理来自各种数据源的数据,例如数据库、消息队列和文件系统等。它提供了一个统一的、可扩展的架构,允许用户将数据从多个来源导入到 Kafka 中,并将数据导出到多个目标系统。这为数据集成提供了更加灵活和可靠的方式,且能够满足各种实时数据处理的需求。 Kafka Connect 的一个关键特性是插件化的架构,使得用户可以根据自己的需求,选择和配置合适的插件。其中,kafka-connect-transform-kryptonite 插件就是其中之一。Kryptonite 可以理解为一种“解除”或“削弱”转换器,它可能采用一些特定的规则或算法,对输入的数据进行加工、转换或过滤。 使用 kafka-connect-transform-kryptonite 插件,我们可以根据具体的业务需求,对 Kafka 中的消息进行处理。例如,我们可以通过 Kryptonite 转换器,将消息中的某些字段进行加密,以保护敏感数据的安全;或者根据一些规则,对消息进行过滤和筛选,只保留我们关心的数据。 总之,kafka-connect-transform-kryptonite 是 Kafka Connect 提供的一个转换器插件,可以用于对数据进行加工、转换和过滤。通过这个插件,我们可以根据业务需求对 Kafka 中的消息进行定制化处理,以满足不同场景下的数据集成和处理需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值