Redis
文章平均质量分 66
程序员面试那点事儿
互联网大厂校招、社招面试官,多年互联网大厂工作经验,分享校招、社招面试题、职场相关内容,互相交流经验
展开
-
学习导航
缓存满了怎么办原创 2021-01-06 21:48:23 · 77 阅读 · 0 评论 -
Redis哨兵机制
文章目录存在问题哨兵机制的基本流程监控选主通知主观下线和客观下线如何选定新主库总结存在问题主从库集群模式下,从库发生故障了,客户端还可以继续向主库和其他从库发送请求。如果主库发生故障了,直接会影响到主库数据的同步和写操作。主库挂了,需要运行一个新主库,比如说把一个从库切换为主库。但涉及三个问题主库真的挂了吗该选择哪个从库作为主库如何把新主库的相关信息通知给从库和客户端呢这就需要哨兵机制了。哨兵机制是实现主从库自动切换的关键机制,有效地解决了主从复制模式下的故障转移的三个问题。哨兵机制的原创 2021-01-07 22:53:39 · 139 阅读 · 0 评论 -
Redis哨兵模式
哨兵模式Sentinel(哨兵)系统是由一到多个Sentinel实例组成,可以监控Redis主、从服务器,并可以实现自动的主从切换。启动并初始化Sentinel初始化服务器。Sentinel本质上是一个运行在特殊模式下的Redis服务器,所以初始的是一个Redis的服务器,由于Sentinel不需要数据库,所以并不会载入RDB或者AOF文件来恢复数据库状态。将普通Redis服务器使用的代码替换成Sentinel专用代码。初始化Sentinel状态。状态如下:struct sentinelS原创 2021-01-07 09:21:40 · 89 阅读 · 0 评论 -
缓存满了怎么办
文章目录淘汰步骤设置多大的缓存淘汰策略LRU如何处理被淘汰的数据?淘汰步骤为了保证较高的性价比,缓存的空间容量必然要小于后端数据库的数据总量。随着要缓存的数据量越来越大,有限的缓存空间不可避免地会被写满,这个时候就需要缓存数据的淘汰机制,分为两步根据一定的策略,筛选出对应用访问来说不重要的数据将这些数据从缓冲中删除,为新来的数据腾出空间设置多大的缓存数据分布的两种类型长尾效应:有 20% 的数据贡献了 80% 的访问了重尾效应:20% 的数据可能贡献不了 80% 的访问,而剩余的 80原创 2020-12-30 08:55:47 · 1023 阅读 · 0 评论 -
Redis是的缓存特征及类型
文章目录缓存特征Redis 缓存处理请求的两种情况缓存的类型只读缓存读写缓存缓存特征一个系统中的不同层之间的访问速度不一样,所以我们才需要缓存,这样就可以把一些需要频繁访问的数据放在缓存中,以加快它们的访问速度。计算机系统中的三层存储结构,以及它们各自的常用容量和访问性能计算机系统中,默认有两种缓存:CPU 里面的末级缓存,即 LLC,用来缓存内存中的数据,避免每次从内存中存取数据;内存中的高速页缓存,即 page cache,用来缓存磁盘中的数据,避免每次从磁盘中存取数据。两个特征原创 2020-12-29 09:55:20 · 317 阅读 · 0 评论 -
Redis中的缓冲区
文章目录客户端输入和输出缓冲区输入缓冲区溢出如何查看如何避免输出缓冲区溢出返回客户端信息种类输出缓冲区组成部分溢出情况缓冲区大小设置问题设置内容客户端分类普通客户端设置订阅客户端设置主从集群中的缓冲区缓冲区是一块用来暂时存放命令数据的内存空间,避免数据和命令处理速度慢而导致数据丢失或性能问题。因为内存缓冲区的空间有限,写入数据的速度持续大于从里面读取数据的速度,会导致缓冲区内存越来越大,超过上限值(不设上限会把Redis内存耗尽而崩溃),就会缓冲区溢出。缓冲区在Redis中的应用场景如下:客户端输入原创 2020-12-28 08:59:20 · 982 阅读 · 1 评论 -
Redis空间存储效率之删除数据后,内存占用率还是很高
文章目录内存碎片内存碎片形成原因内因:内存分配器的分配策略外因:键值对大小不一样和删改操作如何判断是否有内存碎片如何清理内存碎片重启Redis实例Redis内存碎片自动清理数据删除后,Redis释放的内存空间会由内存分配器管理,不会立即返回给操作系统风险点:Redis释放的内存空间不是连续的,不连续的内存空间很有可能会处于一种闲置的状态。降低机器的成本回报率内存碎片可以类比高铁车厢座位,比如5个人出游,但是现在买票的时候发现当前车次每个车厢都留了两个位置,但是你们想5个人坐一起聊天,没有连续的座位,原创 2020-12-27 16:11:07 · 336 阅读 · 0 评论 -
如何应对变慢的Redis-波动的响应延迟
Redis突然变慢了,如何排查呢文章目录问题认定应对方案Redis自身操作特性慢查询命令过期key操作问题认定如何判断Redis是不是真的变慢了?通过Redis的响应延迟大部分时候,Redis延迟很低,某些时刻,Redis实例会出现几秒到十几秒延迟,基本就可以断定Redis变慢了不同的软硬件环境下,Redis判断延迟的标准不同,所以需要通过当前环境下的Redis基线性能做判断Redis基线性能:一个系统在低压力、无干扰下的基本性能,这个性能只由当前的软硬件配置决定如何确定基线性能:redi原创 2020-12-24 08:54:52 · 557 阅读 · 0 评论 -
CPU结构对Redis性能的影响
文章目录CPU架构多核架构多CPU架构CPU架构的影响CPU多核对Redis的影响CPU的多核架构和多CPU架构都会影响到Redis的性能CPU架构多核架构一个CPU处理器一般有多个运行核心每个运行核心是一个物理核,每个物理核都可以运行应用程序每个物理核都有私有的一级缓存L1(指令缓存、数据缓存)以及私有的二级缓存L2物理核的私有缓存只能被当前物理核使用,访问L1、L2的延迟不超过10纳秒(访内存延迟一般在百纳秒级别)数据和指令如果在L1和L2保存的话,就能提高Redis的性能,不过L1、原创 2020-12-23 09:04:07 · 376 阅读 · 0 评论 -
Redis性能之内部阻塞式操作及应对方法
文章目录Redis实例都有哪些阻塞点和客户端交互的阻塞点集合的全量查询和聚合操作bigkey删除操作清空数据库磁盘交互的阻塞点主从节点交互时的阻塞点切片集群实例交互时的阻塞点可以异步执行的阻塞点异步的子线程总结Redis的网络IO和键值对读写都是由主线程完成的。Redis实例都有哪些阻塞点客户端:网络IO,键值对增删改查,数据库操作磁盘:生成RDB快照,记录AOF日志,AOF日志重写主从节点:主库生成、传输RDB文件、从库接收RDB文件,清空数据库,加载RDB文件切片集群实例:向其他实例传输哈原创 2020-12-22 09:04:57 · 265 阅读 · 0 评论 -
影响Redis性能的因素
文章目录Redis内部的阻塞式操作CPU核和NUMA架构Redis关键系统配置Redis内存碎片Redis缓冲区Redis内部的阻塞式操作CPU核和NUMA架构Redis关键系统配置Redis内存碎片Redis缓冲区原创 2020-12-22 08:09:10 · 158 阅读 · 0 评论 -
如何周期性地统计近万台设备的实时状态?Redis时间序列存储方案
文章目录读写特点写读基于Hash和Sorted Set实现(单键和范围查询)单键查询范围查询原子性保障基于RedisTimeSeries实现(聚合计算)场景模拟RedisTimeSeries 使用TS.CREATE 创建一个时间序列数据集合TS.ADD 插入数据TS.GET 读取最新数据TS.MGET 按标签过滤查询数据集合TS.RANGE:支持需要聚合计算的范围查询场景:如何周期性地统计近万台设备的实时状态,包含设备ID、压力、温度、湿度、时间戳时间序列:与发生时间相关的一组数据,没有严格的关系模型,原创 2020-12-18 09:45:40 · 1642 阅读 · 1 评论 -
String类型不太适合的场景
文章目录具体场景为什么String类型开销大String类型的内存空间消耗问题以及节省内存开销的数据类型解决方案具体场景场景:存储图片ID和图片在存储系统中保存的ID对应关系解决方案1:使用String类型,key、value如下:key:存储图片的IDvalue:存储系统保存的ID大概保存了1亿张图片之后,大约使用了6.4GB的内存。String类型并不适用于所有的场合,保存数据时所消耗的内存空间较多为什么String类型开销大根据上面场景,两个ID都采用Long类型的话,只需要1原创 2020-12-16 09:12:54 · 137 阅读 · 0 评论 -
Redis之集合统计型应用
文章目录聚合统计排序统计聚合统计统计多个集合元素的聚合结果,比如交集、差集、并集运算。具体场景:统计手机APP每天的新增用户数和第二天的留存用户数记录过登录过APP的用户ID可以用set类型累计用户set每日用户set每日新增用户:每日用户set和累计用户set的差集留存用户:计算两个日期的差集Set的差集、并集、交集计算复杂度较高,在数据量较大的情况下,如果直接执行会导致阻塞,可以通过从库进行聚合计算,或者将数据读取到客户端进行聚合统计。排序统计...原创 2020-12-15 09:18:05 · 357 阅读 · 1 评论 -
Redis之紧凑列表
基本结构struct listpack<T> { int32 total_bytes; // 占用的总字节数 int16 size; // 元素个数 T[] entries; // 紧凑排列的元素列表 int8 end; // 同 zlend 一样,恒为 0xFF}struct lpentry { int<var> encoding; optional byte[] content; int<var> len原创 2020-12-14 07:48:52 · 175 阅读 · 0 评论 -
Redis之快速列表
文章目录早期实现Quicklist压缩深度早期实现Redis早起版本存储list列表数据结构使用的是压缩列表ziplist和普通的双向链表linkedlist,也就是少时用ziplist,多时用linkedlist链表的附加空间相对较高,prex和next指针要占去16字节(64bit系统的指针是8个字节)每个节点内存单独分配,加剧内存的碎片化,影响内存管理效率Quicklist后续版本中采用quicklist代替了ziplist和linkedlist。代码如下struct ziplis原创 2020-12-11 08:32:17 · 147 阅读 · 0 评论 -
Redis底层结构之压缩列表
文章目录是什么增加元素IntSet集合是什么压缩列表是一块连续的内存空间,zset、hash容器在元素对象较少的时候,采用压缩列表。struct ziplist<T>{ int32 zlbytes;//整个压缩列表占用字节数 int32 zltail_offset://最后一个元素距离压缩列表起始位置的偏移量,用于倒着遍历 int16 zllength://元素个数 T[] extries://元素内容列表,连续存储 int8 zlend://标志压缩列表的结束}stru原创 2020-12-10 07:40:21 · 135 阅读 · 0 评论 -
Redis内部结构之字典
文章目录应用场景dict内部结构渐进式rehash哈希函数扩容条件缩容条件应用场景//Redis数据库的key-value和带有过期时间的key都是一个字典struct RedisDb { dict* dict; // all keys key=>value dict* expires; // all expired keys key=>long(timestamp) ...}//zset中存储value和score值的映射关系也是通过dict结构实现的st原创 2020-12-09 08:44:57 · 161 阅读 · 0 评论 -
Redis数据结构之简单动态字符串、对象头
结构定义struct sdshdr{ //记录buf数组中已使用字节的数量 int len; //记录buf数组中未使用字节的数量 int free; //字节数组,用于保存字符串 char buf[];}buf属性是一个char类型的数组,前五个字节分别保存’R’、‘e’、‘d’、‘i’、‘s’五个字符,SDS遵循C字符串以空字符结尾的惯例,最后一个字节则保存了空字符’\0’。遵循空字符结尾惯例,SDS可以直接重用一部分C字符串函数库里面的函数。和C字符串的区别常数复杂度获取原创 2020-12-09 08:21:50 · 266 阅读 · 0 评论 -
Redis 有序数据结构zset底层原理
ziplist:使用紧挨在一起的压缩列表节点来保存,第一个节点保存member,第二个保存score。ziplist 内的集合元素按 score 从小到大排序,其实质是一个双向链表。虽然元素是按 score 有序排序的, 但对 ziplist 的节点指针只能线性地移动,所以在 REDIS_ENCODING_ZIPLIST 编码的 Zset 中, 查找某个给定元素的复杂度为O(n)。 skiplist:跳跃表是一种有序的数据结构,它通过在每个节点上维持多个指向其它节点的指针来达到快速访问的目的。跳跃表原创 2020-12-08 09:26:50 · 816 阅读 · 0 评论 -
影响Redis的潜在因素
文章目录Redis的内部操作CPU核和NUMA架构的影响Redis关键系统配置Redis内存碎片Redis缓冲区Redis的内部操作CPU核和NUMA架构的影响Redis关键系统配置Redis内存碎片Redis缓冲区原创 2020-12-08 08:52:36 · 67 阅读 · 0 评论 -
Redis主从库如何实现数据一致(同步)
文章目录高可靠性主从第一次同步主从级联模式分担全量复制时的主库压力主从库间网络断了怎么办?高可靠性Redis具有高可靠性数据尽量少丢失:AOF,RDB保证服务尽量少中断:增加冗余副本读写分离读操作:主库、从库都可以接收;写操作:首先到主库执行,然后,主库将写操作同步给从库。读写不分离的话,修改请求发往不同的实例,保持这个数据在三个实例上一致,就要涉及到加锁、实例间协商是否完成修改等一系列操作,但这会带来巨额的开销,当然是不太能接受的。主从库模式采用了读写分离,所有数据的修改只会原创 2020-12-04 08:03:52 · 1582 阅读 · 0 评论 -
大数据量之切片集群
文章目录如何应对数据量的增多纵向扩展(增加大内存云主机)横向扩展(切片集群)Redis横向扩展方案如何应对数据量的增多纵向扩展(增加大内存云主机)优势- 实施简单、直接劣势- 会受到硬件和成本的限制- Redis使用RDB进行持久化的过程中,Redis会fork子进程来完成,fork操作的用时和Redis数据量正相关,fork执行时阻塞主线程。横向扩展(切片集群)切片集群对于保存大数据量的场景是一种好的解决方案切片集群是一种保存大量数据的通用机制,这个机制可以有不同的实现方案。在 Re原创 2020-12-04 08:03:12 · 399 阅读 · 0 评论 -
AOF日志原理详解
AOF日志实现AOF是一种写后日志,即先执行命令,将数据写入内存,然后再记录日志。传统的数据库日志,例如Redo log,记录的是修改后的数据,AOF里记录的是Redis收到的每一条命令AOF日式格式*3代表当前命令有三个部分,每部分都是$+数字开头,$3代表这部分有三个字节。Redis通过写后日志的方式避免了记录错误的命令,同时不会阻塞当前的写操作。执行完一个命令,还没来得及记日志就宕机了,那么数据就有丢失的风险如果使用是缓存,那么还可以从数据库里重新加载如果使用当做数据库,就丢数据原创 2020-12-01 08:22:21 · 989 阅读 · 1 评论 -
RDB内存快照原理详解
文章目录是什么存在的两个问题两个命令快照数据修改快照的频率增量快照混合日志和快照是什么内存快照, 就是指内存中的数据在某一个时刻的状态记录,即某一时刻的状态以文件的形式写到磁盘上。在做数据恢复时,我们可以直接把 RDB 文件读入内存,很快地完成恢复存在的两个问题对哪些数据做快照,关系到快照的执行效率问题为了提供所有数据的可靠性保证,它执行的是全量快照做快照时,Redis 是否被阻塞,能否同时正常处理增删改两个命令通过两个命令来生成 RDB 文件,分别是 save 和 bgsave。原创 2020-12-01 08:22:12 · 2294 阅读 · 0 评论 -
Redis的高性能IO模型
Redis的单线程指的是网络IO和键值对读写是由一个线程来完成的,Redis的持久化、异步删除、集群数据同步等,都是由额外的线程执行。为什么用单线程多线程和系统的吞吐量并不是完全正相关的关系多线程会导致并发访问的控制问题Redis单线程Redis大部分操作都是内存完成,同时采用的数据结构如哈希表、跳表采用了多路复用机制,使网络IO操作中能并发处理大量客户端请求IO模型Redis基本IO模型阻塞模式在操作中,有两个阻塞点,accept和recv。accept:当Redis监听原创 2020-11-30 08:28:48 · 397 阅读 · 0 评论 -
Redis底层数据结构及效率
数据类型与数据结构对应关系如下键值结构Redis使用了一个哈希表来保存所有键值对,哈希表本质就是个数组,数组里的每个元素都是一个哈希桶。哈希桶中的元素保存的都是具体指向值的指标。全局哈希表结构如下:哈希表可以在O(1)的复杂度快速查找,但是存在以下风险哈希表的冲突问题两个key的哈希值和哈希桶计算对应关系时,正好落在了同一个哈希桶里。通过链式哈希来解决哈希冲突。哈希冲突链上的元素只能去遍历查找,但是如果链过长,就会导致查询耗时长,效率低,所以需要rehashrehash带来的操作阻塞原创 2020-11-27 09:22:00 · 280 阅读 · 0 评论 -
键值数据库基本架构及Redis解决方案
文章目录数据类型操作数据访问方式键值定位重启恢复数据类型操作数据访问方式键值定位重启恢复原创 2020-11-26 08:40:54 · 819 阅读 · 0 评论 -
Redis事务
Redis通过MULTI、EXEC、WATCH等命令来实现事务(transaction)功能。事务阶段一个事务会经历三个阶段:事务开始、命令入队、事务执行事务开始MULTI将客户端从非事务状态切换到事务状态,通过将客户端的Flags属性REDIS_MULTI打开实现的。命令入队每个客户端都有自己的事务状态,保存在RedisClient对象的mstate中事务执行当一个处于事务的客户端执行EXEC的时候,服务端会遍历客户端的事务队列,遍历执行,然后把结果返回给客户端。Watch命令的实现原创 2020-10-21 21:31:13 · 88 阅读 · 0 评论 -
详解Redis集群节点、槽指派、重新分片、故障转移
Redis集群是Redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移功能。节点Redis集群中有多个节点组成,节点之间通过CLUSTER MEET <ip> <port>连接起来。运行在集群模式下的Redis服务器的节点会继续使用所有在单机模式中使用的服务器组件,还会使用clusterNode结构、clusterLink结构,clusterState结构。每个节点都会使用一个clusterNode结构来记录自己的状态stru原创 2020-09-30 11:29:23 · 834 阅读 · 0 评论 -
Redis分布式锁
原理Redis 锁主要利用 Redis 的 SETNX 命令。加锁:SETNX key value。键不存在时,对键进行设置操作并返回成功,否则返回失败。KEY 是锁的唯一标识,一般按业务来决定命名。解锁:DEL key。通过删除键值对释放锁,以便其他线程可以通过 SETNX 命令来获取锁。锁超时:EXPIRE key timeout,。设置 key 的超时时间,以保证即使锁没有被显式释放,锁也可以在一定时间后自动释放,避免资源被永远锁住。伪代码如下:if (setnx(key, 1) =原创 2020-09-08 11:49:27 · 213 阅读 · 0 评论 -
有序集合对象
有序集合的编码可以是ziplist或者skiplist。ziplist编码的压缩列表对象使用压缩列表作为底层实现,每个集合元素使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员(member),而第二个元素则保存元素的分值(score)。压缩列表内的集合元素按分值从小到大进行排序,分值较小的元素被放置在靠近表头的方向,而分值较大的元素则被放置在靠近表尾的方向。skiplist编码的有序集合对象使用zset结构作为底层实现,一个zset结构同时包含一个字典和一个跳跃表:struct原创 2020-09-07 18:17:13 · 640 阅读 · 0 评论 -
集合对象
集合对象的编码可以是intset或者hashtable。intset编码的集合对象使用整数集合作为底层实现,集合对象包含的所有元素都被保存在整数集合里面。hashtable编码的集合对象使用字典作为底层实现,字典的每个键都是一个字符串对象,每个字符串对象包含了一个集合元素,而字典的值则全部被设置为NULL。编码转换集合对象保存的所有元素都是整数值;集合对象保存的元素数量不超过512个不能满足这两个条件的集合对象需要使用hashtable编码。...原创 2020-09-07 18:05:45 · 700 阅读 · 0 评论 -
哈希对象
哈希对象的编码可以是ziplist或者hashtable。ziplist编码的哈希对象使用压缩列表作为底层实现。每当有新的键值对要加入到哈希对象时,程序会先将保存键的节点推入到压缩列表表尾,然后再将保存值的节点推入到压缩列表表尾。hashtable编码的哈希对象使用字典作为底层实现,字典的每个键都是一个字符串对象,对象中保存了键值对的键。字典的每个值都是一个字符串对象,对象中保存了键值对的值。使用ziplist哈希对象保存的所有键值对的键和值的字符串长度都小于64字节;哈希对象保存的键原创 2020-09-07 17:50:25 · 502 阅读 · 0 评论 -
列表对象
列表对象的编码可以是ziplist或者linkedlist。ziplist编码的列表对象使用压缩列表作为底层实现,每个压缩列表节点(entry)保存了一个列表元素。另一方面,linkedlist编码的列表对象使用双端链表作为底层实现,每个双端链表节点(node)都保存了一个字符串对象,而每个字符串对象都保存了一个列表元素。简化的字符串表示完整的字符串表示编码转换使用ziplist列表对象保存的所有字符串元素的长度都小于64字节列表对象保存的元素数量小于512个以上两个条件不符合原创 2020-09-07 17:28:03 · 423 阅读 · 0 评论 -
字符串对象
字符串对象的编码可以是int、raw、embstr。int如果一个字符串保存的是整数值,并且这个整数值可以用Long表示,那么字符串对象会被保存到RedisObject里的ptr属性里。raw如果字符串对象保存的是一个字符串值,并且这个字符串值的长度大于32字节,那么字符串对象将使用一个简单动态字符串(SDS)来保存这个字符串值,并将对象的编码设置为raw。会调用两次内存分配函数来分别创建redisObject结构和sdshdr结构embstr如果字符串对象保存的是一个字符串值,并且这个字符原创 2020-09-07 15:49:37 · 161 阅读 · 0 评论 -
对象
对象的类型和编码struct redisObject{ //类型 unsigned type:4; //编码 unsigned encoding:4; //指向底层数据结构的指针 void *ptr;}Redis保存的键值中,键总是一个字符串对象,值可以是字符串对象、列表对象、哈希对象、集合对象或者有序集合。type类型对象的ptr指针指向对象的底层实现数据结构,而这些数据结构由对象的encoding属性决定。Redis的对象系统还实现了基于引用计数技原创 2020-09-07 15:25:38 · 73 阅读 · 0 评论 -
Redis内部结构之压缩列表
压缩列表(ziplist)是列表键和哈希键的底层实现之一。压缩列表是Redis为了节约内存而开发的当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现。压缩列表是Redis为了节约内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型(sequential)数据结构基本结构struct ziplist<T> { int32 zlbytes; // 整个压缩列表占用字节数 int32原创 2020-09-07 11:45:37 · 332 阅读 · 0 评论 -
整数集合
基本结构当一个集合只包含整数值元素且这个集合的元素数量不多时,Redis会使用整数集合作为集合键的底层实现。struct intset{ //编码方式 uint32_t encoding; //包含元素的数量 uint32_t length; //保存元素的数组 int8_t contents[];}contents数组是整数集合的底层实现,元素无重复,按照从小到大排列,真正类型取决于encoding属性的值。根据整数集合的升级规则,当向一个底层为int16_t数组的整数集合添原创 2020-09-07 11:13:11 · 1573 阅读 · 0 评论 -
跳跃表
Redis只在两个地方用到了跳跃表,一个是实现有序集合键,另一个是在集群节点中用作内部数据结构struct zskiplist{ struct zskiplistNode *header,*tail; unsigned long length; int level;}zskiplist;struct zskiplistNode{ struct zskiplistLevel{ struct zskiplistNode *forward; unsigned int span; }lev原创 2020-09-07 10:36:38 · 87 阅读 · 0 评论