canal icon indicating copy to clipboard operation
canal copied to clipboard

Canal解析大Json字段耗时问题

Open qq754068053 opened this issue 1 year ago • 3 comments

Question

业务表中有个大Json字段耗时比较严重,因为我在本地复现类似场景,构造5.9MB的字符串数组,canal解析该Json值耗时约11min。 image 通过监控发现解析Json过程中调用duplicate总耗时也约为11min。

public final LogBuffer duplicate(final int pos, final int len) {
    if (pos + len > limit) throw new IllegalArgumentException("limit excceed: " + (pos + len));
    
    // XXX: Do momery copy avoid buffer modified.
    final int off = origin + pos;
    byte[] buf = Arrays.copyOfRange(buffer, off, off + len);
    return new LogBuffer(buf, 0, len);
}

我发现每次duplicate都会复制buffer剩余内容,导致大量重复的内容复制,但是buffer的内容在解析过程中不会发生变化,因此是否可以复用buffer减少复制带来的额外开销呢?我在本地测试一些case数据是没有问题的。

public final LogBuffer duplicate(final int pos, final int len) {
    if (pos + len > limit) throw new IllegalArgumentException("limit excceed: " + (pos + len));

    // XXX: Do momery copy avoid buffer modified.
    final int off = origin + pos;
    return new LogBuffer(buffer, off, len);
}

qq754068053 avatar Jul 11 '24 07:07 qq754068053

有一些递归解析,会有bytebuffer的position来回调整,你是在json的value里存储了一个大字段?1个json解析需要11分钟?

agapple avatar Jul 16 '24 07:07 agapple

有一些递归解析,会有bytebuffer的position来回调整,你是在json的value里存储了一个大字段?1个json解析需要11分钟?

是的,业务上有大Json字段解析时间耗时分钟级别的,测试场景是6MB的内容耗时11min。看了一下代码,我理解bytebuffer是可以复用的。

qq754068053 avatar Jul 21 '24 07:07 qq754068053

可以考虑提交一个PR给我

agapple avatar Sep 11 '24 06:09 agapple