2020.4.6
redis常用的数据类型有
String、Hash、List、Set、Sorted set、pub/sub、Transactions
1.String
String是最常用的数据类型。普通的key/value存储都可以归为此类,可以完全实现memacached的功能,并且效率更高。而且还可以享受redis的的定时持久化、操作日志以及Replication功能。除了提供与Memcached一样的get、set、incr、decr等操作外,Redis还提供比如获取字符串长度、往字符串append内容、设置和获取字符串的某一段内容或者某一位,批量设置一系列字符串的内容等功能。
2.Hash
Redis的Hash实际是内部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口。
这里有两种实现,这个hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的Hashmap,此时encoding为ht。
比如要存储一个用户信息对象数据,key为用户id,value是一个map,这个Map的key是成员的属性名,value是属性值。这样对数据的修改和存取都可以直接通过内部Map的key(Redis里称内部Map的key为field),也就是通过key(用户id)+field(属性标签)就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。
【如果用普通的key/value结构来存储,主要有以下两种方式】
第一种:将用户id作为key,把其他信息封装程一个对象以序列化的方式存储,缺点是增加了序列化/反序列化的开销,并且在需要修改起哄一项信息时,需要把整个对象取回,并且修改操作需要对并发进行保护,引入CAS等复杂问题。
第二种:这个用户对象有多少成员就存多少key-value对,用 用户id+对应属性的名称作为唯一标识来取得对应属性的值,虽然省去了序列化开销和并发问题,但是用户id重复存储,浪费内存严重。
注意:Redis提供了接口(hgetall)可以直接获取到全部的属性数据,但是如果内部Map的成员很多,那么就会涉及到遍历整个内部Map的操作,由于Redis是单线程,这个遍历操作会比较耗时,可能造成其他客户端的请求完全不响应。
3.List
Redis的应用场景很多,比如推特的关注列表,粉丝列表,最新消息排行,消息队列都可以用List来实现。
可以利用List的PUSH操作,将任务存在Lists中,然后工作线程再用POP操作将任务去除进行执行。Redis还提供了操作Lists中某一段的api。可以直接查询,删除List中某一段的元素。
Redis List的实现为一个双向链表,可以支持反向查找和遍历,不过会造成额外的内存开销。Redis内部的很多实现,比如发送缓冲队列也用到了List这个数据结构。
4.Set
Set的内部时间是一个value用于为null的HashMap,实际上就是通过计算hash的方式来快速排重的,这也是Set能提供判断一个成员是否在集合中内的重要原因。
比如微博,可以将一个用户所有的关注人存在一个集合中,将他所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作。可以非常方便地实现比如说共同关注、共同爱好、二度好友等功能。还额可以使用不同的命令选择将结果返回客户端还是存放到一个新集合中。
为什么不用jvm自带的Set进行去重?
因为系统一般都是集群部署,使用jvm自带的Set比较麻烦,为了一个全局去重,再起一个公共服务太麻烦了。而且Redis提供的交集差集并集等操作,可以计算各种功能很方便。
5 Sorted Set
Redis Sorted Set的内部使用HashMap和跳跃表(skipList)来保证数据的存储和有序,HashMap里放的是成员到Score的映射,而跳跃表立存放的是所有的成员,排序一句是HashMap里存的Score,使用跳跃表的结构可以获得比较高的查询效率。
使用场景与Set类似。区别是set不是自动有序的,而SortedSet可以通过用户额外提供一个优先级(score)的参数为成员排序,并且是自动排序的。当你需要一个不重复的并且有序的集合列表,那就可以选择Sorted Set数据结构。比如微博发表内容或者新闻,可以按照发表时间作为score来存储,这样获取时就是自动按时间来排序的。
另外还可以用来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务,先执行重要的任务。还可以做排行榜应用,取TopN操作,还有延时任务,范围查找等。
6.Pub/Sub
字面理解 发布和订阅 publish和subscribe
在Redis中可以设定对某一个key值进行消息发布和消息订阅,当一个key值上进行了消息发布后,所有订阅它的客户端会收到对应的消息。使用场景 实时消息系统,比如普通的即时聊天,群聊等功能。
7.Transcations
提供的不是严格的ACID事务,但是提供了基本的命令打包执行功能。