`
wuhoujian322
  • 浏览: 63199 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Redis之旅第五篇 - Redis高级命令

阅读更多

一 . 事务
1.基础概念

(1)概念:redis中的事务是一组命令的集合。事务和命令一样都是redis的最小执行单位,一个事务中的命令要么全部执行,要么全部不执行;

(2)原理:先将属于用一个事务的所有命令发送给redis服务器,然后再让redis依次执行这些命令。

(3)语法示例:

127.0.0.1:6379> MULTI 
OK
127.0.0.1:6379> LPUSH list 76 87 99
QUEUED
127.0.0.1:6379> RPOP list 
QUEUED
127.0.0.1:6379> SET foo helo
QUEUED
127.0.0.1:6379> EXEC
1) (integer) 3
2) "76"
3) OK
127.0.0.1:6379>

2.错误处理

(1)语法错误:事务中的命令一条都不会执行

(2)执行错误(比如用SADD命令操作list):错误的那一行不执行,其余的执行

3.WATCH命令
(1)作用:可以监控一个或者多个键,一旦其中有一个键被修改(删除),之后的事务就不会执行。监控一直持续到EXEC执行完毕。

(2)语法示例:

127.0.0.1:6379> set key good
OK
127.0.0.1:6379> WATCH key
OK
127.0.0.1:6379> set key hello
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set key nihaoa
QUEUED
127.0.0.1:6379> EXEC
(nil)
127.0.0.1:6379> get key
"hello"

 

二 . 生存时间
(1)设置某个键的生存时间 EXPIRE key 20 单位秒
说明:返回1表示设置成功,返回0表示键不存在或者设置失败

(2)查看某个键还有多长时间过期 TTL key
说明:返回键的剩余时间 , 如果键不存在返回-2,如果没有为键设置生存时间返回-1(永久存在的键)

(3)取消键的生存时间设置 PERSIST key 
说明:设置成功返回1 , 如果键不存在或者键本来就是永久的返回0


三 . 排序
1.简单排序 (针对列表,集合,有序集合的操作)

默认会把元素转化为浮点数再进行排序,如果元素不是数字,加上ALPHA参数可以把元素按照字典排序。对于有序集合,排序时会忽略分数,只是对元素进行排序。

(2)示例1

127.0.0.1:6379> LPUSH num 33 44 5 89 -2 
(integer) 5
127.0.0.1:6379> SORT num
1) "-2"
2) "5"
3) "33"
4) "44"
5) "89"
127.0.0.1:6379> SORT num DESC LIMIT 0 3
1) "89"
2) "44"
3) "33"

(3)示例2
127.0.0.1:6379> ZADD scores 19 tim 39 tom 55 jane
(integer) 3
127.0.0.1:6379> SORT scores
(error) ERR One or more scores can't be converted into double
127.0.0.1:6379> SORT scores ALPHA
1) "jane"
2) "tim"
3) "tom"
127.0.0.1:6379> SORT scores ALPHA DESC 
1) "tom"
2) "tim"
3) "jane"
127.0.0.1:6379> SORT scores ALPHA DESC LIMIT 0 2
1) "tom"
2) "tim"

2.复杂排序 (综合排序)

(1)BY参数
BY参考键,参考键可以是字符串类型键或者是hash类型键的某个属性(表示为键名->属性名)。一旦提供参考键,那么sort将不会按照值来排序,而是按照参考键的值来排序。
*表示占位符。如果没有提供实际意义的参考键,那么就像没有BY参数一样。

(2)GET参数
GET参数不影响排序。作用是使SORT命令的返回结果不再是元素自身的值,而是GET参数中指定的键值。也是用*作为占位符。GET #表示也返回自身值。
一个SORT命令中可以有多个GET参数,但是BY只能有一个

(3)STORE参数
STORE参数用来把SORT排序后的结果存储起来。并且可以结合EXPIRE命令设置结果的有效时间。 保存后的键为list类型,返回结果为结果的个数。

(3)示例:
127.0.0.1:6379> LPUSH users 2 4 1 3 6 5 
(integer) 6
127.0.0.1:6379> HMSET users_1 name jianjian age 27
OK
127.0.0.1:6379> HMSET users_2 name zhangsan age 46
OK
127.0.0.1:6379> HMSET users_3 name john age 37
OK
127.0.0.1:6379> HMSET users_4 name lisi age 10
OK
127.0.0.1:6379> HMSET users_5 name kart age 60
OK
127.0.0.1:6379> HMSET users_6 name jim age 100
OK
127.0.0.1:6379> KEYS *
1) "users_6"
2) "users_3"
3) "users_5"
4) "users_1"
5) "users_2"
6) "users"
7) "users_4"
127.0.0.1:6379> SORT users
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
127.0.0.1:6379> SORT users BY users-*->age 
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
127.0.0.1:6379> SORT users BY users_*->age 
1) "4"
2) "1"
3) "3"
4) "2"
5) "5"
6) "6"
127.0.0.1:6379> SORT users BY users_*->age DESC 
1) "6"
2) "5"
3) "2"
4) "3"
5) "1"
6) "4"
127.0.0.1:6379> SORT users BY users_*->age DESC LIMIT 1 3
1) "5"
2) "2"
3) "3"
127.0.0.1:6379> SORT users BY users_*->name LIMIT 1 3
(error) ERR One or more scores can't be converted into double
127.0.0.1:6379> SORT users BY users_*->name ALPHA LIMIT 1 3
1) "6"
2) "5"
3) "4"
127.0.0.1:6379> SORT users BY users_*->name ALPHA LIMIT 1 3 GET users_*->name GET users_*->age GET #
1) "jim"
2) "100"
3) "6"
4) "kart"
5) "60"
6) "5"
7) "lisi"
8) "10"
9) "4"

127.0.0.1:6379> SORT users BY users_*->name ALPHA LIMIT 1 3 GET users_*->name GET users_*->age STORE result
(integer) 6
127.0.0.1:6379> TYPE result
list
127.0.0.1:6379> LRANGE result 0 -1
1) "jim"
2) "100"
3) "kart"
4) "60"
5) "lisi"
6) "10"
127.0.0.1:6379> EXPIRE result 20
(integer) 1
127.0.0.1:6379> TTL result
(integer) 2
127.0.0.1:6379> TTL result
(integer) -2
127.0.0.1:6379> KEYS *
1) "users_6"
2) "uname"
3) "scores"
4) "num"
5) "users_5"
6) "users_2"
7) "users_1"
8) "users_3"
9) "nums"
10) "users"
11) "users_4"


四 . 消息通知
1.任务队列 
任务队列就是传递任务的队列。与此相关的双方就是生产者和消费者,前者负责把消息放入队列(比如把一个对象序列化以后放入队列),后者负责从队列里面取出消息并且进行处理。

队列的优点在于松耦合,生产者和消费者可以独立演化。

2.redis实现任务队列的思想
使用list这种数据结构就可以实现消息队列。思路:生产者消费者连接到同一个列表(比如tasks列表),然后生产者使用LPUSH向队列添加新的信息,消费者循环使用RPOP从队列取走消息处理,直至全部处理完毕。

3.BRPOP命令
上面的情况有一种特例。如果队列为空,那么能否实现一旦有新元素加入队列就能马上通知到消费者而不是还让消费者取循环查看是否有新任务到来。

(1)BRPOP queue timeout 
queue代表监听的队列,timeout表示超时时间。 如果超过超时时间仍然没有新元素加入,那么返回nil
timeout = 0时会阻塞住与redis服务器的连接,直到有新任务加入。一旦新的加入,会立即拿走新任务。

(2)示例:使用两个cli
127.0.0.1:6379> LPUSH queue ghjk
(integer) 1

127.0.0.1:6379> BRPOP queue 0
1) "queue"
2) "ghjk"
(52.71s)

4.优先级队列
(1)BRPOP key [key....] timeout 命令
作用:同时检测多个键,如果所有键都没有元素则阻塞,如果其中有一个键有元素则弹出该元素
意义:如果存在多个键(多个列表),那么左边的优先级高于右边。这个思想可以实现优先级队列。

(2)示例:使用两个cli


127.0.0.1:6379> LPUSH q1 89 56b 23y
(integer) 3
127.0.0.1:6379> LPUSH q2 what where which
(integer) 3
127.0.0.1:6379> LPUSH q3 a b c
(integer) 3

 

127.0.0.1:6379> BRPOP q1 q2 q3 0
1) "q1"
2) "89"
127.0.0.1:6379> BRPOP q1 q2 q3 0
1) "q1"
2) "56b"
127.0.0.1:6379> BRPOP q1 q2 q3 0
1) "q1"
2) "23y"
127.0.0.1:6379> BRPOP q1 q2 q3 0
1) "q2"
2) "what"
127.0.0.1:6379> BRPOP q1 q2 q3 0
1) "q2"
2) "where"
127.0.0.1:6379> BRPOP q1 q2 q3 0
1) "q2"
2) "which"
127.0.0.1:6379> BRPOP q1 q2 q3 0
1) "q3"
2) "a"
127.0.0.1:6379> BRPOP q1 q2 q3 0
1) "q3"
2) "b"
127.0.0.1:6379> BRPOP q1 q2 q3 0
1) "q1"
2) "hello"


5.发布 / 订阅
(1)发布订阅模式包含发布者和订阅者两种角色。发布者可以向多个频道发布消息,订阅者可以订阅多个频道。一旦订阅,就会收到消息。用这种方式也可以实现进程之间的通信。

(2)PUBLISH channel message 命令

向指定的频道发送消息,返回订阅者的数量。发送的消息不会持久化,后来订阅者收不到之前发的消息。

(3)SUBSCRIBE channel [channel...] 命令
订阅一个或者多个频道

(4)PSUBSCRIBE channel.?* 命令
按照指定的规则订阅频道。?*表示通配符,代表订阅所有以channel开头的频道

(5)示例,两个cli
127.0.0.1:6379> PUBLISH ch1 fuck
(integer) 1
127.0.0.1:6379> PUBLISH ch2 fuck2
(integer) 1
127.0.0.1:6379> PUBLISH ch3 fuck3
(integer) 0

 

127.0.0.1:6379> SUBSCRIBE ch1 ch2
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "ch1"
3) (integer) 1
1) "subscribe"
2) "ch2"
3) (integer) 2
1) "message"
2) "ch1"
3) "fuck3"
1) "message"
2) "ch2"
3) "fuck3"


127.0.0.1:6379> PSUBSCRIBE ch?*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "ch?*"
3) (integer) 1
1) "pmessage"
2) "ch?*"
3) "ch3"
4) "fuck3"
1) "pmessage"
2) "ch?*"
3) "ch2"
4) "fuck3"

 

五 . 其它
1.主从数据库的复制
(1)首先启动一个redis实例 ./redis-server 然后启动另一个实例:./redis-server --port 6380 --slaveof localhost 6379

上述命令可以保证6380端口的redis已经是6379的从数据库。数据会自动从主数据库同步到所有的从数据库(可以设置多个),一旦主数据库down了,选择其中
一个从数据库为主数据库。主从分离就是为了读写分离,也为了降低单点数据库服务器的访问压力,跟普通数据库这方面的思想相同。

(2)默认情况下,是不能对从数据库进行写操作的,只读模式。可以通过配置修改。

(3)示例 打开两个cli


./redis-cli -p 6380
127.0.0.1:6380> set foo good
(error) READONLY You can't write against a read only slave.
127.0.0.1:6380> get name
"java"
127.0.0.1:6380> get name1
(nil)
127.0.0.1:6380> get name1
"ghbjnkm"

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics