标签:大纲 过期 Redis 学习 内存 key 数据结构 数据
一、数据结构
Redis提供了丰富的数据结构供使用。主要有以下几种数据结构:
String:最普通和常用的一种结构,key/value。
Hash:类似于HashMap,底层也是哈希表。
List:类似于LinkedList,底层是双向链表。
Set:类似于HashSet,于HashSet的特性一样,不允许重复数据,不记录元素添加顺序。
SortSet:会自动的进行排序的set。
Streams(流):18年刚刚发布的一个新的数据结构,不是太了解,相关资料比较少。
二、应用场景
(一)并发竞争
- 通过分布式锁解决
通过在redis设置一个唯一锁,如果存在key,则认为有其他客户端在使用,等待锁释放。如果不存在key,说明没有客户端使用,可以执行任务,执行完毕,解锁,删除key。
- 存在的问题1 :
获得锁后,服务宕机,由于key是唯一的,所以无法被删除.
问题1解决方案:设置过期时间。
- 存在的问题2
任务执行过长,超过过期时间。
问题2解决方案:通过一个守护线程,给线程续命。
- 存在的问题3
任务执行造成死循环,会造成无限续命。
问题3解决方案:设置最大续命时间。
- 客户端加锁(Synchronized)
- 乐观锁(watch命令,这个和数据存储方式有关)
当执行多键值事务操作时,Redis 不仅要求这些键值需要落在同一个Redis 实例上,还要求落在同一个 slot 上,所以 redis 的事务比较鸡肋,不过可以想办法遵循 redis 内部的分片算法把设计到的所有 key 分到同一个 slot。
(二)发布与订阅
在一些发布订阅的场景中可以使用Redis作为消息队列,不过只适合数据量较小的场景,数据量比较大的适合,还是需要考虑Kafka、RocketMQ等组件。
例如之前在做AI中台时,利用Redis作为消息队列,作为用户登录登出状态的发布与订阅。
(三)缓存
Zset:
- 用户的爱好之类
- 打标签
- 公共好友
- 根据时间排序的新闻列表等,
- 阅读排行榜
- 粉丝列表(按关注时间排序);
- 学生成绩排名;
- 文章帖子排名;
- 各类榜单(如微博总热榜、分类热榜);
Hash:
- 适合存一些对象。避免序列化与反序列化,Value实际可以看作HashMap。
- 过期监听
- 用户释放资源
三、部署方式
目前常规的部署方式主要有三种:单节点部署、集群部署(cluster)、哨兵方式部署(sentinel)。
四、底层数据结构
列表键的底层实现之一就是链表。
key-value 存储方式,通过hash值计算,判断key的存储,当容量过大,会通过rehash重新分配字典大小。
Redis 只在两个地方用到了跳跃表,一个是实现有序集合键,另外一个是在集群节点中用作内部数据结构。
整数集合是集合建的底层实现之一,当一个集合中只包含整数,且这个集合中的元素数量不多时,redis就会使用整数集合intset作为集合的底层实现。
压缩列表(ziplist)是列表键和哈希键的底层实现之一。当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值, 要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现。
五、 过期策略
常用的过期策略有两种:定期删除、惰性删除。Redis默认的过期策略是两种同时在使用。如果只采用定期删除过期策略时,当数据量很大时,会严重影响Redis使用;如果只使用惰性删除过期策略时,会出现当大量数据都没有被访问时,实际上过期的数据并没有被删除,会导致内存大量占用。因此综合考虑会结合两种方式优势使用。
Redis 的过期策略都有哪些?手写一下 LRU 代码实现?
六、内存淘汰机制
Redis目前提供了8种内存淘汰机制。
no-enviction(默认策略):禁止驱逐数据。对于写请求不再提供服务,直接返回错误。
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)中任意选择数据淘汰。
Redis3.0对过期策略做了优化。Redis会维护一个候选池(大小为16),每次去其中随机选取5个,淘汰数据。
volatile-lfu(Redis4.0新增):在设置了过期时间的key中使用LFU算法淘汰key。
allkeys-lfu(Redis4.0新增):在所有的key中使用LFU算法淘汰数据。
Redis4.0还提供了一个功能。lazyfree-lazy-expire yes。释放过期Key的内存,可以放到后台进行。
七、单线程
Redis采用了单线程多路复用。Redis认为性能瓶颈是在内存而不在CPU,而且单线程比较省事,因此采用单线程多路复用。
八、持久化
- RDB 持久化
将某个时间点的所有数据都存放到硬盘上。可以将快照复制到其它服务器从而创建具有相同数据的服务器副本。如果系统发生故障,将会丢失最后一次创建快照之后的数据。如果数据量很大,保存快照的时间会很长。
- AOF 持久化
将写命令添加到 AOF 文件(Append Only File)的末尾。使用 AOF 持久化需要设置同步选项,从而确保写命令同步到磁盘文件上的时机。这是因为对文件进行写入并不会马上将内容同步到磁盘上,而是先存储到缓冲区,然后由操作系统决定什么时候同步到磁盘。
有以下同步选项:选项同步频率
always每个写命令都同步。
everysec每秒同步一次。
no让操作系统来决定何时同步。
always选项会严重减低服务器的性能;everysec选项比较合适,可以保证系统崩溃时只会丢失一秒左右的数据,并且 Redis每秒执行一次同步对服务器性能几乎没有任何影响;no选项并不能给服务器性能带来多大的提升,而且也会增加系统崩溃时数据丢失的数量随着服务器写请求的增多,AOF 文件会越来越大。Redis 提供了一种将 AOF 重写的特性,能够去除 AOF 文件中的冗余写命令。
九、问题
- 如何定位
设置日志的频率,如果访问或者设置数据超过5ms记录。
- 值设置为null
Redis中将值设为null,会被认为值未被定义。
- Redis比较慢
Redis为什么变慢了?一文讲透如何排查Redis性能问题 | 万字长文
- 可能是网络问题。
- key或者value比较大。
- 集中过期。
- 实例内存达到上限。
- Fork耗时严重。数据持久化阶段,会fork进程。
- 操作系统开启内存大页。
- 频繁短链接。
- 运维监控。
- Redis为啥快
采用多路复用机制。运行在内存中。数据结构比较简单。
- 常见的性能问题
主服务器写内存快照,会阻塞主线程的工作,当快照比较大时对性能的影响是比较大的,会间歇性暂停服务,所以主服务器组最好不要写内存快照。
Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,主从库最好在同一个局域网内。
标签:大纲,过期,Redis,学习,内存,key,数据结构,数据 来源: https://blog.csdn.net/u010313979/article/details/113827526
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。