分类 Redis 下的文章

PHP redis的使用方法详解。php上使用redis主要有两种方式,一种是Predis,一种是phpredis。phpredis是php的一个扩展,以C语言编写的高性能链表。本文讲解Predis的使用。Predis是PHP语言编写。

PHP redis的使用方法详解。php上使用redis主要有两种方式,一种是Predis,一种是phpredis。phpredis是php的一个扩展,以C语言编写的高性能链表。本文讲解Predis的使用。
Predis是Redis官方推出的由PHP原生语言编写的客户端。由于Predis采用了命名空间的方式,所以Predis要求PHP版本最低为5.3。
Predis开源且托管在GitHub上https://github.com/nrk/predis/。下载整个文件夹复制到项目目录即可。

//引入autoload.php文件
require './predis/autoload.php';

//实例化
$redis = New Predis\Client();
/*这个是简化版,等同于$redis = New Predis\Client(array(
 * 'scheme' => 'tcp',
 * 'host' => '127.0.0.1'
 * 'port' => 6379
 *));
 */

//GET
$redis->get('key');

//LPUSH
$redis->lpush('key', '1', '2', '3');

//MSET 相当于$redis->MSET('article:1:title', 'biaoti', 'article:1:content', 'neirong', 'ctime', 'shijian');
$article = array('article:1:title'=>'biaoti', 'article:1:content'=>'neirong', 'article:1:ctime'=>'shijian');
$redis->MSET('key', $article);

//MGET
$articleKeys = array_keys($article);
$redis->MGET($articleKeys);

//SORT
//SORT articleList BY article:*->time LIMIT 0 10 GET article:*->title GET # DESC ALPHA STORE storeKey
$sort = array(
    'by' => 'article:*->time',
    'limit' => array(0, 10),
    'get' => array('article:*->title', '#'),
    'sort' => 'desc',
    'alpha' => true,
    'store' => 'storeKey'
);

Predis的封装之后,用起来非常方便,关联数组的引入是开发效率非常高的。更多的内容可以参考Predis文档:https://github.com/nrk/predis/blob/v0.8/FAQ.md

Redis管道是大幅提升传输速度和用户体验的一个功能。Redis是使用TCP协议进行传输,当客户端发送一条命令之后,到服务器端接收到这个命令,这个过程是需要发送时间的。当服务器处理完命令返回结果给客户端的时候,这个是需要返回时间的。统称为往返时延。如果多条命令一次性发送过去,Redis服务器端全部处理好后一次性发送回客户端,那么就只需要花费一份的往返时延。这就是Redis的管道命令。Redis底层通信协议对管道命令提供了支持。如:

$ (echo -en "PING\r\nPING\r\nPING\r\n"; sleep 1) | nc localhost 6379
+PONG
+PONG
+PONG

关于管道的具体使用,后期在详细说明。这里只需要知道有这个概念即可。

Redis是实时广播推送的一把好手。Redis提供了发布-订阅者模式。发布消息是PUBLISH 频道名 内容的格式。如:

PUBLISH fm97 hello world

这样,所有订阅fm7频道的用户就可以收到hello world了。PUBLISH返回值是收到的订阅者个数。订阅命令是SUBSCRIBE。如:

SUBSCRIBE fm97

在输入Redis订阅命令之后,值可以输入SUBSCRIBE/UNSUBSCRIBE/PSUBSCRIBE/PUNSUBSCRIBE这四个命令,不然会报错。在SUBSCRIBE模式下,收到的消息第一行是subscribe。第二行是频道名称fm97,第三行是当前的订阅数量。也可能是收到的消息第一行是message。第二行是频道名称fm97,第三行是广播内容hello world。
退定则是UNSUBSCRIBE,如

UNSUBSCRIBE fm97

PSUBSCRIBE 通过通配符来进行订阅,如:

PSUBSCRIBE fm?*

这就订阅了fm开头的所有频道,但不会订阅fm这个频道。
PUNSUBSCRIBE同理。不说啦~

Redis是天生的队列好手。RPOP,LPUSH就可以看到。生产者是队列任务的提出方,消费者队列任务的执行方。生产者提出大量的任务,他们排队一个接一个的被消费者执行。执行一个就RPOP,提出一个新任务就LPUSH。如果要插队呢?就RPUSH。Redis队列的伪代码:

//无限循环
loop
    $task = RPOP queue
    if($task)
        execute($task)
    else
        sleep(1)

一个无限循环,从队列的最头部弹出一个任务,如果该任务存在则执行,如果不存在则睡眠,1秒后再次进入循环。这段代码实现了对队列任务的死循环来进行监听任务列表。这样并不好,每1秒扫描一次,如果一晚上都没有呢,那不是在白白浪费资源吗。这时候借助Redis 队列命令家族中的BRPOP。如果队列列表中有任务则弹出,如果没有任务就一直将连接阻塞,直到有新的任务加入才会放开。

//无限循环
loop
    $task = BRPOP queue 0
    execute($task)

BRPOP第一个参数是键,第二个参数是时间,如果时间为0则没有新任务加入的时候永久阻塞。
Redis队列家族是可以进行优先级的。比如有三个列表任务列表,queue1,queue2,queue3。那么那个优先级高就拍在前面:

    BRPOP queue2 queue3 queue1 0

如果队列2中有任务则优先弹出任务2。

Redis SORT是由Redis提供的一个排序命令。集合中的标签是无序的,可以使用SORT排序。如:

redis>SADD jihe 5
(integer) 1
redis>SADD jihe 1
(integer) 1
redis>SADD jihe 2
(integer) 1
redis>SADD jihe 8
(integer) 1
redis>SORT jihe
1) "1"
2) "2"
3) "5"
4) "8"

如果使用Redis SORT排序的不是数字,是字母,将他们按照字典的顺序排名,则需要使用

SORT jihe ALPHA

如果不加ALPHA参数,则会报错,提示:(error) ERR One or more scores can't be converted into double。我们还可以使用关系型数据库的DESC进行倒序排序和LIMIT offset count来限定获取的条数

SORT jihe DESC LIMIT 0 2

还可以对Redis SORT命令添加BY参数。一条语句只能有一个BY参数。这时,SORT不会根据自身的值排序,比如(1,5,2,8和a,A,g,B),而是根据指定的另一个键中的字段来排序。如:

SORT tag:redis:article BY article:*->time DESC

解释:根据tag:redis:article中的值(tag是redis的文章ID),来组合成一个新的key就是article:(ag:redis:article中的一个值):time。获取到tag是redis的文章ID列表,然后根据他们的发布时间来排序。
Redis SORT命令还有个GET参数,GET参数类似在关系型数据库中的关联查询。比如查询tag是redis的文章ID列表,将列表根据发布时间倒序排序,然后获取每个文章的标题。GET可以有多个:

SORT tag:redis:article BY article:*->time DESC GET article:*->title GET article:*->time GET #

GET #的意思是,将文章ID返回回来,你可以写GET article:*->id,也可以写GET #。
Redis SORT命令还有个参数是STORE,是将排序后的内容存储到一个新的key中。新key的类型是列表类型,如果存在则会覆盖。这个时候可以用EXPIRE来设置缓存:

SORT tag:redis:article BY article:*->time DESC GET article:*->title GET article:*->time GET # STORE resultKey

Redis的SORT命令是Redis最复杂最强大的命令之一,时间复杂度是O(n+mLOGm)。n是待排序的列表长度,m是返回的元素个数。减少n和m会提高SORT的性能。