转载请注明出处:https://www.cnblogs.com/wenjunwei/p/9720033.html
redis的存储模型
redis不是普通的键值对存储,它实际上是一个数据结构存储服务器,可以支持不同类型的值。这意味着redis相比传统键值对字符串key和字符串value存储来说,redis的值可以包含更复杂的数据结构。
redis支持哪些数据结构呢?
1.String: 二进制安全字符串(Binary-safe strings)
2.列表(Lists): 根据插入顺序排序的字符串元素集合。从根本上来说就是链表。
3.集合(Sets): 无序且唯一的字符串元素集合。
4.有序集合(Sorted sets): 与Sets类似,但每个字符串元素都与一个浮点数关联,称为分数(score)。这里的元素总是会按分数来进行排序,因此又与Sets不同。(例如:你可以这样取值: 我要前十名、我要后十名)
5.哈希(Hashes): 是由与值相关联的字段组成的映射。字段和值都是字符串。这与Ruby或Python哈希非常相似。
6.位数组或简称位图(Bit arrays or simply bitmaps): 可以使用特殊命令处理字符串值,如:您可以设置和清除各个位,将所有位设置为1,查找第一组或未设置位等等。
7.HyperLogLogs: 这是一个概率数据结构,用于计算集合的基数。
Redis Key
RedisKey是二进制安全的,这意味着您可以使用任何二进制序列作为key,从"foo"这样的字符串到JPEG文件内容,又或者是空字符串,都是有效键。
rediskey的一些规则:
1.key太长是不好的。例如:一个1024字节的key,在内存方面就占用不少,而且在数据集中查找key的时候可能会需要几次高昂的key对比的过程。即使现在任务需要一个很大的key,我们通过散列法hashing(如SHA1)来获得key,从带宽和内存来看,这也是一个更好的办法。
2.key太短也是不好的。如果你将一个"user:1000:followers"的key改为"u1000flw",那是没有任何意义的。因为这种做法节省的空间很小,但是前者会更顾名思义。我们在工作中应该要找到一个衡量key值的平衡点。
3.最好坚持使用一种命名格式。例如:“object-type:id”,如“user:1000”。而点或短划线通常用于多字词字段,如“comment:1234:reply.to”或“comment:1234:reply-to”。可以定一个命名规范。
4.最大内存。redis中允许的key值最大是512MB。
Redis expires:有时间限制的key
在使用更复杂的数据结构之前,我们讨论一个无论任何数据类型都有的一个特性,称为Redis过期。您可以为key设置一个超时时间,这是一个有限的生存时间。当生存时间过去时,key就会自动销毁,就类似于key被调用了del命令一样。
关于redis到期信息:
1.可以使用秒或者毫秒精度进行设置。
2.但是,到期时间的分辨系数始终为1毫秒。
3.过期信息将被复制保留在磁盘中,当redis服务器停止时,时间依然在度过(这意味着redis会保存key过期的时间)。
一.Redis String
Redis的String类型是最简单的类型,与redis key有着密切关联。也是Memcached中唯一的数据类型,对于新手来说,在redis使用这个类型是很自然的。
由于Redis key是字符串,当value也是字符串的时候,会将字符串映射到另一个字符串。
常见实例:
1.例如缓存HTML片段或页面。
2.session缓存。
3.验证码缓存。
二.Redis Lists
列表实现主要有数组和链表,两种实现方法的到的list的属性差异很大。Redis Lists是通过链表实现的。这意味着即使列表中有数百万个元素,在列表头部或尾部新增元素的速度都是一样的。当然链表结构也是有缺点的,使用数组实现list,通过索引访问元素的速度非常快,而使用链表就咩有那么快了。
Redis使用链表实现Lists,对于数据库而言,最重要的是能够以非常快的方式将元素添加到很长的列表中。当快速访问大量元素集合的中间位置很重要时,可以使用不同的数据结构,称为sorted sets(后面会介绍到)。
常见实例:
1.记住用户发布到社交网络的最新消息。
2.流程之间的通信,使用生产者将项目列表推入订阅模式。redis具有特殊的命令,使用这些用例更加的可靠和高效。
3.每次用户发布新照片,我们都可以将其ID添加到列表中。
4.当用户访问主页时,我们通过LRANGE 0 9命令获取最新的10个项目。
三.Redis Hashes
我们可以将Redis Hashes看为使用'哈希'作为对key/value的映射表。
添加和删除操作都是O(1)(平均)的复杂度。hash类型特别适合用于存储对象,但是放入的hash对象实际上的没有限制(除了可用内存之外),因此在应用程序中可以以许多不同的方式使用散列。
在field的数量在限制的范围内以及value的长度小于指定的字节数,即小哈希中,会在内存中以特殊的方式编码,会比较节省内存。
常用实例:
1.用于存储关系数据表或对象信息:如 {name:'张三',age:17}
四.Redis Sets
Redis Sets是无序的字符串集合。我们可以用作元素集合存储,也可以针对集合做其他操作。比如测试给定的元素是否存在,执行多个集合之间的交集,并集或差异等。
存储的数据结构是哈希表,所以增删改查的操作复杂度都是O(1)。
常见实例:
1.用于集合去重。
2.用于分布式锁。
五.Redis Sorted Sets
Sorted Sets数据类型就像是set和hash的混合。与sets一样,Sorted Sets是唯一的,不重复的字符串组成。可以说Sorted Sets也是Sets的一种。
虽然在Sets内部元素没有进行排序,但是Sorted Sets中每个元素都与浮点值相关联,称为分数(因为每个元素都映射到一个值,所以说有点类似hash)。
此外,Sorted Sets中的元素按顺序排序,他们的规则如下:
1.如果A和B是两个具有不同分数的元素,如果A.score > B.score,则 A > B。
2.如果A和B分数相同,如果A字符串在字典排序上大于B字符串,则A>B。在Sorted Sets中A、B字符串不能相等。
实现方式:Sorted Sets是通过Skip List(跳跃表)和hash Table(哈希表)的双端口数据结构实现的,因此每次添加元素时,Redis都会执行O(log(N))操作。所以当我们要求排序的时候,Redis根本不需要做任何工作了,早已经全部排好序了。元素的分数可以随时更新。
用法实战可看这篇文章:Redis实现世界杯排行榜功能(实战)
常见实例:
1.获取排行集合:获取第10-50名元素集合。
2.在分数范围操作:获取分数在60-80的元素集合。
3.Redis2.8后,在分数相同情况下,我们还可以根据字典顺序进行排序。
4.可以获取某个元素在集合中的名次。
六.Bitmaps
位图不是实际的数据类型,而是String类型上定义了一组面向位的操作。由于字符串是二进制安全的blob ,并且他们的最大长度为512MB,所以他们最多适合2^32不同的位。
位图的最大优势之一就是他们在存储信息时通常可以节省大量的空间。
常见实例:
1.各种实时分析。
2.存储与对象ID关联的节省空间但高性能的布尔信息。
七.HyperLogLogs
HyperLogLogs是用来做基数(不重复元素)统计的算法。HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
常见实例:
1.用来做基数统计的算法
总结
通过上面的类型介绍,我们使用Redis时,通常会接触Redis的5种对象类型(字符串、哈希、列表、集合、有序集合),而每一种数据类型都有着各自的特性,我们需要根据自己的应用场景选择最合适的数据类型,利用最合适的特性,可以达到事半功倍的效果。
感谢您的阅读,如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮。本文欢迎各位转载,但是转载文章之后必须在文章页面中给出作者和原文连接。