Redis(基于狂神说Java-Redis)

最近在进行Redis二刷,看了B站狂神的视频,纯手写的方式做了一个总结,如果这篇文章有帮到你,也希望能够多多支持,也支持一下狂神狂宝宝的视频,一起加油,继续努力!

什么是NoSQL?

为什么要用NoSQL?

先从历史开始讲吧

1、单机数据库时代

90年代,一个基本的网站访问量较小,单个数据库可以顶住当时的访问量

在那个时候,都会去使用静态网页html,因为服务器压力不会太大

缺点:

  • 数据量太大,一台机子放不下了
  • 当数据量达到300万以上,就需要建立索引,MySQL索引,B+树。数据量一大,电脑内存也放不下了
  • 在当时的数据库单机时代,读写一体,服务器承受不了

如果说以上三个条件满足了至少一个,那么就需要做出改变了

]

2、Memcached(缓存)+ MySQL + 垂直拆分(读写分离)

网站在大部分情况下都是在读,当用户在界面中按下一个button,就会对数据库发送一个查询请求,如果说,当一个或者多个用户都在发送一个相同的请求,而这个请求每次都要查询数据库,这很耗费性能,这时候就需要减轻数据库的压力,可以使用缓存来保证效率

发展:优化数据结构和索引----->文件缓存(IO操作)----->Memcached(当时的热门技术)

在这里插入图片描述

3、分库分表 + 水平拆分 + MySQL集群

技术与业务在发展的同时对人开始有越来越高的要求

本质都是在解决数据库的读和写问题

以MySQL的存储引擎为例

  • MyISAM:这个存储引擎支持表锁,并且不支持事务的ACID,影响操作,在高并发下会出现严重的锁问题
  • InnoDB:行锁+表锁,支持事务的ACID

慢慢的由于数据量的增大,慢慢的开始使用分库分表解决写压力!在当时MySQL还推出了一个 表分区 的概念,但是并没有多少的公司愿意去使用

MySQL集群的解决方案,已经在当时解决了大部分的需求

在这里插入图片描述

4、如今最近的年代

2010-2020,过了十年,世界发生了巨大变化,从按键手机到智能手机,定位,也成为了一种数据

MySQL等关系型数据库开始出现性能瓶颈!大数据,数据量很多,变化很快

MySQL可以用来存储一些比较大的文件,博客,图片!数据库表很大,执行IO操作的效率就会很低下,如果有一种数据库专门用来处理这种数据,就可以用来缓解MySQL的压力(如何处理这些问题)

为什么要用NoSQL

用户个人信息,社交网络,地理位置,用户自己产生的信息数据,等等一系列的弹性数据爆发式增长,关系型数据的传统的表结构已经承载不了了,这时候就需要使用NoSQL数据库来解决,NoSQL可以很好处理以上情况

NoSQL简介

什么是NoSQL

NoSQL翻译为Not Only SQL,译为不仅仅是SQL,意指非关系型数据库

web2.0的诞生,传统的关系型数据库已经很难对付web2.0时代!特别是指大规模高并发社区!会出现很多问题,NoSQL在大数据时代发展的十分迅速,尤其是Redis

很多的数据类型用户的个人信息,社交网络,地理位置,这些数据类型的存储不需要一个固定的格式,不需要太多操作就可以实现横向拓展,就比如Redis,它是使用类似于Java的Map<String, Object>来实现存储,键值对的形式存储,这只是NoSQL的解决方式之一

NoSQL 特点

解耦

  1. 方便扩展(数据之间没有联系可以快速拓展)

  2. 大数据量高性能,Redis可以支持8w的并发量(写操作),11w访问量(读操作),NoSQL的缓存记录级,是一种细粒度的缓存,性能比较高

  3. 数据类型多样性(不需要事先设计数据库,随取随用,数据量过大就无法设计)

  4. 传统的关系数据库管理系统(Relational Database Management System:RDBMS)和NoSQL的区别

    传统的RDBMS

    • 结构化
    • SQL
    • 数据和关系存在于单独的表中 row(行) column(列)
    • 数据操作,数据定义语言
    • 严格的一致性
    • 基础的事务

    NoSQL

    • 不仅仅是数据
    • 没有固定的查询语言
    • 键值对存储,列存储,文档存储,图形数据库
    • 最终一致性
    • CAP定律和BASE理论

