Redis_基础
SQL与NoSQL对比
- 数据结构:结构化---非结构化
- 数据关联:关联的---无关联
- 查询方式:SQL查询---非SQL
- 事务特性:ACID---BASE
- 存储方式:磁盘---内存
- 扩展性:垂直---水平
- 使用场景:数据结构固定,相关业务对数据安全性、一致性要求较高---数据结构不固定,对一致性、安全性要求不高,对查询性能要求高。
Redis简介
全称:Remote Dictionary Server 远程字典服务
特征:
- 键值型,value支持多种不同数据结构,功能丰富。
- 单线程,每个命令具备原子性。
- 低延迟,速度快(基于内存、IO多路复用、良好的编码)。
- 支持数据持久化。
- 支持主从集群,分片集群。
- 支持多语言客户端。
String类型
根据字符串的格式不同,分为3类:
- string:普通字符串
- int:整数类型,可以做自增、自减操作。
- float:浮点类型,可以做自增、自减操作。
不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同。字符串类型的最大空间不能超过512m。
常用命令:SET
增,GET
查,MSET
批量增,MGET
批量查,INCR
设置自增1,INCRBY
设置自增x,INCRBYFLOAT
设置自增x,SETNX
不存在才执行增,SETEX
增并且设置有效期。
key的层级结构
key的格式:[项目名]:[业务名]:[类型]:[id]
如果value是一个java对象,例如一个user对象,则可以将对象序列化成JSON字符串后存储。
Hash类型
也叫散列,其value是一个无序字典。
常用命令:HSET key field value
增,HGET key field
查,HMSET
批量增field,HMGET
批量查field,HGETALL
查一个key中所有filed和value,HKEYS
查一个key中所有field,查一个key中所有value,HINCRBY
让一个hash类型key字段自增并指定步长,HSETNX
如果field存在则不执行。
List类型
可以看成一个双向链表结构,支持正向检索和反向检索。
特点:有序、元素可以重复、插入删除快、查询速度一般。
常用命令:LPUSH key element...
左侧插入1个或多个,LPOP key
左侧弹出,RPUSH key element...
右侧插入1个或多个,RPOP key
右侧弹出,LRANGE key star end
返回范围内所有元素,BLPOP和BRPOP
没有元素时等待指定时间,而不是直接返回nil(B代表阻塞)。
Set类型
可以看成一个value为null的HashMap。
特点:无序,元素不可重复,查找快,支持交集、并集、差集等功能。
常见命令:SADD key member
向set添加,SREM key member
移除,SCARD key
计数,SISMEMBER key member
判断元素在不在set中,SMEMBERS
返回set所有元素。SINTER key1 key2
求key1,key2的交集,SDIFF key1 key2
求key1和key2的差集,SUNION key1 key2
求key1和key2的并集。
SortedSet类型
每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表SkipList加hash表。
特点:可排序、元素不重复、查询速度快。
常见命令:ZADD key score member
增,ZREM key member
删,ZSCORE key member
获取score值,ZRANK key member
获取排名,ZCARD key
获取元素个数,ZCOUNT key min max
获取score在范围内的元素的个数,ZINCRBY key increment member
让指定元素自增,ZRANGE key min max
获取指定score范围内的元素,ZRANGEBYSCORE key min max
按照score排序后,获取指定score范围内的元素,ZDIFF、ZINTER、ZUNION
求差集、交集、并集
Redis的Java客户端
有哪些:
Jedis,Lettuce,Redisson,java-redis-client,vetrx-redis-client
Jedis
使用步骤:
- 引入依赖。
- 创建Jedis对象,建立连接。
- 使用Jedis,方法名和命令名一致。
- 释放资源。
Jedis连接池
Jedis本身是线程不安全的,并且频繁的创建和小会连接会有性能损耗,所以我们推荐大家使用Jedis连接池代替Jedis的直连方式。
使用方法:直接获取连接池对象,设置连接池配置、连接属性,从连接池获取连接jedisPool.getResource();
。
Spring Data Redis
介绍:
- 提供了对不同Redis客户端的整合(Lettuce和Jedis)
- 提供了RedisTemplate统一API来操作Redis
- 支持Redis的发布订阅模型
- 支持Redis哨兵和Redis集群
- 支持基于Lettuce的响应式编程
- 支持基于JDK、JSON、字符串、Spring对象的数据序列化和反序列化。
- 支持基于Redis的JDKCollection实现。
spring默认使用Lettuce。
使用步骤:
- 引入spring-boot-starter-data-redis依赖
- 在application.yml配置Redis信息
- 注入RedisTemplate
RedisTemplate的序列化
RedisTemplate可以接收任意的Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认采用JDK序列化。
缺点:可读性差、内存占用大。
改进:
redisTemplate.setKeySerializer(传入下面的参数);
这个改的事key的序列化方式。
key和hashKey使用string序列化RedisSerializer.string()
value和hashValue使用JSON序列化jsonRedisSerializer
缺点:JSON序列化后会存储类的信息,占用大量空间。
StringRedisTemplate
为了节省内存空间,我们并不会用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。
Spring提供了一个StringRedisTemplate类,它的key和value的序列化方式默认都是String方式。省去了我们自定义RedisTemplate的过程。
RedisTemplate的2种序列化实践方案:
方案一:
- 自定义RedisTemplate
- 修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer
弊端:会额外记录类的信息字节码,占用额外的空间
方案二:
- 使用StringRedisTemplate
- 写入Redis时,手动把对象序列化为JSON
- 读取Redis时,手动把读取到的JSON反序列化为对象。