详解Redis,Redis缓存,Redis分布式锁(1)

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 详解Redis,Redis缓存,Redis分布式锁(1)

1、Redis基本知识

简介

Redis是一个支持网络、基于内存、可选持久性的NoSql数据库,目前在很多的系统中都使用了Redis,尤其是在实现缓存功能的时候应用的尤其广泛(缓存功能也是很多人对Redis的认识),那么Redis到底有哪些优点和缺点,为什么会被广泛应用呢?

Redis的优点

Redis的第一个优点就是速度快,Redis使用C语言实现,基于内存,数据的读写效率非常的高,这也是为什么很多系统的缓存功能使用Redis来实现,但是需要明确的是Redis是一个数据库,缓存只是它的一项应用而已。


Redis的第二个优点是单线程模型,所谓单线程模型就是每一个请求都会有一个全新的线程来进行处理,这一点类似于Struts2,每一个请求都会有一个新的线程来进行处理。这样做的好处就是避免了线程频繁切换带来的系统开销,同时也避免了让人头疼的多线程问题。


Redis的第三个优点就是使用了非阻塞I/O (NIO),不在网络上浪费时间,进一步提高了效率。


Redis的第四个优点就是支持多种的数据类型,并且每一种数据类型都提供了丰富的操作命令,适用于很多特殊的场景,并且支持自定义命令创建个性化的操作命令。

2、redis持久化机制

redis服务器宕机,内存数据是会丢失了,为了保证数据不丢失需要对数据做备份,所备份就是持久化,Redis的持久化即将内存中的数据同步到硬盘,主要包括两种方式RDB、AOF。


RDB持久化机制,(默认使用):做当前内存数据的全本快照,

将内存中的数据以快照的方式写入到二进制文件dump.rdb,

在redis.conf中可以设置发起快照保存的条件。在指定的时间内如果有超过指定数量的key被修改,则会发起快照保存。


这种方式在数据的实时性上不高,在突然断电的情况下,可能会出现部分数据的丢失,即最后一次快照之后在内存中发生修改的数据。


简单来说:RDB就是将redis上的所有数据做个备份,存储的是二进制的数据。

AOF持久化机制,(默认是关闭)

AOF是将Redis内存数据库中更改的数据都记录到指定的文件appendonly.aof。在redis.conf中可以进行写磁盘的相关设置。


在突然断电的情况下,由于在appendonly.aof中保存了最后一次写磁盘之后redis内存发生数据修改的指令,所以在这个Redis重启后,基本不会发生数据丢失,比RDB具有更好的数据安全性。


appendfsync always 接收到更改数据的命令,立即将其记录到appendonly.aof中,能保证数据持久化,数据完全不丢失,但效率相对最低。


appendfsync everysec 每秒钟将redis内存数据修改的命令记录到appendonly.aof中,在性能和持久化上做了折中。因频繁执行磁盘操作,在仅存在单个Master执行写操作时,效率可能存在问题。但在多个Master执行写操作的Redis集群中,效率会提升。


appendfsync no 依赖于操作系统,因不会频繁执行磁盘操作而性能最好,但redis内存数据修改持久化没有保证,无法保证数据可靠性


如何开启AOF持久化:

将redis.conf文件中 appendonly 改成 yes ,自动创建appendonly.aof,该文件存储的客户端执行过增删改操作的命令


3、 Redis的数据结构

redis数据库存储数据使用的key-value,键值对方式存储

key是string类型 value的数据结构支持5个string、set、sorted_set、list、hash

4、Redis 的常用命令

String(可以存数字)

可以实现原子性的自增(数据安全)

这是最基本的类型了,没啥可说的,就是普通的set和get,做简单的k-v缓存

hash

这个是类似map的一种结构,这个一般就是可以将结构化的数据,比如一个对象(前提是这个对象没嵌套其他的对象)给缓存在redis里,然后每次读写缓存的时候,可以就操作hash里的某个字段。

key=150
value={
 “id”: 150,
 “name”: “zhangsan”,
 “age”: 20
}

hash类的数据结构,主要是用来存放一些对象,把一些简单的对象给缓存起来,后续操作的时候,你可以直接仅仅修改这个对象中的某个字段的值

value={
 “id”: 150,
 “name”: “zhangsan”,
 “age”: 21
}
list

