Redis作者谈Redis应用场景

  • Post author:
  • Post category:其他


毫无疑问,

Redis

开创了一种新的数据存储思路,使用Redis,我们不用在面对功能单调的数据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用Redis灵活多变的数据结构和数据操作,为不同的大象构建不同的冰箱。希望你喜欢这个比喻。

下面是一篇新鲜出炉的文章,其作者是Redis作者@

antirez

,他描述了Redis比较适合的一些

应用

场景,NoSQLFan简单列举在这里,供大家一览:


1.取最新N个数据的操作

比如典型的取你网站的最新文章,通过下面方式,我们可以将最新的5000条评论的ID放在Redis的List集合中,并将超出集合部分从数据库获取

  • 使用LPUSH latest.comments<ID>命令,向

    list

    集合中插入数据

  • 插入完成后再用LTRIM latest.comments 0 5000命令使其永远只保存最近5000个ID

  • 然后我们在客户端获取某一页评论时可以用下面的逻辑(伪代码)

FUNCTION get_latest_comments(start,num_items):
    id_list = redis.lrange("latest.comments",start,start+num_items-1)
    IF id_list.length < num_items
        id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...")
    END
    RETURN id_list
END

如果你还有不同的筛选维度,比如某个分类的最新N条,那么你可以再建一个按此分类的List,只存ID的话,Redis是非常高效的。


2.

排行榜

应用,取TOP N操作

这个需求与上面需求的不同之处在于,前面操作以时间为权重,这个是以某个条件为权重,比如按顶的次数排序,这时候就需要我们的

sorted set

出马了,将你要排序的值设置成sorted

set

的score,将具体的数据设置成相应的value,每次只需要执行一条ZADD命令即可。


3.需要精准设定过期时间的应用

比如你可以把上面说到的sorted set的score值设置成过期时间的时间戳,那么就可以简单地通过过期时间排序,定时清除过期数据了,不仅是清除Redis中的过期数据,你完全可以把 Redis里这个过期时间当成是对数据库中数据的索引,用Redis来找出哪些数据需要过期删除,然后再精准地从数据库中删除相应的记录。


4.

计数器

应用

Redis的命令都是原子性的,你可以轻松地利用INCR,DECR命令来构建计数器系统。


5.Uniq操作,获取某段时间所有数据排重值

这个使用Redis的set数据结构最合适了,只需要不断地将数据往set中扔就行了,set意为集合,所以会自动排重。


6.实时系统,

反垃圾

系统

通过上面说到的set功能,你可以知道一个终端用户是否进行了某个操作,可以找到其操作的集合并进行分析统计对比等。没有做不到,只有想不到。


7.Pub/Sub构建实时消息系统

Redis的Pub/Sub系统可以构建实时的消息系统,比如很多用Pub/Sub构建的实时聊天系统的例子。


8.构建

队列

系统

使用list可以构建队列系统,使用sorted set甚至可以构建

有优先级

的队列系统。


9.

缓存

这个不必说了,性能优于Mem

cache

d,数据结构更多样化。


1.在主页中显示最新的项目列表。



Redis使用的是常驻内存的缓存,速度非常快。LPUSH用来插入一个内容ID,作为关键字存储在列表头部。LTRIM用来限制列表中的项目数最多为5000。如果用户需要的检索的数据量超越这个缓存容量,这时才需要把请求发送到数据库。


  1. list:

  2. lpush + ltrim  //$r->lTrim($key,0,4999);


2.删除和过滤。

如果一篇文章被删除,可以使用LREM从缓存中彻底清除掉。

  1. list:

  2. $r->lRem($key,’find_id’,-2);/从右边删除2个value为find_id的元素


3.排行榜及相关问题。

排行榜(leader board)按照得分进行排序。ZADD命令可以直接实现这个功能,而ZREVRANGE命令可以用来按照得分来获取前100名的用户,ZRANK可以用来获取用户排名,非常直接而且操作容易。

  1. zset:

  2. zadd z1 100 aaa

  3. zrevrange z1 0 -1 withscores 分数从大到小

  4. zrank z1 aaa  分数从小到大 返回aaa的排名

  5. zincrby z1 5 111 给值为111的元素的score 加5


4.按照用户投票和时间排序。

这就像Reddit的排行榜,得分会随着时间变化。LPUSH和LTRIM命令结合运用,把文章添加到一个列表中。一项后台任务用来获取列表,并重新计算列表的排序,ZADD命令用来按照新的顺序填充生成列表。列表可以实现非常快速的检索,即使是负载很重的站点。

  1. list:

  2. lpush ltrim

  3. zset:

  4. zadd


5.过期项目处理。

使用unix时间作为关键字,用来保持列表能够按时间排序。对current_time和time_to_live进行检索,完成查找过期项目的艰巨任务。另一项后台任务使用ZRANGE…WITHSCORES进行查询,删除过期的条目。

  1. zset:把时间作为score值

  2. zrange z1 0 -1 withscores  分数从小到大

  3. zrangebyscore z1 过期时间戳) +inf  有效条目


6.计数。

进行各种数据统计的用途是非常广泛的,比如想知道什么时候封锁一个IP地址。INCRBY命令让这些变得很容易,通过原子递增保持计数;GETSET用来重置计数器;过期属性用来确认一个关键字什么时候应该删除。

  1. string:

  2. incr、incrby


设计模式:

GETSET可以和INCR组合使用,实现一个有原子性(atomic)复位操作的计数器(counter)。


举例来说,每次当某个事件发生时,进程可能对一个名为mycount的key调用INCR操作,通常我们还要在一个原子时间内同时完成获得计数器的值和将计数器值复位为0两个操作。


可以用命令GETSET mycounter 0来实现这一目标。

  1. redis> INCR mycount

  2. (integer) 11

  3. redis> GETSET mycount 0  # 一个原子内完成GET mycount和SET mycount 0操作

  4. “11”

  5. redis> GET mycount

  6. “0”


    7.特定时间内的特定项目。

    这是特定访问者的问题,可以通过给每次页面浏览使用SADD命令来解决。SADD不会将已经存在的成员添加到一个集合。

  7. set:

  8. sadd


8.实时分析正在发生的情况,用于数据统计与防止垃圾邮件等。

使用Redis原语命令,更容易实施垃圾邮件过滤系统或其他实时跟踪系统。

阻塞式命令。

  1. bpoplpush




9.Pub/Sub。

在更新中保持用户对数据的映射是系统中的一个普遍任务。Redis的pub/sub功能使用了SUBSCRIBE、UNSUBSCRIBE和PUBLISH命令,让这个变得更加容易。

  1. subscribe xx //阻塞方式

  2. publish xx 123




10.队列。

在当前的编程中队列随处可见。除了push和pop类型的命令之外,Redis还有阻塞队列的命令,能够让一个程序在执行时被另一个程序添加到队列。你也可以做些更有趣的事情,比如一个旋转更新的RSS feed队列。

  1. list:

  2. 入队列lpush、

  3. 出队列rpop或rpoplpush(计划任务失败补发)




11.缓存。

Redis缓存使用的方式与memcache相同。

  1. string:

  2. set、setnx、setex




转载于:https://my.oschina.net/u/267858/blog/471904