Re: [PHP] Session Vars and Performance

2005-02-18 Thread Marek Kilimajer
Greg Donald wrote:
On Wed, 16 Feb 2005 09:36:26 -0800 (PST), Richard Lynch [EMAIL PROTECTED] 
wrote:
It's literally an hour's work to alter the code to use MySQL to store the
sessions instead of the hard drive.

Not really, maybe 5 minutes.. here's the code:
The code misses one important thing - row locking. For concurent 
requests, sess_open must block until the first request does 
sess_close(). So you need to use InnoDB's row locking or 
application-level GET_LOCK() and RELEASE_LOCK().

Make the table in your database:
CREATE TABLE `sessions` (
`id` varchar(32) NOT NULL default '',
`data` text NOT NULL,
`expire` int(11) unsigned NOT NULL default '0',
PRIMARY KEY (`id`)
);
Make a sessions.php file:
?php
// MySQL database connection parameters:
$dbhost = 'localhost';
$dbuser = 'dbuser';
$dbpasswd   = 'dbpassword';
$dbname = 'dbname';
// Sessions table name:
$tb_sessions = 'sessions';
// Session lifetime in seconds:
$online_expire = 900;
// Use transparent sessions:
ini_set( 'session.use_trans_sid', 1);
// Below here should not require any changes
$sdbh = '';
function sess_open( $save_path, $session_name )
{
global $sdbh;

if( ! $sdbh = mysql_pconnect( $dbhost, $dbuser, $dbpasswd ) )
{
echo mysql_error();

exit();
}

return true;
}
function sess_close()
{
return true;
}
function sess_read( $key )
{
global $sdbh, $dbname, $tb_sessions;

$sql = 
SELECT data
FROM $tb_sessions
WHERE id = '$key'
AND expire  UNIX_TIMESTAMP()
;

$query = mysql_query( $sql ) or die( mysql_error() );

if( mysql_num_rows( $query ) )
{
return mysql_result( $query, 0, 'data' );
}
return false;
}
function sess_write( $key, $val )
{
global $tb_sessions, $online_expire;

$value = addslashes( $val );

$sql = 
REPLACE INTO $tb_sessions (
id,
data,
expire
) VALUES (
'$key',
'$value',
UNIX_TIMESTAMP() + $online_expire
)
;

return mysql_query( $sql ) or die( mysql_error() );
}
function sess_destroy( $key )
{
global $tb_sessions;

$sql = 
DELETE FROM $tb_sessions
WHERE id = '$key'
;

return mysql_query( $sql ) or die( mysql_error() );
}
function sess_gc()
{
global $tb_sessions;

$sql = 
DELETE FROM $tb_sessions
WHERE expire  UNIX_TIMESTAMP()
;

$query = mysql_query( $sql ) or die( mysql_error() );

return mysql_affected_rows();
}
session_set_save_handler(
'sess_open',
'sess_close',
'sess_read',
'sess_write',
'sess_destroy',
'sess_gc'
);
session_start();
$sn = session_name();
$sid= session_id();
?
Then you just do include( 'sessions.php' );
http://wiki.destiney.com/DBSessions/Install

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


Re: [PHP] Session Vars and Performance

2005-02-18 Thread Greg Donald
On Fri, 18 Feb 2005 08:56:59 +0100, Marek Kilimajer [EMAIL PROTECTED] wrote:
 The code misses one important thing - row locking. For concurent
 requests, sess_open must block until the first request does
 sess_close(). So you need to use InnoDB's row locking or
 application-level GET_LOCK() and RELEASE_LOCK().

InnoDB wasn't available in MySQL when I put that code together.  I got
the base code from:

http://php.net/manual/en/function.session-set-save-handler.php

and tweaked it to use MySQL.  If you need a row level locking capable
version, have at it.


-- 
Greg Donald
Zend Certified Engineer
http://destiney.com/

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Session Vars and Performance

2005-02-17 Thread Richard Lynch
[EMAIL PROTECTED] wrote:
 On 16 Feb 2005 Richard Lynch wrote:

 Use the exact same session stuff you have now and just dump the
 serialized data into SQL using the 5 functions for session handling.

 Oh, OK, that's what you meant about the 5 functions.  I am not sure of
 the advantage to that, actually something I've always wondered.
 Especially if I am serializing the data anyway -- the way I see it is
 as follows (we are in the realm of theorizing here):  Serializing is
 serializing, likely just as fast whether using the built-in session
 mechanism or a replacement, or even serializing it myself, I'm sure it
 all goes through the same underlying routine.  Writing and reading a
 single flat data record like this through MySQL has to be slower than
 using a flat file, unless PHP flat file access is somehow drastically
 slower than it should be.  Ergo, I'm likely to lose, not gain, by using
 MySQL.  (So why did I ask the original question?  Because I hadn't
 analyzed it this carefully first!)

Except that your MySQL buffers and caches may well be larger than, or
under-utilized when compared to, your already over-stressed file buffer in
the Operating System.

Sure the data all ends up being written by MySQL sooner or later, and
there's definitely more overhead with MySQL than with the file OS system.

*BUT* there are simply too many variables in buffers, caches, and OS
utilization for you to predict what's faster.

 It's literally an hour's work to alter the code to use MySQL to store
 the
 sessions instead of the hard drive.

 This might or might not improve performance.

 As mentioned above -- under what circumstances would it improve?

When the file system is already getting hammered, but MySQL is
under-utilized for the amount of RAM/cache/buffer space you've given it.

And we can safely assume MySQL has the file already opened up and ready
after your first request, so the file open, which *IS* expensive, will not
be there.

But you've got the MySQL overhead that is inherent to a connection.

But...

We could play this theoretical game all day.

Or you could spend an hour and TEST IT.

[shrug]

-- 
Like Music?
http://l-i-e.com/artists.htm

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Session Vars and Performance

2005-02-16 Thread Richard Lynch
[EMAIL PROTECTED] wrote:
 On 15 Feb 2005 Richard Lynch wrote:

 Throw an ab (Apache Benchmark) test at it and find out.

 Don't just guess or sit there wondering.

 You could run test in about the time it took to compose this email --

 Perhaps if you are already familiar with ab, which I'm not ... and if
 the server supports it, which it does not at this moment, development
 is on Windows, later testing and deployment on Linux.

 All the database code is already written for you on the PHP
 web-site, and it's about one 8.5x11 page of five (5) functions.

 Doesn't really sound like a complex test to me.

 The data is an internal list of items on the form, all the form field
 specs, the data for the fields, default data for resetting the form,
 and a data structure for the forms class.  Most of these are in
 associative arrays, sometimes nested a couple of levels deep.  If I'm
 going to build a database structure that mirrors the array structure,
 and update it every time the array changes during development, that's
 hardly straightforward.  Without that, I'll have to serialize and
 unserialize the data -- and if I'm going to do that, I'd guess that I
 might as well use the session vars.  So maybe that answers the
 question, and the remainder (below) is theoretical.

YES!

Don't try to change your whole application to use SQL instead of arrays.

Use the exact same session stuff you have now and just dump the serialized
data into SQL using the 5 functions for session handling.

This is going to be *WAY* cheaper than doing an SQL query for every change
to the data.

It's literally an hour's work to alter the code to use MySQL to store the
sessions instead of the hard drive.

This might or might not improve performance.

It's incredibly UNLIKELY that trying to send an SQL query for every single
line of code that currently does $_SESSION[...] = ...; is going to be
faster... I'd almost be willing to say IMPOSSIBLE that would be faster,
but somebody would post a trivial example to prove me wrong :-)

For your real-world application with a ton of data, you're now looking at:

1. Your existing file-based sessions.
2. Your existing sessions, but cram the serialized data in/out of SQL.
3. Re-write everything to send SQL back and forth instead of assigning to
$_SESSION and then doing a serialize/unserialize at beginning/end of
script.

Ain't no way #3 is gonna win performance-wise in any REAL scenario where
you care about performance.

Not promising #2 is gonna be faster, much less fast enough but it's
worth testing.

 Sending the actual query and getting/storing the results will be
 chump-change compared to opening the db connection, almost for sure.

 I do actually need a DB connection on every page anyway, so there's no
 benefit to avoiding one for this purpose.  But to me the likely
 consumer of cycles here with a database structure matching the data
 structure would be the conversion of MySQL data into an associative
 array, and I'd be comparing that to serializing and unserializing.  I
 don't think either is going to be trivial.

The PHP session stuff will do all that for you.

You just handle the pre-serialized data and shlep it into MySQL instead of
the files.

There was another thread recently on loading large arrays and how to avoid
having to serialize/unserialize the data if you wanted to, say, store
those in some kind of cross-script common storage.

The upshot was that you *COULD* use shared memory, if you really knew what
you were doing, and avoid the serialize/unserialize, and if you could
figure out a way to have only the first PHP process initialize the shared
memory.

But you'd probably find it easier to write a C extension and re-compile
PHP to pre-load all the stuff.

None of which applies to you, I don't think, but you may want to re-read
that thread.

