Redis介绍
Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。
Redis 与其他 key - value 缓存产品有以下三个特点:
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
- Redis支持数据的备份,即master-slave模式的数据备份。
五种类型
1.String(字符串)
String是最简单的类型,一个key对应着一个value,string类型是二进制安全的
-
使用场景:
此类型和memcache相似,作为常规的key-value缓存应用。
应用 Memcached和CKV的所有场景。字符串和数字直接存取。结构化数据需要先序列化,再set到value;相应的,get到value后需要反序列化。
注:一个键最大能存储512MB -
常用命令:
set,get,decr,incr,mget 等。
2.Hash(哈希)
Hash存的是字符串和字符串值之间的映射。适合用于存储对象,Hash将对象的各个属性存入Map里,可以只读取/更新对象的某些属性。这样有些属性超长就让它一边呆着不动,另外不同的模块可以只更新自己关心的属性而不会互相并发导致覆盖冲突。
-
使用场景:
存放结构化数据,比如用户信息。在Memcached或CKV中,对于用户信息比如用户的昵称、年龄、性别、积分等,我们需要先序列化后存储为一个字符串的值,这时候在需要修改其中某一项时,通常需要将所有值取出反序列化后,修改某一项的值,再序列化存储回去。这样不仅增大了开销,也不适用于一些可能并发操作的场合(比如两个并发的操作都需要修改积分)。Key是用户ID, value是一个Map,这个Map的key是成员的属性名,value是属性值,这样对数据的修改和存取都可以直接通过其内部Map的Key(Redis里称内部Map的key为field), 也就是通过key(用户ID) + field(属性标签) 就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。 -
常用命令:
hget,hset,hgetall 等。
3.List(链表)
list是一个链表结构,主要功能是push,pop等等,其实就是每一个元素为string类型的双向链表
-
使用场景:
各种列表,比如关注列表、粉丝列表等,最新消息排行、每篇文章的评论等也可以用Redis的list结构来实现。
消息队列,可以利用Lists的PUSH操作,将任务存在Lists中,然后工作线程再用POP操作将任务取出执行。这里的消息队列并没有ack机制,如果消费者把任务给Pop走了又没处理完就死机了怎么办?解决方法之一是加多一个sorted set,分发的时候同时发到list与sorted set,以分发时间为score,用户把任务做完了之后要用ZREM消掉sorted set里的job,并且定时从sorted set中取出超时没有完成的任务,重新放回list。另一个做法是为每个worker多加一个的list,弹出任务时改用RPopLPush,将job同时放到worker自己的list中,完成时用LREM消掉。如果集群管理(如zookeeper)发现worker已经挂掉,就将worker的list内容重新放回主list。
利用LRANGE可以很方便的实现list内容分页的功能。取最新N个数据的操作:LPUSH用来插入一个内容ID,作为关键字存储在列表头部。LTRIM用来限制列表中的项目数最多为5000。如果用户需要的检索的数据量超越这个缓存容量,这时才需要把请求发送到数据库。 -
常用命令:
lpush,rpush,lpop,rpop,lrange等
4.Set(集合)
set是集合,它是string类型的无序集合,对集合可以取并集,交集,差集等操作
-
使用场景:
某些需要去重的列表,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。
可以存储一些集合性的数据,比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。又比如QQ有一个社交功能叫做“好友标签”,大家可以给你的好友贴标签,比如“大美女”、“土豪”、“欧巴”等等,这里也可以把每一个用户的标签都存储在一个集合之中。 -
常用命令:
sadd,spop,smembers,sunion等
5.Sorted Set(有序集合)
是set的一个升级版本,在set的基础上增加了一个顺序属性,这一属性在添加时可以指定,每次指定后,zset会自动重新按新的值调整顺序
Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,跳跃表按score从小到大保存所有集合元素。使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。时间复杂度与红黑树相同,增加、删除的操作较为简单。
-
使用场景:
可以做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行。
存放一个有序的并且不重复的集合列表,比如排行榜
新闻按照用户投票和时间排序,ZADD时的score = points / time^alpha, 这样用户的投票会相应的把新闻挖出来,但时间会按照一定的指数将新闻埋下去。
过期项目处理:使用unix时间作为关键字,用来保持列表能够按时间排序。对current_time和time_to_live进行检索,完成查找过期项目的艰巨任务。另一项后台任务使用ZRANGE...WITHSCORES进行查询,删除过期的条目。 -
常用命令:
zadd,zrange,zrem,zcard等
在线测试地址:
https://try.redis.io/
Redis命令地址:
http://www.redis.cn/commands.html
//String
SET wang 'hello world'
GET wang
//Hash
HSET user:1000 name "wangyong"
HGET user:1000 name
HSET user:1000 sex "man"
HGETALL user:1000
HMSET user:1001 name "wangyong1234" sex "man" mail "609300460@qq.com"
//List
RPUSH friends "aa"
RPUSH friends "bb"
LPUSH friends "cc"
LPUSH friends "dd"
LLEN friends //List长度
LRANGE friends 0 -1 //返回一个子列表,第一个为起始,第二个为截止,第二个参数为-1则表示到最后
//SET
SADD wangdata "hello"
SADD wangdata "hello2"
SMEMBERS wangdata
//Sorted Set
ZADD page_rank 1 ceibs.com 2 baidu.com 3 youku 4 iqiyi
ZRANGE page_rank 0 -1 WITHSCORES
ZADD page_rank 122 youku
ZRANGE page_rank 0 -1 WITHSCORES