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机器也不均匀了

浙公网安备 33010602011771号