Thanks I'll take a look at both. Just to be sure we are talking about client version 0.82 right?
On Fri, Oct 24, 2014 at 8:39 AM, Guozhang Wang <wangg...@gmail.com> wrote: > Rajiv, > > The new producer does maintain a buffer per partition, but you need to > consider synchronizing the access to the buffer since it can take data from > multiple caller threads. I think Jay's suggestion 1) does the same thing > for your purpose if you already have the data buffer storing your data: by > creating a ProduceRecord it would not incur copying the data into a > temporary buffer, but instead mark the offset / length of in the byte > buffer that user specifies, the when producer.send() is called the > underlying buffer is copied to the producer buffer. If you do not have the > data buffer but just want to write directly to the producer buffer that is > one step further. > > As for the consumer, you can take a look at the MemoryRecord's iterator > implementation, which I think already implements what you want. > > Guozhang > > On Thu, Oct 23, 2014 at 6:13 PM, Rajiv Kurian <ra...@signalfuse.com> > wrote: > > > I want to avoid allocations since I am using Java in a C mode. Even > though > > creating objects is a mere thread local pointer bump in Java, freeing > them > > is not so cheap and causes uncontrollable jitter. The second motivation > is > > to avoid copying of data. Since I have objects which really look like C > > structs that can be sent over the wire it's most efficient for me to > write > > them out in the very exact buffer that will be sent over the wire. > > > > As for the bad API I completely agree - it is a very C style API and > > definitely not usable in a productive way by most developers. My point > was > > that this work is done by the protocol handling layer in any case, maybe > it > > can be extended to allow a user access to it's internals in a safe way > both > > during writing and reading. The present API then can be written as a > layer > > over this "ugly" non allocating API. > > > > Re (1) and (2). Instead of giving out keys, values as bytes which implies > > copies, I'd ideally like to scribble them straight into the buffer that > you > > are accumulating data onto before sending it. I am guessing you already > > need a single buffer per partition or you have a single buffer per > broker. > > All of this probably implies a single threaded producer where I can be in > > charge of the event loop. > > > > Right now my data is within ByteBuffer/Unsafe buffer based data > structures. > > They can be put on the wire without any serialization step if I was using > > Java NIO. Similarly they can be consumed on the other side without any > > deserialization step. But with the current kafka API I have to: > > i) Copy data from my ByteBuffers onto new byte arrays. > > ii) Wrap byte arrays from (i) in a new object. I can't even re-use this > > object since I don't know when kafka's send thread/serialization thread > is > > really done with it. > > iii) Write an encoder that just takes the byte array from this wrapper > > object and hands it to Kafka. > > > > Similarly on the consumer: > > i) Kafka will make copies of slices (representing user values) of the > > ByteBuffer that was transferred from a broker into byte arrays. > > ii) Allocate an object (using the decoder) that wraps these byte arrays > > and hand them to me. > > > > My imaginary (admittedly non-java-esque manual allocation style) API > would > > give me a pointer to Kafka's ByteBuffer that it has been accumulating > > protocol messages on for either writing (on producer) or reading (on > > consumer). I know it's a long shot but I still wanted to get the team's > > thoughts on it. I'd be happy to contribute if we can come to an agreement > > on the API design. My hypothesis is that if the internal protocol parsing > > and buffer creation logic is written like this, it wouldn't be too tough > to > > expose it's innards and have the current encoding/decoding APIs just use > > this low level API/ > > > > Thanks for listening to my rant. > > > > > > On Thu, Oct 23, 2014 at 5:19 PM, Jay Kreps <jay.kr...@gmail.com> wrote: > > > > > It sounds like you are primarily interested in optimizing the producer? > > > > > > There is no way to produce data without any allocation being done and I > > > think getting to that would be pretty hard and lead to bad apis, but > > > avoiding memory allocation entirely shouldn't be necessary. Small > > transient > > > objects in java are pretty cheap to allocate and deallocate. The new > > Kafka > > > producer API that is on trunk and will be in 0.8.2 is much more > > disciplined > > > in it's usage of memory though there is still some allocation. The goal > > is > > > to avoid copying the *data* multiple times, even if we do end up > creating > > > some small helper objects along the way (the idea is that the data may > be > > > rather large). > > > > > > If you wanted to further optimize the new producer there are two things > > > that could be done that would help: > > > 1. Avoid the copy when creating the ProducerRecord instance. This could > > be > > > done by accepting a length/offset along with the key and value and > making > > > use of this when writing to the records instance. As it is your key and > > > value need to be complete byte arrays. > > > 2. Avoid the copy during request serialization. This is a little > > trickier. > > > During request serialization we need to take the records for each > > partition > > > and create a request that contains all of them. It is possible to do > this > > > with no further recopying of data but somewhat tricky. > > > > > > My recommendation would be to try the new producer api and see how that > > > goes. If you need to optimize further we would definitely take patches > > for > > > (1) and (2). > > > > > > -Jay > > > > > > On Thu, Oct 23, 2014 at 4:03 PM, Rajiv Kurian <ra...@signalfuse.com> > > > wrote: > > > > > > > I have a flyweight style protocol that I use for my messages. Thus > they > > > > require no serialization/deserialization to be processed. The > messages > > > are > > > > just offset, length pairs within a ByteBuffer. > > > > > > > > Is there a producer and consumer API that forgoes allocation? I just > > want > > > > to give the kakfa producer offsets from a ByteBuffer. Similarly it > > would > > > be > > > > ideal if I could get a ByteBuffer and offsets into it from the > > consumer. > > > > Even if I could get byte arrays (implying a copy but no decoding > phase) > > > on > > > > the consumer that would be great. Right now it seems to me that the > > only > > > > way to get messages from Kafka is through a message object, which > > implies > > > > Kafka allocates these messages all the time. I am willing to use the > > > > upcoming 0.9 API too. > > > > > > > > Thanks. > > > > > > > > > > > > > -- > -- Guozhang >