五种数据类型介绍
常用的类型主要是 String、List、Hash、Set、ZSet 这5种。
类型 | 存储值 | 操作 | 常见应用场景 |
---|---|---|---|
String | 字符串,整型,浮点数 | 字符串操作对整数和浮点数执行自增、自减操作 | 缓存、限流、计数器、分布式锁、分布式Session |
List | 链表 | 两端压入、弹出元素;保持顺序;读取单个或者多个元素;删除、保留范围内元素 | 微博关注人时间轴列表、简单队列 |
Hash | 由键值对组成的无序列表 | 添加、获取、移除单个键值对;获取所有键值对;检查某个键是否存在 | 存储用户信息、用户主页访问量、组合查询 |
Set | 无序集合 | 添加、随机获取、移除单个元素;检查一个元素是否存在于集合中;计算交集、并集、差集 | 标签、好友关系 |
ZSet | 有序集合,增加了一个权重参数score,集合中的元素能按score进行有序排列 | 添加、获取、删除元素个元素;根据分值范围或者成员来获取元素;计算一个键的位置 | 排行榜 |
注意:set方法会丢失已经设置过期时间key的过期时间,变成永不过期的(-1)。
如果不设置过期时间,默认是不过期。然后超过内存设置的话,就会根据过期键处理机制进行处理(按照实际配置的数据淘汰策略)。
为什么说Redis是单线程的以及Redis为什么这么快!
- 完全基于内存
- 数据结构简单,对数据操作也简单
- 使用多路 I/O 复用模型
*多数操作时间复杂度是o(1)
进阶问题
- 二八定律
缓存的应用:网站访问数据的特点大多数呈现在"二八定律":80%的业务访问集中在20%的数据上。这时为了减轻数据的压力和提高网站的数据访问速度,则可以使用缓存机制来优化网站。
-
热点数据
-
淘汰策略
redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:
volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据 -
持久化方式及其优缺点对比
一种是RDB持久化(原理是将Reids在内存中的数据库记录定时 dump到磁盘上的RDB持久化)
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
RDB存在哪些优势呢?
- 一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对于文件备份而言是非常完美的。比如,你可能打算每个小时归档一次最近24小时的数 据,同时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复。
- 对于灾难恢复而言,RDB是非常不错的选择。我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上,使用RDB文件进行数据恢复比使用AOF要快很多。
- 性能最大化。对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。
- 相比于AOF机制,如果数据集很大,RDB的启动效率会更高。
RDB又存在哪些劣势呢?
- 如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
- 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。
另外一种是AOF(append only file)持久化(原理是将Reids的操作日志以追加的方式写入文件)
AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
AOF的优势有哪些呢?
- 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其 效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变 化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,无需多言,我想大家都能正确的理解它。
- 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操 作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据 一致性的问题。
- 如果日志过大,Redis可以自动启用rewrite机制。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创 建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性。
- AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建。
AOF的劣势有哪些呢?
- 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
- 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。
二者选择的标准,就是看系统是愿意牺牲一些性能,换取更高的缓存一致性(aof),还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。rdb这个就更有些 eventually consistent的意思了。
- redis主从复制 分布式数据同步方式
- redis能用来做消息队列吗?怎么实现?可能会存在什么问题?
利用Redis 实现消息队列
什么场景下适合使用redis?redis优缺点?
回到文章开始的表格。一句话总结来说就是小而热的数据!
- 缓存 将热点数据放到内存中
- 消息队列 List 类型是双向链表,很适合用于消息队列
- 计数器 快速、频繁读写操作;string的单线性自增减 ++ --
- 共同好友关系 set 交集运算,很容易就可以知道用户的共同好友
- 排名 zset有序集合
使用redis需要考虑的问题
-
redis 本身是否可靠?
-
线程阻塞的风险
-
redis 带宽造成延迟,网络io瓶颈,受到内存限制
-
redis rdb持久化风险
-
数据淘汰
-
时钟跳跃问题 在某些时候,redis的服务器时间发生的跳跃,由于锁的过期时间依赖于服务器时间,所以也会出现两个客户端同时获取到锁的情况发生
-
扩容困难,需要运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费
网友评论