软考终于结束了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中有username和password两个字段,那么可以有
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序列化和反序列化器为StringRedisSerializer或GenericJackson2JsonRedisSerializer。
GenericJackson2JsonRedisSerializer会在json中添加一条@class属性来注释它由哪个Java对象类型转换而来,这样反序列化时能够自动转换,但是却增加了存储成本。
因此,Spring提供了一个StringRedisTemplate类,其设计理念是所有KV都视为String类型,若要与Java中的对象类型转换,则需要我们手动使用jacksonObjectMapper.writeValueAsString(),jacksonObjectMapper.readValue()这样的工具来处理。