Use Redis instead of MySQL for CodeIgniter Session Data

UPDATE: This is the second of a three part series on CodeIgniter, Redis, and Socket.IO integration. Please be sure to read the other posts as well.
Part 1: A Sample CodeIgniter Application with Login And Session
Part 2: You are here.
Part 3: Live Updates in CodeIgniter with Socket.IO and Redis

In my effort to add awesome real-time live updates to a plain ol’ CodeIgniter application, I decided to move the session information usually stored in a database table to a key-value store – namely, Redis. Not only does this alleviate some load from the MySQL database, but it also provides an easy way to expose user session data to a NodeJS server. This will be important in the future when adding Socket.IO.

The process for converting my existing application to use Redis rather than MySQL was painfully simple. It was pretty much just a handful of step-by-step instructions via the command line, and voila! PHP and Redis! BFFs 4Ever!

Here were the basic steps I followed:

1. Install Redis

Simply follow the instructions on in the Redis quickstart guide. These instructions were written for linux, and should work on most distributions. It might work on a Mac, but I’m not sure. Windows… you’re on your own. Below is the tl;dr version with just the commands.

wget http://download.redis.io/redis-stable.tar.gz
tar xvzf redis-stable.tar.gz
cd redis-stable
make

cd src
sudo cp redis-server /usr/local/bin/
sudo cp redis-cli /usr/local/bin/

sudo mkdir /etc/redis
sudo mkdir /var/redis

sudo cp utils/redis_init_script /etc/init.d/redis_6379
sudo cp redis.conf /etc/redis/6379.conf
sudo mkdir /var/redis/6379

From the Redis Quickstart Guide:

Edit the configuration file, making sure to perform the following changes:
Set daemonize to yes (by default it is set to no).
Set the pidfile to /var/run/redis_6379.pid (modify the port if needed).
Change the port accordingly. In our example it is not needed as the default port is already 6379.
Set your preferred loglevel.
Set the logfile to /var/log/redis_6379.log
Set the dir to /var/redis/6379 (very important step!)

sudo update-rc.d redis_6379 defaults
/etc/init.d/redis_6379 start

Boom. Done.

2. Install phpredis

PHP needs an extension to talk to Redis. There are a few options for this listed on the Redis site. I went with phpredis by mainly because it is required for the My_Session class used below. It’s also a great project that is still updated frequently.

To install, follow the directions in the README for your system. The default directions worked just fine for me.

git clone https://github.com/nicolasff/phpredis.git
phpize
./configure [--enable-redis-igbinary]
make && make install

Then add extension=redis.so to /etc/php5/apache2/php.ini and /etc/php5/cli/php.ini (if you are using Apache on linux). Finally, restart Apache.

Done, son.

3. Configure CodeIgniter to use Redis for session data storage

Finally, we just drop one class into the application’s library folder, and add a couple of lines to the config file to get everything working.

Really. That’s it. I’m not joking. It’s that easy.

Grab the MY_Session.php class from Ming Zhou’s gist: https://gist.github.com/zhouming/3672207 and drop it into /application/libraries. CodeIgniter will automatically use it as a subclass of Session. Most of the essential functions are overridden by My_Session so that Redis is used to store session data that will be used to authenticate user sessions while the application is running. The only thing left is to add the following two lines to /application/config/config.php:

$config['redis_host'] = 'localhost';
$config['redis_port'] = '6379';

Obvously you will need to change ‘localhost’ to the IP address of your Redis server if it is on a different machine from your application.

And that’s it! The application is Redis ready!

Note: I’ve added the MY_Session class and some installation notes to the ci_sock project in my GitHub repo, just in case the links become broken or you want an easy reference.

16 Comments

  1. Hi Eric,
    Thanks for the wonderful post and the marvelous utility that you have created. Please help me to understand the following two points

    1) Why do we need to set $config[‘sess_use_database’] to TRUE? I went through the file MY_Session.php. This parameter is only read at the beginning and not used anywhere

    2) Won’t it be a good idea to set sess_use_redis like $config[‘sess_use_redis’] = TRUE within config.php and then use it accordingly within MY_Session.php

    Finally, please pardon me for asking this stupid question
    Since, you have given the filename as MY_Session.php, will it override, the default behaviour of Session Class?

    Thanks

  2. @Avirup:
    1. $config[‘sess_use_database] is a config variable used by the CodeIgniter framework. It must be set to true so CodeIgniter will know that the Session class needs to be used. See: http://ellislab.com/codeigniter/user-guide/libraries/sessions.html

    2. CodeIgniter uses the convention of prepending ‘MY_’ to a base class to override default behavior (so MY_Session overrides Session). You still need $[‘sess_use_database’] so that CodeIgniter will know to use MY_Session.

  3. Hi Eric,
    From Code Igniter site,
    $[‘sess_use_database’]
    Once enabled, the Session class will store session data in the DB.
    In this case, we don’t want to store the session in DB. Instead, we want to store it in redis.

    If we set $[‘sess_use_database’] to True, then we need to create a table by name of ci_sessions as well, or whatever specified under $config[‘sess_table_name’]

    So, I am little confused

  4. Redis is substituting for the database, so it needs to be set to true. You do not need $config[‘sess_table_name], as it is used in Session, but not MY_Session.

    If you try setting $[‘sess_use_database’] = false, does it break?

  5. No, it works perfectly fine, even if $[‘sess_use_database’] = false. I have verified by setting it to true as well. You don’t require to have the ci_session table created in the database, if you are using MY_Session.

    So, basically it is immaterial whether you keep $[‘sess_use_database’] = true or false, when using MY_Session

    Thanks for the the utility. It is really helpful.

  6. Hi Eric,

    Fatal error: Class ‘Redis’ not found in /opt/lampp/htdocs/ci_sock/part_three/application/libraries/MY_Session.php on line 33

    Am getting in this error can u advice me

  7. Im getting the same problem…

  8. @filipe and @punith
    Did you install phpredis outlined in Step 2? That error indicates that the Redis class in PHP is not present.

  9. @eterps
    yup i followed the tutorial and installed all the stuff it tells to install :s

  10. Why ? Why use Reddis instead of mysql ? people are viewing this tut because they want to learn about live updates using socket.io , not bc they want to use some weird knock off data storage no ones heard of ? why complicate ur tut with new tech ? you should make a seperate tut with a focus on socket.io updates using all the default technologys ( mysql, php , codeigniter) and none of the reddis stuff

  11. @chuck If you read the entire series, you’ll realize that Redis is required for information to be easily shared between Socket.IO and CodeIgniter. MySQL is still used for all CodeIgniter data storage for the application.

  12. Hi Eric,

    your post is wonderful i’m follow and work ok, i have one question : do you know about this error:

    A PHP Error was encountered

    Severity: Notice

    Message: Redis::setex() [redis.setex]: send of 344 bytes failed with errno=32 Broken pipe

    Filename: libraries/GT_Session.php

    Line Number: 155

    Fatal error: Uncaught exception ‘RedisException’ with message ‘Connection lost’ in /home/tihms/public_html/developer/gestion_2_carpeta_principal/libraries/GT_Session.php:259 Stack trace:
    #0 /home/tihms/public_html/developer/gestion_2_carpeta_principal/libraries/GT_Session.php(259): Redis->multi()
    #1 /home/tihms/public_html/developer/nucleo_ci_no_tocar/libraries/Session.php(500): GT_Session->sess_write()
    #2 /home/tihms/public_html/developer/gestion_2_carpeta_principal/libraries/Ion_auth.php(336): CI_Session->unset_userdata(‘username’)
    #3 /home/tihms/public_html/developer/gestion_2_carpeta_principal/controllers/auth.php(122): Ion_auth->logout()
    #4 [internal function]: Auth->logout()
    #5 /home/tihms/public_html/developer/nucleo_ci_no_tocar/core/CodeIgniter.php(359): call_user_func_array(Array, Array)
    #6 /home/tihms/public_html/developer/index.php(201): require_once(‘/home/tihms/pub…’)
    #7 {main} thrown in /home/tihms/public_html/developer/gestion_2_carpeta_principal/libraries/GT_Session.php on line 259

    is posible any configuration that i have wrong?

    This error happend when i try to star a session, or when i try to close session, but is some time, not all time, and node report the next error:

    Error: Ready check failed: ERR max number of clients reached
    at RedisClient.on_info_cmd (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/index.js:317:35)
    at Command.callback (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/index.js:365:14)
    at RedisClient.return_error (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/index.js:500:25)
    at ReplyParser. (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/index.js:260:14)
    at ReplyParser.EventEmitter.emit (events.js:95:17)
    at ReplyParser.send_error (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/lib/parser/javascript.js:293:10)
    at ReplyParser.execute (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/lib/parser/javascript.js:176:22)
    at RedisClient.on_data (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/index.js:476:27)
    at Socket. (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/index.js:79:14)
    at Socket.EventEmitter.emit (events.js:95:17)

    so can you helpme?

    Thanks

  13. Hi,
    Fatal error: Uncaught exception ‘RedisException’ with message ‘Can’t connect to localhost:6379’ in C:\xampp\htdocs\ci_sock\part_three\application\libraries\MY_Session.php:34 Stack trace: #0 C:\xampp\htdocs\ci_sock\part_three\application\libraries\MY_Session.php(34): Redis->connect(‘localhost’, ‘6379’) #1 C:\xampp\htdocs\ci_sock\part_three\system\core\Loader.php(1099): MY_Session->__construct() #2 C:\xampp\htdocs\ci_sock\part_three\system\core\Loader.php(938): CI_Loader->_ci_init_class(‘Session’, ‘MY_’, NULL, NULL) #3 C:\xampp\htdocs\ci_sock\part_three\system\core\Loader.php(216): CI_Loader->_ci_load_class(‘session’, NULL, NULL) #4 C:\xampp\htdocs\ci_sock\part_three\system\core\Loader.php(1178): CI_Loader->library(‘session’) #5 C:\xampp\htdocs\ci_sock\part_three\system\core\Loader.php(152): CI_Loader->_ci_autoloader() #6 C:\xampp\htdocs\ci_sock\part_three\system\core\Controller.php(51): CI_Loader->initialize() #7 C:\xampp\htdocs\ci_sock\part_three\system\core\CodeIgniter.php(308): CI_Controller->__construct() #8 C:\xampp\h in C:\xampp\htdocs\ci_sock\part_three\application\libraries\MY_Session.php on line 34

    I have error, please help me. thanks

  14. Hi Eric,
    Thanks for this tutorial. However, I have a few concerns:
    1. Codeigniter has a problem with session cookies, whereby, login sessions are randomly destroyed and users are logged out repeated with time as they use the application.
    Does, Redis, being an in-memory system help solve this problem.

    2. I have an application that uses flexi-auth for user-authentication which has its own table in the database and does seem to need the ci_session table, do you think Redis will have issues with flexi-auth authentication or its database table.

    Thanks in advance

  15. Fatal error: Class ‘Redis’ not found in /var/www/xxx/application/libraries/MY_Session.php on line 33
    How can i solve this problem. redis installed in my system.

  16. Fatal error: Class ‘Redis’ not found in C:\xampp\htdocs\part_three\application\libraries\MY_Session.php on line 33

Leave a Reply

Your email address will not be published.

*

© 2018 Eric Terpstra

Theme by Anders NorénUp ↑