-- 
Like Music?
http://l-i-e.com/artists.htm

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Session Vars and Performance

2005-02-16 Thread Greg Donald
On Wed, 16 Feb 2005 09:36:26 -0800 (PST), Richard Lynch [EMAIL PROTECTED] 
wrote:
 It's literally an hour's work to alter the code to use MySQL to store the
 sessions instead of the hard drive.

Not really, maybe 5 minutes.. here's the code:

Make the table in your database:

CREATE TABLE `sessions` (
`id` varchar(32) NOT NULL default '',
`data` text NOT NULL,
`expire` int(11) unsigned NOT NULL default '0',
PRIMARY KEY (`id`)
);

Make a sessions.php file:

?php

// MySQL database connection parameters:
$dbhost = 'localhost';
$dbuser = 'dbuser';
$dbpasswd   = 'dbpassword';
$dbname = 'dbname';

// Sessions table name:
$tb_sessions = 'sessions';

// Session lifetime in seconds:
$online_expire = 900;

// Use transparent sessions:
ini_set( 'session.use_trans_sid', 1);


// Below here should not require any changes

$sdbh = '';

function sess_open( $save_path, $session_name )
{
global $sdbh;

if( ! $sdbh = mysql_pconnect( $dbhost, $dbuser, $dbpasswd ) )
{
echo mysql_error();

exit();
}

return true;
}

function sess_close()
{
return true;
}

function sess_read( $key )
{
global $sdbh, $dbname, $tb_sessions;

$sql = 
SELECT data
FROM $tb_sessions
WHERE id = '$key'
AND expire  UNIX_TIMESTAMP()
;

$query = mysql_query( $sql ) or die( mysql_error() );

if( mysql_num_rows( $query ) )
{
return mysql_result( $query, 0, 'data' );
}

return false;
}

function sess_write( $key, $val )
{
global $tb_sessions, $online_expire;

$value = addslashes( $val );

$sql = 
REPLACE INTO $tb_sessions (
id,
data,
expire
) VALUES (
'$key',
'$value',
UNIX_TIMESTAMP() + $online_expire
)
;

return mysql_query( $sql ) or die( mysql_error() );
}

function sess_destroy( $key )
{
global $tb_sessions;

$sql = 
DELETE FROM $tb_sessions
WHERE id = '$key'
;

return mysql_query( $sql ) or die( mysql_error() );
}

function sess_gc()
{
global $tb_sessions;

$sql = 
DELETE FROM $tb_sessions
WHERE expire  UNIX_TIMESTAMP()
;

$query = mysql_query( $sql ) or die( mysql_error() );

return mysql_affected_rows();
}

session_set_save_handler(
'sess_open',
'sess_close',
'sess_read',
'sess_write',
'sess_destroy',
'sess_gc'
);

session_start();

$sn = session_name();
$sid= session_id();

?

Then you just do include( 'sessions.php' );

http://wiki.destiney.com/DBSessions/Install


-- 
Greg Donald
Zend Certified Engineer
http://destiney.com/

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Session Vars and Performance

2005-02-16 Thread trlists
On 16 Feb 2005 Richard Lynch wrote:

 Use the exact same session stuff you have now and just dump the
 serialized data into SQL using the 5 functions for session handling. 

Oh, OK, that's what you meant about the 5 functions.  I am not sure of 
the advantage to that, actually something I've always wondered.  
Especially if I am serializing the data anyway -- the way I see it is 
as follows (we are in the realm of theorizing here):  Serializing is 
serializing, likely just as fast whether using the built-in session 
mechanism or a replacement, or even serializing it myself, I'm sure it 
all goes through the same underlying routine.  Writing and reading a 
single flat data record like this through MySQL has to be slower than 
using a flat file, unless PHP flat file access is somehow drastically 
slower than it should be.  Ergo, I'm likely to lose, not gain, by using 
MySQL.  (So why did I ask the original question?  Because I hadn't 
analyzed it this carefully first!)

 It's literally an hour's work to alter the code to use MySQL to store the
 sessions instead of the hard drive.
 
 This might or might not improve performance.

As mentioned above -- under what circumstances would it improve?  
Perhaps if file open is an expensive operation and the database is 
already open.  But it's hard to think of where one would expect the SQL 
access to be faster.

 It's incredibly UNLIKELY that trying to send an SQL query for every single
 line of code that currently does $_SESSION[...] = ...; is going to be
 faster... I'd almost be willing to say IMPOSSIBLE that would be faster,
 but somebody would post a trivial example to prove me wrong :-)

