php redis扩展实现

使用代码如下:
<?php
ini_set("session.save_handler","redis");
ini_set("session.save_path","tcp://172.21.107.247:6379");
ini_set("session.name","preOrderID");
ini_set("session.cookie_lifetime", 3600*24*30);
if(!isset($_SESSION)){
        session_start();
}
$_SESSION['test'] = 123;
echo $_SESSION['test'];
?>

一些关键的函数如下:ps_open_redis, ps_read_redis, ps_write_redis

其中根据key选择服务器的函数为redis_pool_get_sock,key即为生成的sessionid, 代码如下:

PHP_REDIS_API redis_pool_member *
redis_pool_get_sock(redis_pool *pool, const char *key TSRMLS_DC) {
    redis_pool_member *rpm = pool->head;
    unsigned int pos, i;

    memcpy(&pos, key, sizeof(pos));
    pos %= pool->totalWeight;

    for(i = 0; i < pool->totalWeight;) {
        if(pos >= i && pos < i + rpm->weight) {
            int needs_auth = 0;
            if(rpm->auth && rpm->auth_len && rpm->redis_sock->status != REDIS_SOCK_STATUS_CONNECTED) {
                    needs_auth = 1;
            }
            redis_sock_server_open(rpm->redis_sock, 0 TSRMLS_CC);
            if(needs_auth) {
                redis_pool_member_auth(rpm TSRMLS_CC);
            }
            if(rpm->database >= 0) { /* default is -1 which leaves the choice to redis. */
                redis_pool_member_select(rpm TSRMLS_CC);
            }

            return rpm;
        }
        i += rpm->weight;
        rpm = rpm->next;
    }

    return NULL;
}


即根据key得到一个数值,而服务器则是根据权重来排列的,
打个比方,如有两台服务器:
redisa 权重为100
redisb 权重为50

则pool->totalWeight的总权重为150,其中第一台负责的范围为0-99,第二台的范围为100-149;

最终在redis中保存的信息还会加上前缀:PHPREDIS_SESSION

注 意:这里的字节序是高字节在前,即如果sessionid为jq24n8bsh740sr205igaku08g2,在32位机上,会取前4个字符 jp24来计算key的,实际值为0x3432716a,这就决定了sessionid生成如果不均匀,则最终落在redis机器也不均匀了

posted @ 2015-06-20 23:50  szphper  阅读(323)  评论(0)    收藏  举报