有序列表,这个是可以玩儿出很多花样的

微博,某个大v的粉丝,就可以以list的格式放在redis里去缓存

key=某大v
value=[zhangsan, lisi, wangwu]
key=书名
value=[评论1, 评论2, 评论3]

比如可以通过list存储一些列表型的数据结构,类似粉丝列表了、文章的评论列表了之类的东西


比如可以通过lrange命令,就是从某个元素开始读取多少个元素,可以基于list实现分页查询,这个很棒的一个功能,基于redis实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西,性能高,就一页一页走


比如可以搞个简单的消息队列,从list头怼进去,从list尾巴那里弄出来


set

无序集合,自动去重


直接基于set将系统里需要去重的数据扔进去,自动就给去重了,如果你需要对一些数据进行快速的全局去重,你当然也可以基于jvm内存里的HashSet进行去重,但是如果你的某个系统部署在多台机器上呢?


得基于redis进行全局的set去重


可以基于set玩儿交集、并集、差集的操作,比如交集吧,可以把两个人的粉丝列表整一个交集,看看俩人的共同好友是谁?对吧


把两个大v的粉丝都放在两个set中,对两个set做交集


sorted set 跳表

排序的set,去重但是可以排序,写进去的时候给一个分数,自动根据分数排序,这个可以玩儿很多的花样,最大的特点是有个分数可以自定义排序规则


比如说你要是想根据时间对数据排序,那么可以写入进去的时候用某个时间作为分数,人家自动给你按照时间排序


排行榜:将每个用户以及其对应的什么分数写入进去,zadd board score username,接着zrevrange board 0 99,就可以获取排名前100的用户;zrank board username,可以看到用户在排行榜里的排名


总结:优先掌握 String 即可


5、数据失效时间

场景:

手机验证码登录 手机验证码注册

验证码后台生成 Redis

  1. 集中存储
  2. 可以设置过期时间
验证码  
key = 手机号 
value = 验证码  
设置3分钟过期

Redis中可以设置数据的存活时间

命令

expire key 存活时间的秒
ttl key 查看key对应的数据的存活时间.
pexipre key 存活时间的毫秒
pttl key 查看key对应的数据的存活时间,毫秒单位

expire key 存活时间的秒

失效的原理

  1. 定期随机删除+惰性删除
key  
1    1分钟
2    1分钟  
3    1分钟
4    1分钟
5
6
redis 每过100ms 随机抽取一定数量的设置了失效时间的key 将过期的删除
有些key过期了 每次都没有随机到  就一直删不掉  怎么办?
惰性删除 get key 的时候 先判断 key是否过期 如果过期 返回数据为空

定期随机删除 例如100ms

查询的时候 先检查key

内存淘汰机制

如果redis的内存占用过多的时候,此时会进行内存淘汰,有如下一些策略:


redis 10个key,现在已经满了,redis需要删除掉5个key


1个key,最近1分钟被查询了100次


1个key,最近10分钟被查询了50次


1个key,最近1个小时被查询了1次


noeviction:当内存不足以容纳新写入数据时,新写入操作会报错,这个一般没人用吧,实在是太恶心了


allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(这个是最常用的)


allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key,这个一般没人用吧,为啥要随机,肯定是把最近最少使用的key给干掉啊


volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key(这个一般不太合适)


volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key


volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除

LRU算法 扩展视野


6、Redis的基本应用!!!

二级缓存
  1. 为什么要做缓存
  2. 缓存的选择(二级缓存)
  3. 二级缓存的基本概念
  1. 是什么
  2. 如何开启
  1. 二级缓存的缺点
  2. 使用Redis集成二级缓存的步骤
  1. 实现cache接口
  1. 缓存的作用
  2. 数据从内存获取,提升数据获取速度.
  3. 减轻了数据库读操作的访问压力(数据基本不变)

MyBatis二级缓存机制(开启)

机制:

Java本地缓存空间.(jar)


mybaits事务提交后操作缓存


Mybatis根据Mapper文件的namespace划分多个缓存空间.


mybatis会将查询语句执行结果,缓存在 sql所在mapper文件对应的namespace对应的缓存空间中.


会将执行的查询sql(对sql处理后产生的对象)作为key.


MyBatis执行DML,在事务提交之后,默认清空当前sql所在的mapper文件对应的namespace对应的缓存空间中