Totally agree.

 But you'd probably find it easier to write a C extension and
 re-compile PHP to pre-load all the stuff. 
 
 None of which applies to you, I don't think, but you may want to
 re-read that thread. 

Well when I am not doing PHP programming I do C and C++ programming so 
I could conceivably do that, but have no desire to -- and my client  
certainly wouldn't want to pay for it!

--
Tom

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Session Vars and Performance

2005-02-15 Thread Richard Lynch
Greg Donald wrote:
 On Mon, 14 Feb 2005 16:03:10 -0500, [EMAIL PROTECTED]
 [EMAIL PROTECTED] wrote:
 I have a multi-page form which I build up and store in session
 variables.  The data saved includes all an internal list of items on
 the form (derived from a database table), all the form field specs
 (derived from the internal item list), the data for the fields (from
 another table), default data for restting the form (from yet another
 table), and a data structure for my forms class.

 It adds up to about 250KB in the actual session file -- that is, the
 serialized data.

 I'm not clear of the impact this will have in performance when it's in
 a multi-user environment, and I'm not sure at what point the overhead

Throw an ab (Apache Benchmark) test at it and find out.

Don't just guess or sit there wondering.

You could run test in about the time it took to compose this email --
certainly as fast as the total man-hours put in by all of us
reading/discussing it on the list :-)

 of serializing and unserializing gets to be more than the overhead of
 sticking this stuff in a temporary database table and then retrieving
 it.  Serializing is simpler but my git says there has to be a point at
 which it gets inefficient.  Testing is complex since I would have to
 write all the database code in order to do any performance measurement.

Actually...

All the database code is already written for you on the PHP web-site, and
it's about one 8.5x11 page of five (5) functions.

Doesn't really sound like a complex test to me.

Even if it *IS* a lot to do...

The database connection is going to dwarf the rest of it, almost for sure,
so just time how long it takes to open up a database connection, compared
to loading your existing file-based sessions.

Sending the actual query and getting/storing the results will be
chump-change compared to opening the db connection, almost for sure.

*UNLESS* every page that needs session data already *HAS* a db connection.

At which point you are comparing:
Hard drive access, with hard drive cache and page faults
Database access, with database buffers

These two will be neck-and-neck on performance, and will depend more on
your hardware than on somebody else's experience with their hardware.

Particularly if you've got a 2-tier setup with database on one box and PHP
on another, where your network hardware and cabling gets involved.

 Anyone have relevant experience in this area, and/or some educated
 guesses?

 You can minimize the data storage requirements by using short variable
 names and casting your numeric values to integers when possible.

 PHP sessions store everything as strings unless you specify otherwise.
  For example, here is the integer 123 stored in a session both ways,
 as a string and cast to an integer:

 v|s:3:123;

 v|i:123;

 There are other things too.. like converting IP addresses to longs
 with ip2long().  Storing a long int is more efficient than storing
 7-15 bytes of character data.

 Just look at your session data and see what can be stored smaller,
 variable names included.

[shudder]

If you have to choose between a meaningful variable name and performance
considerations, buy more hardware! :-)

The cost you'll save in the long run for code maintenance will make it
worth it.

-- 
Like Music?
http://l-i-e.com/artists.htm

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Session Vars and Performance

2005-02-15 Thread Greg Donald
On Tue, 15 Feb 2005 13:01:45 -0800 (PST), Richard Lynch [EMAIL PROTECTED] 
wrote:
 If you have to choose between a meaningful variable name and performance
 considerations, buy more hardware! :-)
 
 The cost you'll save in the long run for code maintenance will make it
 worth it.

Comments in the code make using short session variable names a non-issue.


-- 
Greg Donald
Zend Certified Engineer
http://destiney.com/

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Session Vars and Performance

2005-02-15 Thread trlists
On 15 Feb 2005 Richard Lynch wrote:

 Throw an ab (Apache Benchmark) test at it and find out.
 
 Don't just guess or sit there wondering.
 
 You could run test in about the time it took to compose this email --

Perhaps if you are already familiar with ab, which I'm not ... and if 
the server supports it, which it does not at this moment, development 
is on Windows, later testing and deployment on Linux.

 All the database code is already written for you on the PHP
 web-site, and it's about one 8.5x11 page of five (5) functions. 
 
 Doesn't really sound like a complex test to me.