大数据时代的3V + 3高

大数据时代的3V

  1. 海量Volume
  2. 多样Variety
  3. 实时Velocity

大数据时代的3高

  1. 高并发
  2. 高可用(随时水平拆分,机器不够了,随时扩展)
  3. 高性能(保证用户体验和性能)

真正在公司中用到的实践,NoSQL + 关系型数据库,这是最强组合,也是阿里巴巴的架构演进

阿里巴巴架构演进

PDF

在这里插入图片描述
在这里插入图片描述

没有什么是加一层解决不了的,如果有,就加两层

# 商品的基本信息
名称、价格、商家信息
MySQL / Oracle 去IOE化(IOE:IBM、Oracle、EMC存储设备)

# 商品描述
评论,文本信息多
文档型数据库,MongoDB

# 图片
分布式文件系统 FastDFS
淘宝:TFS
Google:GFS
Hadoop:HDFS
阿里云:OSS

# 商品关键字(搜索)
搜索引擎 solr elasticsearch
淘宝:ISearch,ISearch作者,阿里的多隆

# 商品热门波段信息
内存数据库
Redis  Tair  Memcached...

# 商品交易,外部支付接口
第三方应用

推荐文章:https://developer.aliyun.com/article/653511

大型互联网应用

  • 数据类型多样!
  • 数据源多样,频繁重构!
  • 数据改造,大面积改动!

解决问题

在这里插入图片描述

热点缓存

在这里插入图片描述

NoSQL的四大分类

KV键值对

  • 新浪:Redis
  • 美团:Redis + Tair
  • 阿里,百度:Redis + Memcached

文档型数据库(Bson,Binary Json,二进制Json)

  • MongoDB,需要掌握,它是一种基于分布式文件存储的数据库,由C++编写,主要用来处理大量的文档

    它是一种介于关系型数据库和非关系型数据库之间的一种中间产品,功能丰富,而且MongoDB是NoSQL中最像关系型数据库的产品

  • ConthDB

列存储数据库

  • HBASE
  • 分布式文件系统

图形关系数据库

  • 它不是存图片的!它存放的是关系,就好比一个人的社交圈,可以动态扩充
  • Neo4j,InfoGrid

4种分类的对比

在这里插入图片描述

Redis入门

本次使用的Redis的版本采用的是5.0.10

Redis简介

什么是Redis?

Redis(Remote Directory Server),中文译为远程字典服务,免费开源,由C语言编写,支持网络,可基于内存也可持久化的日志型,KV键值对数据库,并且提供多种语言的API,是当下NoSQL中最热门的技术之一!被人们称之为结构化数据库!

并且Redis支持多种语言(如下图)

在这里插入图片描述

redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步

Redis能干嘛?

  1. 内存存储,持久化,因为内存断电即失,并且Redis支持两种持久化方式,RDB / AOF

  2. 效率高,可用于高速缓存

  3. 消息发布订阅(消息队列)

  4. 地图信息分析

  5. 计数器(eg:微博浏览量)

特性

  1. 数据类型多样

  2. 持久化

  3. Redis集群

  4. 事务

配置(在哪下)

官网:https://redis.io/

Redis中文文档:http://www.redis.cn/documentation.html

下载地址:进入官网下载即可(Windows版本需要在GitHub上下载,并且Redis版本已停更较长时间,不建议使用)

并且,Redis官方推荐在Linux服务器上进行搭建

Linux安装Redis

安装Redis的第一种,官网下载安装包

  1. 下载安装包,redis-5.0.10.tar.gz

  2. 下载到Windows之后,用Xftp工具上传至Linux

  3. 解压安装包并将其解压到opt目录下

    tar -zxvf redis-5.0.10.tar.gz -C /opt 
    

