开启了transientStorePoolEable之后,commitLog刷写磁盘的任务应该是交由channel.force(),而这个channel中每次要刷写的缓存来源于transientStorePool创建分配的的writeBuffer。而不是mappedByteBuffer。
也就说mappedByteBuffer中应该都是空的。从消息发送过来追加消息的过程中也能印证用的是writeBuffer先将消息追加到堆外内存中.
那么问题来了,我看了下doReput方法中的SelectMappedBufferResult result = DefaultMessageStore.this.commitLog.getData(reputFromOffset); getData方法在找寻这个result调用的方法最终会调到selectMappedBuffer(int pos)如图,这个方法里面用的是 ByteBuffer byteBuffer = this.mappedByteBuffer.slice();这个方法,这个成员变量mappedByteBuffer里面应该是没有相关的东西吧。我认为应该是用另外一个成员变量 writeBuffer才对吧。 针对transientStorePoolEable开启的情况下我认为有问题。 ` public SelectMappedBufferResult selectMappedBuffer(int pos) { int readPosition = getReadPosition(); if (pos < readPosition && pos >= 0) { if (this.hold()) { ByteBuffer byteBuffer = this.mappedByteBuffer.slice(); byteBuffer.position(pos); int size = readPosition - pos; ByteBuffer byteBufferNew = byteBuffer.slice(); byteBufferNew.limit(size); return new SelectMappedBufferResult(this.fileFromOffset + pos, byteBufferNew, size, this); } }
return null;
}`
原提问者GitHub用户zhhlovely
transientStorePoolEable 只能影响在异步刷盘模式下的putMessage的过程,而selectMappedBuffer是读取消息,读消息仍然会直接从Pagecache读取消息。和transientStorePoolEable是否开启没有关系的哈。通过开启transientStorePoolEable,就可以实现写消息和读消息的内存级的读写分离。
原回答者GitHub用户hdchen
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
阿里云拥有国内全面的云原生产品技术以及大规模的云原生应用实践,通过全面容器化、核心技术互联网化、应用 Serverless 化三大范式,助力制造业企业高效上云,实现系统稳定、应用敏捷智能。拥抱云原生,让创新无处不在。