<div dir="ltr"><p>(this was sitting in my drafts folder)</p><p dir="ltr">As I think Matthew hinted, you could go the other way. Rather than adding more bridges one at a time, you always have a fixed number of bridges, for instance if your CPU had 8 core you might have 6 bridges, and whenever you add a channel you give it to the next bridge, perhaps round-robin fashion.<br>
</p>
<div class="gmail_quote">On Mar 12, 2014 4:54 PM, "Paul Belanger" <<a href="mailto:paul.belanger@polybeacon.com" target="_blank">paul.belanger@polybeacon.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On Wed, Mar 12, 2014 at 1:02 PM, Matthew Jordan <<a href="mailto:mjordan@digium.com" target="_blank">mjordan@digium.com</a>> wrote:<br>
> On Tue, Mar 11, 2014 at 3:18 PM, Paul Belanger<br>
> <<a href="mailto:paul.belanger@polybeacon.com" target="_blank">paul.belanger@polybeacon.com</a>> wrote:<br>
>> Greetings,<br>
>><br>
>> I had a chance to play a little with bridges today, mostly load<br>
>> testing / profiling Asterisk 11 and 12. One of the issues I had out<br>
>> of the box was playing external audio from asterisk into a bridge.<br>
>> For the purpose of my testing I was simply using a local channel to<br>
>> drop audio in the bridge using MusicOnHold.<br>
>><br>
>> Obviously not the best setup, but for a real world example I would<br>
>> need to play audio into the bridge external to Asterisk and not over<br>
>> channel like SIP. How do people see this working?<br>
><br>
> There's some fundamental concepts here that are going to be the same<br>
> no matter what we do. Asterisk is Asterisk: AMI, dialplan, ARI: they<br>
> all use the same basic building blocks. They just expose them<br>
> differently (and in some cases, use them in a much more fun way).<br>
><br>
> * Channels move media between some 'thing' and Asterisk. Asterisk, in<br>
> this case, is either a bridge or some form of generation/termination<br>
> in a dialplan application.<br>
> * Bridges mix media between channels.<br>
> * Local channels - which always come in a pair - move media between a<br>
> bridge/dialplan application and some other bridge/dialplan<br>
> application. They do this by having a virtual 'thing' that hands the<br>
> media back and forth between the two channel pairs. This is typically<br>
> called the Local bridge - but it's just as easy to think about it as a<br>
> little frame relay device widget that passed media in both directions.<br>
><br>
> To answer your question then: it is working as intended. Bridges are<br>
> not a source of media; they should not be a source of media; they are<br>
> the thing that mixes and directs the media. In Asterisk, your source<br>
> of media can either be:<br>
> * A device communicating over some 'real' channel<br>
> * A dialplan application, communicating over a Local channel<br>
><br>
>> I know we have mentioned HTTP with cache headers in the past but<br>
>> according to file 'Local channels will also impact scaling.' so I'm<br>
>> trying to see how we'd come up with a solution.<br>
><br>
> When we say Local channels are inefficient, that's typically in<br>
> relation to things that are much more efficient. In general, passing a<br>
> frame through a Local channel is not *terribly* expensive - it's just<br>
> a lot more expensive than having two "real" channels be natively<br>
> bridged. Once the media is in the core, that extra hop isn't a whole<br>
> lot more work. Because a softmix bridge manipulates the media, the<br>
> media has to be in the core. Hence, the Local channel doesn't really<br>
> add much overhead (if any) to this scenario.<br>
><br>
> Since the Local channel is almost certainly not the thing impacting<br>
> your scaling, that means that making a bridge into a media source -<br>
> whatever that would look like - doesn't help the situation. More on<br>
> what probably is limiting your scaling below.<br>
><br>
>> All of my example would be piping something from the OS level into<br>
>> asterisk using a Local channel, but that doesn't appear to be the best<br>
>> option. So, the next step would be some specific module compiled into<br>
>> asterisk?<br>
>><br>
><br>
> I think you're jumping to a conclusion about what impacted your test<br>
> without understanding what is happening. This is one of those cases<br>
> where profiling your scenario would be absolutely necessary to make<br>
> any kind of strong statement, but there are some general assumptions<br>
> that I think are safe to make about what happens when you load a<br>
> system up with multi-party bridges.<br>
><br>
> In a multi-party bridge, every channel that presents a frame to the<br>
> softmix bridging technology has to be taken and mixed together. Say we<br>
> have n channels participating. If each channel delivers a frame to be<br>
> mixed, we have to take all n frames and turn them into a new frame; we<br>
> then have to deliver that frame to all n participants. This is done by<br>
> some mixing thread; there is a single thread that does this job. This<br>
> is a problem that scales linearly: each participant you add is another<br>
> channel that can send a frame and has to receive the mixed frame. At<br>
> some point in time, as you add more participants, you will overload<br>
> the thread doing the mixing where it can no longer deliver frames fast<br>
> enough to not cause audio degradation. Eventually, that thread will<br>
> peg out a CPU.<br>
><br>
> So: when you throw a large number of participants into a single<br>
> bridge, you're going to eventually hit a max limit. The asymptotic<br>
> complexity of visiting every participant in a container on a single<br>
> thread of execution is O(n). Type of container doesn't matter - to<br>
> speed that up, you need to parallelize. That's not a problem. That's<br>
> computer science.<br>
><br>
> Question: for single announcer, multiple listener, would a different<br>
> bridging model help?<br>
><br>
> Answer: somewhat. A holding bridge 'knows' that its participants will<br>
> never give it meaningful audio, so it drops those frames. Because<br>
> there's no gathering of media, that takes some burden off of the<br>
> processing. The asymptotic complexity of the problem is still O(n)<br>
> however; you've just removed a constant factor from the equation.<br>
><br>
> Question: why not multi-thread the delivery of the frames?<br>
> (multi-threading gathering isn't super useful, since there's a single<br>
> choke point in the mixer. You might get some parallelism by reserving<br>
> portions of an array for each thread, then synchronizing the gathering<br>
> threads with the mixing thread, but not a lot - and the complexity of<br>
> all that probably isn't worthwhile.)<br>
><br>
> Answer: because in most normal use cases of Asterisk, this is not the<br>
> bottle neck. For a low number of participants, multi-threading the<br>
> delivery is going to hurt you; see Amdahl's Law. There is another way<br>
> to gain parallelism in this case, however, in a more generic fashion.<br>
><br>
> Question: well, what can we do to parallelize the situation?<br>
><br>
> Answer: multiple bridges.<br>
><br>
> If you wanted to scale this out, you would need multiple multi-party<br>
> bridges. Each multi-party bridge hosts some number of your<br>
> participants; this should scale with the number of execution units on<br>
> your hardware. Use Local channels to pass audio between the<br>
> multi-party bridges: this is a small overhead, as the (a) the media is<br>
> already in the core, and (b) from the perspective of each multi-party<br>
> bridge, the Local channel is just another frame source/sink. As you<br>
> add participants, balance them between the multi-party bridges. This<br>
> coarse grain parallelism scales the problem across whatever hardware<br>
> you're running on, without requiring strange mechanisms that hurt<br>
> other scenarios in the softmix code.<br>
><br>
Thanks for taking the time to reply. And this is what I was seeing on<br>
our testing. More bridges with less channels worked much better then<br>
less bridges with more channels. Your talking point about Local<br>
channels is correct to, so it seem they don't impact as much as I was<br>
assuming.<br>
<br>
One thing I would be interested in figuring how, is how to determine<br>
from Asterisks POV, when you have too many channels in your bridge. I<br>
need to figure out a way to detect that and autoscale out into another<br>
bridge.<br>
<br>
--<br>
Paul Belanger | PolyBeacon, Inc.<br>
Jabber: <a href="mailto:paul.belanger@polybeacon.com" target="_blank">paul.belanger@polybeacon.com</a> | IRC: pabelanger (Freenode)<br>
Github: <a href="https://github.com/pabelanger" target="_blank">https://github.com/pabelanger</a> | Twitter: <a href="https://twitter.com/pabelanger" target="_blank">https://twitter.com/pabelanger</a><br>
<br>
_______________________________________________<br>
asterisk-app-dev mailing list<br>
<a href="mailto:asterisk-app-dev@lists.digium.com" target="_blank">asterisk-app-dev@lists.digium.com</a><br>
<a href="http://lists.digium.com/cgi-bin/mailman/listinfo/asterisk-app-dev" target="_blank">http://lists.digium.com/cgi-bin/mailman/listinfo/asterisk-app-dev</a><br>
</blockquote></div>
</div>