并且解压之后可以看见Redis的配置文件redis.conf

在这里插入图片描述

同时还需要基本的环境搭建

# 保证Redis的正常运行,gcc的安装也是必要的
yum install gcc-c++
# 安装Redis所需要的环境
make
# 此命令只是为了确认当前所有环境全部安装完毕,可以选择不执行
make install 

Redis的安装,默认在/usr/local/bin下

在这里插入图片描述

之后,需要将Redis的配置文件复制到bin目录下,可以提前准备好一个目录,然后在复制到新创建好的目录中

在这里插入图片描述

然后修改复制之后的配置文件,修改一条信息,修改的信息就是图中划红线的位置,它的意思是指守护进程模式启动,即可以在后台运行Redis

]

随后就可以开始启动Redis服务(通过指定的配置文件启动服务)

redis-server /usr/local/bin/myconfig/redis.conf

在这里插入图片描述

使用Redis客户端连接指定的端口号

redis-cli -p 6379

redis-benchmark性能测试工具

在这里插入图片描述

# 当前命令表示,性能测试,在本机,端口号6379,并发连接数100,每个连接10w个请求数量
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
# 测试结果如下,以Redis的set命令为例
====== SET ======
  100000 requests completed in 1.85 seconds # 十万个请求在1.85秒之内被处理
  100 parallel clients # 每次请求都有100个客户端在执行
  3 bytes payload # 一次处理3个字节的数据
  keep alive: 1 # 每次都保持一个服务器的连接,只用一台服务器处理这些请求

28.68% <= 1 milliseconds
97.99% <= 2 milliseconds
99.47% <= 3 milliseconds
99.59% <= 4 milliseconds
99.62% <= 5 milliseconds
99.68% <= 6 milliseconds
99.79% <= 7 milliseconds
99.90% <= 22 milliseconds
99.97% <= 23 milliseconds
100.00% <= 23 milliseconds # 所有的请求在23秒之内完成
54054.05 requests per second # 平均每秒处理54054.05个请求

Redis基础知识

备注:在Redis中,关键字语法不区分大小写!

Redis有16个数据库支持,为啥嘞,可以查看redis.conf配置文件

在这里插入图片描述

并且初始数据库默认使用0号数据库(16个数据库对应索引0到15)

可以使用select命令切换数据库:select n(0-15)

127.0.0.1:6379> SELECT 12
OK
127.0.0.1:6379[12]> SELECT 0
OK
127.0.0.1:6379> DBSIZE # 查看当前库的key数量
(integer) 0

删除数据库信息

127.0.0.1:6379> keys * 
1) "mylist"
2) "myset:__rand_int__"
3) "counter:__rand_int__"
4) "key:__rand_int__"
127.0.0.1:6379> FLUSHDB # 删除当前数据库
OK
127.0.0.1:6379> keys * 
(empty list or set)
# 还有一个删除的命令,叫做FLUSHALL,它的意思是删除16个数据库中的全部信息。
# 不管在那种数据库中,删库一直都是需要慎重操作的

题外话:为什么Redis选用6379作为默认端口号?

6379在是手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字。MERZ长期以来被Redis作者antirez及其朋友当作愚蠢的代名词。后来Redis作者在开发Redis时就选用了这个端口。(摘自知乎)

Redis是单线程的(从Redis6.0.1开始支持多线程)

Redis的读写速度很快,官方表示,Redis基于内存操作,CPU不是Redis的性能瓶颈,Redis的性能瓶颈是根据机器的内存和带宽

Redis是C语言编写,官方提供的数据为10万+的QPS(Queries-Per-Second,每秒内的查询次数)

Redis单线程为什么速度还是这么快?

对于Redis,有两个误区:

  1. 高性能的服务器一定是多线程的?
  2. 多线程一定比单线程效率高?

Redis将所有的数据全部放在内存中,使用单线程去操作效率比较高,对于多线程,CPU有一种东西叫做上下文切换,这种操作耗时,对于内存系统来说,没有上下文切换,效率一定是最高的。

Redis使用单进程的模式来处理客户端的请求,对大部分事件的响应都是通过epoll函数的加强封装,Redis的实际处理速度依靠主进程的执行效率,epoll可以显著提高程序在大量并发连接中系统的CPU利用率

Redis五大数据类型

Redis中文网翻译:

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库缓存消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

Redis-key

# 基础语法:
# SET key value	          设置一个key
# GET key                 获取一个key对应value
# EXISTS key              查询key是否存在
# MOVE key n(数字)	     将当前key移动到指定的几号数据库中
# KEYS *                  查询当前数据库中全部的key
# EXPIRE key time         设置当前key的过期时间
# TTL key                 查询当前key的存活时间
# TYPE key                查看key的数据类型
127.0.0.1:6379> set name xiaohuang # 设置key-value
OK
127.0.0.1:6379> get name # 查询key指定的value
"xiaohuang"
127.0.0.1:6379> EXISTS name # 查看当前key是否存在
(integer) 1
127.0.0.1:6379> EXISTS name1
(integer) 0
127.0.0.1:6379> MOVE name 1 # 将当前key移动到1号数据库
(integer) 1
127.0.0.1:6379> KEYS *
(empty list or set)
127.0.0.1:6379> SELECT 1 # 选择数据库
OK
127.0.0.1:6379[1]> KEYS *
1) "name"
127.0.0.1:6379[1]> EXPIRE name 10 # 设置当前key的过期时间,单位是秒
(integer) 1
127.0.0.1:6379[1]> KEYS *
1) "name"
127.0.0.1:6379[1]> KEYS *
1) "name"
127.0.0.1:6379[1]> KEYS *
1) "name"
127.0.0.1:6379[1]> KEYS *
1) "name"
127.0.0.1:6379[1]> ttl name # 查看指定key的存活时间,
(integer) -2 # 返回-2表示当前key已经过期,如果为-1,表示永不过期
127.0.0.1:6379[1]> KEYS *
(empty list or set)
127.0.0.1:6379> set name xiaojiejie
OK
127.0.0.1:6379> set age 26
OK
127.0.0.1:6379> KEYS *
1) "age"
2) "name"
127.0.0.1:6379> TYPE name # 查看指定key的value的数据类型
string
127.0.0.1:6379> TYPE age
string
127.0.0.1:6379> 

String(字符串)

# 语法:
# APPEND key appendValue                 对指定key实现字符串拼接,如果key不存在,等同于set
# STRLEN key                             查看指定key的长度
# INCR key                               对指定key进行自增,类似于Java中的i++
# DECR key                               自减,类似于Java的i--
# INCRBY key n                           对指定key按照指定的步长值进行自增
# DECRBY key n											   按照指定的步长值自减
# SETRANGE key index value               从指定key的索引开始,插入指定的value值。
# 																    如果key不存在且索引>1,那么当前的索引之前的数据,会用\x00代替并占用一个索引位置,相当于ASCII码中的null
# GETRANGE key startIndex endIndex			将指定key按照索引的开始和结束范围进行截取,成为一个新的key
# SETEX key time value							 	 设置一个有存活时间的key
# SETNX key value                     	如果这个key不存在,即创建
# MSET key value ...								 	 设置多个key value
# MGET key ...												获取多个key指定的value
# GETSET key value                    	先获取指定的key,然后再设置指定的value
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> KEYS * # 获取当前数据库中所有的key
1) "k1"
127.0.0.1:6379> APPEND k1 hello #给k1再继续追加value值
(integer) 7
127.0.0.1:6379> get k1
"v1hello"
127.0.0.1:6379> APPEND k1 ,xiaohuang
(integer) 17
127.0.0.1:6379> STRLEN k1 # 查看当前k1的长度
(integer) 17
127.0.0.1:6379> get k1
"v1hello,xiaohuang"
127.0.0.1:6379> KEYS * 
1) "k1"
127.0.0.1:6379> APPEND name xiaohuang
(integer) 9
127.0.0.1:6379> get name
"xiaohuang"
127.0.0.1:6379> KEYS *
1) "k1"
2) "name"
###################实现自增自减效果################
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
0
127.0.0.1:6379> INCR views # 设置value的自增效果
(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 # 设置value的自减效果
(integer) 1
127.0.0.1:6379> DECR views
(integer) 0
127.0.0.1:6379> get views
"0"
############可以在自增自减时设置步长##############
127.0.0.1:6379> INCRBY views 2 # 自增,设置步长为2
(integer) 2
127.0.0.1:6379> INCRBY views 2
(integer) 4
127.0.0.1:6379> get views
"4"
127.0.0.1:6379> DECRBY views 3 # 自减,设置步长为3
(integer) 1
127.0.0.1:6379> DECRBY views 3
(integer) -2
127.0.0.1:6379> get views
"-2"
# 注意:value的自增和自减只适用于Integer类型
127.0.0.1:6379> incr name 
(error) ERR value is not an integer or out of range
#################实现字符串截取效果#################
127.0.0.1:6379> set k1 hello,xiaohuang
OK
127.0.0.1:6379> get k1
"hello,xiaohuang"
127.0.0.1:6379> GETRANGE k1 0 3 # 实现字符串截取,有起始索引和结束索引,相当于Java中的subString()
"hell"
# 如果结束索引为-1,则表示当前截取的字符串为全部
127.0.0.1:6379> GETRANGE k1 0 -1
"hello,xiaohuang"
###############实现字符串的替换效果#################
127.0.0.1:6379> set key2 abcdefg
OK
127.0.0.1:6379> get key2
"abcdefg"
127.0.0.1:6379> SETRANGE key2 2 hello # 实现字符串的替换效果,命令中的数字“2”表示从索引2的位置开始将其替换为指定字符串
(integer) 7
127.0.0.1:6379> get key2
"abhello"
##################################################
# setex(set with expire) # 设置过期时间
# setnx(set with not exist) # 如果key不存在,创建(分布式锁中常用)
127.0.0.1:6379> setex k3 10 v3 # 设置一个k3,过期时间为10秒
OK
127.0.0.1:6379> keys *
1) "k1"
2) "key2"
3) "name"
4) "views"
5) "k3"
# 10秒之后会自动删除
127.0.0.1:6379> keys *
1) "k1"
2) "key2"
3) "name"
4) "views"
127.0.0.1:6379> setnx lan redis # 如果key不存在,即创建
(integer) 1 
127.0.0.1:6379> setnx lan mongodb
(integer) 0 # 0表示没有设置成功,也可理解为“有0行受到影响”
127.0.0.1:6379> get lan
"redis"
######################一次性设置(获取)多个键值对#####################
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 # 同时设置多个值
OK
127.0.0.1:6379> KEYS * 
1) "k2"
2) "k1"
3) "k3"
127.0.0.1:6379> mget k1 k2 k3 # 同时获取多个值
1) "v1"
2) "v2"
3) "v3"
# 也可以在这边的语法前面加上一个m,代表设置多个
127.0.0.1:6379> msetnx k1 vv1 k4 v4 
(integer) 0
# 但是这边同时设置多个值,如果有一个key已经存在,那么这一条设置语句便不会执行成功,
# 因为Redis单条语句是原子操作,要么同时成功,要么同时失败
127.0.0.1:6379> keys * 
1) "k2"
2) "k1"
3) "k3"
# 在Redis中,还推荐了一个比较有意思的东西
# 这是Redis中关于key的命名,可以用“:”来代表层次结构,可以对指定的key进行分类存储
127.0.0.1:6379> mset user:1:name xiaohuang user:1:age 21
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "xiaohuang"
2) "21"
127.0.0.1:6379> getset sqlan redis # 先获取当前key指定的value,如果不存在,会返回nil(null),然后设置新值
(nil)
127.0.0.1:6379> get sqlan
"redis"
127.0.0.1:6379> getset sqlan hbase
"redis"
127.0.0.1:6379> get sqlan
"hbase"
####################################################################

类似于Redis中String这样的使用场景,value值可以是字符串,也可以是其他类型

String的存储的字符串长度最大可以达到512M

主要用途

  • 计数器
  • 统计多单位的数量
  • 一个用户的粉丝数
  • 一个有过期时间的验证码

List(列表)

Redis中的List列表可以做很多事情,可以将其看成数据结构中的栈,也可以是队列,或者阻塞队列

# 命令:
# LPUSH key value1 value2 ...                      设置一个key,从头部插入数据(头插法)
# RPUSH key value1 value2 ...										 设置一个key,从尾部插入数据(尾插法)
# LRANGE key startIndex endIndex                   返回列表中从开始索引到结束索引位置的value值
# LPOP key                                         从key头部弹出一个value
# RPOP key                                         从尾部弹出一个value
# LINDEX index                                     返回key中指定索引的value值
# LREM key n value                                 删除key中的指定的value值,n代表删除几个
# LLEN key                                         返回key的长度
# LTRIM key startIndex endIndex                    截取key,截取的范围从开始索引到结束索引
# LSET key index value                             从当前key的索引开始插入指定的value值
# RPOPLPUSH key1 key2                              从key1的尾部弹出一个元素,将此元素从key2的头部插入
# LINSERT key BEFORE|AFTER oldValue newValue       从指定key中已存在的value的前面或者后面插入一个指定的value
127.0.0.1:6379> LPUSH list one # 从list头部插入一个或者多个元素(从左边插入,看命令首字母)
(integer) 1
127.0.0.1:6379> LPUSH list two
(integer) 2
127.0.0.1:6379> LPUSH list three
(integer) 3
# 返回存储在列表中指定范围的元素,0和-1代表开始索引和结束索引,
# -1不代表实际位置的索引,它表示需要返回到这个列表的最后一个元素
127.0.0.1:6379> LRANGE list 0 -1 
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> LRANGE list 0 1 # 返回list中指定位置的元素
1) "three"
2) "two"
127.0.0.1:6379> RPUSH list right # 从list尾部插入一个或多个元素(从右边插入,同第一行一样)
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
4) "right"
127.0.0.1:6379> LPOP list # 从list头部(左)弹出(删除)一个元素
"three"
127.0.0.1:6379> RPOP list # 从list末尾(右)弹出一个元素
"right"
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
######################################################################################################################
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> LINDEX list 0 # 从头部查询list中指定索引的元素
"two"
127.0.0.1:6379> LINDEX list 1 
"one"
######################################################################################################################
127.0.0.1:6379> lrange list 0 -1 
1
  • 20
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
《狂神说-Redis》视频中的学习笔记是完整的,而且加入了个人的理解和认知。这些笔记工整清晰,适合进行记忆学习。 笔记内容包括以下主题: 1. Nosql概述和为什么要使用Nosql。 2. Redis的基础操作和为什么Redis是单线程且如此快速。 3. Redis的五大基本数据类型,包括String、List、Set、Hash和Zset(有序集合)。 4. Redis的三种特殊类型,包括geospatial(地理位置)、Hyperloglog和Bitmaps。 5. Redis的事务处理和Jedis的使用。 6. Redis与SpringBoot的整合。 7. Redis的配置详解。 8. Redis的持久化方式,包括RDB和AOF(Append only file)以及扩展。 9. Redis的发布订阅功能。 10. Redis的主从复制和哨兵模式。 11. 缓存穿透与雪崩问题的解决方案。 此外,Redis还通过PUBLISH、SUBSCRIBE和PSUBSCRIBE等命令实现了发布和订阅功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [狂神说-Redis完整版笔记](https://download.csdn.net/download/qq_40986062/79709157)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Redis学习笔记(狂神说)](https://blog.csdn.net/qq_43295483/article/details/119649501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [【狂神说】Redis笔记](https://blog.csdn.net/Redemption___/article/details/120799492)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值