排序
可以通过SORT命令对集合、列表、有序集合进行排序。其中,对有序集合进行排序时是以元素本身为准的(忽略分数)。

127.0.0.1:6379> SADD tag:ruby:posts 2 6 12 26
(integer) 4
127.0.0.1:6379> SORT tag:ruby:posts
1) "2"
2) "6"
3) "12"
4) "26"
127.0.0.1:6379> LPUSH list 4 5 2 3 8
(integer) 5
127.0.0.1:6379> SORT list
1) "2"
2) "3"
3) "4"
4) "5"
5) "8"
127.0.0.1:6379> ZADD zset 50 2 100 3 87 1
(integer) 3
127.0.0.1:6379> SORT zset
1) "1"
2) "2"
3) "3"

还可以给SORT添加ALPHA参数实现字典序排序。

127.0.0.1:6379> LPUSH charlist a b d e c f
(integer) 6
127.0.0.1:6379> SORT charlist
(error) ERR One or more scores can't be converted into double
127.0.0.1:6379> SORT charlist ALPHA
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"

DESC参数指定按照逆序排序。LIMIT offset count参数用于选取返回结果范围。

127.0.0.1:6379> SORT tag:ruby:posts DESC
1) "26"
2) "12"
3) "6"
4) "2"
127.0.0.1:6379> SORT tag:ruby:posts DESC LIMIT 0 1
1) "26"
127.0.0.1:6379> SORT tag:ruby:posts DESC LIMIT 0 2
1) "26"
2) "12"

BY参数用于选定排序的基准参考值。

127.0.0.1:6379> HSET post:2 time 1000
(integer) 1
127.0.0.1:6379> HSET post:6 time 900
(integer) 1
127.0.0.1:6379> HSET post:12 time 1900
(integer) 1
127.0.0.1:6379> HSET post:26 time 100
(integer) 1
127.0.0.1:6379> SORT tag:ruby:posts BY post:*->time DESC
1) "12"
2) "2"
3) "6"
4) "26"

其中,Redis会自动用SORT后的元素值替换BY参数中的*值。

当BY参数中不包含*值时,排序操作不会进行。

127.0.0.1:6379> LPUSH sortbylist 2 1 3
(integer) 3
127.0.0.1:6379> SET itemscore:1 50
OK
127.0.0.1:6379> SET itemscore:2 100
OK
127.0.0.1:6379> SET itemscore:3 -10
OK
127.0.0.1:6379> SORT sortbylist BY itemscore:* DESC
1) "2"
2) "1"
3) "3"
127.0.0.1:6379> SORT sortbylist BY any
1) "3"
2) "1"
3) "2"

SORT语句中可以增加GET参数,用于替换排序返回的结果。

127.0.0.1:6379> HSET post:2 title redis
(integer) 1
127.0.0.1:6379> HSET post:6 title python
(integer) 1
127.0.0.1:6379> HSET post:12 title linux
(integer) 1
127.0.0.1:6379> HSET post:26 title libuv
(integer) 1
127.0.0.1:6379> SORT tag:ruby:posts BY post:*->time DESC GET post:*->title
1) "linux"
2) "redis"
3) "python"
4) "libuv"

SORT语句可以有多个GET参数,将一并返回。原始的SORT返回结果可以用GET #。

127.0.0.1:6379> SORT tag:ruby:posts BY post:*->time DESC GET post:*->title GET post:*->time GET #
 1) "linux"
 2) "1900"
 3) "12"
 4) "redis"
 5) "1000"
 6) "2"
 7) "python"
 8) "900"
 9) "6"
10) "libuv"
11) "100"
12) "26"

STORE参数可以将排序后的结果保存到一个键中,保存结果为列表类型。

127.0.0.1:6379> SORT tag:ruby:posts BY post:*->time DESC GET post:*->title GET post:*->time GET # STORE sort.result
(integer) 12
127.0.0.1:6379> LRANGE sort.result 0 -1
 1) "linux"
 2) "1900"
 3) "12"
 4) "redis"
 5) "1000"
 6) "2"
 7) "python"
 8) "900"
 9) "6"
10) "libuv"
11) "100"
12) "26"

消息通知

Redis中,可以通过LPUSH/RPOP操作实现一个简单的消息队列。生产者不断的LPUSH消息到队列中,而消费者则不断的从队列中RPOP消息。

127.0.0.1:6379> LPUSH queue 1 2 3
(integer) 3
127.0.0.1:6379> RPOP queue 
1) "queue"
2) "1"
127.0.0.1:6379> RPOP queue 
1) "queue"
2) "2"
127.0.0.1:6379> RPOP queue 
1) "queue"
2) "3"

Redis还提供了一个BRPOP操作,它有两个参数,一个是键值,一个是超时时间。超时时间填0时,如果队列中是空的,那么BRPOP将一直阻塞知道队列中有值。

127.0.0.1:6379> BRPOP queue 0
# another redis-client begin
127.0.0.1:6379> LPUSH queue 4
# another redis-client end
(integer) 1
1) "queue"
2) "4"
(5.34s)

BRPOP还可以同时接受多个键,任何一个键中有值,那么BRPOP就返回。多个键中均有值,则按照从左到右的优先级返回。

127.0.0.1:6379> BRPOP queue queue2 0
# another redis-client begin
127.0.0.1:6379> LPUSH queue2 5
# another redis-client end
(integer) 1
1) "queue2"
2) "5"
(6.01s)

Redis还提供了发布/订阅模式用于进程间消息传递。

# client A
127.0.0.1:6379> PUBLISH channel.1 hi
(integer) 0
127.0.0.1:6379> SUBSCRIBE channel.1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel.1"
3) (integer) 1
# client B
127.0.0.1:6379> PUBLISH channel.1 hello
(integer) 1
# client A
1) "message"
2) "channel.1"
3) "hello"

此外,更复杂一些,可以通过PSUBSCRIBE按照规则订阅,支持通配符匹配。

# client A
127.0.0.1:6379> PSUBSCRIBE channel.?*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "channel.?*"
3) (integer) 1
# client B
127.0.0.1:6379> PUBLISH channel.10 hello
(integer) 1
127.0.0.1:6379> PUBLISH channel.12 hello
(integer) 1
# client A
1) "pmessage"
2) "channel.?*"
3) "channel.10"
4) "hello"
1) "pmessage"
2) "channel.?*"
3) "channel.12"
4) "hello"

节省空间

下面有一些节省存储空间的小建议:

  • 精简键名
  • 内部编码优化(由redis自动选择,可以通过 OBJECT ENCODING car查看)
  • 当数据量较小时,采用牺牲一定速度的方式来减少内存用量;数据量变大后,则优先保证存取速度;
Last modification:April 17, 2020
如果觉得我的文章对你有用,请随意赞赏