【高频】redis快的原因

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
日志服务 SLS,月写入数据量 50GB 1个月
简介: 【高频】redis快的原因

相关问题:

1.为什么Redis能够如此快速地进行数据存储和检索?

2.Redis作为内存数据库,其内存存储有什么优势吗?

3.Redis的网络模型有何特点,如何帮助提升性能?


一、问题回答

  • Redis使用了内存数据结构,例如字符串、哈希表、列表、集合、有序集合等,这些数据结构在内存中操作速度很快,有助于Redis的高性能。
  • Redis采用单线程模型,避免了多线程的线程切换和同步开销,提高了处理速度。


  • Redis使用了非阻塞I/O,可以在一个线程中处理多个客户端请求,提高了并发处理能力。


  • Redis支持多种持久化方式,包括RDB快照和AOF日志,可以根据需要选择合适的持久化方式,同时保证数据安全和性能。


  • Redis主要是基于内存操作,避免了频繁的磁盘IO操作,从而提高了读写性能。


二、redis的数据类型

1.String:主要用来存储字符串,底层基于动态字符串SDS实现,其通过动态调整长度节省内存。


场景:分布式锁session、分布式锁。  指令:set, hget, setnx, set ex


2.hash:类似于map,底层采用两种方式,当数据量较少并且元素占用内存少(小整数或短字符串时)采用ziplist(压缩列)。


场景:实现购物车    指令:hset, hgetall, hdel


3.list:有序可重复集合,当数据量少并且元素占用内存少,用ziplist,反之用quicklist(快速列表),节省内存。


【ziplist: 连续内存空间,通过紧凑的存储来节省空间。 quicklist:基于ziplist和链表,节省内存,高效增删】


场景:栈(LPush+Lpop) \ 队列(Lpush + Lpop) \ 发布订阅


4.set:元素不可重复,当数据量少且元素为整,用intset(整数集合),反之用hashtable(哈希表)。


【intset:有序数组,紧凑空间。 hashtable:基于dict(字典)实现,采用拉链表解决。】


场景:抽奖(srandmember) \点赞收藏关注(sadd) \共同关注(sinter)\可能认识的人(sdiff)


5.zset(sorted set):有序不可重复,数据量少用ziplist,反之skiplist(跳表)+dict(字典)。


【skiplist:有序链表配上多级索引,通过多级索引位置的跳转实现快速查找元素,按分值排序。】


场景:排行榜(zrange\zreverange\zunionscore)


6.bitmap:位图。


场景: 月打卡、月活跃、布隆过滤器


7.stream:参考kafka设计的消息队列,支持持久化,适合小基数的消息队列场景。


三、Reactor模型

Reactor 模式也叫 Dispatcher 模式,即 I/O 多路复用监听事件,收到事件后,根据事件类型分配(Dispatch)给某个进程 / 线程

1.单线程模式:一个线程负责多个事件处理,当连接数过多时会造成性能瓶颈,适合连接数少,复杂度低的场景。


2.多线程模式(单线程、工作线程池):在单线程的基础上,将业务处理部分交给了线程池提高并发能力,需要注意线程安全。


3.主从多线程模式:将整体拆分为主、从Reactor


  • 主:负责监听连接事件,将事件分发给从Reactor去处理。
  • 从:负责与客户端读写操作,充分利用多核CPU,提升并发。


四、IO多路复用

一种同步IO模型,允许单线程去同时监听多个文件描述符,一旦文件描述符就绪就会通知程序处理。【多个请求复用了一个进程,这就是多路复用】

select/poll/epoll 内核提供给用户态的多路复用系统调用,进程可以通过一个系统调用函数从内核中获取多个事件。


select:基于数组实现,每次调用都进行遍历,最大连接有上限。

poll:基于链表实现,无最大连接上限。

epoll:通过哈希表实现,通过事件通知,当IO事件就绪,系统注册的回调函数就被调用,无上限。【epoll 支持两种事件触发模式,分别是边缘触发(edge-triggered,ET)和水平触发(level-triggered,LT)】

注:(以下摘自:这次答应我,一举拿下 I/O 多路复用!)


1.poll 和 select 并没有太大的本质区别,都是使用「线性结构」存储进程关注的 Socket 集合,因此都需要遍历文件描述符集合来找到可读或可写的 Socket,时间复杂度为 O(n),而且也需要在用户态与内核态之间拷贝文件描述符集合,这种方式随着并发数上来,性能的损耗会呈指数级增长。


2.epoll 通过两个方面,很好解决了 select/poll 的问题。


  • epoll 在内核里使用红黑树来跟踪进程所有待检测的文件描述字,把需要监控的 socket 通过 epoll_ctl() 函数加入内核中的红黑树里,红黑树是个高效的数据结构,增删查一般时间复杂度是 O(logn),通过对这棵黑红树进行操作,这样就不需要像 select/poll 每次操作时都传入整个 socket 集合,只需要传入一个待检测的 socket,减少了内核和用户空间大量的数据拷贝和内存分配。
  • epoll 使用事件驱动的机制,内核里维护了一个链表来记录就绪事件,当某个 socket 有事件发生时,通过回调函数内核会将其加入到这个就绪事件列表中,当用户调用 epoll_wait() 函数时,只会返回有事件发生的文件描述符的个数,不需要像 select/poll 那样轮询扫描整个 socket 集合,大大提高了检测的效率。


