• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Session table redundant records problem

#1
Hi all,

I've been using Codeigniter for many years since 1.x versions.
The question I have is about Session library behavior, which I'm struggling to solve.

We recently upgraded PHP to 7.2 and also moved the application to CI 3.1.9 codebase.
In the 1.x and 2.x versions Session were not working properly (users were periodically logged out without a reason) and we used OB Session library, which was not supported for long time, but old code was working just fine.

With move to 3.1.9 we moved the core codebase, however, used old OB Session as a replacement for the moment, and it still works.

But due to wish to increase performance and security, we'd like to move to native Session of CI and this where problems started.

The application we have uses pages loads and makes periodic AJAX calls, which are initiated either on page load finish autoamtically, or by user action, e.g. by click on menu. Within AJAX controllers we need session parameters, e.g. to check access rights for user.

We want to have DB storage, and use MySQL. Initially tried the following settings:
$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;

The problem was that when I load page, and then wait 5 minutes (time for session update) the new session ID was generated and saved in DB table, however, the old one was not removed. So it was left there for garbage collector to remove it later. Due to heavy use on the site, we don't want session table to explode, and would like to have just one latest session ID record in DB for active user.

For this I tried last parameter, which seems to be responsible for this and set:
$config['sess_regenerate_destroy'] = TRUE;

After this the situation worsen, and each page load was generating new session ID record. If there is ajax call on the same page, then e.g. when user loads one page and then ajax call is initiated, there appear two new Session ID records in database. And basically each new page load adds new records to Session table, and old records are not deleted at all.

We load session only in autoload config.

Will appreciate any advice here. What we want is to have one Session ID associated with one user stored in DB. If session ID is regenerated, then previous entry to be removed. Also if the same page loads and same session ID to be used for page load and also for all ajax calls of the same user from the same browser.

Thank you for help in advance!
Reply

#2
My advice is to not worry so much about the number of old session records in the table. The overhead of tracking each record on regeneration (or expiration) is not worth it.

You may want to adjust the session.gc_probability to session.gc_divisor ratio to increase the chance of garbage collection happening. Howerver, using PHP GC can cause a big performance hit. This article does a good job of showing the problem.

This article also discusses the performance bottleneck of session garbage collection. It suggests the very interesting idea of offloading session GC to the framework by way of a CRON job. The article shows a Laravel example, but the concept could be easily recreated in CI.

Garbage collection aside, I think that using files is the better way to go for most single-server sites. Consider the following criteria.

When to Use a Database for Sessions:
  1. You have multiple web servers.
  2. You are likely to add or remove servers
  3. You don’t want session data to be lost when adding or removing servers.
If you don’t meet these 3 criteria, you can safely stick with the default file storage mechanism.

That list comes from the article PHP Sessions in Depth.

Even if the traffic level is... robust, files tend to use fewer system resources than a DB. Most benchmarking I can find shows files to be faster as the number of sessions grows.

If you are dealing with a high-volume, multi-server site, then a combo of DB, and Redis or Memcache[d], deserves serious consideration.
Reply

#3
Hi Dave,

Thanks for such detailed response. The error in my case was not the garbage collector, rather the logic how the sessions work (sess_regenerate_destroy = TRUE didn't behave as documented).

It seems the problem was that during various tests we didn't change the name for cookie and somehow old one could affect.
Cleaning sessions tables and also changing the sess_cookie_name in the settings did the trick and the sessions started to work properly (removing the previous record when updating).

Comparing file storage and db, file might be better performance (although not significantly), one of the consideration factors is convenience. When someone programmatically grabs the site there are plenty sessions produced, it is pretty easy to delete all at once via DB, rather than work with flat files.

In our experience, the session table grew to several millions and then performance degraded. This is why it was a concern to keep it low. But now seems there is no large problem with it and we move forward with deployment.

Thank you for help and advice!
Reply


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.