特征
- 键值(key-value)型,value支持多种不同数据结构,功能丰富
- 单线程,每个命令具备原子性
- 低延迟,速度快(基于内存、IO多路复用、良好的编码)
- 支持数据持久化
- 支持主从集群、分片集群(把数据拆分再存储)
- 支持多语言客户端
安装redis
安装gcc
yum install -y gcc tcl
下载tar压缩包并解压(我这里下载的是redis-6.2.12)
tar -zxvf /opt/redis-6.2.12.tar.gz -C /usr/local/
进入redis目录,执行编译安装
make && make install
配置(一般要改的):
bind 0.0.0.0 -::1
daemonize yes
requiredpass 123456
后台启动
进入redis文件夹
redis-server redis.conf
配置开机自启:
vi /etc/systemd/system/redis.service
内容:
[Unit]
Description=redis-server
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /usr/local/redis-6.2.12/redis.conf
PrivateTmp=true
[Install]
WantedBy=multi-user.target
重载系统服务
systemctl daemon-reload
# 启动
systemctl start redis
# 停止
systemctl stop redis
# 重启
systemctl restart redis
# 查看状态
systemctl status redis
开机自启
systemctl enable redis
客户端
- redis-cli
redis-cli [options] [commonds]
options有:
-h 127.0.0.1 指定连接的redis节点的ip地址
-p 6379
-a 123456 指定redis的访问密码
commonds:
ping
选择1号库
SELECT 1
- 图形化界面
现在有官方的了,RedisDesktopManager,但是现在官网不让下了,让你下RedisInsight,有点繁琐,没RESP简洁。推荐RESP
数据结构
- 基本类型
- String
- Hash
- List:跟java中的LinkedList类似,可以看作一个双向列表支持正向检索,反向检索
- Set
- SortedSet
- 特殊类型
- GEO
- BitMap
- HyperLog
通用命令
- KEYS:匹配模板查询
- DEL:删除
- EXISTS:判断存在
- EXPIRE:设置有效期,key second
- TTL:查看剩余有效期
命令不看了,用到的时候去查就行了
参考文档:https://www.redis.com.cn/commands.html
Key的层级格式
redis的key允许有多个单词形成层级结构,多个单词之间用":"隔开
例如:
项目名:业务名:类型:id
Redis的Java客户端
Jedis
//配置jedis
public void before01() {
jedis = new Jedis("{你的redis的ip}", 6379);
jedis.auth("{你的密码(如果有的话)}");
jedis.select(0);
}
Jedis连接池
private static final JedisPool jedisPool;
static {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(8);
jedisPoolConfig.setMaxIdle(8);
jedisPoolConfig.setMinIdle(0);
jedisPoolConfig.setMaxWaitMillis(200);
jedisPool = new JedisPool(jedisPoolConfig, "{你的redis的ip}", 6379, 1000, "{你的密码(如果有的话)}");
}
SpringDataRedis
参考文档:https://spring.io/projects/spring-data-redis#support
- 支持基于JDK、JSON、字符串、Spring对象的数据序列化和反序列化
RedisTemplate可以接收任意Object作为值写入redis,默认是采用JDK序列化
缺点:
- 可读性差
- 内存占用较大
修改序列化器
springboot项目
application.yml:设置redis服务器配置
spring:
redis:
host: {你的ip}
port: 6379
password: {你的密码(如果有的话)}
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: 100
添加@Configuration
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
return redisTemplate;
}
为什么上面序列化器加了toString下面不用?
上面使用了RedisSerializer.string()方法来获取一个字符串类型的序列化器。这个序列化器将Java字符串对象转换为Redis字符串,也可以将Redis字符串转换为Java字符串对象。这个序列化器可以保证在Java字符串对象和Redis字符串之间进行正确的转换。
对于ValueOperations操作类中的setValue()方法和HashOperations操作类中的put()方法,由于方法的参数是Object类型,因此RedisTemplate会自动根据setValueSerializer()和setHashValueSerializer()方法设置的序列化器对参数进行序列化和反序列化,因此不需要手动进行toString()操作。
而对于key和hash key,由于Redis中的key和hash key必须是字符串类型,因此RedisTemplate在将Java对象作为key或hash key写入Redis时,需要使用序列化器将Java对象序列化为字符串。因此,在这里我们需要将RedisSerializer.string()设置为key和hash key的序列化器,并将Java对象转换为字符串类型,以保证正确地写入Redis。
添加依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.2</version>
</dependency>
这种存储方式每次往redis里面存储数据的时候会自动添加@class,数据量大了之后占用的额外空间会变得很大。为了节省内存空间,我没并不会使用json来处理value,而使用String序列化器。如果需要存储Java对象时,手动完成序列化和反序列化。String默认提供StringRedisTemplate,key和value默认的序列化方式都是String方式。
User user = new User("tjqtjq", 56);
String s = mapper.writeValueAsString(user);
stringRedisTemplate.opsForValue().set("stu:122", s);
String userString = stringRedisTemplate.opsForValue().get("stu:122");
User val = mapper.readValue(userString, User.class);
System.out.println("user: " + val);
hash用stringRedisTemplate.opsForHash().put(),put写法比较亲近于java