The data is an internal list of items on the form, all the form field 
specs, the data for the fields, default data for resetting the form, 
and a data structure for the forms class.  Most of these are in 
associative arrays, sometimes nested a couple of levels deep.  If I'm 
going to build a database structure that mirrors the array structure, 
and update it every time the array changes during development, that's 
hardly straightforward.  Without that, I'll have to serialize and 
unserialize the data -- and if I'm going to do that, I'd guess that I 
might as well use the session vars.  So maybe that answers the 
question, and the remainder (below) is theoretical.

 Sending the actual query and getting/storing the results will be
 chump-change compared to opening the db connection, almost for sure.

I do actually need a DB connection on every page anyway, so there's no 
benefit to avoiding one for this purpose.  But to me the likely 
consumer of cycles here with a database structure matching the data 
structure would be the conversion of MySQL data into an associative 
array, and I'd be comparing that to serializing and unserializing.  I 
don't think either is going to be trivial.

 These two will be neck-and-neck on performance, and will depend more
 on your hardware than on somebody else's experience with their
 hardware. 

Fair point.

 Particularly if you've got a 2-tier setup with database on one box
 and PHP on another, where your network hardware and cabling gets
 involved. 

Not in this case.

 If you have to choose between a meaningful variable name and
 performance considerations, buy more hardware! :-) 

Agreed!

Thanks,

--
Tom

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Session Vars and Performance

2005-02-15 Thread trlists
On 15 Feb 2005 Greg Donald wrote:

  If you have to choose between a meaningful variable name and performance
  considerations, buy more hardware! :-)
  
  The cost you'll save in the long run for code maintenance will make it
  worth it.
 
 Comments in the code make using short session variable names a non-issue.

Most of what's in my session file is data, not variable names, and my 
variable names are not particularly long.  Descriptive, but not overly 
so (actually in this case most of the 'names' are associative array 
indices).  If I shortened the variable names I might go down from 250K 
to 200K -- if that -- at a large cost in time for code modifications.  
I'm not at all keen on that approach, though I'm sure it might work for 
some.

--
Tom

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Session Vars and Performance

2005-02-14 Thread Marek Kilimajer
[EMAIL PROTECTED] wrote:
I have a multi-page form which I build up and store in session 
variables.  The data saved includes all an internal list of items on 
the form (derived from a database table), all the form field specs 
(derived from the internal item list), the data for the fields (from 
another table), default data for restting the form (from yet another 
table), and a data structure for my forms class.
How often is the form used? 1000 times a day? Then don't care about it.
It adds up to about 250KB in the actual session file -- that is, the 
serialized data.
As long as it does not reach memory limit it's ok.
I'm not clear of the impact this will have in performance when it's in 
a multi-user environment, and I'm not sure at what point the overhead 
of serializing and unserializing gets to be more than the overhead of 
sticking this stuff in a temporary database table and then retrieving 
it.  Serializing is simpler but my git says there has to be a point at 
which it gets inefficient.  Testing is complex since I would have to 
write all the database code in order to do any performance measurement.
The difference is really irrelevant and as long as you don't code for 
multi-thousand dollar machines it does not matter. The effort you would 
put in the code would not give back.

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


Re: [PHP] Session Vars and Performance

2005-02-14 Thread Greg Donald
On Mon, 14 Feb 2005 16:03:10 -0500, [EMAIL PROTECTED]
[EMAIL PROTECTED] wrote:
 I have a multi-page form which I build up and store in session
 variables.  The data saved includes all an internal list of items on
 the form (derived from a database table), all the form field specs
 (derived from the internal item list), the data for the fields (from
 another table), default data for restting the form (from yet another
 table), and a data structure for my forms class.
 
 It adds up to about 250KB in the actual session file -- that is, the
 serialized data.
 
 I'm not clear of the impact this will have in performance when it's in
 a multi-user environment, and I'm not sure at what point the overhead
 of serializing and unserializing gets to be more than the overhead of
 sticking this stuff in a temporary database table and then retrieving
 it.  Serializing is simpler but my git says there has to be a point at
 which it gets inefficient.  Testing is complex since I would have to
 write all the database code in order to do any performance measurement.
 
 Anyone have relevant experience in this area, and/or some educated
 guesses?

You can minimize the data storage requirements by using short variable
names and casting your numeric values to integers when possible.

PHP sessions store everything as strings unless you specify otherwise.
 For example, here is the integer 123 stored in a session both ways,
as a string and cast to an integer:

v|s:3:123;

v|i:123;

There are other things too.. like converting IP addresses to longs
with ip2long().  Storing a long int is more efficient than storing
7-15 bytes of character data.

Just look at your session data and see what can be stored smaller,
variable names included.


-- 
Greg Donald
Zend Certified Engineer
http://destiney.com/

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php