A Mapper User表 脏读


B Mapper User表 删除 缓存清空


缓存空间融合


所有关于User表的操作都写在一个Mapper中

Mapper配置 融合缓存空间(基本没有人使用)

第三方的缓存空间

ehcache

Redis

MyBatis缓存实现原理(源码)

org.apache.ibatis.cache.impl.PerpetualCache.class


根据namepace划分缓存空间(id)


MyBatis二级缓存本质是一个Map结构


key :和执行的sql先关


value:查询结果相关


存放数据的功能: select语句(key)----查询结果(value)


获得数据的功能: 根据key


清空缓存的功能: clear


MyBatis管理每个缓存,使用Map管理 key:id(namespace) value:PerpetualCache

MyBatis缓存的问题?(缓存数据量不能太多)

  1. mybatis缓存在tomcat的jvm内部分配的缓存空间.
  2. 缓存数据过多,挤占java运行期间需要的内存.

解决办法:

将Mybatis的二级缓存空间转移到Redis数据库中

Mybatis二级缓存空间划分

Redis缓存空间的划分设计

核心:

  1. 每个缓存空间是一个map
  2. 每个缓存空间对应一个namespace.(管理多个cache空间)

方案:

  1. 将mybatis的namespace作为redis的key
  2. 将key对应的value作为hash数据结构使用.(替换PerpetualCache)

相关实践学习
基于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
目录
相关文章
|
5天前
|
canal 缓存 NoSQL
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
根据对一致性的要求程度,提出多种解决方案:同步删除、同步删除+可靠消息、延时双删、异步监听+可靠消息、多重保障方案
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
|
6天前
|
缓存 NoSQL Java
谷粒商城笔记+踩坑(12)——缓存与分布式锁,Redisson+缓存数据一致性
缓存与分布式锁、Redisson分布式锁、缓存数据一致性【必须满足最终一致性】
谷粒商城笔记+踩坑(12)——缓存与分布式锁,Redisson+缓存数据一致性
|
6天前
|
存储 NoSQL Redis
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
Redis持久化、RDB和AOF方案、Redis主从集群、哨兵、分片集群、散列插槽、自动手动故障转移
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
|
17天前
|
缓存 NoSQL 关系型数据库
MySQL与Redis缓存一致性的实现与挑战
在现代软件开发中,MySQL作为关系型数据库管理系统,广泛应用于数据存储;而Redis则以其高性能的内存数据结构存储特性,常被用作缓存层来提升数据访问速度。然而,当MySQL与Redis结合使用时,确保两者之间的数据一致性成为了一个重要且复杂的挑战。本文将从技术角度分享MySQL与Redis缓存一致性的实现方法及其面临的挑战。
40 2
|
19天前
|
Java UED Maven
紧跟技术潮流:手把手教你构建响应式Vaadin应用,让用户体验无缝接轨!
【8月更文挑战第31天】本文从零开始,详细介绍如何使用强大的Java框架Vaadin构建流畅且响应式的Web应用程序。首先,确保安装JDK 1.8+、Maven 3.3.9+及IDE。接着,创建Maven项目并添加Vaadin依赖。然后,通过继承`UI`类创建主界面,并定义自定义主题与样式。利用Vaadin的响应式布局组件,如`HorizontalLayout`和`VerticalLayout`,实现多设备兼容性。
27 0
|
NoSQL Java 关系型数据库
浅谈Redis实现分布式锁
浅谈Redis实现分布式锁
|
存储 canal 缓存
|
NoSQL PHP Redis
redis实现分布式锁
redis实现分布式锁
163 0
redis实现分布式锁
|
NoSQL Redis 数据库
用redis实现分布式锁时容易踩的5个坑
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 近有不少小伙伴投入短视频赛道,也出现不少第三方数据商,为大家提供抖音爬虫数据。 小伙伴们有没有好奇过,这些数据是如何获取的,普通技术小白能否也拥有自己的抖音爬虫呢? 本文会全面解密抖音爬虫的幕后原理,不需要任何编程知识,还请耐心阅读。
用redis实现分布式锁时容易踩的5个坑
|
消息中间件 负载均衡 监控
【Redis】Redis实现分布式锁
分布式锁无论在开发中还是面试里都是老八股了,本篇文章整理江湖上常见的Redis分布式锁解决方案
263 0