五、持久化机制

1.RDB 就是 Redis DataBase 的缩写,中文名为快照/内存快照,RDB持久化是把当前进程数据生成快照保存到磁盘上的过程,由于是某一时刻的快照,那么快照中的值要早于或者等于内存中的值。【自动触发 和 手动触发】


2.Redis是“写后”日志,Redis先执行命令,把数据写入内存,然后才记录日志。日志里记录的是Redis收到的每一条命令,这些命令是以文本形式保存。PS: 大多数的数据库采用的是写前日志(WAL),例如MySQL,通过写前日志和两阶段提交,实现数据和逻辑的一致性。 【而AOF日志采用写后日志,即先写内存,后写日志。 】


RDB:通过快照进行持久化,通过快照触发条件将内存中的数据写到rdb文件中。

AOF:一种接近实时的方式,通过执行命令都写到AOF中。

很少使用RDB,因为它容易丢失数据,通常会采用AOF,但AOF持久化速度慢,故混合使用。


RDB全量持久化 + AOF增量持久化


  1. 若数据不敏感,可不开启持久化
  2. 数据比较重要且允许几分钟数据丢失用RDB
  3. 作为内存数据,建议都开启,优先从AOF中进行数据恢复,因为它数据更完整。


六、基于内存操作

内存直接由 CPU 控制,也就是 CPU 内部集成的内存控制器,所以说内存是直接与 CPU 对接,享受与 CPU 通信的最优带宽。Redis 将数据存储在内存中,读写操作不会因为磁盘的 IO 速度限制。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
7月前
|
消息中间件 缓存 NoSQL
Redis经典问题:缓存雪崩
本文介绍了Redis缓存雪崩问题及其解决方案。缓存雪崩是指大量缓存同一时间失效,导致请求涌入数据库,可能造成系统崩溃。解决方法包括:1) 使用Redis主从复制和哨兵机制提高高可用性;2) 结合本地ehcache缓存和Hystrix限流降级策略;3) 设置随机过期时间避免同一时刻大量缓存失效;4) 使用缓存标记策略,在标记失效时更新数据缓存;5) 实施多级缓存策略,如一级缓存失效时由二级缓存更新;6) 通过第三方插件如RocketMQ自动更新缓存。这些策略有助于保障系统的稳定运行。
720 1
|
2月前
|
存储 消息中间件 NoSQL
【redis】redis的特性和主要应用场景
【redis】redis的特性和主要应用场景
112 1
|
7月前
|
缓存 监控 NoSQL
Redis经典问题:数据不一致
小米探讨了Redis数据不一致问题及其原因,包括缓存更新失败和rehash异常。提出了解决方案,如重试策略、缩短缓存时间、优化写入策略、监控报警、一致性验证、缓存分层和数据回滚机制。通过这些方法可提升应用的稳定性和性能。
602 2
|
存储 缓存 NoSQL
【Redis从头学-10】分分钟入门Redis内存淘汰机制
【Redis从头学-10】分分钟入门Redis内存淘汰机制
209 1
|
存储 NoSQL 容灾
【Redis从头学-11】分分钟入门Redis持久化机制
【Redis从头学-11】分分钟入门Redis持久化机制
75 1
|
存储 缓存 NoSQL
Redis高频面试题
Redis高频面试题
|
存储 NoSQL 关系型数据库
神奇,Redis存储原理竟然是这样!
Redis是一个Key-Value模式的非关系型数据库,那么Key和Value的保存模式我们在这里说一说。 其实kv给大家的第一影响是啥?数组?哈希? 没错就是哈希,redis其实是用哈希表保存的键值对,键为str,值为数据类型,哈希表中的每一对元素是哈希桶
227 0
神奇,Redis存储原理竟然是这样!
Redis的高性能怎么做到的?
Redis的高性能怎么做到的? Redis这个NOSQL数据库在计算机界可谓是无人不知,无人不晓。只要涉及到数据那么就需要数据库,数据库类型很多,但是NOSQL的kv内存数据库也很多,redis作为其中一个是怎么做到行业天花板的呢?是怎么做到高性能的呢?怎么做到高可用的呢?今天这篇八股文我就整理一些redis的设计写写,本篇还是偏关于高性能这一块。
|
NoSQL Redis
【Redis原理机制 四】基于Redis实现延时任务
【Redis原理机制 四】基于Redis实现延时任务
59 0
为什么 Redis 的查询很快,Redis 如何保证查询的高效
Redis 如何保证高效的查询效率 为什么 Redis 比较快 Redis 中的查询速度为什么那么快呢?