Redis
1. 互联网行业的特点:
# 互联网行业的特点:
1. 高并发
同时的访问量过大
2. 高可用
网站什么时候都可以访问
3. 海量数据
动态的数据很大,比如qq的用户
* 传统的数据库 比如关系型数据库: mysql 是扛不住的,mysql能够支持的最大的并发量为2000左右,所有无法来面对高并发等高要求了
* 非关系型数据库是为了配合关系型数据库来解决互联网的行业中的一些问题而产生的,他们之前不是竞争的关系 ,而是互补的关系
1.1 NoSQL
# NoSQL: (not only sql )非关系型数据库,它提倡使用非关系型的数据存储结构来保存数据
主流的nosql产品
| 分类 | 特点 | 代表产品 |
|---|---|---|
| 键值存储 | 数据一般存在内存中,读写速度快(10w/s),适合作为缓存服务 | redis |
| 文档型数据库 | 数据结构要求不严格,适合存储结构不确定或者价值较低的数据 | mongdb |
| 列存储数据库 | 查找速度快,更容易进行分布式扩展,适合作为文件存储服务 | Hbase |
| 图形数据库 | 使用“图结构”进行存储,适合做社交网络计算等等 | Neo4j |
特点:
# redis的特点:
redis是由C语言开发的开源的高性能键值对数据库,它的所有的数据都是保存在内存中的,这也就是它读写数据块的原因
1. 内存的读写速度是硬盘的读写速度的一万倍
2. redis在企业中的最大的作用是作为缓存服务器使用
3. redis的默认端口号为: 6379
2. Redis的数据类型
# redis采用的是键值对存储的数据,键只能是字符串,值支持五种数据类型
1. String 字符串
2. Hash 哈希------- HashMap
3. List 列表--------LinkedArrayList 有序的,可重复的
4. Set 集合--------HashSet 无序的,不能重复的
5. Zset 有序集合-----LinkedHashSet 有序的,不能重复的
2.1 Redis的常见的命令
String字符串
# redis的常见的命令:
类似于操作mysql 的sql语句
根据不同的类型有不同的操作命令
1. 操作String:
string类型是二进制安全的,可以包含任意的数据类型
一个建大概能存储的521M
1.1 增加数据:
set key value
set 100 zhangsan
1.2 获取数据:
get key
get 100
1.3 删除数据:
del key
del 100
1.4 增加数据的时候设置过期时间
set key 存活时间(s秒为单位) value
常用在短信的验证码中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CR68WQri-1575171162361)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1573280791386.png)]
Hash哈希
2. Hash 哈希
类似于java中的map 可以存储一组组的键值对
适合存储一些对象的信息
1.1 增加数据
hset key hkey hvalue
hset 100 name zhangsan
1.2 获取数据
hget key hkey 获取一个属性
hgetall key 获取一条记录
1.3 删除数据
hdel key hkey 删除一个属性
del key 删除一条记录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vUvGng9a-1575171162363)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1573280720501.png)]
List列表
3. List 列表
List底层是一个双向的字符串链表,里面的元素是有序的,可重复的
我们可以从链表的任何一端进行元素的增删
1.1 增加数据:
lpush(rpush) key value 从左边或者右边添加数据
1.2 查询数据:
lrange key [开始位置 结束位置]
1.3 删除数据
lpop(rpor) key
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6q0gADh8-1575171162364)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1573280678170.png)]
Set集合
# Set 类型底层是一张hash表.里面的元素是无序的,不可重复的
1.1 增加数据:
sadd key value
1.2 查询数据:
smembers key
1.3 删除数据
srem key value
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LlldEG44-1575171162365)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1573280985028.png)]
Zset 有序集合
# Zset在set的基础上,加入了有序的功能,在添加元素的时候,允许指定一个分数,他会按照这个分数排序
1.1 添加数据
zadd key value
1.2 查询数据
zrange key [开始索引 结束索引]
1.3 删除数据
zrem key value
通用的命令
1. 模糊查询:
keys*
2. 根据键判断记录是否存在:
EXISTS key
3. 根据键判断值的类型
type key
4. 选择数据库
select 数据库的索引[从0开始]
5. 清空当前数据库
flushdb
6. 清空所有的数据库
flushall
3. Redis的持久化
# redis 的数据都是存储到内存中的,一旦出现宕机,势必会造成数据的丢失,这样就需要持久化的操作了,也就是将内存中的数据存储到硬盘上去
* 注意,redis虽然有持久化的机制,但是他的数据依旧还是都在内存中的,持久化只是为了数据的安全和备份
* Redis 提供了两种的持久化的机制
RDB 和 AOF
RDB持久化
# RDB(Redis Database) 这是redis默认的持久化的方案
* 特点:
他通过设置配置文件中的一些条件,当条件满足的时候,redis就会触发RDB快照机制,将当前时刻的redis在内存中的数据全部的持久化到硬盘上去
* 工作机制:
1. 当RDB持久化的条件满足的时候,redis会创建一条子线程来专门负责数据的持久化(也就是将内存中的数据保存到磁盘上去)
2. 这个过程中redis会创建创建一个新的rdb类型的备份文件,而不是改变原来的备份文件.
3. 当新的rdb备份文件备份完毕以后,redis会用新的备份文件替换到旧的备份文件
也就是说当新的备份文件备份的过程中出现宕机的现象,印象的仅仅是备份之前的数据,员数据并没有改变
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3DPuz8Vu-1575171162367)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1573282339853.png)]
AOF
# AOF(Append Only File )此持久化的机制默认是关闭的.
* 工作机制:
它采用日志的形式来记录Redis的每一次的写操作,并且追加到文件中.
Redis重启会根据日志文件的内容将写指定从前到后执行一次以完成数据的恢复
* 条件配置:
1. AOF就是redis会记录每次的写操作.但是每次写操作都是由缓冲的,不会立即写入磁盘,但是可以通过调用系统的fsync()函数强制写入.
2. 根据这一个特性,redis提供一个配置来决定什么时候调用这个函数
appendfsync always 每次操作都会调用
appendfsync everysec 每秒调用一次
appendfsync no 不配置 ,有系统决定什么时候来调用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z3igPrpE-1575171162368)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1573285165511.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2GtO4YUJ-1575171162369)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1573285248721.png)]
两种持久化操作的对比
# RDB使用的是快照机制保存数据,也就是它保存的数据是某一时刻的完整的数据
这种机制适合做备份的使用,但是redis一旦宕机的话,机会丢失最后一次快照之后的数据
# AOF可以通过控制调用系统的函数的执行时间来最大程度的保证数据的完整性,但是相同的数据,aof的备份文件远大于rdb 的备份文件,而且恢复数据的时候要比rdb要慢的多
* aof 的备份文件是以aof 结尾的
* rdb 的备份文件是以rdb结尾的
1. aof文件比rdb的更新频率高,优先使用aof 还原数据
2. aof文件比rdb文件更安全也更大
3. rdb的性能要比aof的性能要好
4. 如果两个都配置了优先加载aof
4. Redis的应用场景
缓存
1. 缓存:
缓存一些访问量大,但是又不经常修改的数据,如广告栏,导航栏等
# 程序先从redis中查询
1. 如果查询的到的话,就直接放回结果
2. 如果查询不到的话,就去数据库查询,然后将数据放到redis中,再放回数据
这样以后的查询如果redis中存在的话,就不去数据库中进行查询,这样就减轻了数据库的压力
* 如果数据库的数据有更新的话,就要及时的向redis中同步
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WCPO0fKh-1575171162370)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1573286580329.png)]
秒杀
* 可以将秒杀的数据先存储到redis中,等秒杀结束,在慢慢的转入到数据库中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LucvYDRO-1575171162371)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1573286939328.png)]
分布式session存储
# 分布式环境下,用来存储登陆用户的信息来模仿session的效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FRkuTJr4-1575171162373)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1573287032162.png)]
临时验证码的存储
# 手机发送验证码后,将验证码存储到redis中,如果到指定的时间没有验证的话,就会失效
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WUqBum7H-1575171162374)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1573287106185.png)]
5. Redis中的架构模式
单机版
# 单机版
* 特点:简单
* 问题:
1. 内存的容量有限
2. 处理能力有限
3. 无法高可用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EZqRWrR3-1575171162375)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1573288854948.png)]
主从复制
# redis的复制功能允许用户根据一个redis服务器来创建任意多个该服务器的复制品
* 其中被复制的服务器为主服务器,赋值出来的服务器为从服务器
* 描述:
只要主从服务器之间的网络连接正常,主从服务器两者会有相同的数据
主服务器会一直讲发生在自己身上的数据同步给从服务器,从而保证主从服务器的数据相同
* 特点:
1. 存在两个角色 master(主服务器)/slave(从服务器)
2. master/slave两者的数据相同
3. 降低了master的读的压力
* 问题:
1. 无法保证高可用
2. 没有解决master(主服务器的写的压力)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cv8UjEro-1575171162376)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1573289530572.png)]
哨兵
#
待补充
6. Redis中常见的问题
一般的缓存系统,都是按照key去缓存查询
缓存雪崩
# 缓存雪崩可以简单的理解为: 由于原有的缓存失效,新缓存还没有到来
例如:
我们设置了缓存时采用了相同的过期的时间,在同一时刻出现了大面积的缓存过期,
我们原本访问缓存的请求都去访问了数据库,而对数据库CPU和内存造成了很大的压力
严重的情况下会照成宕机,造成一系列的连锁反应,严重的话会造成系统的瘫痪
* 解决方案:
1. 在缓存失效后,通过加锁或者队列的方式来控制读数据库写缓存的线程数量:
加锁是指:对于某个key只允许单个线程来查询数据库,其他线程等待
队列: 对于查询数据库的请求都进行排队,数据库能处理多少处理多少
2. 做二级缓存:
比如A1为原始缓存,A2为拷贝缓存,当A1失效后,可以访问A2
A1失效的时间可以设置为短期,A2的时间可以设置为长期
3. 不同的key,设置不同的失效的时间
让缓存失效的时间分散开来
缓存穿透
# 缓存穿透 :用户恶意查询不存在的value值
一把缓存系统都是根据key去查询对应的value值
如果不存在对应的value值,那么就回去数据库中查询
一些恶意的请求会故意查询不存在的key值
请求量很大,就会对数据库造成很大的压力
所有的请求都会绕过缓存直接查询数据库,进行多次无用的查询
* 解决方案:
1. 对结果为空的情况也进行缓存
缓存的时间设置短一点
或者该key对应的数据insert之后清除缓存
2. 对一定不存在的key进行过滤
可以把所有存在的key放到一大的Bitmap(典型的就是哈希表)中
查询时通过该bitmap进行过滤
不存在key不会再去查询数据库了
缓存预热
# 缓存预热: 就是项目上线之前,把相关的缓存数据直接加载到缓存的系统中
* 提前把缓存的额数据加载到缓存系统中,在用户发送请求的时候,可以从缓存中查询,避免直接查询数据库,对数据库造成压力
* 解决思路:
1. 直接写个缓存刷新页面,上线时手工操作下
2. 数据量不大,可以在项目启动的时候自动加载
3. 定时刷新缓存
缓存更新
# 除了缓存服务器自带的缓存失效策略之外(Redis默认的有6中缓存策略),我们可以根据自己的业务需求来自动缓存的淘汰机制
* 常见的缓存的策略有两种:
1. 定时的去清理过期的缓存
2. 当有用户请求过来的时候,在判断这个缓存是否过期
过期的话就去数据库查询,进行更新
两者的区别是: 第一种维护大量缓存的key是比较麻烦的
第二种的业务逻辑相对复杂
缓存降级
2万+

被折叠的 条评论
为什么被折叠?



