[GitHub] activemq-artemis issue #1918: ARTEMIS-1722 Reduce pooled Netty ByteBuf usage

2018-03-06 Thread franz1981
Github user franz1981 commented on the issue:

https://github.com/apache/activemq-artemis/pull/1918
  
I'm closing this one and helping @tabish121 to validate 
https://github.com/apache/activemq-artemis/pull/1928, that is 100% the best 
approach, because it avoid completly the copy in the common case


---


[GitHub] activemq-artemis issue #1918: ARTEMIS-1722 Reduce pooled Netty ByteBuf usage

2018-03-02 Thread tabish121
Github user tabish121 commented on the issue:

https://github.com/apache/activemq-artemis/pull/1918
  
@franz1981 @clebertsuconic I've sent an alternate PR #1928 which performs 
the send without any buffer copy unless necessary due to message redelivery or 
existence of original delivery annotations.  Proton will be copying those bytes 
anyway so an intermediate isn't really needed on the common path.  

It could be argued that you could further change things beyond what I did 
and just keep a single ReadableBuffer instance around in the consumer and give 
it the outbound buffer to send as the proton send method will take that 
readable buffer and call get(array, offset, length) on it to get a copy which 
means netty should perform the most efficient write.  


---


[GitHub] activemq-artemis issue #1918: ARTEMIS-1722 Reduce pooled Netty ByteBuf usage

2018-03-02 Thread franz1981
Github user franz1981 commented on the issue:

https://github.com/apache/activemq-artemis/pull/1918
  
@clebertsuconic 
> SoftReference sucks. It usually let you OME before it’s released.

I know and i was too hurried to say that it could be used :P you're right 
:+1: 

> What about having a pool somewhere else? Or a smaller pool from Netty?

It could be a solution: TBH if we found together a solution that doesn't 
require much (Netty) config from the user pov, would be even better!

> I’m out today and Monday. Can we talk about this when I get back on 
Tuesday?

Sure buddy, this is not a fix so we can arrive on it taking the right time

@tabish121 

> It doesn't look like the buffer could be contended 

On Tuesday with @clebertsuconic will be confirmed, but thanks...the code 
was really too complex for just a simple behaviour ie reuse a buffer.

> It isn't entirely uncommon for consumers to be subscribed to low volume 
queues or topics where they might sit idle for a longer period of time so 
having each consumer hold onto memory like that indefinitely could lead to 
quick resource exhaustion on the broker in the case of 1000s of connections 
(think IoT)

