Redis基本使用和基础知识整理

Redis是做什么的?

  • Redis是一个开源,内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列。
  • Redis将数据储存在内存当中

内存的特点

  1. 易失性(在断电之后数据就没有了)
  2. 进行读取数据等IO操作的速度要比存在硬盘中的数据要更快
  3. 缺点是内存的价格更高

正因为redis将数据存储在内存当中,又因为内存的易失性所以像订单信息等需要持久化存储的数据就不适合存放在redis当中。

Redis的适用场景

  1. 在大型的秒杀库存扣减,app首页流量高峰,很容易将传统的关系型数据库(mysql,oracle等)给压垮。(当系统有系统瓶颈的时候,比如说表里面有2000万条数据(数据量非常大),并且表的访问量非常高的时候。redis的引入是为了减轻数据库的压力,防止大数据量的查询将mysql压垮。
  2. 很多没必要持久化的数据,比如说短信验证码,点赞数等。

  3. 分布式锁。

  4. 分布式缓存(session共享)。

为什么点赞要用redis去实现,而不是用mysql?

  1. 点赞属于频率高的操作,需要频繁的对点赞数进行读取和更改操作。也就意味着会有许多用户同时对点赞数进行访问和更改。对于低于千万级的数据量,我们可以用mysql的分表和cache去解决点赞问题。但是对于千万级以上的数据量,会对mysql数据库造成很大的压力。
  2. 在mysql不进行加锁处理的情况下,如果有很多的线程对点赞数进行访问和修改,很可能线程一刚获取到了点赞数10,但是线程二在线程一读取之后立刻对点赞数进行了加操作,变成11。但是线程一并不知道点赞数已经发生了变化。在进行+1后将点赞数更新回去。这样就造成了原本应该被更新为12的点赞数仍为11,造成了数据的错误。虽然mysql中读操作是一个原子操作,写操作也是一个原子操作。但是读后写入并不是一个原子操作。所以就导致了这样的错误。redis中虽然没有事务,但是redis中的所有操作都是线程安全的,这样也就保证了对点赞数的每次操作,数据都是正确的。

Redis是数据库,mysql也是数据库,什么时候用redis,什么时候用mysql?

  • 我们引入redis做缓存的目的是为了减缓mysql数据库的压力。所以在mysql数据库有压力的情景下我们使用redis,也就是在大数据量和访问频繁的情况下去使用redis
  • 而缓存如何去规划要取决于我们的业务本身。业务=数据结构+算法,根据业务来选取适合业务场景的数据结构,来将数据存放到redis,作缓存。

Redis和mysql的索引的底层区别

mysql索引相当于字典的目录,通过增加索引可以很快的提高MySQL的查询性能。mysql的索引也是存在内存里的,但是和redis也有区别。比如说有一个主键索引,相当于mysql将所有的id都以B+树的数据结构存储到内存当中,当我们根据id想要去查询一条数据时,有了索引的存在我们不用全表扫描一页一页的去查,而是根据索引去查。但是redis比加了索引的mysql还要快,因为redis中的数据以键值对的形式存储,和java中的map同理。map的时间复杂度为O(1),而B+树的时间复杂度要比O(1)要高。

数据库可视化软件

Redis DeskTopManager 

redis存储的数据类型

redis的存储是以key-value的键值对的形式存储的,其中key都是String类型,value常见的就是以下的5种:String,Hash,List,Set,SortedSet。

String

字符串类型,可以包含任何数据,最大可以是512MB,内部的实现结构和ArrayList类似,采用内分配冗余的形式,来减少内存的频繁分配(降低CPU压力)

常用语句
set name zhangsan   --存放字符串键值对
mset name zhangsan age 18 --批量存放键值对
SETNX name zhangsan  --如果不存在key为name,那么就设置value(分布式锁的原理)
get name   -- 获取key
mget name age  --批量获取key
DEL key -- 删除key
expire key 60 --设置过期时间,单位为秒
INCR key -- 将key中存储的数字加1
DECR key -- 将key中存储的数字减1
INCRBY key 2  --将key中存储的值都加上2
DECRBY key 2 --将key中存储的值都减去2

ps:尽量避免同时操作大批量的key,比如给所有的key设置过期时间,因为redis是单线程的,如果操作耗费太多时间,会造成redis的假死(暂时不对外提供服务)。

使用场景

1,不需要持久化的数据或者频繁更新的数据,比如验证码,点赞数

2,对象缓存。可以通过序列化工具类,来缓存java对象,比如将某个对象序列化为json,需要用的时候再取出来,反序列化。常见的使用方式有mybatis二级缓存,接口级别缓存等等。

3,使用setnx来实现分布式锁,(使用分布式锁时一定要设置过期时间,防止不能释放锁,造成死锁)

4,可以用incr,decr来实现点赞数

5.分布式全局id:在一个大型的系统下,如果涉及到分库分表后,mysql 的自增id,肯定满足不了需要,如果用户量不大,可以每次从redis 这里通过自增获取id,但是如果用户量大,每次都拿肯定会给redis造成压力,可以一次取1000个,放本地缓存里,等用完了再去取。

Hash

是一个key-value的键值对,和java里的hashMap相似,当数据量较小是采用的是ziphash(默认),当数据量较大时采用hashtable。至于什么转换可以在配置文件进行配置。

常用语句
hset hash name zhangsan --设置值,
hget hash name  -- 获取值
hmset hash name zhangsan age 18 --批量设置
hmget hash name age --批量获取
hgetall hash 获取key的所有值
hkeys hash 获取hashmap中所有的key
hvals hash 获取hashmap中所有的value
使用场景

1,可以用于存储系统中对象的数据。

2,也可以用于做缓存,来解决数据一致性的问题(不推荐)。

List

redis的list为quickList(快速链表)即多个ziplist(压缩链表)组合起来的。如图所示:

ziplist;当数组容量较小的时候,会开辟一个连续的内存空间,只有当数组容量过多的时候,才会改为quickList,这样做的好处就是,如果采用普通的链表,当我们节点只存int类型的数据,还需要开辟两个指针,连接节点的上一个元素和下一个元素,会比较浪费空间。所以采用了quickList的方式,既能满足快速插入删除性能,又不会出现太大的空间浪费。

这么做也有缺点,就是当我们的list要变动时,肯定会涉及到内存重新分配和数据拷贝,这个是很影响性能的,list越大,修改元素的代价越大,所以一般我们不会存储过多元素。

redis的list是按插入顺序排序的,可以添加的一个节点到链表的头部(头插)或者尾部(尾插),是一个双向链表,对两端的操作性能会比较高,对中间节点的操作性能相对来说较差(因为得通过指针对遍历对应的节点)。

常用语句
rpush myList valu5e1 --向 list 的头部(右边)添加元素
rpush myList value2 value3 --向list的头部(最右边)添加多个元素
lpop myList # 将 list的尾部(最左边)元素取出
rpop myList2 value1 --尾插
使用场景

可以实现栈和队列,需要注意的是,push和pop的操作是原子性的,所以操作redis的时候,直接用就行了,不要把list读出来,通过java修改,再放回去,这样不能保证数据一致性。(先读先写或先读后写)

实现队列
rpush queue001 q1
rpush queue001 q2
rpush queue001 q3
lpop queue001
lpop queue001
lpop queue001

实现栈
rpush stack001 t1
rpush stack001 t2
rpush stack001 t3
rpop stack001
rpop stack001
rpop stack001

Set

redis的set和list相似,只不过可以自动去重。(java的set也可以自动去重)。

当你需要存储一个没有重复数据的列表时就可以选择set,同时set也可以判断某个数据在不在集合里面。

set的底层结构是一个value为null的哈希表,也就意味着他的时间复杂度为O(1),也就意味着即使数据再多,查找的时间也是一样的。

使用场景

可以用来计算多个数据源的交集或并集

SortedSet

和set很相似,sortedSet是一个有序不重复的列表。SortedSet里面的每个节点都关联了一个权重,用来排序。(集合里的每个节点是唯一的,但是评分却可以是相同的),利用这个特性我们可以利用redis来实现排行榜。也可以很快速的获取到一个区间内的节点。

SortedSet的底层是hash和跳表(一个很典型的数据机构,牺牲空间来换取时间)。hash的作用是存储每个节点和权重,跳表的作用是用来快速获取一个区间里的节点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/513871.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ssm核心面试题汇总

文章目录 1. Spring1.1 Spring Beans1.谈谈你对Spring的理解以及优缺点2. 什么是Spring beans3. 配置注册Bean有哪几种方式4. Spring支持的几种bean的作用域5. 单例bean的优势6. 单例bean是线程安全的吗?如何优化为线程安全7. 谈一谈spring bean的自动装配8. Spring…

基于华为atlas的unet分割模型探索

Unet模型使用官方基于kaggle Carvana Image Masking Challenge数据集训练的模型。 模型输入为572*572*3,输出为572*572*2。分割目标分别为,0:背景,1:汽车。 Pytorch的pth模型转化onnx模型: import torchf…

Linux笔记--make

使用上一节的 main.c、add.c、sub.c文件进行编译,编译的过程有很多步骤,如果要重新编译,还需要再重来一遍,能不能一步完成这些步骤?将这些步骤写到makefile文件中,通过make工具进行编译 一个工程中的源文件不计其数&a…

Vue基础入门(4)- Vuex的使用

Vue基础入门(4)- Vuex的使用 Vuex 主要内容:Store以及其中的state、mutations、actions、getters、modules属性 介绍:Vuex 是一个 Vue 的 状态管理工具,状态就是数据。 大白话:Vuex 是一个插件&#xff…

Ubuntu18.04运行ORB-SLAM3

ORB-SLAM3复现(ubuntu18) 文章目录 ORB-SLAM3复现(ubuntu18)1 坐标系与外参Intrinsic parameters2 内参Intrinsic parameters2.1 相机内参① 针孔模型Pinhole② KannalaBrandt8模型③ Rectified相机 2.2 IMU内参 3 VI标定—外参3.1 Visual calibration3.2 Inertial calibration…

CSS标准文档流与脱离文档流,分享一点面试小经验

大厂面试真题整理 CSS: 1,盒模型 2,如何让一个盒子水平垂直居中? 3,css 优先级确定 4,解释下浮动和它的工作原理,清除浮动的方法? 5,CSS隐藏元素的几种方法 6&#xff0…

CSS常用五类选择器,附面试题

学习路线 第一阶段:网页制作 HTML:常用标签,锚点,列表标签,表单标签,表格标签,标签分类,标签语义化,注释,字符实体 CSS:CSS介绍,全局…

docker 安装rabbitmq并配置hyperf使用

这里我想完成的是 制作消息(多个协程制造)——》推送到rabbitmq——》订阅消息队列——》消费消息(ws协程客户端【一次消费多条】/ws前端) 利用 WebSocket 协议让客户端和服务器端保持有状态的长链接,保存链接上来的客…

06 - 镜像管理

1 了解镜像 Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。 但注意, 镜像不包含任何动态数据&#…

【Mining Data】收集数据(使用 Python 挖掘 Twitter 数据)

@[TOC](【Mining Data】收集数据(使用 Python 挖掘 Twitter 数据)) 具体步骤 第一步是注册您的应用程序。特别是,您需要将浏览器指向 http://apps.twitter.com,登录 Twitter(如果您尚未登录)并注册新应用程序。您现在可以为您的应用程序选择名称和描述(例如“Mining Demo”…

政安晨【TypeScript高级用法】(四):模块与声明文件

TypeScript是一种静态类型的JavaScript超集语言,它支持模块化开发和声明文件。 模块化开发是一种将代码分割为独立的模块,每个模块只关注自己的功能,然后通过导入和导出来实现模块之间的交互和复用。在TypeScript中,可以使用impo…

设置video的进度条常显

根据网上的方法,把隐藏的元素显示 在chrome中F12或者通过其他方式打开开发者工具(相信应该知道从哪里打开),然后点击右上的齿轮,进入设置,勾选Show user agent shadow DOM 就能在elements里面查看视频的播…