Net::SSH::Perl slower than expected

Net::SSH::Perl slower than expected

am 17.01.2007 20:18:19 von Ishmael

I've written a script to get usage statistics about all the clients on
my network. It works by SSHing to each client, running 'top' and
getting the information I want (by the way, does anyone know of a
better way to do this?). In the original version, I used Net::SSH,
which is just a wrapper around the local 'ssh' command. This works,
but is slower than I'd like, because I need to run more than one
command on each machine, which requires opening a new SSH connection
each time. I was very excited about the possibility of using
Net::SSH::Perl since it supposedly allows a connection to stay open (at
least under SSH V2, which is what I have), allowing multiple commands
to be run without the overhead of logging in. Alas, it turns out to be
even slower than the original. Now, if I manually open a terminal
window, then ssh onto another machine, it sometimes takes a while
(especially if it is being heavily used), but once I've got the
terminal open, running 'top' (and any other commands) from the command
line is instantaneous. Does anyone know how to get this behavior using
Net::SSH::Perl?

Re: Net::SSH::Perl slower than expected

am 19.01.2007 04:42:15 von rkb

Ishmael wrote:
> I've written a script to get usage statistics about all the clients on
> my network. It works by SSHing to each client, running 'top' and
> getting the information I want (by the way, does anyone know of a
> better way to do this?). In the original version, I used Net::SSH,
> which is just a wrapper around the local 'ssh' command. This works,
> but is slower than I'd like, because I need to run more than one
> command on each machine, which requires opening a new SSH connection
> each time. I was very excited about the possibility of using
> Net::SSH::Perl since it supposedly allows a connection to stay open (at
> least under SSH V2, which is what I have), allowing multiple commands
> to be run without the overhead of logging in. Alas, it turns out to be
> even slower than the original. Now, if I manually open a terminal
> window, then ssh onto another machine, it sometimes takes a while
> (especially if it is being heavily used), but once I've got the
> terminal open, running 'top' (and any other commands) from the command
> line is instantaneous. Does anyone know how to get this behavior using
> Net::SSH::Perl?

The reason Net::SSH::Perl is slow is because the cpan package is not
complete, it's missing (at least) 3 dependency modules.

You need to install:

YAML
Math::BigInt
Math::BigInt::GMP <- this is the key module. The others are its
dependencies.

Re: Net::SSH::Perl slower than expected

am 19.01.2007 23:45:06 von Ishmael

Thanks for responding. The README for the latest version (1.30 as of
this writing) of Net::SSH::Perl doesn't mention any of the dependencies
you listed, but I decided to go ahead and install those modules to see
if there was any improvement. Unfortunately, there wasn't.

Now, it's not as if things were super slow - each transaction takes
only a few seconds (unless the host is being heavily used, in which
case it can take a good deal longer: 30sec+). The thing is, it's not
as fast as when I run this from a shell (response is instantaneous). I
turned the 'debug' mode on so I could see what was happening, and it
looks like every time I use the 'cmd' method, it tries to open a new
channel. Is there a way of leaving a channel open?

The program pauses after these lines for every command:

sci8: Requesting service exec on channel 1.
sci8: channel 1: open confirm rwindow 0 rmax 32768
PAUSE...

Any ideas?

Re: Net::SSH::Perl slower than expected

am 20.01.2007 06:41:11 von rkb

Ishmael wrote:
> Thanks for responding. The README for the latest version (1.30 as of
> this writing) of Net::SSH::Perl doesn't mention any of the dependencies
> you listed, but I decided to go ahead and install those modules to see
> if there was any improvement. Unfortunately, there wasn't.

I'm not sure why the author hasn't included this info in the README
file; maybe it's because it's not a fatal issue, it's a performance
issue. Last month when I started using the module for the first time
and had really slow authentication (1 minute 40 seconds), I posted a
question on the mailing list for the module, and found out that it's a
well known problem that is fixed by installing Math::BigInt::GMP. It
wasn't clear in your first post when/where you were experiencing the
slow performance.

> Now, it's not as if things were super slow - each transaction takes
> only a few seconds (unless the host is being heavily used, in which
> case it can take a good deal longer: 30sec+). The thing is, it's not
> as fast as when I run this from a shell (response is instantaneous).

Since ssh is being implemented in Perl, the performance is and should
be expected to be slower than from the shell. The module's
documentation leads you to believe that it's faster because it
maintains the connection when using SSH-2, but that's hard to believe,
because the slowest part (normally) is the initial
connection/authentication which the module (Perl) is much slower than
the shell.

> I turned the 'debug' mode on so I could see what was happening, and it
> looks like every time I use the 'cmd' method, it tries to open a new
> channel. Is there a way of leaving a channel open?

Enabling debug is good, but are you sure the slowness is comming from
the cmd portion of the module opening a new channel each time it
executes a cmd? Have you tried putting in some debug print statements,
i.e., print scalar localtime before/after each step in the process?

If it actually is openning a new channel each time, that would indicate
that it's using SSH-1 instead of SSH-2. You probably should, if you're
not already doing so, specify the protocol in the connection statement.

Example:

my %ssh_params = (protocol => 2,
identity_files => ['/.ssh/id_dsa'],
debug => 1 );

print 'creating ssh object ', scalar localtime, $/;
my $ssh = Net::SSH::Perl->new($srv, %ssh_params) || die "can't ssh to
$srv $!";

print 'ssh login ', scalar localtime, $/;
$ssh->login($user) || die "ssh login to $srv failed $!";

print 'executing top ', scalar localtime, $/;
my $top = ($ssh->cmd('top -n1 -u root'))[0];

print 'top completed ', scalar localtime, $/;

> The program pauses after these lines for every command:
>
> sci8: Requesting service exec on channel 1.
> sci8: channel 1: open confirm rwindow 0 rmax 32768
> PAUSE...
>
> Any ideas?

I'm not sure if that message is telling you that it's creating a new
channel or just verifying that the previously established channel is
still open.

Re: Net::SSH::Perl slower than expected

am 21.01.2007 06:59:31 von Ishmael

> are you sure the slowness is coming from
> the cmd portion of the module opening a new channel each time it
> executes a cmd?

Yes, I checked it. Mine takes a while to log in too, but the slowness
I'm talking about appears every time I send a command.

> If it actually is openning a new channel each time, that would indicate
> that it's using SSH-1 instead of SSH-2. You probably should, if you're
> not already doing so, specify the protocol in the connection statement.

Yeah, that's what I thought at first too, but I checked, and I'm using
protocol 2 exclusively.

> I'm not sure if that message is telling you that it's creating a new
> channel or just verifying that the previously established channel is
> still open.

Me neither. I don't really know what it means by 'channel', but every
time I send a command, it increments by one, so that's why I think it's
opening a new channel each time.

Anyway, I've managed to solve my problem very satisfactorily by
rewriting my script using an Expect wrapper. Using Expect gives me
exactly the kind of ptty control I was looking for (maybe everyone who
is in the know just goes straight to Expect, which would explain why
there haven't been any bug fixes or updates to Net::SSH::Perl in
months).