PHP中Redis的一点使用经验

2 篇文章 0 订阅

PHP中Redis的一点使用经验

1.生存时间

基本用法

$redis->expire($key,60); //使用秒为单位
$redis->pExpire($key,60000);//使用毫秒作为单位
$redis->expireAt($key,1476868380);//使用Unix timestamp,指定时间过期
$redis->pExpireAt($key,1476868380000);//使用Unix timestamp在指定时间过期,区别是毫秒作为单位
$redis->persist($key);//移除给定key的生存时间
$redis->ttl($key);//返回key剩余的过期时间,使用秒为单位
$redis->pttl($key);//返回key剩余的过期时间,使用毫秒作为单位

注意:
1. incr ,hset,lpush,sadd等操作 并不会改变key的生存时间
2. RENAME old-key new-key 后,new-key会继承原key的生存时间
3. 只有 SET GETSET DEL 命令才会清除生存时间

2.BLPOP / BRPOP

基本用法

BLPOP / BRPOP 是 LPOP/RPOP 的阻塞版本,在给定list无法弹出任何元素的时候阻塞连接,如果list被添加一个元素会及时弹出该元素

当有元素弹出时返回一个数组,第一个元素是弹出list的 key,第二个元素是 value。

$key1 = 'key-list1';
$key2 = 'key-list2';
$timeout = 100;
try {
    while ($item = $redis->brPop($key1, $key2, $timeout)) {
        var_dump($item);
        /*
            when >RPUSH key-list1 a 
            array(2) {
               [0]=> string(9) "key-list1" list name
               [1]=> string(1) "a"         item value
            }
        */
    }
} catch (RedisException $e) {
    //TODO
}

注意:
1.$timeout 超时后 会抛出一个RedisException 异常
2.$timeout 设置为0 表示没有超时时间
3. BRPOP里的 $timeout 在PHP里会被 public function connect( $host, $port = 6379, $timeout = 0.0 ) 方法设置的$timeout 覆盖

3. SETBIT / BITCOUNT

SETBIT key offset value :设置或者清空key的value(字符串)在offset处的bit值。

BITCOUNT key [start end] : 统计字符串被设置为1的bit数.

默认整个字符串都会被进行计数,指定 start 、 end 参数,可以统计指定范围内。

这两个命令有个典型应用 来源官方文档

Bitmap 对于一些特定类型的计算非常有效。
例如,统计用户在指定日期范围内的上次频率等需求,可以使用 SETBIT 和 BITCOUNT 来实现。

以某个日期作为起点,如果用户在第x天登录,就执行SETBIT uid x 1,以此类推。
想计算用户登录次数 执行 BITCOUNT uid即可,加上范围就可以获取更多个性化需求。

4.批量操作(linux cli)

有时候需要批量删除部分key,可以借助xargs

redis-cli -h host -p port -a auth -n db --scan --pattern Pattern|xargs redis-cli -h host -p port -a auth -n db DEL

不建议使用keys ,keys 时间复杂度为O(N),SCAN 时间复杂度为O(1)
SCAN 常见用法

$it = null;
$redis->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
while ( $ret = $redis->scan($it,'test*',3)){
    foreach ($ret as $item){
        echo $item.PHP_EOL;
    }
}
5.PIPELINE

Redis::MULTI 默认开启一个事务,但是通过设置参数可以使用PIPELINE,能够节省时间

两种用法

$pip = $redis->multi(Redis::PIPELINE);
$re = $pip->incr($key1)->incr($key2)->del($key3)->exec();

或者

$pip = $redis->multi(Redis::PIPELINE);
$pip->incr($key1);
$pip->incr($key2);
$pip->del($key3);
$ret = $pip->exec();

$ret 包括了每一个执行的返回结果

6.事务 MULTI

执行使用$redis->multi();将开始一个事务,或者$redis->multi(Redis::MULTI);

$ret = $redis->multi()
           ->set('key1', 'val1')
           ->get('key1')
           ->set('key2', 'val2')
           ->get('key2')
           ->exec();

使用和PIPELINE 类似,但没有事务保证

7.WATCH/UNWATCH/DISCARD

WATCH key
watch 命令会监视给定的key,当exec时候如果key从调用watch后发生过变化,则整个事务会失败。
也可以调用watch多次监视多个key,这样就可以对指定的key加乐观锁了。
watch的key是对整个连接有效的,事务也一样。如果连接断开,监视和事务都会被自动清除。
exec,discard,unwatch命令都会清除连接中的所有监视.

$redis->watch($key2);
$ret = $redis->multi(Redis::MULTI)->get($key)
->incr($key1)->del($key2)->exec();

DISCARD 清空事务的命令队列并退出事务上下文,如果已使用WATCH,DISCARD将释放所有被WATCH的key。

Redis 事务仍然有一定不足

127.0.0.1:6379> incr test8
(integer) 2
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> incr test8
QUEUED
127.0.0.1:6379> hset test8 1 1
QUEUED
127.0.0.1:6379> exec
1) (integer) 3
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> get test8
"3"

redis只能保证事务的每个命令连续执行,但是如果事务中的一个命令失败了,并不回滚其他命令

8.Geo

Redis 3.2.0 以后的版本支持Geo查询

GEOADD key longitude latitude member [longitude latitude member ...]

添加一个地理位置点,经度必须在纬度前面


GEODIST key member1 member2 [unit]

计算两个点之间的距离(存在误差,因为地球不是标准球体)
unit: m 表示单位为米(默认),km 表示单位为千米,mi 表示单位为英里,ft 表示单位为英尺。

GEORADIUS key longitude latitude radius m|km|ft|mi 
[WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]

以给定的经纬度为中心, 返回与中心的距离不超过给定最大距离的所有位置元素。

GEORADIUSBYMEMBER key member radius m|km|ft|mi 
[WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]

与GEORADIUS类似,只不过计算与某个点距离不超过 radius的元素

GEOPOS key member [member ...] #返回元素的经纬度
GEOHASH key member [member ...]#返回一个标准Geohash 

GEOHASH 有如下特点,应用广泛
字符串越长,表示的范围越精确。编码长度为9时,精度在2米左右,Redis 使用11位。
字符串相似的位置距离也相近,利用前缀匹配,可以快速查询某个坐标附近的地理位置。
geohash计算的字符串,可以反向解码出原来的经纬度。

可以在 geohash.org 网站使用,网址http://geohash.org/<geohash-string>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值