当前位置:网站首页>Redis基础
Redis基础
2022-08-09 09:05:00 【dehuisun】
什么是redis
Redis(Remote Dictionary Server) 是一个使用 C 语言编写的,开源的(BSD许可)高性能非关系型(NoSQL)的键值对数据库。
用途及缺点
用途:高性能、高并发
缺点:双写不一致,缓存雪崩、缓存穿透,缓存并发竞争
应用场景
计数器、缓存、会话缓存、分布式锁、消息队列。
Redis为什么这么快
1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是O(1);
2、数据结构简单,对数据操作也简单,Redis 中的数据结构是专门进行设计的;
3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
4、使用多路 I/O 复用模型,非阻塞 IO;
数据类型
Redis主要有5种数据类型,包括String,List,Set,Zset,Hash
类型 | 可存储值 | 应用场景 |
String | 字符串、整数、浮点 | 简单键值对缓存 |
List | 列表 | 存储列表数据 |
Set | 无序集合 | 交集、并集、差集操作 |
Zset | 有序集合 | 去重排序 |
Hash | 无需散列表 | 结构化数据,如对象 |
持久化
持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。Redis 提供两种持久化机制 RDB(默认) 和 AOF 机制。
RDB
RDB是Redis默认的持久化方式。按照一定的时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。通过配置文件中的save参数来定义快照的周期。
优点:
1、只有一个文件 dump.rdb,方便持久化。
2、容灾性好,一个文件可以保存到安全的磁盘。
3、性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能
4.相对于数据集大时,比 AOF 的启动效率更高。
缺点:
1、数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候)
2、AOF(Append-only file)持久化方式:是指所有的命令行记录以 redis 命令请 求协议的格式完全持久化存储)保存为 aof 文件。
AOF
AOF持久化(即Append Only File持久化),则是将Redis执行的每次写命令记录到单独的日志文件中,当重启Redis会重新将持久化的日志中文件恢复数据。
优点:
1、数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次 命令操作就记录到 aof 文件中一次。
2、通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。
3、AOF 机制的 rewrite 模式。AOF 文件没被 rewrite 之前(文件过大时会对命令 进行合并重写),可以删除其中的某些命令(比如误操作的 flushall))
缺点:
1、AOF 文件比 RDB 文件大,且恢复速度慢。
2、数据集大的时候,比 rdb 启动效率低。
对比:
AOF文件比RDB更新频率高,优先使用AOF还原数据。
AOF比RDB更安全也更大
RDB性能比AOF好
如何选择合适的持久化方式
一般来同时使用两种持久化功能。在这种情况下,当 Redis 重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
如果可以承受数分钟以内的数据丢失,那么你可以只使用RDB持久化。
有很多用户都只使用AOF持久化,但并不推荐这种方式,因为定时生成RDB快照非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比AOF恢复的速度要快,除此之外,使用RDB还可以避免AOF程序的bug。
如果只希望数据在服务运行的时候存在,也可以不使用任何持久化方式。
过期策略
过期策略通常有以下三种:
定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。
惰性过期:只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。
定期过期:每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。
Redis中同时使用了惰性过期和定期过期两种过期策略。
内存淘汰策略:
noeviction: 当内存不足以容纳新写入数据时,新写入操作会报错,这个一般没人用,实在是太恶心了。
allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)。这种策略更加节省空间,因为这种策略下可以不为键设置过期时间。
allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key,这个一般没人用吧,为啥要随机,肯定是把最近最少使用的 key 给干掉啊。
volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key(这个一般不太合适)。
volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key。
volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。
缓存异常
缓存雪崩
缓存雪崩是指缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。
解决方案
缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
一般并发量不是特别多的时候,使用最多的解决方案是加锁排队。
给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存。
缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。
解决方案
接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力
缓存击穿
缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。和缓存雪崩不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
解决方案
设置热点数据永远不过期。
加互斥锁,互斥锁。
线程模型
事务
关注公众号,发送 ztzl 免费下载《中台战略:中台建设与数字商业》。
边栏推荐
猜你喜欢
XCTF高校战“疫”网络安全分享赛Misc wp
【场景化解决方案】OA审批与用友U9数据集成
When and How to use MALLOC
【愚公系列】2022年08月 Go教学课程 033-结构体方法重写、方法值、方法表达式
+ 6000 words, help you understand the Internet architecture evolution.
【场景化解决方案】钉钉财务审批同步金蝶云星空
没有对象的可以进来看看, 这里有对象介绍
小程序调用百度api实现图像识别
leetcode 34. 在排序数组中查找元素的第一个和最后一个位置(二分经典题)
使用C语言实现双向链表(带头结点)
随机推荐
XCTF College War "Epidemic" Network Security Sharing Competition Misc wp
支付宝小程序禁止页面弹性下拉或上拉
QT设置exe可执行文件的图标
The 5th Blue Cap Cup preliminary misc reappears after the game
历史遗留问题
convert转换时间详解
mysql进阶(三十一)常用命令汇总
PoPW token distribution mechanism may ignite the next bull market
QT程序生成独立exe程序(避坑版)
mysql-5.5.40的完全卸载
MySQL创建索引的技巧
常用SQL server语句
leetcode 34. 在排序数组中查找元素的第一个和最后一个位置(二分经典题)
leetcode 37. 解数独 (困难)
【Harmony OS】【ARK UI】公共事件模块
JVM进程诊断利器——Arthas
对于栈、递归的关系的理解
gin中简单的curd接口例子
mysql优化——show processlist命令详解
nyoj306 走迷宫(搜索+二分)