基本常见的数据类型

字符串 hash list set zset

字符串:

哈希: Hash的命令前面多了个H,类似java里面的Map<String,Map<String,String>> 这种格式,比较适合存储类这种数据。

List: 类似LinkedList一样,

向头部添加数据

1
lpush linkedlist 1 2 3

– 向尾部添加数据

1
rpush linkedlist 1 2 3

向指定元素前面后面插入元素

1
linsert linkedlist before/after 1 4

blpop有点类似阻塞的这种形式

1
blpop linkedlist 10

set:跟着HashSet一样可以过滤

1
sadd <key> <value>

ZSet 类似java里面的TreeSet

1
zadd <key> [<value> <score>]...

持久化

RDB快照

1
2
3
save
-- 注意上面这个命令是直接保存,会占用一定的时间,也可以单独开一个子进程后台执行保存
bgsave

执行后,会在服务端目录下生成一个dump.rdb文件,而这个文件中就保存了内存中存放的数据,当服务器重启后,会自动加载里面的内容到对应数据库中。保存后我们可以关闭服务器:

AOF

然RDB能够很好地解决数据持久化问题,但是它的缺点也很明显:每次都需要去完整地保存整个数据库中的数据,同时后台保存过程中也会产生额外的内存开销,最严重的是它并不是实时保存的,如果在自动保存触发之前服务器崩溃,那么依然会导致少量数据的丢失。

而AOF就是另一种方式,它会以日志的形式将我们每次执行的命令都进行保存,服务器重启时会将所有命令依次执行,通过这种重演的方式将数据恢

AOF重写机制

但是,我们多久写一次日志呢?我们可以自己配置保存策略,有三种策略:

  • always:每次执行写操作都会保存一次
  • everysec:每秒保存一次(默认配置),这样就算丢失数据也只会丢一秒以内的数据
  • no:看系统心情保存
1
2
3
4
5
6
# 注意得改成也是
appendonly yes

# appendfsync always
appendfsync everysec
# appendfsync no

优缺点:

  • AOF:
    • 优点:存储速度快、消耗资源少、支持实时存储
    • 缺点:加载速度慢、数据体积大
  • RDB:
    • 优点:加载速度快、数据体积小
    • 缺点:存储速度慢大量消耗资源、会发生数据丢失

事务

开启事务

1
multi

执行事务

1
exec

取消事务

1
discard

又提到锁了,实际上这个概念对我们来说已经不算是陌生了。实际上在Redis中也会出现多个命令同时竞争同一个数据的情况,比如现在有两条命令同时执行,他们都要去修改a的值,那么这个时候就只能动用锁机制来保证同一时间只能有一个命令操作。

虽然Redis中也有锁机制,但是它是一种乐观锁,不同于MySQL,我们在MySQL中认识的锁是悲观锁,那么什么是乐观锁什么是悲观锁呢?

  • 悲观锁:时刻认为别人会来抢占资源,禁止一切外来访问,直到释放锁,具有强烈的排他性质。
  • 乐观锁:并不认为会有人来抢占资源,所以会直接对数据进行操作,在操作时再去验证是否有其他人抢占资源。

Redis中可以使用watch来监视一个目标,如果执行事务之前被监视目标发生了修改,则取消本次事务:

是一种乐观锁 watch来监控 利用的是版本号 并不是实体的数值

SpringBoot整合redis

我们接着来看如何在SpringBoot项目中整合Redis操作框架,只需要一个starter即可,但是它底层没有用Jedis,而是Lettuce

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

starter提供的默认配置会去连接本地的Redis服务器,并使用0号数据库,当然你也可以手动进行修改:

1
2
3
4
5
6
7
8
spring:
redis:
#Redis服务器地址
host: 192.168.10.3
#端口
port: 6379
#使用几号数据库
database: 0

默认定义好了两个类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.boot.autoconfigure.data.redis;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
public RedisAutoConfiguration() {
}

@Bean
@ConditionalOnMissingBean(
name = {"redisTemplate"}
)
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}

@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}

默认定义了一个类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package cn.wsy.code.service;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

@Service
public class RedisService {
@Resource
StringRedisTemplate stringRedisTemplate;
@PostConstruct
public void init() {
stringRedisTemplate.setEnableTransactionSupport(true);
}
@Transactional
public void test() {
stringRedisTemplate.multi();
stringRedisTemplate.opsForValue().set("d","aaa");
stringRedisTemplate.exec();
}
}

主从复制

哨兵模式

集群搭建