北京尚学堂2020java_Redis

4.2 AOF

AOF默认是关闭的,需要在配置文件中开启AOF。Redis支持AOF和RDB同时生效。如果同时存在,AOF优先级高于RDB(redis重新启动时会使用AOF进行数据恢复)
RDB记录的是紧凑的数据,AOF记录的是命令。
把配置文件中的appendonly从no改成yes
每秒钟记录一次日志信息

第五节 Redis主从复制

高可用:不是所有全部挂掉,还是可以使用的。
主从:备份安全性
哨兵:可用性(推荐使用哨兵)
集群:安全性&可用性&性能
搭建方式尽量掌握。
主从复制主要在安全上来考量这个问题,只要一个redis,那么可能就存在数据丢失的可能性。主要作为主要redis的一个备份。

5.1 主从优点

增加单一节点健壮性,提升整个集群稳定性
从节点可以对主节点数据备份,提供容灾能力

5.2 一主多从搭建

首先查看redis端口并关闭掉单机版

ps aux | grep redis
bin/redis-cli shutdown
cd /usr/local
mkdir redis-relicas
cp -r redis redis-replica/redis-m
cd redis-replica/redis-m
rm -r dump.rdb
cd ../
cp -r redis-m/ redis-s1/
cp -r redis-m/ redis-s2/
vi redis-m/redis.conf  #只需要修改端口即可
vi redis-s1/redis.conf # port 7002 \n replicaof 192.168.2.129 7001
vi redis-s2/redis.conf # port 7003 \n replicaof 192.168.2.129 7001

接下来新建一个shell脚本/usr/local/redis-replicas/startup.sh

cd redis-m/
bin/redis-server redis.conf
cd ../redis-s1/
bin/redis-server redis.conf
cd ../redis-s2/
bin/redis-server redis.conf

赋予执行权限:

chmod 755 startup.sh


然后和客户端建立连接

cd redis-m/
 bin/redis-cli -h localhost -p 7001

然后可以登录从节点的客户端来查看文件:

cd /usr/local/redis
bin/redis-cli -p 7002

分别使用7001、7002和7003

第六节 哨兵Sentinel

主从模式下,当主节点宕机后,从节点没办法立刻主节点。
在redis主从默认是只有主具备写的能力,而从只能读。如果主宕机,整个节点不具备写能力。如果这样让一个从变成主,整个节点就可以继续工作。即使之前的主恢复过来也当作这个节点的从即可。
单哨兵:只要发现master宕机了,直接选取另一个master。
多哨兵:达到一定数量哨兵认为master宕机了才会重新选取主节点。

第九节 使用SpringBoot整合SpringDataRedis操作redis

9.1 使用SpringDataRedis进行读写

  1. 引入依赖
  2. 配置好连接文件
  3. 写一个配置器类解析配置文件返回模板
  4. 在测试类中调用该模板
    还是首先要引入一个springboot的依赖,scope为import,type为pom
    依赖:1.springboot的核心启动器2.spring-boot-start-data-redis 3.jedis 4.spring-boot-starter-test
    spring data redis:底层使用netty实现redis远程访问的框架,性能相对优于jedis。
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.2.5.RELEASE</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.2.0</version>
    </dependency>
</dependencies>

21_redis/src/main/resources/application.yml:

spring:
  redis:
    host: 192.168.2.129
    port: 6379
    database: 0 # 数据库编号

实现一个配置类21_redis/src/main/java/com/bjsxt/config:

@Configuration
public class RedisConfiguration {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        // 提供连接工厂
        redisTemplate.setConnectionFactory(factory);
        return redisTemplate;
    }
}

写好测试类21_redis/src/test/java/com/bjsxt/TestSpringDataRedis.java

/**
 * 配置类型 创建一个适用于RedisTemplate对象
 */
@Configuration
public class RedisConfiguration {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        // 提供连接工厂
        redisTemplate.setConnectionFactory(factory);
        return redisTemplate;
    }
}

9.2 序列化器

9.2.1默认序列化器

SpringDataRedis默认情况下,做数据访问时,使用的数据序列化方案是JDK序列化方案。
要求:使用SpringDataRedis做持久化的数据,无论是key还是value,都必须可序列化。

  1. 先写一个User类,属性为username,password,需要序列化(在网络上传递就需要IO流,而使用IO流就必须刷序列化
  2. 将上面的类的实例化对象放进redis中testSetUser() 保存一个Java对象到redis中
  3. 取出一下看下数据

9.2.2 JSON序列化

配置key和value的序列化器,默认使用JDK序列化,使用JSON序列化。

@Configuration
public class RedisConfiguration {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        // 提供连接工厂
        redisTemplate.setConnectionFactory(factory);
        // 配置key和value的序列化器,不使用默认的JDK序列化,使用JSON序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
        // 如果使用hash数据类型,可以提供额外的序列化器
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
        return redisTemplate;
    }
}

只不过最后拿到的不是com.bjsxt.pojo.User类型的对象,而是linkedHashMap,需要进行转换:

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestSpringDataRedis {
    @Autowired
    private RedisTemplate<String, Object> template;

    @Test
    public void get() {
        Object value = template.opsForValue().get("key-1");
        System.out.println(value.getClass().getName() + " -   -" + value);
        // 通过模板设置值的反序列化来获得User类型的返回对象
        template.setValueSerializer(new Jackson2JsonRedisSerializer<User>(User.class));
        value = template.opsForValue().get("user");
        System.out.println(value.getClass().getName() + " -   -" + value);
    }

9.3操作其他数据类型

操作List:

@Test
public void testList() {
    // 左增加
    template.opsForList().leftPushAll("list-k", "v-1", "v-2", "v-1", "v-3");
    // 右增加
    template.opsForList().rightPushAll("list-k", "v-100", "v-200", "v-300");
    //
    List<Object> list = template.opsForList().range("list-k", 0, -1);
    System.out.println(list);
}

操作Hash:

@Test
public void testHash() {
    // 一个个放入
    template.opsForHash().put("hash-k", "hash-field1", "hash-value1");
    template.opsForHash().put("hash-k", "hash-field2", "hash-value2");
    // 一堆一起放入
    Map<Object, Object> hashValues = new HashMap<>();
    hashValues.put("map-k1", "map-v1");
    hashValues.put("map-k2", "map-v2");
    // 查
    template.opsForHash().putAll("hash-k", hashValues);
    System.out.println(template.opsForHash().get("hash-k", "hash-field1"));
    // 用entries最好
    Map result = template.opsForHash().entries("hash-k");
    System.out.println(result);
}

9.4 泛型序列化器

在配置类那里设置序列化时的使用使用泛型的即可。
使用json来描述每个对象的类型,但反向解析的时候可能会出现classNotFoundException。

// 如果使用hash数据类型,可以提供额外的序列化器
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
return redisTemplate;

我怎么感觉使用的时候也大同小异:

@Test
public void testGet() {
    template.opsForValue().set("k-new",
            Arrays.asList(
                    new User("a", "1"),
                    new User("b", "2"),
                    new User("c", "3"),
                    new User("d", "4")
            ));
    System.out.println(template.opsForValue().get("k-new"));
}

第十节 使用Redis效果

使用redis作为缓存

对db进行增删改查之后需要和redis、solr等缓存进行同步。

要保证数据存储和额外存储的一致。

posted @ 2022-04-29 14:39  明卿册  阅读(27)  评论(0编辑  收藏  举报