目录
一、初识Redis
1、认识NoSQL
总结:
对于扩展性 :关系型数据库的数据都是存储在本机的,故影响其性能的就是本机这台机器的服务器的性能,只能提升该机器的性能来提升其能力。虽然像Mysql这样的是支持主从的,但主从仅仅提升了机器的数量及读写的性能,但是并不能提升数据存储的量,因为你主和从存的数据是一模一样的。数据存储的总量并没有发生变化,只不过做了备份而已。与此对应,对于非关系型数据库来说,无论是redis还是elasticsearch也好,他们在设计之初就考虑到了数据拆分的需求。故他们在插入数据的时候往往会采用数据的id或唯一的标识去做一个哈希运算,根据哈希运算来判断这个数据到底应该存储在哪一个不同的节点上,从而实现数据的拆分,天然的就支持这种水平的扩展。(虽然Mysql默认情况下是不支持水平扩展的,但是也可以基于第三方的组件来实现数据库的分库。当然,一旦引入第三方组件肯定会对性能造成影响并且在开发的时候需要考虑的问题也会更多,复杂度就会增加)
SQL&NoSQL的选择:数据业务的数据结构相对固定或数据业务对于一致性和安全性要求较高,建议使用关系型数据库;如下订单,订单数据就属于安全性要求较高的数据,肯定需要用关系型数据库存储,当然为了查询性能,我们可以冗余的把部分订单数据放到NoSQL数据库里去提升他的查询效率。所以两者结合使用。因此非关系型数据库往往就是用于一些数据结构不固定,且对于一致性和安全性要求不高,但是对于产品性能要求较高的场景下去使用。在实际开发中,根据自己需求灵活的去选择即可
2、认识Redis
❓redis6.0已经变成多线程?
答:仅仅针对网路请求处理这一块,而核心的命令的执行这部分依然是单线程的
❓为什么redis明明是单线程性能却这么好?答:1.基于内存(核心原因⭐:磁盘与内存差异太大)
2.基于IO多路复用(大大提高了整个服务的吞吐能力)
3.良好的编号(基于C语言编写,写得好👍)
3、安装Redis
二、Redis常见命令
1、5种常见数据结构
2、通用命令
3、不同数据结构的操作命令
补充: redis的key的格式:[项目名]:[业务名]:[类型]:[id]
三、Redis的Java客户端
1、Jedis客户端
Jedis的官网地址:https://github.com/redis/jedis
Jedis快速入门
- Jedis使用的基本步骤
Jedis连接池
Jedis本身是线程不安全,故我们在使用时需要为每一个线程创建独立的Jedis对象。但频繁的创建和销毁链接会有性能损耗,故我们使用Jedis连接池代替Jedis的直连方式
◽ 最大空闲连接指的是即便没人访问这个池子,池子也可以预备8个连接供给使用。即,当有人从池子中取Jedis对象时就不用再临时创建了,直接使用即可
2、SpringDataRedis客户端
SpringDataRedis
JDKCollection:JDK中各种各样的集合,springdataredis基于redis重新实现来了一下这些集合。如,队列、链表等等;
为什么要重新实现呢:由于基于redis的这种实现是分布式、跨系统的。所以springdataredis对这些做了重新的实现。
使用SpringDataRedis对Redis操作的核心: RedisTemplate
springdataredis中提供了redistemplate工具类,其中封装了各种对redis的操作。并且将不同数据类型的操作API封装到了不同的类型中
SpringDataRedis快速入门
基于springboot去使用:由于springboot已经默认整合了springdataredis并且做了自动装配,使用起来会极其的方便。
- 1.
连接池依赖:由于无论是jdeis还是lettuce,底层都会基于commons-pool来实现连接池效果,所以需要去引入这个依赖
1.springboot自动装配的好处就是不用再去写编码了。如创建jedis连接池时,代码仍有一定复杂度。但基于springboot时,只需在yml文件配置一些信息即可,如ip地址、端口号、密码及连接池信息等;
2.连接池可选jedis或lettuce。若选择jedis需要再在pom文件中引入jedis相关依赖,因为springdataredis默认使用的是lettuce;
3.一定要在yml中手动配置 jedis/lettuce pool 连接池才会生效
总结:
SpringDataRedis的序列化方式
RedisTemplate可以接收任意Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果是这样的:
redistemplate的set方法接收的参数并不是字符串而是Object。这是基于springdataredis的一个特殊功能,它可以接收任何类型的对象,然后将其转成redis可以处理的字节。故我们存进去的键或值都被当成了java对象,而redistemplate底层默认对这些对象的处理方式就是利用jdk的序列化工具ObjectOutputStream
缺点:① 可读性差;② 内存占用较大。 故,若想要所见即所得,就必须去改变redistemplate的序列化方式了。
一般情况下key均为字符串,就可以用StringRedisSerializer来修改key的序列化;而值可能是对象,是对象时,可以用GenericJackson2JsonRedisSerializer来修改值的序列化。用JdkSerializationRedisSerializer在redis中存储的是字节流,用StringRedisSerializer存储的是字符串,而用GenericJackson2JsonRedisSerializer存储的是json字符串
我们可以自定义RedisTemplate的序列化方式,代码如下:
redistemplate的构建需要连接工厂,但工厂不需要我们自己创建,因为工厂会由springboot帮我们自动创建,我们只需要注入进来即可
存入字符串:
存入对象:
当对象以json字符串形式存入redis时同时还会存入一个该类的字节码名称。因为有这样一条属性,所以才能在反序列化时读取到类的名称字节码,从而将json字符串精准反序列化为该类对象并返回
缺点:为了在反序列化时知道对象的类型,json序列化器会将类的class类型写入json结果中,存入redis,会带来额外的内存开销。 故,为了节省内存空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化,如下图所示。
但我们无需自定义一个键值均为String的RedisTemplate,因为Spring默认提供了一个StringRedisTemplate类,它的key和value的序列化方式默认就是String方式。省去了我们自定义RedisTemplate的过程,代码如下:
总结:
补充:对hash类型的操作redis图形化界面: