狂神聊Redis
疯狂的Redis课程安排:
-
nosql讲解
-
阿里巴巴架构演进
-
nosql数据模型
-
Nosql四大分类
-
CAP
-
BASE
-
Redis入门
-
Redis安装(window&Liunx服务器)
-
五大基本数据类型
- String
- List
- Set
- Hash
- Zset
-
三种特数的数据类型
- geo
- hyperloglog
- bitmap
-
Redis配置详解
-
Redis持久化
- RDB
- AOF
-
Redis事务操作
-
Redis实现订阅发布(消息队列)
-
Redis哨兵模式
-
缓存穿透及解决办法
-
缓存击穿及解决办法
-
缓存雪崩及解决办法(微服务一环套一环,水桶的短板)
-
基础API之Jedis详解
-
SpringBoot集成Redis操作
-
Redis的实践分析
Nosql概述
为什么要用Nosql
我们现在处在什么年代2020年,大数据时代;
大数据一般的数据库无法进行处理了!2006年Hadoop已经发布了
SpringBoot SpringCloud
压力会越来越大,适者生存!一定要逼着自己学习,这是在这个社会生存的唯一法则!
淘宝php
单机Mysql的年代!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RjtYLOKO-1606232760099)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124082124970.png)]
90年代,一个基本的网站访问量一般不会太大,单个数据库足够!
那个时候更多的是静态的网页~服务器根本没有太大的压力!
思考一下,这种情况下:整个网站的瓶颈是什么?
1、数据量如果太大,一个机器放不下!
2.数据的索引300万条就一定建立索引(如果数据中的索引值都差不多的话也是会影响效率的)!(B+Tree),一个机器内存也刚不下。了解什么是(B+Tree)
3.访问量(读写混合),一个服务器承受不了
如果你要开始出现以上三种情况之一,那么你就要晋级
2.Memcashed(缓存)+MySQL+垂直拆分(读写分离)
网站80%的情况呢都是在读,每次都要查询数据库的话就十分的麻烦!所以说我们希望减轻服务器的压力!我们可以使用缓存来保存数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jgchu7za-1606232760102)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124083824399.png)]
发展过程:优化数据结构和索引–》文件缓存(io)(缺:流读写比较快但是:不能共享)–
》Memcached(当时最热门的技术!)
不缺人,缺人才(想不通),你们的竞争对手不是人才,而是那些图安稳又踏实(老实人)
3.分库分表+水平拆分+mysql集群(m+s)——主从节点
技术和业务在发展的同时,对人的要求也越来越高!
本质:数据库(读、写)
早些年MyISAM引擎:表锁(100万 张三–密码等查出来之后才能被打开使用),十分影响效率!高并发下就会出现严重的锁问题,
转战Innodb:行锁
慢慢的就开始使用分库分表来解决写的压力!MySQL在哪个年代推出了表分区!这个并没有多少公司使用!
MySQL的集群,很好满足哪个年代的多有需求!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XEdIu51o-1606232760103)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124091530754.png)]
4、如今最近的年代
技术爆炸:
2010-2020十年之间,世界已经发生了翻天覆地的变化;(定位,也是一种数据,音乐,热榜)
MysSQL的关系型数据库就不够用了!数据量很多,变化很快~!
MySQL有的使用它来存储一些比较大的文件,博客,图片!数据库表很大,效率就低了!如果有一种数据库来专门处理这种数据,Mysql的压力就会很小(研究如何处理这些问题!)大数据的IO压力下,表几乎没法更大!
灰度发布!
目前一个基本的互联网项目!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9jnaa6Qc-1606232760104)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124095232074.png)]
为什么要用NoSQL!
用户 个人信息,社交网络,地理位置用户自己产生的数据,用户日志等等爆发式增长!
这时候我们就需要使用NoSQL数据库的,Nosql可以很好的处理以上的情况!
什么是NoSQL
NoSQL
NoSQL=Not Only SQL
关系型数据库:表格,行,列。列代表类型(poijava的api可以操作表格)。行代表记录。
泛指非关系型数据库的,随着web2.0互联网的诞生!传统的关系型数据库很难对付web2.0时代!尤其是超大规模的高并发量的社区!暴露出来很多难以克服的问题,Nosql在当今的大数据环境下发展的十分迅速,Redis是发展对快的,而且是我们当下必须要掌握的一个技术!
很多的数据类型用户的个人信息,社交网络,地理位置。这些数据类型的存储不需要一个固定的格式!不需要多的操作就可以横线扩展的!Map<String,Object>使用键值对来控制!
NoSQL特点
解耦!
1、方便扩展(数据之间没有关系,很好扩展!)
2.大数据量高性能(Redis一秒写8万次,读取11万次,NoSQL的缓存记录级,是一种细颗粒度的缓存,性能就比较高!)
3.数据类型是多样型的!(不需要事设计数据库!随取随用!如果是数据量是十分大的表,很多人无法设计了)
4.传统RDBMS和NoSQL
传统的RDBMS
-结构化组织
-SQL
-数据和关系都存储在单独的表中row col
-操作操作,数据定义语言
-严格的一致性
-基础的事务
-...
Nosql
-不仅仅是数据
-没有固定的查询语言
-键值对存储,列存储,文档存储,图形数据库(社交关系)
-最终一致性
-CAP定理和BASE(异地多活!)初级架构师(理念:只要学不死,就往死里学!)
-高性能,高可用,高可扩
-....
了解:3v+3高
大数据时代的3v:主要是描述问题的
- 海量Volume
- 多样Variety
- 实时Velocity(4G)
大数据时代的3高:主要是对程序的要求
- 高并发
- 高可扩(随时水平拆分,机器不够了,可以加一台机器来处理)
- 高性能(保证用户体验和性能!)
真正在公司中的实践:NoSQL+RDBMS一起使用才是最强的,阿里巴巴的架构演进!
技术没有高低之分,就看你如何去使用!(提升内功,思维的提高!)
阿里巴巴演进分析
思考问题:这么多东西难道都是在一个数据库的吗?
技术急不得,越是慢慢学,才能越扎实!
敏捷开发、极限编程
- 敏捷
- 业务快速增长,每天都是上线大量的小需求。
- 应用系统日益膨胀,耦合恶化,架构越来越复杂,会带来更高的开发成本。如何保持业务开发敏捷性?
开源才是技术的王道!
12年2008年,汶川地震
任何一家互联网的公司,都不可能只是简简单单让用户能用就好了!
大量公司做的都是相同的业务;(竞品协议)
随着这样的竞争,业务是越来越完善,然后对于开发者的要求是越来越高的!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lUYNRV0D-1606232760113)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124115005048.png)]
如果你未来想当一个架构师:没有什么是加一层解决不了的!
#1、商品的基本信息
名称、价格、商家信息;
关系型数据库就能解决了!Mysql、oracle(淘宝早年就去IOE了!-王坚 推荐读:阿里云的这群疯子;十分重要!)
淘宝内部的Mysql不是大家用的Mysql
#2、商品的描述、评论(文字比较多)
文档型数据库中,Redis/MongoDB
#3、图片
分布式文件系统 FastDFS
-淘宝自己的 TFS
-Google的 GFS
-Hadoop HDFS
-阿里云的 oss
#4、商品的关键字(搜索)
- 搜索引擎 solr elasticsearch
- ISerach: 多隆(多去了解一下技术大佬!)
所有牛逼的人都有一段苦逼的岁月!但是你只要像SB一样坚持,终将牛逼!
#5商品的热门波段信息
-内存数据库
-Redis Tair、Memache...
#6商品的交易,外部的支付接口
-三方应用
要知道,一个简单的网页背后的技术一定不是大家想象的那么简单!
大型互联网应用问题:
- 数据类型太多了
- 数据源繁多,经常重构!
- 数据要改造,大面积改造?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gJsbGfmt-1606232760114)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124121925513.png)]
这里以上都是NoSQL入门概述,不仅能够提高大家的知识,还可以帮助大家了解大厂的工作内容!
NoSQL的四大分类
kv键值对:
-
新浪:Redis
-
美团:Redis+Tair
-
阿里、百度:Redis+memecach
文档型数据库(bson格式和json一样)
-
MongoDB(一般必须要掌握)
- MongoDB是一个基于分布式文件存储的数据库,C++编写,主要用来存储大量的文档
- MongoDB是一个介于关系型数据库和非关系型数据中中间的产品!MongoDB是非关系性数据库中功能最丰富,最像关系型数据库的!
-
ConthDB
-
注意:他是key-Value类似,Value是结构化的数据
列存储数据库
- HBase
- 分布式文件系统
图关系数据库
- 他不是存图形的,放的是关系,比如:朋友圈社交网络,广告推荐!
- Neo4j,InfoGrid
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ClaANQ0c-1606232760115)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124123528961.png)]
敬畏之心可以使人进步!宇宙!科幻!
活着的意义?帮助更多的人!
最求幸福,探索未知!
物资基础、家人开心,帮助他人;不断的学习,未知的宇宙,努力学习,不要被这个社会抛弃!
Redis入门
概述
Redis是什么?
Remote Dictionary Server,即远程字典服务!
是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lf045DqO-1606232760115)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124125504519.png)]
区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
免费和开源!是当下最热门的NoSQL技术之一!也被人们称之为结构化数据库!
Redis能干嘛?
1.内存存储、持久化,内存是断电即失的、所以说持久化很重要(rdb、aof)
2.效率高,可以用于高速缓存
3.发布订阅系统
4,地图信息分析
5,计时器、计数器(浏览量!incr decre)
6…
特性
1、多样的数据类型
2、持久化
3、集群
4、事务
…
学习中需要用到的东西
1、狂神的公众号:狂神说
2、官网:https://redis.io/
3.中文网:http://www.redis.cn/
4.下载地址:通过官网下载即可
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RZ0ekCEI-1606232760116)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124130320003.png)]
注意:window在Github上下载(停止更新很久了!)
Redis推荐都是在Linux服务器上搭建的,我们基于Linux学习
Windows安装
1.下载安装包https://github.com/dmajkic/redis/releases
2.下载完毕得到压缩包:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E4lQ6fS5-1606232760116)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124140506355.png)]
3.解压到自己电脑上的环境目录下的就可以的!Redis十分的小。只有5M
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UMy0Fx2W-1606232760117)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124141217794.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xZZuihEl-1606232760117)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124141445985.png)]
5.使用redis客户端来连接redis
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ei1bb496-1606232760118)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124141741138.png)]
记住一句话windows下使用确实简单,但是 Redis推荐我们使用Linux
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-idHgh7Kb-1606232760118)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124143707445.png)]
Linux安装
1.下载安装包!redis-5.0.10.tar.gz
2.解压Redis的安装包!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j6qLvfeG-1606232760119)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124145750706.png)]
3.进入解压后的文件,可以看到Redis的配置文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zfw1X57C-1606232760119)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124145723019.png)]
4.基本的环境安装
yum install gcc-c++
可以先看看网
gcc -v
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FTuWjjd5-1606232760120)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124150112353.png)]
上边的情况是没有问题的
执行make命令
make
make install
会将所需要的环境给自己配上去
执行完毕之后
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v5TVkwic-1606232760120)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124150606335.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XzOYLEZh-1606232760121)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124150536485.png)]
5.redis的默认安装路径/usr/local/bin
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tKoD3tE6-1606232760121)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124151248826.png)]
6.将redis配置文件。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fDtTWMmW-1606232760121)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124152001230.png)]
7.redis默认不是后台启动的,修改配置文件!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kQGAFnTG-1606232760122)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124152528985.png)]
8.启动redis服务!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mj1PtMDs-1606232760122)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124153815882.png)]
9.使用redis-cli进行连接测试!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lmgOHvXE-1606232760123)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124154248781.png)]
10.查看redis的进程是否开启!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BnOQscou-1606232760123)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124154938056.png)]
11.如何关闭Redis服务呢?shutdown
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KkA4dVow-1606232760124)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124154909428.png)]
12.再次查看进程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ggbUYVwP-1606232760124)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124155027513.png)]
13.后边我们会使用单机多Redis启动集群测试!
测试性能
redis-benchmark是一个压力测试工具!
官方自带的性能测试工具!
图片来自菜鸟教程:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IHxHKWTX-1606232760125)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124155440487.png)]
我们来简单测试下:
#测试:100个并发连接 100000个请求
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cXNbzpdK-1606232760125)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124160240361.png)]
如何查看这些参数呢?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ra8iLMb6-1606232760126)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124161029235.png)]
基础知识
redis默认有16个数据库
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X4YX0AkY-1606232760126)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124163922230.png)]
默认使用的是第0个
可以使用select进行切换数据库!
127.0.0.1:6379> select 3 #切换数据库
OK
127.0.0.1:6379[3]> DBSIZE #查看DB大小!
(integer) 0
127.0.0.1:6379[3]>
切换数据库
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pOSI6Z2p-1606232760127)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124164646759.png)]
127.0.0.1:6379[3]> keys * #查看数据库所有的key
1) "name"
清楚当前数据库
127.0.0.1:6379[3]> flushdb #清空当前所有的数据
OK
清空全部数据库的内容“FLUSHALL”
思考:为什么redis是6379!(了解一下即可)
Redis是单线程的!
明白Redis是很快的,官方表示,Redis是基于内存操作,CPU不是Redis性能瓶颈,Redis的瓶颈是根据机器的内存和网络带宽既然可以使用单线程来实现,就使用单线程了!
Redis是C语言写的,官方提供的数据为100000+的QPS,完全不比同样是使用key-vale的Memecashe差!
Redis为什么单线程还这么快?
1、误区1:高性能的服务器都是多线程的。
2、误区2:多线程(cpu上下文切换!)一定比单线程效率高!
cup》内存》硬盘的速度的
核心:redis是将所有的数据全部放在内存中的,所以说使用单线程去操作效率就是最高的。多线程(CPU上下文会切换:这是一个耗时的操作!)对于内存系统来说如果没有上下文切换效率就是最高的!多次读写都是在一个cpu上的,在内存情况下,这个就是最佳的方案!
五大数据类型:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PnALYtjc-1606232760127)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124172212720.png)]
全段翻译:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nb7J1G2U-1606232760128)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124172333044.png)]
消息中间件MQ 发布订阅
现在讲解的所有命令大家一定要全部记住,使用SpringBoot。jedis,所有的方法就是这些命令!
单点登录
Redis-key
keys * #查看所有的key
set key value #设置key的值
exists key #判断当先的key是否存在
move key db #移除当前的库到db库
expire key seconds #设置过期时间,单位是秒
ttl key #查看当前key的剩余时间
type name # 查看当前的类型
以后如果遇到不会的命令,可以在官网查看帮助文档!
127.0.0.1:6379> move name 1 #命令:将key:name移动到1数据库;move key db
(integer) 1
String(字符串)
90%的java程序员使用redis只会使用一个String类型!
#####################################################
127.0.0.1:6379> set key1 v1 #设置值
OK
127.0.0.1:6379> get key1 #获取值
"v1"
127.0.0.1:6379> keys * #获取所有的key
1) "key1"
127.0.0.1:6379> exists key1 #判断值是否存在
(integer) 1
127.0.0.1:6379> append key1 "hello" #追加值,如果key不存在重新创建
(integer) 7
127.0.0.1:6379> get key1
"v1hello"
127.0.0.1:6379> strlen key1 #获取字符串长度
(integer) 7
127.0.0.1:6379> append key1 kuangshen
(integer) 16
##################################################################
# i++
# 步长 i+=10
127.0.0.1:6379> set views 0 # 初始浏览量为0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views # 自增1 初始浏览量为1
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> decr views # 自减1 初始浏览量为0
(integer) 1
127.0.0.1:6379> incrby views 10 #可以设置步长,指定增量!
(integer) 11
#################################################################
字符串范围 range
127.0.0.1:6379> set key1 "hello,kaixintiantian"
OK
127.0.0.1:6379> getrange key1 0 3 #查看指定范围的字符串,getrange key star end[0,3]
"hell"
127.0.0.1:6379> getrange key1 0 -1 #查看从第0 个到最后一个元素
"hello,kaixintiantian"
127.0.0.1:6379> getrange key1 -1 -1 #输出的是最后一个元素
"hello,kaixintiantian"
# 替换!
127.0.0.1:6379> set key2 "abcdefghijk"
OK
127.0.0.1:6379> setrange key2 1 xx #替换指定位置的字符串
(integer) 11
127.0.0.1:6379> get key2
"axxdefghijk"
################################################################
# setex(set with expire) # 设置过期时间
# setnx(set if not exist) # 不存在在设置(在分布式锁中会常常使用!)
setex key seconds value #
setnx key "redis"
127.0.0.1:6379> setex key4 30 "hello" #设置一个值并设置其存活时间 xxx秒
OK
127.0.0.1:6379> ttl key4
(integer) 24
127.0.0.1:6379> ttl key4
(integer) 20
127.0.0.1:6379> get key4
(nil)
127.0.0.1:6379> setnx mykey "redis" #该key不存在就创建
(integer) 1
127.0.0.1:6379> get mykey
"redis"
127.0.0.1:6379> setnx mykey "MonggoDB" #因为key此时存在所以就设置不成功
(integer) 0
#################################################################
mset # 批量设置
mget # 批量获取
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 k4 v4 # 同时设置多个值
OK
127.0.0.1:6379> keys *
1) "k4"
2) "k3"
3) "k1"
4) "k2"
127.0.0.1:6379> mget k1 k2 k3 # 同时获取多个值
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 v1 k4 v4 # msetnx是个原子操作,要么一起成功,要么一起失败
(integer) 0
127.0.0.1:6379> get key4
(nil)
# 对象
set user:1 {name:zhangshan,age:18} # 设置一个user:1对象 值为json字符串来保存一个对象
#这里的key是一个巧妙的设计:user:{id}:{filed},如此设计在Redis中是完全ok了!
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "2"
#################################################################
getset # 先get再set
127.0.0.1:6379> getset db redis # 如果不存在,则放回nil;返回的是get的结果,最终结果是执行set
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db redis
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongodb #如果存在值获取原来的值,并设置新的值
"redis"
127.0.0.1:6379> get db
"mongodb"
#################################################################
数据结构是相通的!
String类似的使用场景:value除了是我们的字符串还可以是我们的数字!
- 计数器
- 统计多单位的数量 uid:952523424:follow 0 incr
- 粉丝数
- 对象缓存存储!
List
基本的数据类型,列表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KzH5tpAj-1606232760129)(C:\Users\MSI-NB\AppData\Roaming\Typora\typora-user-images\image-20201124213814788.png)]
在redis里面,我们 可以把list完成,栈、队列、阻塞队列!
所有的list命令都是用l开头的,Redis不区分大小写命令
#################################################################
127.0.0.1:6379> LPUSH list one #将一个值或者多个值,插入到列表的头部(左),插入前相当于之前的值向后移动
(integer) 1
127.0.0.1:6379> LPUSH list two
(integer) 2
127.0.0.1:6379> LPUSH list three
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1 #获取字符串中list中的值!
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> LRANGE list 0 1 #通过区间获取具体的值!
1) "three"
2) "two"
127.0.0.1:6379> RPUSH list rihght
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
4) "rihght"
#################################################################
LPOP
RPOP
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
4) "rihght"
127.0.0.1:6379> lpop list #移除列表的第一个元素
"three"
127.0.0.1:6379> RPOP list #移除列表的最后一个元素
"rihght"
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379>
#################################################################
LINDEX
127.0.0.1:6379> LINDEX list 1 # 通过下标获取值 list中的某一个值
"one"
#################################################################
Llen
127.0.0.1:6379> lpush list one
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> llen list #返回列表的长度
(integer) 3
#################################################################
移除指定的值!
取关 uid
Lrem
127.0.0.1:6379> lpush list one
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> llen list
(integer) 3
127.0.0.1:6379> lpush list three
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> lrem list 1 one # 移除list集合中指定个数的value,精确匹配
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "two"
127.0.0.1:6379> lpush list three
(integer) 4
127.0.0.1:6379> keys *
1) "list"
127.0.0.1:6379> lrange list o -1
(error) ERR value is not an integer or out of range
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "three"
4) "two"
127.0.0.1:6379> lrem list 2 three
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
#################################################################
trim 修剪,list中表示截断
127.0.0.1:6379> rpush mylist "hello"
(integer) 1
127.0.0.1:6379> rpush mylist "hello1"
(integer) 2
127.0.0.1:6379> rpush mylist "hello2"
(integer) 3
127.0.0.1:6379> rpush mylist "hello3"
(integer) 4
127.0.0.1:6379> ltrim mylist
(error) ERR wrong number of arguments for 'ltrim' command
127.0.0.1:6379> ltrim mylist 1 2 #通过下标截取指定的长度,这个list已经被改变了,截断了只剩下截取的元素!
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "hello1"
2) "hello2"
#################################################################
rpoplpush
127.0.0.1:6379> rpush mylist "hello"
(integer) 1
127.0.0.1:6379> rpush mylist "hello1"
(integer) 2
127.0.0.1:6379> rpush mylist "hello2"
(integer) 3
127.0.0.1:6379> rpush mylist "hello3"
(integer) 4
127.0.0.1:6379> rpoplpush mylist myotherlist # 移除列表的最后以后一个元素,将他移动到新的列表中!
"hello3"
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "hello1"
3) "hello2"
127.0.0.1:6379> lrange myotherlist 0 -1
1) "hello3"
#################################################################
lset #将列表中指定下标的值替换为另外一个值,更新操作
127.0.0.1:6379> exists list # 判断这个列表是否存在
(integer) 0
127.0.0.1:6379> lset list 0 item #如果不存在列表我们去更新就会报错
(error) ERR no such key
127.0.0.1:6379> lpush list value1
(integer) 1
127.0.0.1:6379> lrange list 0 0
1) "value1"
127.0.0.1:6379> lset list 0 item # 如果存在,更新当前下标值
OK
127.0.0.1:6379> lrange list 0 0
1) "item"
127.0.0.1:6379> lset list 1 other #如果不存在就会报错
(error) ERR index out of range
#################################################################
linsert #在集合元素的某个值之前或之后插入一个元素
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush myslist "hello"
(integer) 1
127.0.0.1:6379> rpush myslist "world"
(integer) 2
127.0.0.1:6379> linsert myslist before "world" "other" #在world 之前插入一个other元素
(integer) 3
127.0.0.1:6379> lrange myslist 0 -1
1) "hello"
2) "other"
3) "world"
127.0.0.1:6379> linsert myslist after world new #在world 之后插入一个new元素
(integer) 4
127.0.0.1:6379> lrange myslist 0 -1
1) "hello"
2) "other"
3) "world"
4) "new"
127.0.0.1:6379> linsert myslist after world new
(integer) 5
127.0.0.1:6379> lrange myslist 0 -1
1) "hello"
2) "other"
3) "world"
4) "new"
5) "new"
127.0.0.1:6379> linsert myslist after new chasha
(integer) 6
127.0.0.1:6379> lrange myslist 0 -1 #默认的是找到第一个指定的元素的值
1) "hello"
2) "other"
3) "world"
4) "new"
5) "chasha"
6) "new"
127.0.0.1:6379>
小结
- 它实际上是一个链表,before Node after,left,right都可以插入值
- 如果key不存在,创建新的链表
- 如果key存在,新增内容
- 如果移除了所有值,空链表,也代表不存在!
- 在两边插入改动值,效率最高!中间元素,相对来说效率会低一点
消息排队!消息队列 (Lpush Rpop)| 栈(Lpush Lpop)