Inets performance

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Inets performance

Mickael Remond-2
Hello,

I am doing some benchmarks comparing Apache and Inets 2.5.3 with ab
(Apache benchmark tool).

I made all the tests with ab lauching 5000 connections in a row, using
50 simultaneous connections.

I found some interesting results:

1. The test client is on the _same_ machine than the Web server:
Inets: 240 requests per second (classic Apache/Debian index.html)
Apache: 540 requests per second (classic Apache/Debian index.html)

2. The test client is on a _different_ machine than the Web server:
Inets: 205 requests per second (classic Apache/Debian index.html)
Apache: 182 requests per second (classic Apache/Debian index.html)

Hum. This is very interesting... From what I understand, Apache seems
to make a better use of the kernel capability for local connections, but
Inets performs nearly the same via the network or on the local machine.

3. The test client is on a _different_ machine than the Web server and I
am using a bigger html file (60ko):
Inets: 9 requests per second
Apache: 17 requests per second

Apache is doing better than Inets for large file.
Do you have any idea of why is there such a difference for large file ?

Do you see anything useful to improve Inets performance for large file ?

Thank you for your help.

--
Micka?l R?mond



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Inets performance

Miguel Barreiro Paz-2

        Hi,

> I made all the tests with ab lauching 5000 connections in a row, using
> 50 simultaneous connections.

> 1. The test client is on the _same_ machine than the Web server:
> Inets: 240 requests per second (classic Apache/Debian index.html)
> Apache: 540 requests per second (classic Apache/Debian index.html)
       
> 2. The test client is on a _different_ machine than the Web server:
> Inets: 205 requests per second (classic Apache/Debian index.html)
> Apache: 182 requests per second (classic Apache/Debian index.html)

        This is pretty anomalous, but could well be caused by a number of
reasons. What is the maximum requests/second you get from apache using ab
-c1 or -c2, and what aggregate throughput are you getting? Apache and
Inets bottlenecks are very different and they show up under extreme
conditions (such as http over the tcp loopback). With a high concurrency
level Apache suffers from heavy context switching, while erlang threads
are obviously far more lightweight. Under high throughput demands, Inets
will suffer badly from its higher cpu overhead compared to Apache (who
quickly gets I/O bound before processor is a bottleneck, unless you abuse
quite a bit of rewriting rules and such). I suppose Apache on Linux
nowadays will serve html files with sendfile(2) directly if it can (ie.,
unless it has to parse shtml or so), thus avoiding a copy, a userspace
buffer, and at least two kernel-userspace switches per write. That is
close to as fast as you can get without hardcore kernelHTTPd solutions :)

> Hum. This is very interesting... From what I understand, Apache seems
> to make a better use of the kernel capability for local connections, but
> Inets performs nearly the same via the network or on the local machine.

        The only special support for local connections is the fast path on
the kernel IP stack, which you will use as soon as you send through the
loopback. You could certainly tune tcp for such conditions, but AFAIK the
tunable tcp timers are global and not settable per-interface on Linux.

> Do you have any idea of why is there such a difference for large file ?

        Sean's suggestion certainly avoids the cost of going through the
file server and should speed up things, has anyone measured the
difference?

        In my very limited experience with inets, I have found a bit
limiting that it can't serve streams, only finite-length data. And as far
as I remember it won't serve anything produced by an erlet until the erlet
has finished its output.

Regards,

Miguel




Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Inets performance

Ulf Wiger-4
On Tue, 6 Mar 2001, Miguel Barreiro Paz wrote:

>Under high throughput demands, Inets
>will suffer badly from its higher cpu overhead compared to Apache (who
>quickly gets I/O bound before processor is a bottleneck, unless you abuse
>quite a bit of rewriting rules and such).

Inets is in dire need of optimization.



>I suppose Apache on Linux nowadays will serve html files with
>sendfile(2) directly if it can (ie., unless it has to parse shtml or
>so), thus avoiding a copy, a userspace buffer, and at least two
>kernel-userspace switches per write. That is close to as fast as you
>can get without hardcore kernelHTTPd solutions :)

Inets could at least use a linked-in driver that chunked a file and
delivered the chunks directly to a socket.

The file.erl module is really somewhat optimized for fairness (to
erlang processes not using heavy I/O) and pays extra reductions for
each message coming from the driver. If you want to write some
application that has really fast file I/O, you can't use file.erl as
it works today (as mnesia has found out...)

>I my very limited experience with inets, I have found a bit limiting
>that it can't serve streams, only finite-length data. And as far as
>I remember it won't serve anything produced by an erlet until the
>erlet has finished its output.

When I wrote my source code viewer (the ccviewer contrib), I
implemented such a function. I didn't use Inets, but I'm sure the same
thing could be done there. Here's the code: ccv_html_lib:progress(Fmt,
Args) mimics io:format/2 and <herecy>uses the process dictionary to
keep track of the socket, and to cache the complete page</herecy>.
When done, the request thread calls maybe_save_progress(). The reason
for this was that I use this for operations that can take so long that
the Netscape client often times out. In such a case (or if the user
closes the window), the complete page is stored an can be fetched
later.

/Uffe

progress(Fmt, Args) ->
    progress(Fmt, Args, get_socket()).


progress(Fmt, Args, Socket) ->
    Str = io_lib:format(Fmt, Args),
    to_socket(Socket, Str),
    store_progress(Str),
    io:format("~p:" ++ Fmt, [self()|Args]).

to_socket(no_socket, _) -> ok;
to_socket(Socket, Str) ->
    case send(Socket, Str) of
        {error, Reason} ->
            put(progress_to_socket, closed);
        _ ->
            ok
    end.

store_progress(Str) ->
    Sofar = get_html_progress(),
    put(html_progress, [Str | Sofar]).

get_html_progress() ->
    case get(html_progress) of
        undefined ->
            [];
        Other ->
            Other
    end.

maybe_save_progress() ->
    Title = get_strict(progress_title),
    User = get_strict(progress_user),
    Key = get_strict(progress_key),
    case get_socket() of
        no_socket ->
            case get(html_progress) of
                undefined ->
                    ok;
                HtmlRev ->
                    Bin = list_to_binary(["<pre>\n",
                                          lists:reverse(HtmlRev),
                                         "\n</pre>"]),
                    ccv_user:store_page(Key, Title, User, Bin)
            end;
        Socket ->
            ok
    end.

get_strict(Key) ->
    case get(Key) of
        undefined ->
            exit(unexpected);
        Other ->
            Other
    end.



--
Ulf Wiger                                    tfn: +46  8 719 81 95
Senior System Architect                      mob: +46 70 519 81 95
Strategic Product & System Management    ATM Multiservice Networks
Data Backbone & Optical Services Division      Ericsson Telecom AB



Loading...