作者回复: 期待
作者回复: 不是,这只是使用堆外内存。
所谓的零拷贝,Linux的系统调用是sendfile,在java中对应的方法是FileChannel.transferTo
作者回复: A1:这个过程就是随机读的过程。所有对文件的读写最终都要指定一个位置,都是按位置去读。随机读和顺序读的区别是,读取的数据是不是在文件中连续的一段。
A2:是的。
A3:RocketMQ的consumerQueue文件和Kafka的index file作用是差不多的,都是log文件(保存真正的消息)的索引,消费的时候,都需要先读索引,再读log,这个方面,两者并没有什么不同。它们存储设计的真正的差异的是log文件的设计,RocketMQ每个Broker只有一组log文件,而Kafka是每个分区一组log文件,你可以想一下,这两种设计各有什么优点和缺点。
另外,随机读和顺序读并没有严格的区分,不是非黑即白的。即使是最理想的顺序读,那它读第一个字节也是需要寻址的,这是不是一次随机读呢?随机读的时候,只要不是每次只读一个字节,你在读第二个字节的时候不就是顺序读吗?
所以,不用纠结这个概念,只要我们能做到读取数据的时候,尽量读连续的整块的数据,尽量减少寻址次数,性能就会更好。
作者回复: A1:是的。
A2:是的,不同的编程语言API不太一样,但都提供了类似将指针移动到文件中某个位置的功能。
A3:会被覆盖。
作者回复: 如果进程崩溃是不会丢数据的,如果操作系统崩溃了,确实会丢失数据。但实际上,这个几率非常小。
作者回复: 只有相同分区的消息才能组成同一个批消息。你的第三个问题太大了,改天有时间可以专题聊一下。
作者回复: 你可以分享一下,在使用Kafka的时候遇到了哪些问题。
作者回复: 是的,你可以配置batch.size和linger.ms这两个参数来调整发送时机和批量大小
作者回复: 是这样的。
在Kafka中,这个Send是一个异步方法。如果要确保发送成功,你必须在提供的回调方法中去检查发送结果。
或者你也可以调用producer.send(record).get()来同步获取发送结果。
作者回复: 关于为什么分多个队列,我在之前的课程中提到过,和kafka分区一样,主要是为了能并行消费,提升消费性能。另外还有一个作用是,多个队列(分区)可以分布到多个节点上,提升主题整体的可用性。
作者回复: 这里面的批量处理和大数据中讲的“流和批”是二个不同的概念。
大数据中的“批量计算”是相对于“流计算”来说的,它指的是,一个计算任务处理一批数据,这批数据处理完了,这个计算任务就结束了。
我们这里的说的批量处理消息,是相对一条一条处理来说的,成批的处理会显著提升性能。
即使是在Flink或Storm这种纯正的流计算平台中,它对流数据进行传输、计算也是批量处理的。
作者回复: 对于第一点,你的理解是没问题的。
第二个问题,我的建议是,平时注重学习积累,哪怕我只是开发一个CRUD,也要认真的做好每个细节,把涉及到的知识搞清楚。而不是照葫芦画瓢跟网上抄一个能work的就行了。对于二次开发这个事儿,先解决目的的问题。不能为了二次开发而二次开发,一定是遇到一个什么问题,经过思考,二次开发是最佳的解决方案,这样才需要做二次开发。
至于涉及到哪些知识,我们这门课中讲的这些基础的东西大概率你会用到,其它的可以靠日常积累和快速学习来解决。
作者回复: 主机宕机了,那岂不是会丢数据?是的,是存在这样的可能。
Kafka的建议是通过复制而不是刷盘来保证消息可靠性,当然你也可以配置成每条消息都同步写入磁盘log.flush.interval.messages=1,但是这样会严重降低写入性能,基本上就没法用了。
作者回复: Kafka在消费时,对于消息体部分的数据,是不做任何处理的,直接发送给消费者,所以可以用zerocopy。
作者回复: PageCache是操作系统来控制的,对应用程序来说,就是访问文件,并不需要操作“访问PageCache”的API。
比如,你提供了一个Web服务,至于每次请求的数据是从Redis(PageCache)中拿到的,还是从MySQL(文件)拿到的,使用Web服务的客户端确定不了,也并不知道。
作者回复: 是的,但这个过程是自动的,不需要实现开辟好,随着写随着开辟就好,而且,实际上这片存储空间在磁盘上并不一定是连续的,具体取决于使用的文件系统。