文章目录
初识Redis
Sql 与 NoSql
认识Redis
特征:
- 键值(key-value)型,value支持多种不同数据结构,功能丰富
- 单线程,每个命令具备原子性
- 低延迟,速度快(基于内存、IO多路复用、良好的编码)。
- 支持数据持久化
- 支持主从集群、分片集群。
- 支持多语言客户端
图形化客户端
https://github.com/lework/RedisDesktopManager-Windows/releases
数据结构
通用命令
- KEYS: 查看符合模板的所有key,不建议在生产环境下使用(会阻塞)
- DEL:删除指定key
- EXISTS: 判断一个key是否存在
- EXPIRE:给一个key设置一个有效期,有效期到期时key会被自动删除
- TTL: 查看一个key的有效时间(-1代表永久有效)
String类型
String类型的常见命令
-
SET:添加或者修改已经存在的一个String类型的键值对
-
GET:根据key获取string类型的value
-
MSET:批量添加多个string类型的键值对
-
MGET:根据多个key获取多个string类型的value
-
INCR:让一个整形key自增1
-
INCRBY:让一个整形key自增并且指定步长,例如让一个整形key自增2
-
INCRBYFLOAT:让一个浮点类型数字自增并指定步长
-
SETNX:添加一个string类型的键值对,前提是这个key不存在,否则不执行
-
SETEX:添加一个string类型的键值对,并且指定有效期
key的结构(层级结构)
例如
项目名:业务名:类型:id
Hash类型
格式: key(key:value)
Hash 类型的常见命令
- HSET key field value :添加或者修改 hash 类型 key 的 field 的值.
- HGET key field :获取一个 hash 类型 key 的 field 的值
- HMSET :批量添加多个 hash 类型 key 的 field 的值
- HMGET :批量获取多个 hash 类型 key 的 field 的值
- HGETALL :获取一个 hash 类型的 key 中的所有的 field 和 value
- HKEYS :获取一个 hash 类型的 key 中的所有的 field
- HVALS :获取一个 hash 类型的 key 中的所有的 value
- HINCRBY :让一个 hash 类型 key 的字段值自增并指定步长
- HSETNX :添加一个 hash 类型的 key 的 field 值,前提是这个 field 不存在,否则不执行
List类型
可以看作一个双向链表结构
有序,可重复,插入和删除速度快,查询速度一般
List 的常见命令有:
- LPUSH key element …:向列表左侧插入一个或多个元素
- LPOP key :移除井返回列表左侧的第一个元素,没有则返回 nil
- RPUSH key element …:向列表右侧插入一个或多个元素
- RPOP key :移除并返回列表右侧的第一个元素
- LRANGE key star end :返回一段角标范围内的所有元素
- BLPOP 和 BRPOP :与 LPOP 和 RPOP 类似,只不过在没有元素时等待指定时间,而不是直接返回 nil
Set类型
无序,不可重复,查找快,支持交集,并集,差集等功能
Set 类型的常见命令
Set 的常见命令有:
-
SADD key member …:向 set 中頃加一个或多个元素
-
SREM key member …:移除 set 中的指定元素
-
SCARD key :返回 set 中元素的个数
-
SISMEMBER key member :判断一个元素是否存在于 set 中
-
SMEMBERS :获取 set 中的所有元素
-
SINTR key1key2…;求key1与key2的交集
-
SDIFF key1key2…:求key1与key2的差集
-
SUNION key1key2.:求key1和key2的并集
并集:以属于A或属于B的元素为元素的集合成为A与B的并(集)
交集:以属于A且属于B的元素为元素的集合成为A与B的交(集)
差集:以属于A而不属于B的元素为元素的集合成为A与B的差(集)
SortedSet类型
可排序,不重复,查询快
SortedSet 类型的常见命令
SortedSet 的常见命令有:
- ZADQ key SCore member :漆加一个或多个元素到 sorted set ,如果已经存在则更新其 score 值
- ZREM key member :删除 Sorted set 中的一个指定元素
- ZSCORE key member :获取 sorted set 中的指定元素的 score 值
- ZRANK key member :获取 sorted set 中的指定元素的排名
- ZCARD key :获取 sorted set 中的元素个数
- ZCOUNT key min max :统计 score 值在给定范围内的所有元素的个数
- ZINCRBY key increment member :让 sorted set 中的指定元素自增,步长为指定的 increment 值
- ZRANGE key min max :按照 score 排序后,获取指定排名范围内的元素
- ZRANGEBYSCORE key min max :按照 score 排序后,获取指定 score 范围内的元素
- ZDIFF . ZINTER 、 ZUNION :求差集、交集、并集
Redis的java客户端
Jedis
- 添加依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.0.1</version>
</dependency>
- 单例链接
Jedis jedis = new Jedis("124.222.94.56", 6379);
jedis.auth("000415");//redis密码
//ping通显示PONG
System.out.println(jedis.ping());//去ping我们redis的主机所在ip和端口
- 使用 JedisPool 连接池
public class JedisPoolUtil {
/**
* host
*/
private static String ADDR = "124.222.94.56";
/**
* password
*/
private static String AUTH = "000415";
/**
* port
*/
private static int PORT = 6379;
private static JedisPool jedisPool = null;
private static int TIMEOUT = 10000;
/**
* 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
*/
private static int MAX_WAIT = 10000;
/**
* 在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
*/
private static boolean TEST_ON_BORROW = true;
/**
* 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
*/
private static int MAX_IDLE = 200;
static {
try {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(MAX_IDLE);
config.setTestOnBorrow(TEST_ON_BORROW);
config.setMaxWaitMillis(MAX_WAIT);
jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Jedis getJedis() {
if (jedisPool != null) {
Jedis jedis = jedisPool.getResource();
return jedis;
}
return null;
}
public static void close(Jedis jedis) {
if (jedis != null) {
jedis.close();
}
}
}
spring-data-redis
- 引入依赖
<!-- spring boot redis缓存引入 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- lecttuce 缓存连接池-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
- 添加application.yml配置
spring:
redis:
host: 124.222.94.56
port: 6379
database: 2
# password: 000415 #默认为空
lettuce:
pool:
max-active: 20 #最大连接数,负值表示没有限制,默认8
max-wait: -1 #最大阻塞等待时间,负值表示没限制,默认-1
max-idle: 8 #最大空闲连接,默认8
min-idle: 0 #最小空闲连接,默认0
SpringDataRedis序列化实践方案
- RedisTemplate可以接收任意Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认是采用JDK 序列化;缺点:可读性差,内存占用较大。
改变RedisTemplate的序列化方式。
package com.tian.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
// 创建RedisTemplate对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 设置连接工厂
template.setConnectionFactory(connectionFactory);
// 创建JSON序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
// key和 hashKey采用 string序列化
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
// value和 hashValue采用 JSON序列化
template.setValueSerializer(jsonRedisSerializer);
template.setHashValueSerializer(jsonRedisSerializer);
// 返回RedisTemplate
return template;
}
}
由于用到了Jackson,所以我们需要在pom文件中引入相关的依赖:
<!--引入Jackson依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
- StringRedisTemplate
为了节省内存空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。
package com.tian;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tian.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.Map;
@SpringBootTest
class RedisDemoApplicationTests {
@Autowired
private StringRedisTemplate redisTemplate;
@Test
void testString() {
// 插入一条string类型数据
redisTemplate.opsForValue().set("name", "xiaoma");
// 读取一条string类型数据
Object name = redisTemplate.opsForValue().get("name");
System.out.println("name = " + name);
}
// ObjectMapper是SpringMVC默认的序列化工具, 你也可以使用诸如FastJson之类的序列化工具
private static final ObjectMapper mapper = new ObjectMapper();
@Test
void testSaveUser() throws JsonProcessingException {
// 创建对象
User user = new User("Rose", 21);
// 手动序列化
String json = mapper.writeValueAsString(user);
// 写入数据
redisTemplate.opsForValue().set("user:200", json);
// 获取数据
String jsonUser = redisTemplate.opsForValue().get("user:200");
// 手动反序列化
User user1 = mapper.readValue(jsonUser, User.class);
System.out.println("user1 = " + user1);
}
@Test
void testHash() {
// 存入数据
redisTemplate.opsForHash().put("user:02", "name", "aaa");
redisTemplate.opsForHash().put("user:02", "age", "01");
// 取出数据
Map<Object, Object> entries = redisTemplate.opsForHash().entries("user:02");
System.out.println(entries);
}
}