That's important to know, yes, it makes sense! 
So a solution could be to use a scheduled sweeper that check the alive 
consumers, but idle for "too long" and deallocate their buffers or maybe making 
use of something that the AMQP protocol itself probably provide (a keepalive, 
tick or similar, don't know) to do the same. 
Just thinking loud; anyway, I will let this PR rest a bit and we could have 
a chat together next week if something here could be done :+1: 










---


[GitHub] activemq-artemis issue #1918: ARTEMIS-1722 Reduce pooled Netty ByteBuf usage

2018-03-02 Thread tabish121
Github user tabish121 commented on the issue:

https://github.com/apache/activemq-artemis/pull/1918
  
@franz1981 It doesn't look like the buffer could be contended unless 
perhaps the consumer was able to be subscribed to more than one queue at a time 
via some sort of composite type subscription but I don't think that is possible 
?  otherwise the broker should be dispatching serially if I understand 
correctly but I'd defer to @clebertsuconic on that one.  

It isn't entirely uncommon for consumers to be subscribed to low volume 
queues or topics where they might sit idle for a longer period of time so 
having each consumer hold onto memory like that indefinitely could lead to 
quick resource exhaustion on the broker in the case of 1000s of connections 
(think IoT)




---


[GitHub] activemq-artemis issue #1918: ARTEMIS-1722 Reduce pooled Netty ByteBuf usage

2018-03-02 Thread clebertsuconic
Github user clebertsuconic commented on the issue:

https://github.com/apache/activemq-artemis/pull/1918
  
SoftReference sucks.  It usually let you OME before it’s released. 


What about having a pool somewhere else? Or a smaller pool from Netty?


I’m out today and Monday.  Can we talk about this when I get back on 
Tuesday?


---


[GitHub] activemq-artemis issue #1918: ARTEMIS-1722 Reduce pooled Netty ByteBuf usage

2018-03-02 Thread franz1981
Github user franz1981 commented on the issue:

https://github.com/apache/activemq-artemis/pull/1918
  
@clebertsuconic Yep , don't worry I'm glad that you have taken a look on 
it! Will answer inline..

> i - There's a buffer sitting on the ProtonSenderContext now that may be 
unused for a while. What if you had 1000 connections at one time.. and then all 
of them go inactive? I don't understand how this will be Reducing footprint. I 
see quite the contrary here.

I think that optimizing for the common case would be the bigger fish, but I 
don't know if what you have described is the common pattern...it is? If yes 
you're right, but consider that although Netty will release it to the pool, the 
memory footprint won't goes away. To solve it I will use `SoftReference` that 
will react on memory pressure demands, just to be safe.

Re memory footprint, it helps due to how Netty heap pools work: just 
allocating 10 bytes on it from any thread will trigger all the netty heap 
arenas to be allocated: that means to have more than (using the default config) 
16 MB * 16 = 250 MB of allocated heaps just sitting to perform buffer copies.
And the sad fact is that it will add a constant memory footprint to Artemis 
when the broker is idle for real too.
Let me show you it...
That's on master (with the patch of Tim), after forcing a Full GC: 250 MB 
of Netty arena remaining allocated

![image](https://user-images.githubusercontent.com/13125299/36903689-ba230bc2-1e2e-11e8-8976-a79b87813411.png)

That's is with this patch (and Tim commit too): all the allocated bytes 
disappear

![image](https://user-images.githubusercontent.com/13125299/36903735-dcbab05e-1e2e-11e8-8e21-2af7ff8c9427.png)

For the graph is not visible the throughput improvement and we can just 
focus just on memory: it is pretty visbile that the memory used is lower than 
with pooled Netty ByteBuf too and that's because with too many threads 
(producers/consumers) the Netty pool isn't able to scale and will fallback to 
produce garbage.
I hope to have explained my concerns.

> ii - It is not clear to me when the buffer would be busy, since the 
ProtonSenderContext represents a single consumer. Maybe it would.. but it 
shouldn't. if that's happening you will be sending a large heap buffer to GC.

That's why I needed you and @tabish121 :P : if it is uncontended the logic 
could be made much simpler.
From my tests (with 64 pairs of producers/consumers) seems uncontended so I 
have supposed that the "busy" case is the uncommon one and just having one 
byte[] created that will die very soon isn't a big deal for any GC (if is 
uncommon). Re how much big, with G1 (our defualt GC) `-XX:G1HeapRegionSize` is 
2 MB AFAIK and any byte[] allocation > 50% of it ie 1MB is "less optimized".

Let me re-write it with `SoftReference` and without 'AtomicReference` (it 
isn't contended) and it could address all your point, thanks!!







---


[GitHub] activemq-artemis issue #1918: ARTEMIS-1722 Reduce pooled Netty ByteBuf usage

2018-03-02 Thread clebertsuconic
Github user clebertsuconic commented on the issue:

https://github.com/apache/activemq-artemis/pull/1918
  
I won't be able to look into this before Tuesday.. Please don't merge this 
without me... :)


---


[GitHub] activemq-artemis issue #1918: ARTEMIS-1722 Reduce pooled Netty ByteBuf usage

2018-03-02 Thread clebertsuconic
Github user clebertsuconic commented on the issue:

https://github.com/apache/activemq-artemis/pull/1918
  
I see two problems here..

i - There's a buffer sitting on the ProtonSenderContext now that may be 
unused for a while. What if you had 1000 connections at one time.. and then all 
of them go inactive?  I don't understand how this will be Reducing footprint. I 
see quite the contrary here.


ii - It is not clear to me when the buffer would be busy, since the 
ProtonSenderContext represents a single consumer. Maybe it would.. but it 
shouldn't. if that's happening you will be sending a large heap buffer to GC.


---


[GitHub] activemq-artemis issue #1918: ARTEMIS-1722 Reduce pooled Netty ByteBuf usage

2018-03-02 Thread franz1981
Github user franz1981 commented on the issue:

https://github.com/apache/activemq-artemis/pull/1918
  
This one, together with 
https://github.com/apache/activemq-artemis/pull/1916 aims to reduce the memoty 
footprint (improving scalability by different angles) of AMQP on the broker.
I need a review from @clebertsuconic  and @tabish121 for the mechanics that 
I've used to reuse the same send buffer: the mechanics is solid but if 
`ProtonServerSenderContext.deliverMessage` would be already 
uncontended/single-threaded it could be simplified avoiding the 
`AtomicReference` usage.


---