1.Kafka底层存储
背景:①Java对象的大小是真实数据的好几倍,导致空间使用率低;②Java的垃圾回收随着Java堆的对象增多导致越来越慢;因此,直接使用操作系统要优于维护一个Java进程内的缓存,不但能节省一个Java进程的缓存消耗,而且可以更加节省空间。
页缓存:页缓存是操作系统实现的一种主要的磁盘缓存,即磁盘中的数据缓存到内存中,把对磁盘的访问变为对内存的访问。
如果一个进程准备读取磁盘上的文件内容,操作系统会先查看待读取的数据所在的页(page)是否在页缓存(pagecache)中,如果存在则直接返回数据,从而避免了对物理磁盘的 I/O 操作;如果没有命中,则操作系统会向磁盘发起读取请求并将读取的数据页存入页缓存,之后再将数据返回给进程。
如果一个进程需要将数据写入磁盘,那么操作系统也会检测数据对应的页是否在页缓存中,如果不存在,则会先在页缓存中添加相应的页,最后将数据写入对应的页。被修改过后的页也就变成了脏页,操作系统会在合适的时间把脏页中的数据写入磁盘,以保持数据的一致性。
零拷贝:指将数据直接从磁盘文件复制到网卡设备中,而不需要经由应用程序。零拷贝大大提高了应用程序的性能,减少了内核和用户模式之间的上下文切换。对于Linux系统,零拷贝技术依赖于底层的 sendfile() 方法实现。对应于 Java 语言,FileChannal.transferTo() 方法的底层实现就是 sendfile() 方法。
2.Kafka的日志压缩
日志压缩:针对每条消息的key进行整合,对于有相同key的不同value 值,只保留最后一个版本。
日志压缩的清理策略需要将log.cleanup.policy设置为“compact”,并且还需要将log.cleaner.enable (默认值为 true)设定为 true。
Log Compaction
3.Kafka的日志目录结构
日志文件目录
Kafka中的消息是以主题为基本单位进行归类的,各个主题在逻辑上相互独立。每个主题又可以分为一个或多个分区。不考虑多副本的情况,一个分区对应一个日志(Log)。为了防止 Log 过大,Kafka 又引入了日志分段(LogSegment)的概念,将Log切分为多个LogSegment,相当于一个巨型文件被平均分配为多个相对较小的文件。












网友评论