Redis

0 redis背景

Redis诞生背景

关系型数据库据中一大半操作都是读操作,而且经常都是重复查询一个东西,这浪费了数据库很多时间去进行磁盘I/O.这也是后续很多内存数据库崛起的背景.

学习CPU给数据库也加一个缓存,诞生了Redis.应用程序从mysql查询到的数据,先在redis登记,后续再有读请求,先在redis进行查询.redis把数据都存储在内存内存中不需要进行磁盘I/O,所以速度极快.为Mysql减轻了很大的负担.

Redis缓存管理机制

防止缓存无限制增加,给缓存增加一个超时时间,超出超时时间的内容进行清空.

考虑到缓存中存了大量数据,全面扫描一次进行清理需要很长时间,严重影响接受新的请求,所以Redis采取随机选取部分进行清理.

但是概率上会存在部分数据可能长时间不被清理掉.于是在原来定期删除的基础之上,增加:原来已经超期的键值,如果遇到查询请求,则立即进行删除.这是被动式触发,如果不查询就不会删除,因此叫惰性删除.

还会有一部分数据既逃离了随机删除算法也逃离了惰性删除,慢慢的可用的内存空间则会越来越少,(或者设置过期时间很长,还没来得及清理,内存就吃满了),-出现内存淘汰策略

结合以上策略,可以不用担心内存爆满的问题

定时删除 + 惰性删除 + 内存淘汰

缓存穿透:如果查询数据不存在,那么redis也没办法缓存,所以同样的请求来了,每次还是需要mysql进行查询,(如果存在大量重复的恶意或者批量查询,严重影响数据库性能)

热点数据过期,被redis删除,但是删除后短时间内大量请求,就会都到mysql服务器

缓存雪崩:如果一大批数据同时或者一起过了有效期,又发生了很多对这些数据的请求,比起缓存穿透规模更大

解决缓存雪崩的方案:让应用程序对缓存过期时间设置的长一点均匀一点,不让缓存一起过期.把键值的过期时间随机一下+热点数据永不过期

Redis持久化存储机制

Redis为基于内存的,进程服务down掉内容丢失.需要做持久化存储

持久化方案:RDB持久化是将全部数据记录定时dump到磁盘上进行持久化,恢复数据通过读取原始数据加载到内存恢复数据,数据恢复快,效率高,但是数据容易丢失(数据同步有时间间隔).

为了节约空间,二进制格式生成RDB文件,但是数据量大,全部备份时间成本较高,不能太频繁备份.如果一直都是读取操作没有写入操作,也不需要重复备份.提供周期性备份参数.即使断电或者服务器宕机,可以在启动的时候读取备份文件,恢复状态

RDB的问题:数据丢失问题

AOF持久化是将操作日志追加形式写入文件,恢复数据通过命令恢复数据,缓存一致性更高,牺牲性能.

Mysql中的BinLog => AOF

多久进行一次写入呢? 建立临时缓冲区aof_buf 再择机将临时缓冲区内容写入文件

但是随着时间推移,AOF备份文件越来越大,加载分析越来越慢

AOF重写:去除冗余指令给AOF文件瘦身,- 工作量太大

指令合并

Redis哨兵与高可用

即使有了缓存持久化管理,但是也要考虑redis稳定性高可用问题

命令传播:主节点将命令传播给从节点

考虑到子节点掉线,数据同步问题

从节点中选择一个管理员,不负责数据的读写,只负责协调各个节点,称为哨兵Sentinel

哨兵每隔10s中用info命令去询问主节点,主节点回复都有哪些从节点,哨兵则每隔一秒用ping命令与各个子节点交互.如果发现主节点掉线,这时候判定为主观下线,多个哨兵一起判定,如果都认为下线则是客观下线

故障转移选择新的主节点

Redis集群工作原理

主从复制+哨兵可以解决高可用问题,但是不能解决数据量大的问题

变成集群解决数据量大的问题

存储公平问题  -hash随机性

1.redis基础

1.1 基础概念

key - value

键值数据库 -> NoSql数据库

1.1.1 初始redis

sql关系型数据库

NoSql非关系型数据库 或者 not only sql

对比差异:

  • S-Structured 结构化  nosql对数据格式没有严格约束,可以是键值型、文档型或者图格式
  • R-Relational 关联 传统数据库中存在外键约束即关联。nosql不存在关联,
  • Q-Query查询 sql查询通常使用select ...等等语句 但是nosql方式不统一:redis mongoDB elasticSearch查询方式不同
  • 事务:事务满足ACID,而nosql往往不支持事务,只能实现一些基本的一致性 base理论。如果对ACID要求严格,尽量首选sql而不是nosql
  • 存储方式:sql大多数以磁盘为主,nosql通常以内存为主

redis - Remote Dictionary Server 远程词典服务器 基于内存的键值型nosql数据库

特征:

  • 键值型 key-value型:支持多种不同的数据结构 功能丰富
  • 单线程,每个命令有原子性
  • 低延迟,速度快
  • 支持数据持久化
  • 支持主从集群、分片集群

1.1.2 redis常用命令

常见数据结构

redis为key-value的数据库,其中key通常为string类型,但是value类型种类多样

  • String:分为普通string int float 底层都是字节数组形式存储,只是编码方式不同 操作:SET GET MSET MGET INCR INCRBY 
  • Hash:也叫散列。其value是一个无序字典,类似于java中的hashMap。更加灵活。操作:HSET HGET HGETALL [HSET dlut:user:1 name kasha age 18  设置key为dlut:user:1的hash中name=kasha age=18] []

  • List : 与java中的LinkedList类似,可以看成一个双向链表。支持正向检索也支持反向检索。
  • Set
  • SortedSet - 也叫zSet 其中每个元素都要指定一个score值和member值,可以根据socre值排序 number必须唯一 可以根据member查询分数  zset底层数据结构必须满足 键值存储 键必须唯一 可排序 skiplist 可以排序
  • GEO 地理坐标
  • BitMap 位操作
  • HyperLog 位操作

通用常用命令

  • keys push_news_*  :查找相关的key redis为单线程会造成阻塞
  • del push_news_1 push_news_2: 删除key
  • exists keys_1 :判断key是否存在
  • expire :给key设置有效期,有效期到期时key自动删除
  • TTL key_2 : 查看key的剩余时长

官网上常用命令:Commands | Docsicon-default.png?t=N7T8https://redis.io/docs/latest/commands/

1.1.3 关于key - key的分级存储

因为redis没有sql中表的概念,如果学生id为1,教师id也是1 怎么办?

key的结构:redis的key允许多个单词形成层级结构,多个单词之间用:隔开,格式如下:

项目名称:业务名称:类型:id

user相关的key:dlut:user:1

product相关的key:dlut:product:1

如果value是一个java对象,则可以将对象序列化为json字符串之后进行存储

1.1.3 redis的java客户端

  • 26
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值