软考终于结束了Haha!终于可以静下来心来学习技术了……先从Redis基础开始吧!

Redis的几种数据结构

Value类型 e.g.
String Hello World
Hash {name: “Jack”,age: 21}
List [A->B->C->D]
Set {A,B,C}
SortedSet {A:1,B:2,C:3}
GEO {A: (120.2,23.5})
BitMap 0001010100
HyperLog 0010101010

Redis常见通用命令

KEYS [pattern]:查看所有符合条件的key 如果数据量过大会导致数据库阻塞 因为Redis是单线程的

DEL [keys]:删除Key(s)

EXISTS [keys]判断一个Key是否存在

EXPIRE key seconds设置一个Key的过期时间

TTL key查看Key的过期时间:-1永久有效 -2已过期

Key的层级结构

Key可以由多个单词分割组成层级结构:项目名:业务名:对象名:id

当然也可以自行按照需求修改,以冒号分割就是一层,同时value中的数据可以以JSON的格式进行存储,以方便与Java中的对象实现反序列化和序列化

比如user中有usernamepassword两个字段,那么可以有

K:dango:user:1

V:{"username": "dango","password": "qwe123"}

String类型

是Redis中最简单的存储类型,其value是字符串

字符串可分为string,int,float,其中后两者可以自己自增减操作

无论哪种字符串,底层都是字节数组,只不过是编码方式不同;String类型最大空间不能超过512m。

String操作命令

SET:添加或修改一个已存在的String键值对

GET:根据key获取String类型的value

MSET/MGET:批量添加/获取多个String的Value

INCR:让一个整型自增+1

INCRBY/INCRBYFLOAT:让一个整型/浮点型数按步长增长

SETNX:添加一个String键值对,前提是不存在(用于原子性、分布式事务锁)

Hash类型

Redis中的Hash散列类型有点像Java中的Map<String,<String,String>>类型,value中可以有多个field,可以对每个field 单独进行增删改查,是一个无序字典。

Key field:values
dango:user:1 name:dango,sex:man,age:18

Hash操作命令

HSET:添加或修改一个Hash类型的key的field值

HGET/HGETALL:获取一个Hash类型key的field值

HMGET/HMSET:批量获取/设置多个Hash类型Key的field值

HKEYS/HVALS:获取一个Hash类型的key中的所有field/values

HINCRBY:让一个Hash类型的key的field值按步长自增

HSETNX:添加一个Hash类型的field值,前提是不存在

List类型

Redis中的List类型与Java中的LinkedList相似,是一个双向链表,元素有序可重复,插入删除快,查询速度一般(因为要遍历链表)。

常用来存储:朋友圈点赞列表、评论列表。

List常用命令

LPUSH/RPUSH:向列表左/右端点添加一个元素

LPOP/RPOP:从列表左/右端点取出一个元素

LRANGE:返回一段下标范围内的所有元素

BLPOP/BRPOP:从列表左/右端点取出一个元素,若没有元素则阻塞(消息队列)

Set类型

Redis中的Set和Java中的HashSet类似,像一个袋子,是一个Hash表,有无序、不可复、查找快、支持交并差集功能,常用来存储:好友列表。

Set常用命令

SADD/SREM:用于向Set中添加/删除元素

SCARD:统计Set中的元素个数

SISMEMBER:判断一个元素是否存在Set

SMEMBERS:获取Set中所有的元素

SINITER/SDIFF/SUNION:求Set1和Set2的交、差、并集

SortedSet类型

Redis中的SortedSet是一个可排序的Set,每一个元素都带一个score,可以基于score属性对元素进行排序,底层的实现是一个跳表(SkipSet)和一个Hash表,可排序,元素不重复,查询速度快,用于排行榜。

SortedSet常用命令

ZADD/ZREM:添加或删除元素到SortedSet

ZSCORE:查询指定元素的score

ZRANK:查询指定元素的排名

ZCARD:查询一个Sortedset的元素个数

ZCOUNT:统计score值在指定范围内的所有元素个数

ZINCRBY:增加指定元素的score

ZRANGE:列出指定排名范围内的元素

ZRANGEBYSCORE:按照SCORE排序后,列出在指定score范围内的元素

ZDIFF/ZINTER/ZUNION:求SortedSet的差、交、并集

Redis&Java

Redis的常见Java客户端

名称 特点
Jedis 以Redis命令作为方法名称,简单易用,但线程不安全,多线程要配合线程池使用
lettue 基于Netty,支持同步,异步,响应式编程且线程安全,支持Redis的多种模式
Redisson 基于Redis实现分布式可伸缩的Java数据集合。
Spring Data Redis 集成了Jedis和lettue,提供一层统一API便于使用

Jedis的使用

单例模式(线程不安全): 构造一个Jedis对象->auth()验证,select()选库->用完后close()

连接池模式(线程安全): 创建一个JedisConnectFactory类->创建JedisPoolConfig对象->通过JedisPoolConfig中的方法配置连接池信息->创建JedisPool对象->getResource()方法来获取一个Redis链接-> auth()验证,select()选库->用完后close()

close方法会判断当前链接是否是创建自连接池,如果此链接来自连接池则实际调用pool.returnResource方法而不是直接销毁。

Spring Data Redis的使用

Spring Data Redis 免去了复杂的连接管理和原始 Redis 命令操作,默认使用lettue

引入spring-boot-starter-data-redis,commons-pool2依赖->配置application.properties:spring.data.redis->创建RedisTemplate对象/创建StringRedisTemplate->注意序列化和反序列化问题->使用opsForXXX()方法访问Redis

RedisTemplate:

默认使用JDK的序列化和反序列化器,会把输入转换为乱码(?),需要写一个配置类,指定temple的Key和Value序列化和反序列化器为StringRedisSerializerGenericJackson2JsonRedisSerializer

GenericJackson2JsonRedisSerializer会在json中添加一条@class属性来注释它由哪个Java对象类型转换而来,这样反序列化时能够自动转换,但是却增加了存储成本。

因此,Spring提供了一个StringRedisTemplate类,其设计理念是所有KV都视为String类型,若要与Java中的对象类型转换,则需要我们手动使用jacksonObjectMapper.writeValueAsString()jacksonObjectMapper.readValue()这样的工具来处理。

代码实现