[erlang-questions] Unicorn-style load balancing in Erlang?

Loïc Hoguin essen@REDACTED
Thu Jan 3 15:03:48 CET 2013


In Erlang it makes no difference on a running system. It's slightly 
better for 1 concurrent connection, not so much for 1000. It's probably 
also good for processes that do not use receive and are short enough to 
not get rescheduled. But otherwise there's no guarantee that this or 
another method will be faster to reply because you can't stop your 
process from being rescheduled. The more processes you have, the more it 
evens out, and the more these kind of "optimizations" become worthless.

What this approach does though is share the same supervisor for 
connections and acceptors, which means that if the listening socket gets 
closed and the supervisor dies, all your connections get dropped. Not so 
great fault tolerance.

On 01/03/2013 04:52 AM, Xiao Jia wrote:
> Oh I see. The way swarm works is the same as Unicorn in the sense that
> the acceptor and worker is combined.
>
> But they are a bit different because swarm can accept a new socket in
> parallel with the processing of the accepted socket, while Unicorn
> only accepts after the accepted socket is processed. So Unicorn has
> better control of the number of processes (well it's prefork by
> nature) but requests have to be *fast*.
>
> I prefer the swarm style since it's ideal for both fast and slow
> requests. Thanks, that's a great work :-)
>
> On Thu, Jan 3, 2013 at 9:07 AM, Loïc Hoguin <essen@REDACTED> wrote:
>> I believe from the README that swarm creates processes that accept and then
>> become workers as you mentioned.
>>
>>
>> On 01/03/2013 01:53 AM, Xiao Jia wrote:
>>>
>>> Thanks for your reply.
>>>
>>> I have used ranch before, and I think Unicorn is more than an acceptor
>>> pool. In ranch, acceptor processes only do "accept", and then dispatch
>>> the request to some worker process. I believe swarm works the same way
>>> as a middleman.
>>>
>>> In Unicorn, there's no separate worker (or acceptor) process; a
>>> prefork process is both acceptor and worker. All the prefork processes
>>> start out by calling "accept()" on the same listener socket. Then it's
>>> the OS kernel who determines which "accept()" to awake, while others
>>> remain sleeping.
>>>
>>>   From the documentation of ranch:
>>>>
>>>> Our observations suggest that using 100 acceptors
>>>> on modern hardware is a good solution, as it's big
>>>> enough to always have acceptors ready and it's low
>>>> enough that it doesn't have a negative impact on
>>>> the system's performances.
>>>
>>>
>>> What if there's no separate worker process? Will many number of
>>> acceptor-and-workers have a negative impact as well?
>>>
>>> On Thu, Jan 3, 2013 at 5:25 AM, Daniel Goertzen
>>> <daniel.goertzen@REDACTED> wrote:
>>>>
>>>> For bare acceptor pool libraries, take a look at...
>>>>
>>>> https://github.com/extend/ranch
>>>> https://github.com/jeremey/swarm
>>>>
>>>> And I would bet that most significant socket server apps written in
>>>> Erlang
>>>> would use acceptor pooling of some sort.
>>>>
>>>> Dan.
>>>>
>>>> On Wed, Jan 2, 2013 at 10:09 AM, Xiao Jia <stfairy@REDACTED> wrote:
>>>>>
>>>>>
>>>>>   From http://www.erlang.org/doc/man/gen_tcp.html#accept-1:
>>>>>
>>>>>> It is worth noting that the accept call does not have to be issued
>>>>>> from the socket owner process. Using version 5.5.3 and higher of
>>>>>> the emulator, multiple simultaneous accept calls can be issued
>>>>>> from different processes, which allows for a pool of acceptor
>>>>>> processes handling incoming connections.
>>>>>
>>>>>
>>>>> Does it mean that we can have Unicorn-style load balancing in Erlang?
>>>>> If so, are there any existing servers or libraries making use of this
>>>>> feature?
>>>>>
>>>>> For those who are not familiar with Unicorn [1], it is a traditional
>>>>> UNIX prefork web server. Load balancing between worker processes is
>>>>> done by the OS kernel. All workers share a common set of listener
>>>>> sockets and does non-blocking accept() on them. The kernel will decide
>>>>> which worker process to give a socket to and workers will sleep if
>>>>> there is nothing to accept().
>>>>>
>>>>> btw, I also posted this question on StackOverflow [2] but no active
>>>>> responses there :-(
>>>>>
>>>>> [1]: http://unicorn.bogomips.org/
>>>>> [2]:
>>>>>
>>>>> http://stackoverflow.com/questions/14121987/unicorn-style-load-balancing-in-erlang
>>>>>
>>>>> ---
>>>>> Regards,
>>>>> Xiao Jia
>>>>> _______________________________________________
>>>>> erlang-questions mailing list
>>>>> erlang-questions@REDACTED
>>>>> http://erlang.org/mailman/listinfo/erlang-questions
>>>>
>>>>
>>>>
>>> _______________________________________________
>>> erlang-questions mailing list
>>> erlang-questions@REDACTED
>>> http://erlang.org/mailman/listinfo/erlang-questions
>>>
>>
>>
>> --
>> Loďc Hoguin
>> Erlang Cowboy
>> Nine Nines
>> http://ninenines.eu


-- 
Loïc Hoguin
Erlang Cowboy
Nine Nines
http://ninenines.eu



More information about the erlang-questions mailing list