没有合适的资源?快使用搜索试试~ 我知道了~
Redis是由意大利人Antirez(Salvatore Sanfilippo)在2009年创造的开源内存数据结构存储系统。Redis的名字来自意大利语“Repubblica di Redis”,意思是“基于字典的共和国”。它是一个基于内存的键值对存储系统,具有快速、稳定、可靠的特点。 Redis的诞生背景是互联网技术的快速发展,尤其是Web 2.0和移动互联网的兴起。这些技术需要处理大量的用户生成内容,而传统的关系型数据库在处理这些数据时存在性能瓶颈。Redis的出现,解决了关系型数据库在处理大量数据时的性能问题,成为了一种高效、可扩展的解决方案。
资源推荐
资源详情
资源评论
1. 背景
Redis是由意大利人Antirez(Salvatore Sanfilippo)在2009年创造的开源内存数据结构存储系统。Redis的
名字来自意大利语“Repubblica di Redis”,意思是“基于字典的共和国”。它是一个基于内存的键值对存储系
统,具有快速、稳定、可靠的特点。
Redis的诞生背景是互联网技术的快速发展,尤其是Web 2.0和移动互联网的兴起。这些技术需要处理大量的
用户生成内容,而传统的关系型数据库在处理这些数据时存在性能瓶颈。Redis的出现,解决了关系型数据库
在处理大量数据时的性能问题,成为了一种高效、可扩展的解决方案。
2. 特点
1. 内存存储:Redis将所有数据存储在内存中,这使得读写操作非常快速。内存访问速度远高于磁盘访问
速度,因此Redis可以提供非常高的读写性能。同时,内存存储也意味着Redis适用于需要高速访问的应
用场景,如实时分析、实时游戏等。
2. 数据结构丰富:Redis支持多种数据结构,如字符串、哈希、列表、集合和有序集合等。这些数据结构
可以满足不同类型的应用需求,如列表可以用于实现队列、栈等数据结构,哈希可以用于实现关联表
等。同时,Redis还支持对这些数据结构进行丰富的操作,如插入、删除、查找等。
3. 高性能:由于Redis将所有数据存储在内存中,读写操作非常快速,因此Redis具有非常高的性能。在处
理大量数据时,Redis可以提供非常高的读写速度和并发处理能力。同时,Redis还支持多种数据结构和
丰富的操作,可以满足不同类型的应用需求。
4. 持久化:虽然Redis将所有数据存储在内存中,但它也支持将数据持久化到磁盘上。这样可以在系统崩
溃或重启时保证数据的完整性。Redis支持多种持久化方式,如RDB和AOF等。RDB通过生成数据快照
的方式进行持久化,而AOF则通过记录操作日志的方式进行持久化。
5. 主从复制和集群:Redis支持主从复制和集群部署,可以实现数据的高可用性和扩展性。主从复制可以
将数据从一个Redis实例复制到多个从实例,当主实例出现故障时,可以从实例可以接管数据。集群部
署可以将多个Redis实例组成一个集群,实现数据的分布式存储和访问。
3. 数据结构
3.1 String
字符串 string 是 Redis 最简单的数据结构。Redis 所有的数据结构都是以唯一的 key 字符串作为名称,然后
通过这个唯一 key 值来获取相应的 value 数据。不同类型的数据结构的差异就在于 value 的结构不一样。
Redis 的 string 可以包含任何数据,比如 jpg图片或者序列化的对象(java 中对象序列化函数 serialize)。
String 采用预分配冗余空间的方式来减少内存的频繁分配,内部为当前字符串实际分配的空间 capacity 一般
要高于实际字符串长度 len。当字符串长度小于 1M 时,扩容都是加倍现有的空间,如果超过 1M,扩容时一
次只会多扩 1M 的空间。需要注意的是字符串最大长度为 512M。
字符串是由多个字节组成,每个字节又是由 8 个 bit 组成,如此便可以将一个字符串看成很多 bit 的组合,
这便是 bitmap「位图」数据结构。
3.2 List
Redis 的列表相当于 Java 语言里面的 LinkedList,注意它是链表而不是数组,而且是双向链表。这意味着
list 的插入和删除操作非常快,时间复杂度为 O(1),但是索引定位很慢,时间复杂度为O(n),这点让人非常
意外。
当列表弹出了最后一个元素之后,该数据结构自动被删除,内存被回收。
Redis 的列表结构常用来做异步队列使用。将需要延后处理的任务结构体序列化成字符串塞进 Redis 的列
表,另一个线程从这个列表中轮询数据进行处理。
3.3 Hash
hash的底层存储有两种数据结构
ziplist:如果hash对象保存的键和值字符串长度都小于64字节且hash对象保存的键值对数量小于512,则采
用这种。
dict(字典):其他情况采用这种数据结构。
hash 结构也可以用来存储用户信息,不同于字符串一次性需要全部序列化整个对象,hash 以对用户结构中
的每个字段单独存储。这样当我们需要获取用户信息时可以进行部分获取。而以整个符串的形式去保存用户
信息的话就只能一次性全部读取,这样就会比较浪费网络流量。
hash 也有缺点,hash 结构的存储消耗要高于单个字符串,到底该使用 hash 还是字符串,需要根据实际情
况再三权衡。
3.4 Set
Set 是一个无序的、自动去重的集合数据类型,Set 底层用两种数据结构存储。
intset:如果元素个数少于默认值512且元素可以用整型,则用这种数据结构。
dict(字典):其他情况采用这种数据结构。
当集合中最后一个元素移除之后,数据结构自动删除,内存被回收。 set 结构可以用来存储活动中奖的
用户 ID,因为有去重功能,可以保证同一个用户不会中奖两次。
3.5 ZSet(有序集合)
zset 可能是 Redis 提供的最为特色的数据结构,它也是在面试中面试官最爱问的数据结构。zset为有序(有
限score排序,score相同则元素字典排序),自动去重的集合数据类型,其底层实现为 字典(dict) + 跳表
(skiplist),当数据比较少的时候用 ziplist 编码结构存储。
ziplist :如果有序集合保存的所有元素的长度小于默认值64字节且有序集合保存的元素数量小于默认值128
个,则采用这种数据结构
字典(dict) + 跳表(skiplist):其他情况采用这种数据结构。
4. 过期策略
Redis 所有的数据结构都可以设置过期时间,时间一到,就会自动删除。你可以想象 Redis 内部有一个死
神,时刻盯着所有设置了过期时间的 key,寿命一到就会立即收割。
你还可以进一步站在死神的角度思考,会不会因为同一时间太多的 key 过期,以至于忙不过来。同时因为
Redis 是单线程的,收割的时间也会占用线程的处理时间,如果收割的太过于繁忙,会不会导致线上读写指
令出现卡顿。在过期这件事上,Redis 非常小心。
4.1 过期 key 集合
redis 会将每个设置了过期时间的 key 放入到一个独立的字典中,以后会定时遍历这个字典来删除到期的
key。除了定时遍历之外,它还会使用惰性策略来删除过期的 key,所谓惰性策略就是在客户端访问这个 key
的时候,redis 对 key 的过期时间进行检查,如果过期了就立即删除。定时删除是集中处理,惰性删除是零
散处理。
4.2 定时扫描策略
Redis 默认会每秒进行十次过期扫描,过期扫描不会遍历过期字典中所有的 key,而是
采用了一种简单的贪心策略。
1、从过期字典中随机 20 个 key;
2、删除这 20 个 key 中已经过期的 key;
3、如果过期的 key 比率超过 1/4,那就重复步骤 1;
同时,为了保证过期扫描不会出现循环过度,导致线程卡死现象,算法还增加了扫描时间的上限,默认不会
超过 25ms。
设想一个大型的 Redis 实例中所有的 key 在同一时间过期了,会出现怎样的结果?
毫无疑问,Redis 会持续扫描过期字典 (循环多次),直到过期字典中过期的 key 变得稀疏,才会停止 (循环次
数明显下降)。这就会导致这期间线上读写 QPS 下降明显。还有另外一种原因是内存管理器需要频繁回收内
存页,这也会产生一定的 CPU 消耗。
这里解析一下,假如单台 Redis 读写请求 QPS 是 10w,也就是每个请求需要 0.00001s 来完成,每秒执行十
次过期扫描,每次过期扫描都达到上限 25ms,那么每秒过期扫描总花费 0.25s,相当于 QPS 降低了
2.5W。
所以业务开发人员一定要注意过期时间,如果有大批量的 key 过期,要给过期时间设置一个随机范围,而不
能全部在同一时间过期。
剩余13页未读,继续阅读
资源评论
孤蓬&听雨
- 粉丝: 8559
- 资源: 364
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功