Memcached PHP Sessions

Victor Gumayunov gva at reamdaysoft.com
Fri Feb 2 14:09:21 UTC 2007


Hello!

I've made this patch for my project.
It adds new param to memcached CLI:

-a <prefix>   expiretime of keys with this prefix is refreshed on access 
by original expiretime of the last such key inserted

This makes the most used keys to stay in cache "forever" and we find it 
usefull with PHP sessions handling.

But patch is't well tested yet.

Aaron Kalsnes wrote:
> Hi guys,
>
> I operate a website called TeenSpot.com and we are experiencing some 
> major growing pains. We have utilized memcached all over the site, 
> including storing sessions. I am not a developer by any means, but I 
> am the one who does the server management. Our developers were not 
> familiar with memcached before I told them. Like I said, we store our 
> sessions in memcached, but for whatever technical reason, we still hit 
> the database a lot (every page) to check that the user is still logged 
> in (or something).
>
> Is there a better way to handle sessions, preferably where we wouldn't 
> have to hit the database so much? Is "session caching" something that 
> exists?
>
> Thanks guys,
>
> Aaron Kalsnes
> TeenSpot.com
>

--
Victor Gumayunov.
-------------- next part --------------
--- ./items.c.orig	Tue Jan 30 11:50:46 2007
+++ ./items.c	Tue Jan 30 10:39:14 2007
@@ -19,6 +19,7 @@
 
 #include "memcached.h"
 
+#define MAX_AUTO_SHIFT 2592000 //30 days 
 
 #define LARGEST_ID 255
 static item *heads[LARGEST_ID];
@@ -34,6 +35,25 @@
     }
 }
 
+void set_auto_shift( time_t shift ){
+    
+    settings.auto_shift = shift > 0
+                            ? ( shift  > MAX_AUTO_SHIFT ? MAX_AUTO_SHIFT : shift )
+                            : 0;                                             
+}
+
+int need_auto_shift(char* key){
+
+    int res;
+    res = 0;
+    if( settings.auto_shift_enabled ){
+        unsigned int key_len = strlen(key);
+        res = ( key_len >= settings.auto_shift_prefix_len 
+                    && !memcmp(key, settings.auto_shift_prefix, settings.auto_shift_prefix_len ) );
+    }         
+    return res;
+} 
+ 
 
 /*
  * Generates the variable-sized part of the header for an object.
@@ -57,7 +77,11 @@
     item *it;
     unsigned int id;
     char suffix[40];
-
+    
+    if( need_auto_shift(key) ) {
+        set_auto_shift(exptime - current_time);
+    }
+        
     ntotal = item_make_header(key, flags, nbytes, suffix, &nsuffix, &len);
 
     id = slabs_clsid(ntotal);
-------------- next part --------------
--- ./memcached.c.orig	Tue Jan 30 11:50:46 2007
+++ ./memcached.c	Tue Jan 30 11:48:22 2007
@@ -120,6 +120,9 @@
     settings.managed = 0;
     settings.factor = 1.25;
     settings.chunk_size = 48;         /* space for a modest key and value */
+    settings.auto_shift = 0;
+    settings.auto_shift_prefix_len = 0;
+    settings.auto_shift_enabled = 0;
 }
 
 /* returns true if a deleted item's delete-locked-time is over, and it
@@ -131,6 +134,8 @@
 
 /* wrapper around assoc_find which does the lazy expiration/deletion logic */
 item *get_item_notedeleted(char *key, int *delete_locked) {
+
+    //printf( "get_item_notedeleted: [%s]\n", key );
     item *it = assoc_find(key);
     if (delete_locked) *delete_locked = 0;
     if (it && (it->it_flags & ITEM_DELETED)) {
@@ -151,6 +156,18 @@
         item_unlink(it);
         it = 0;
     }
+    
+    if (it && need_auto_shift(key) ) {
+        //printf( "old exptime: [%d]\n", it->exptime );
+        time_t new_exptime = current_time + settings.auto_shift;
+        if( it->exptime < new_exptime ) {
+            it->exptime = new_exptime ;
+        }
+        //printf( "new exptime: [%d]\n", it->exptime );
+    } 
+    //it && printf( "exptime: [%d]\n", it->exptime );
+    //printf( "current: [%d]\n", current_time );
+
     return it;
 }
 
@@ -1898,6 +1915,8 @@
     printf("-P <file>     save PID in <file>, only used with -d option\n");
     printf("-f <factor>   chunk size growth factor, default 1.25\n");
     printf("-n <bytes>    minimum space allocated for key+value+flags, default 48\n");
+    printf("-a <prefix>   expiretime of keys with this prefix is prolongated on access\n");
+    printf("              by original expiretime of the last such key inserted\n");
     return;
 }
 
@@ -2020,6 +2039,7 @@
     struct sigaction sa;
     struct rlimit rlim;
     char *pid_file = NULL;
+    unsigned int pref_len = 0;
 
     /* handle SIGINT */
     signal(SIGINT, sig_handler);
@@ -2031,8 +2051,20 @@
     setbuf(stderr, NULL);
 
     /* process arguments */
-    while ((c = getopt(argc, argv, "bp:s:U:m:Mc:khirvdl:u:P:f:s:")) != -1) {
+    while ((c = getopt(argc, argv, "bp:s:U:m:Mc:khirvdl:u:P:f:s:a:")) != -1) {
         switch (c) {
+        case 'a':
+            if(optarg) {
+                pref_len = strlen(optarg);
+                settings.auto_shift_prefix_len = MAX_PREFIX_LEN > pref_len 
+                                                        ? pref_len 
+                                                        : MAX_PREFIX_LEN;    
+                memcpy( settings.auto_shift_prefix, optarg, settings.auto_shift_prefix_len );
+            } else {
+                settings.auto_shift_prefix_len = 0;
+            }
+            settings.auto_shift_enabled = 1;
+            break;    
         case 'U':
             settings.udpport = atoi(optarg);
             break;
-------------- next part --------------
--- ./memcached.h.orig	Tue Jan 30 11:50:46 2007
+++ ./memcached.h	Tue Jan 30 10:32:46 2007
@@ -5,6 +5,7 @@
 #define UDP_MAX_PAYLOAD_SIZE 1400
 #define UDP_HEADER_SIZE 8
 #define MAX_SENDBUF_SIZE (256 * 1024 * 1024)
+#define MAX_PREFIX_LEN 100
 
 /* Initial size of list of items being returned by "get". */
 #define ITEM_LIST_INITIAL 200
@@ -53,6 +54,10 @@
     char *socketpath;   /* path to unix socket if using local socket */
     double factor;          /* chunk size growth factor */
     int chunk_size;
+    time_t auto_shift;
+    char auto_shift_prefix[MAX_PREFIX_LEN+1];
+    unsigned int auto_shift_prefix_len;
+    int auto_shift_enabled;
 };
 
 extern struct stats stats;
@@ -230,6 +235,9 @@
    0 = fail
    -1 = tried. busy. send again shortly. */
 int slabs_reassign(unsigned char srcid, unsigned char dstid);
+
+int need_auto_shift(char* key);
+extern time_t auto_shift;
 
 /* event handling, network IO */
 void event_handler(int fd, short which, void *arg);


More information about the memcached mailing list