Redis常用的一些场景
# Redis常用的一些场景
说某个东西擅长或者常用于某个领域,一定要从它自身的特性出发。因为它有某种特性,因此它才擅长做某件事。那要说Redis常用于哪些场景,那我们就要先了解下它的特性,或者说它支持的数据结构有哪些。
# 数据类型
# 基本数据-5种
Redis的基本数据类型有5种,
String(字符串):字符串是最基本的数据类型,可以存储简单的字符串或者是二进制数据。字符串类型的值可以是最大为 512MB 的二进制数据。
List(列表):列表是按照插入顺序排列的字符串列表,适合用来存储消息队列或者是用户的浏览历史等有序数据。列表可以方便地从头部(push)或尾部(pop)添加或移除元素。
# 从右边添加三个元素,并判断该键listkey的 底层数据结构
127.0.0.1:6379> rpush listkey e1 e2 e3
(integer) 3
127.0.0.1:6379> object encoding listkey
"ziplist”
2
3
4
5
Hash(哈希表):哈希表允许用户将一个键值对映射存储在一个哈希中,类似于 Python 中的字典。适合存储对象,因为可以将一个对象的不同属性映射到同一个键上。
基本语法:HSET key field value
# 创建一个名为 user 的哈希表,并添加两个字段
HSET user name "zhangsan"
HSET user age 25
2
3
Set(集合):集合存储的是唯一的字符串元素。集合中的元素不会重复,适用于存储唯一元素的集合,比如用户好友列表或者是用户ID的集合。
Sorted Set(有序集合/zset):有序集合与集合相似,但是每个成员都关联了一个分数,这个分数决定了成员在集合中的顺序。有序集合可以按照分数来排序集合中的成员。注意:有序集合中的元素不能重复,但是score可以重复,就和一个班里的同学学号不能重复,但是考试成绩可以相同。
# 扩展
除了上述五种基本的数据结构之外,Redis 还提供了扩展的数据结构以支持更多的使用场景:
在字符串的基础之上演变出了位图(Bitmaps)
和HyperLogLog(计数器)
两种神奇的“数据结构”,
随着LBS(Location Based Service,基于位置服务)的不断发展,Redis3.2版本中加入有关Geospatial Indexes(地理空间索引)
。
Bitmaps:Bitmaps本身不是一种数据结构,实际上它就是字符串
),但是它可以对字符串的位进行操作。可以把Bitmaps想象成一个以位为单位的数组,数组的每个单元只能存储0和1,数组的下标在Bitmaps中叫做偏移量。
因为 bitmaps 是基于字符串类型实现的,而 Redis 中的字符串(String)类型实际上可以存储的最大长度是 512 MB,所以bitmaps 的最大长度是 512 MB,即 232232 个比特位(bits)。
setbit key offset value
注意:虽然理论上 bitmaps 的长度可以达到 512 MB,但在实际应用中,你可能需要考虑服务器内存的限制以及单个键的大小限制。此外,对于非常大的 bitmaps,某些操作可能会变得较为耗时,因此在设计应用时应考虑到这一点。
HyperLogLog (HLL):它也不是新的数据类型,实际类型仍为字符串类型,但通过一种基数算法——能够以极小的空间消耗来近似计算一个集合中不重复元素的数量。用于估算大量数据中的不同元素的数量(即基数)。
HyperLogLog 算法是由 Philippe Flajolet 等人提出的一种概率算法,其特点是能够以极小的空间消耗来近似计算一个集合中不重复元素的数量。
特点
- 内存高效:相对于精确计算基数所需的空间,HyperLogLog 只需极少的内存即可实现近似的计算。
- 近似计算:HyperLogLog 提供的是一个估计值,而不是精确值。但是,随着数据量的增长,误差率会逐渐稳定在一个较低的水平。
- 无状态:多个 HyperLogLog 结构可以合并成一个,这使得它可以很方便地用于分布式的环境。
# 应用场景
- 缓存:在绝⼤多数的互联⽹项⽬中,为了提供数据的访问速度、降低数据库的访问压⼒,我们可以使⽤redis 作为缓存来实现,此外,Redis还提供了键值过期时间设置,提供了灵活控制最大内存和内存溢出后的淘汰策略。极大的提高了软件的稳定性。
- 点赞、计数器等功能:对数据实时读写要求⽐较⾼(更新频繁),但是对数据库的⼀致性要求并不是太⾼的功能、场景 ,我们使用Redis提供的列表和有序集合数据结构,可以很方便地构建各种排行榜系统,或者通过计数器功能,实现点赞、播放量功能等,或者还可以通过redis的过期功能,进行限速功能:如一分钟内只允许发送一次短信等功能。
- 历史记录、投票系统、评论系统:存储用户的操作历史或者其他需要保留的历史数据,可以将最新的记录推入列表的一端,当列表长度超过预设的最大长度时,可以移除多余的旧记录、投票系统:可以使用列表来记录用户的投票情况,每个用户投票后将其记录到列表中,可以使用列表的长度来统计投票总数。以上场景都是
list
数据类型非常适合的 - 标签:
set集合类型
比较典型的使用场景是标签(tag)。例如一个用户可能对娱乐、体育比较感兴趣,另一个用户可能对历史、新闻比较感兴趣,这些兴趣点就是标签。有了这些数据就可以得到喜欢同一个标签的人。但实际上一个标签系统远比你想得要复杂得多,这里只是提供一个简要的思路 - 排行榜:zset有序集合比较典型的使用场景就是排行榜系统
- 分布式锁:基于redis的操作特性可以实现分布式锁功能
- 分布式会话:在分布式系统中可以使⽤redis实现 session (共享缓存)
- 消息队列系统:可以使⽤redis实现应⽤之间的通信。或者直接使用Redis提供的发布订阅功能和阻塞队列的功能,虽然和专业的消息队列比还不够足够强大,但是对于一般的消息队列功能基本可以满足。
除了以上场景,Redis还能用在其他地方,这里就不一一列举了。但需要注意的是,因为Redis的特性,为了尽可能的保证一致性,对于使用的数据,要尽量选取不经常修改的数据。
# Redis的局限
新的技术总是会解决一些以前无法解决的问题,或者提高以前解决某些问题的效率,但同样的,技术上没有唯一的银弹
,新技术也会有一些局限。下面就说下Redis的局限,或者说不建议它使用的场景。
我们知道Redis的数据是存放在内存中的,如果海量的数据都存放在此,那我们需要多大的内存呢?对于技术实现是一个巨大的挑战,更不要说内存的价格比硬盘的价格要贵,过高的经济成本也会让我们无法负担。
因此,一些大规模的数据则不建议存放Redis。
同时,如果某些数据不频繁变动,那存Redis的意义也不大,因为频繁的读操作本身相对于写操作来说,通常对数据库的负担较小。因此,对于一些频繁变动的数据才建议放在Redis中,其他的则还是放在传统数据库,如MySql等中。