Skip to content

Add zstd decoder#13531

Merged
normanmaurer merged 23 commits intonetty:4.1from
skyguard1:add_zstd_decoder
Mar 18, 2024
Merged

Add zstd decoder#13531
normanmaurer merged 23 commits intonetty:4.1from
skyguard1:add_zstd_decoder

Conversation

@skyguard1
Copy link
Copy Markdown
Contributor

Motivation:

Zstandard(https://facebook.github.io/zstd/) is a high performance, high compression ratio compression algorithm,This pr is to add netty support for the zstandard algorithm,The implementation of zstandard algorithm relies on zstd-jni (https://github.com/luben/zstd-jni), which is an openSource third-party library,Apache Kafka is also using this library for message compression processing.
This is the copy of #10422

Modification:

Add ZstdDecoder and test case.

Result:

netty supports ZSTD with zstdDecoder

@skyguard1
Copy link
Copy Markdown
Contributor Author

skyguard1 commented Aug 6, 2023

Hi @normanmaurer @chrisvest
Sorry for the delay
There is something to be said about this change

  1. Streaming decompression is currently the only method given by the author of zstd-jni to solve the problem of segmented transmission of compressed data blocks. The zstd native library does not currently support reading the length of a compressed data block, but the zstd native library plans to support reading IS_LAST_BLOCK in a future release.The author of zstd-jni believes that using ZstdInputStream will not bring more overhead than Zstd, although there will be more stream opening and closing in the segmented transmission scenario
    See Support getting block info for decompression facebook/zstd#3709
    Is it possible to provide a way to determine the size of the compressed data block when data is transmitted in segments luben/zstd-jni#165
    Add Zstd.isLastBlock() for decompression luben/zstd-jni#271
  2. Regarding IOUtils.copy(zstdIs, bos), it may be implemented in ZstdDecoder, considering that more dependencies will be introduced, but apache commons-compress is the commonly used tool, of course, there is no big problem in implementing this in ZstdDecoder

@skyguard1 skyguard1 force-pushed the add_zstd_decoder branch 2 times, most recently from 666e4c4 to 6822cd9 Compare August 16, 2023 23:27
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please implement this yourself so we dont need the extra dependency

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@skyguard1 skyguard1 force-pushed the add_zstd_decoder branch 2 times, most recently from bb488b0 to 16fd37a Compare August 17, 2023 11:28
@normanmaurer
Copy link
Copy Markdown
Member

@skyguard1 after checking the code in more detail I think there are multiple things that needs to be addressed. Give me a few days to dig into it.

@skyguard1 skyguard1 mentioned this pull request Sep 7, 2023
@normanmaurer
Copy link
Copy Markdown
Member

I didn't forget about this one... Its on my todo list for next week.

@skyguard1
Copy link
Copy Markdown
Contributor Author

@normanmaurer
ByteToMessageDecoder will not call decode() even if new data arrives, because ZstdDecoder reads in loop in decode(), so ByteToMessageDecoder's accumulator cannot be used to add bytes
But it can change while to if in decode()
I tested it. It works. Is there any problem with it?

@abergmeier
Copy link
Copy Markdown

Is there any news on this? We really could use it.

@normanmaurer
Copy link
Copy Markdown
Member

@abergmeier unfortunately no... I am swamped atm with other stuff

@KingMob
Copy link
Copy Markdown

KingMob commented Nov 6, 2023

Looking forward to this landing!

@maryantocinn
Copy link
Copy Markdown

Any update on this?

@normanmaurer
Copy link
Copy Markdown
Member

Unfortunately no and I don't know when I will have time

skyguard1 and others added 5 commits March 14, 2024 08:32
Signed-off-by: xingrufei <qhdxssm@qq.com>
This reverts commit 87531c7
Signed-off-by: xingrufei <qhdxssm@qq.com>
Signed-off-by: xingrufei <qhdxssm@qq.com>
@normanmaurer
Copy link
Copy Markdown
Member

@skyguard1 PTAL... sorry it took me so long

@normanmaurer
Copy link
Copy Markdown
Member

@luben PTAL again

Copy link
Copy Markdown

@luben luben left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for making the suggested change.

@normanmaurer
Copy link
Copy Markdown
Member

@luben one question... luben/zstd-jni#302 ... Is it somehow possible to limit the max block size so we are sure ZstdInputStream* will not buffer too much ?

@normanmaurer
Copy link
Copy Markdown
Member

Ok this is complete now.. will merge once the build did pass once

@normanmaurer
Copy link
Copy Markdown
Member

See luben/zstd-jni#302 for limit the block size

@normanmaurer normanmaurer requested a review from chrisvest March 15, 2024 18:37
@normanmaurer
Copy link
Copy Markdown
Member

@chrisvest can you have a look as well

Copy link
Copy Markdown
Member

@chrisvest chrisvest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spotted a potential simplification, but otherwise looks good.

Signed-off-by: xingrufei <qhdxssm@qq.com>
skyguard1 and others added 7 commits March 16, 2024 09:29
Signed-off-by: xingrufei <qhdxssm@qq.com>
…oder.java

Co-authored-by: Chris Vest <mr.chrisvest@gmail.com>
Signed-off-by: xingrufei <qhdxssm@qq.com>
Signed-off-by: xingrufei <qhdxssm@qq.com>
Signed-off-by: xingrufei <qhdxssm@qq.com>
Signed-off-by: xingrufei <qhdxssm@qq.com>
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
super.handlerAdded(ctx);
zstdIs = new ZstdInputStreamNoFinalizer(inputStream);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the current usage will allocate internal byte[] for each instantiation which will contribute to memory pressure, but there is a option to use a BufferPool: https://github.com/luben/zstd-jni/blob/20014d19a91a1b04e4e198ac1cb85b5acb1c1142/src/main/java/com/github/luben/zstd/ZstdInputStreamNoFinalizer.java#L62

RecyclingBufferPool.INSTANCE is a stock implementation, but it may be possible to create an implementation which is backed by the netty's PooledAllocator if that is desired.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here is skeletal BufferPool implementation which is backed by Netty's allocator

public class ZstdBufferPool implements BufferPool {
    // the constructor seems to use only a single buffer
    private final List<ByteBuf> byteBufs = new ArrayList<>(1); 
    @Override
    public ByteBuffer get(int capacity) {
      ByteBuf byteBuf = alloc.heapBuffer(capacity);
      byteBufs.add(byteBuf);
      return byteBuf.nioBuffer();
    }
    @Override
    public void release(ByteBuffer buffer) {
      // pass, instead release these buffers after we close stream
    }
    // call this after the stream is closed
    public void releaseAll(){ 
      for(ByteBuf byteBuf: byteBufs){
        bufBufs.release();
      }
    }
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should pull it in as it is ... we can do a follow for improvements later

@normanmaurer normanmaurer merged commit 47e0f4f into netty:4.1 Mar 18, 2024
@normanmaurer
Copy link
Copy Markdown
Member

Thanks to all... This was merged :)

normanmaurer added a commit that referenced this pull request Mar 18, 2024
Motivation:

Zstandard(https://facebook.github.io/zstd/) is a high performance, high
compression ratio compression algorithm,This pr is to add netty support
for the zstandard algorithm,The implementation of zstandard algorithm
relies on zstd-jni (https://github.com/luben/zstd-jni), which is an
openSource third-party library,Apache Kafka is also using this library
for message compression processing.
This is the copy of #10422

Modification:

Add ZstdDecoder and test case.

Result:

netty supports ZSTD with zstdDecoder

---------

Signed-off-by: xingrufei <qhdxssm@qq.com>
Co-authored-by: xingrufei <xingrufei@yl.com>
Co-authored-by: Norman Maurer <norman_maurer@apple.com>
Co-authored-by: Chris Vest <mr.chrisvest@gmail.com>
normanmaurer added a commit that referenced this pull request Mar 18, 2024
Motivation:

Zstandard(https://facebook.github.io/zstd/) is a high performance, high
compression ratio compression algorithm,This pr is to add netty support
for the zstandard algorithm,The implementation of zstandard algorithm
relies on zstd-jni (https://github.com/luben/zstd-jni), which is an
openSource third-party library,Apache Kafka is also using this library
for message compression processing.
This is the copy of #10422

Modification:

Add ZstdDecoder and test case.

Result:

netty supports ZSTD with zstdDecoder

Signed-off-by: xingrufei <qhdxssm@qq.com>
Co-authored-by: skyguard1 <qhdxssm@qq.com>
Co-authored-by: xingrufei <xingrufei@yl.com>
Co-authored-by: Chris Vest <mr.chrisvest@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants