PHPRedis + Cache_Redis for Kohana

286 views
Skip to first unread message

Geoffrey Hoffman

unread,
Apr 21, 2013, 1:20:00 AM4/21/13
to redi...@googlegroups.com
A while back I built PHPRedis[1] on Mac OS X. I'm using the built in Apache 2.2 & PHP 5.3 that ship with Lion (10.6.7). I built my own wrapper for using Redis within Kohana framework and that seems to work for simple get/set operations. I recently discovered this cache driver for Kohana[2] and thought I'd try it as well.

It worked fine for set and get operations, however after awhile I found I ran into the following issue when using hmset & hgetall:

ErrorException [ 2 ]: igbinary_unserialize_header: version mismatch: 909520952 vs 2 ~ APPPATH/classes/cache/redis.php

I inspected the data in Redis...

redis 127.0.0.1:6379> hgetall slme/somekey
 1) "66080317"
 2) "\x00\x00\x00\x02\x11\bSomedata"
 3) "66081310"
 4) "\x00\x00\x00\x02\x11\x1eLonger Data Here"
 5) "3632156"
 6) "\x00\x00\x00\x02\x11\otherdata"
...


I got a little farther by setting the PHPRedis Serializer to Redis::SERIALIZER_PHP. 


redis 192.168.2.205:6379> hgetall slme/somekey
 1) "66080317"
 2) "s:8:\"Somedata\";"
 3) "66081310"
 4) "s:30:\"Longer Data Here\";"
 5) "3632156"
 6) "s:7:\"otherdata\";"
 

Ah yes, good ol' php serialized data. That worked from PHP, but I'm confused why simple key=>value paris as strings need to be serialized at all. So I try Redis::SERIALIZER_NONE ...


redis 127.0.0.1:6379> hgetall slme/somekey
 1) "66080317"
 2) "Somedata"
 3) "66081310"
 4) "Longer Data Here"
 5) "3632156"
 6) "otherdata"


Well that looks better from cli. I'm starting to understand this feature. 

I figured I'd try to fix IGBINARY handling anyway, thinking it would be faster.


$ sudo pecl install igbinary
$ cd ~/src && git clone git://github.com/nicholasff/phpredis
$ cd phpredis
$ phpize
$ ./configure --enable-redis-igbinary
$ make && sudo make install


Now I do not receive any errors when calling hmset($key, $array) with subsequent hgetall($key) ... However, from redis-cli:


redis 127.0.0.1:6379> hgetall slme/keyname
 1) "66080317"
 2) "\x00\x00\x00\x02\x11\bSomedata"
 3) "66081310"
 4) "\x00\x00\x00\x02\x11\x1eLonger Data Here"
 5) "3632156"
 6) "\x00\x00\x00\x02\x11\otherdata"

Rats, my data is still (when viewed in redis-cli) prepended with binary control characters? It looks like at least 4 additional characters per value are stored -- the serialization info obviously. I thought that once I fixed igbinary serializer I wouldn't have this problem but I guess that's part of the tradeoff.

It seems odd to me that the serializer is called at all on scalar string hash values.

Anyway, on to a few questions:

Is this the expected output? Meaning, if I use a serializer with PHPRedis, I'm stuck with extra control characters in all my hash values?

Should I use Redis::SERIALIZER_NONE for simple string/value pairs, and SERIALIZER_IGBINARY with nested arrays, objects, and binary data? Meaning, I need to type check the argument before using hmset on it and switch the serializer? 

Or should I just ignore these extra control characters? 

This seems like some added overhead I wasn't planning on having to deal with. I am kind of used to being able to tweak certain things via redis-cli but if my hashes are always serialized in this fashion it makes that much harder, or I'll have to always work from PHP to use the correct serializer... do I have that figured correctly? 

Thanks in advance for feedback.


Geoffrey Hoffman

unread,
Apr 21, 2013, 2:33:08 AM4/21/13
to redi...@googlegroups.com
I wrote a PHP function (just a simple wrapper for gettype[1]) to check the argument I want to store in a hash and optionally call 

$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_IGBINARY);

in cases where the data I want to store requires serialization, and otherwise:

$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE);

But now I'm thinking that's a dumb idea since to use it, I also need to keep track of whether the data I stored in each key is serialized or not, and have to check that first in order to declare whether to use the serializer on the actual read. Either way, I thought the PHPRedis extension was magically smarter than that somehow. I tried storing an object of type stdClass in a hash key with Redis::SERIALIZER_NONE and got (string) "Object" on hget hash key. Makes sense.
 
I think for my app I can safely go with Redis::SERIALIZER_NONE and perform serialization/deserialization in client code where applicable. 
 
Reply all
Reply to author
Forward
0 new messages