清空对象里面所有的value值_Redis---Key-Value的NoSQL数据库(三)

c6c6e208f82e88003b7e08d7cc9bbc0a.png

遇到困难时不要抱怨,既然改变不了过去,那么就努力改变未来。

【Redis】

八、集群(Cluster)

集群原理

  1. 集群搭建完成后由集群节点平分(不能平分时,前几个节点多一个槽)16384个槽。
  2. 客户端可以访问集群中任意节点。所以在写代码时都是需要把集群中所有节点都配置上。
  3. 当向集群中新增或查询一个键值对时,会对Key进行Crc16算法得出一个小于16384值,判断值在哪个节点上,然后就操作哪个节点。

fbc70e8dd7d5f55253bc73732f51fc4d.png

前提:已经安装好redis单机版。

当集群中超过或等于1/2节点不可用时,整个集群不可用。为了搭建稳定集群,都采用奇数节点。

演示:创建3个节点,每个节点搭建一主一从。

1. 复制redis

在/usr/local下新建redis-cluster

  • # mkdir /usr/local/redis-cluster

把单机redis复制到redis-cluster中

  • # cd /usr/local/redis
  • # cp -r bin /usr/local/redis-cluster/redis1

2. 修改redis.conf

  • # cd /usr/local/redis-cluster/redis1
  • # vim redis.conf

需要修改如下:

port 7001
cluster-enabled yes
cluster-config-file nodes-7001.conf
cluster-node-timeout 15000
# appendonly yes 如果开启aof默认,需要修改为yes。如果使用rdb,此处不需要修改
daemonize yes
protected-mode no
pidfile /var/run/redis_7001.pid

3. 复制redis

把redis1复制5份

  • # cd /usr/local/redis-cluster

执行之前一定要先删除dump.rdb,清空Redis中数据。

  • # rm -f redis1/dump.rdb
  • # cp -r redis1 redis2
  • # cp -r redis1 redis3
  • # cp -r redis1 redis4
  • # cp -r redis1 redis5
  • # cp -r redis1 redis6

新复制的5个redis的配置文件redis.conf都需要需改三处。

  • # vim redis2/redis.conf
  • # vim redis3/redis.conf
  • # vim redis4/redis.conf
  • # vim redis5/redis.conf
  • # vim redis6/redis.conf

例如redis2/redis.conf中需要把所有7001都换成7002。

可以使用 :%s/7001/7002/g 进行全局修改。

port 7002
cluster-config-file nodes-7002.conf
pidfile /var/run/redis_700.2pid

4. 启动6个redis

  • # vim startup.sh

先启用编辑状态,再粘贴下面内容

cd redis1
./redis-server redis.conf
cd ..
cd redis2
./redis-server redis.conf
cd ..
cd redis3
./redis-server redis.conf
cd ..
cd redis4
./redis-server redis.conf
cd ..
cd redis5
./redis-server redis.conf
cd ..
cd redis6
./redis-server redis.conf
cd ..
  • # chmod a+x startup.sh
  • # ./startup.sh

5. 查看启动状态

ps aux|grep redis

52d39b11ed11f2ac286c3183316f8b60.png

6. 建立集群

在redis3的时候需要借助ruby脚本实现集群。在redis5中可以使用自带的redis-cli实现集群功能,比redis3的时候更加方便了。

建议配置静态ip,ip改变集群失效

  • # cd redis1
  • # ./redis-cli --cluster create 192.168.8.129:7001 192.168.8.129:7002 192.168.8.129:7003 192.168.8.129:7004 192.168.8.129:7005 192.168.8.129:7006 --cluster-replicas 1

执行完命令后,询问是否按照当前配置创建集群,输入yes而不是y。

692a15fbe8ab69e6c8f468992062181d.png

7. 测试

集群测试时,千万不要忘记最后一个-c参数。

  • # ./redis-cli -p 7001 -c
  • # set age 18

8. 编写关闭脚本

  • # cd /usr/local/redis-cluster
  • # vim stop.sh
  • # chmod a+x stop.sh
./redis1/redis-cli -p 7001 shutdown
./redis2/redis-cli -p 7002 shutdown
./redis3/redis-cli -p 7003 shutdown
./redis4/redis-cli -p 7004 shutdown
./redis5/redis-cli -p 7005 shutdown
./redis6/redis-cli -p 7006 shutdown

九、Jedis

Redis给Java语言提供了客户端API,称之为Jedis。

Jedis API和Redis 命令几乎是一样的。

例如:Redis对String值新增时set命令,Jedis中也是set方法。所以本课程中没有重点把所有方法进行演示,重要演示Jedis如何使用。

Jedis API特别简单,基本上都是创建对象调用方法即可。由于Jedis不具备把对象转换为字符串的能力,所以每次都需要借助Json转换工具进行转换,这个功能在Spring Data Redis中已经具备,推荐使用Spring Data Redis。

1. 添加依赖

<dependencies>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.3.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <version>2.2.6.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

2. 单机版

public void testStandalone(){
    Jedis jedis = new Jedis("192.168.32.132",6379);
    jedis.set("name","smallming-standalone");
    String value = jedis.get("name");
    System.out.println(value);
}

3. 带有连接池

public void testPool(){
    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    jedisPoolConfig.setMaxTotal(20);
    jedisPoolConfig.setMaxIdle(5);
    jedisPoolConfig.setMinIdle(3);
    JedisPool jedisPool = new JedisPool(jedisPoolConfig,"192.168.32.132",6379);
    Jedis jedis = jedisPool.getResource();
    jedis.set("name","smallming-pool");
    String value = jedis.get("name");
    System.out.println(value);
}

4. 集群

public void testCluster(){
    Set<HostAndPort> set = new HashSet<>();
    set.add(new HostAndPort("192.168.32.132",7001));
    set.add(new HostAndPort("192.168.32.132",7002));
    set.add(new HostAndPort("192.168.32.132",7003));
    set.add(new HostAndPort("192.168.32.132",7004));
    set.add(new HostAndPort("192.168.32.132",7005));
    set.add(new HostAndPort("192.168.32.132",7006));
    JedisCluster jedisCluster = new JedisCluster(set);
    jedisCluster.set("name","smallming");
    String value = jedisCluster.get("name");
    System.out.println(value);
}

十、 使用SpringBoot整合SpringDataRedis操作redis

1. Spring Data简介

Spring Data是Spring公司的顶级项目,里面包含了N多个二级子项目,这些子项目都是相对独立的项目。每个子项目是对不同API的封装。

所有Spring Boot整合Spring Data xxxx的启动器都叫做spring-boot-starter-data-xxxx

Spring Data 好处:很方便操作对象类型(基于POJO模型)。

把Redis不同值的类型放到一个opsForXXX方法中。

opsForValue : String值(最常用),如果存储Java对象或Java中时就需要使用序列化器,进行序列化。

  • opsForList : 列表List
  • opsForHash: 哈希表Hash
  • opsForZSet: 有序集合Sorted Set
  • opsForSet : 集合

2. Spring Data Redis序列化器介绍

经常需要向Redis中保存Java中Object或List等类型,这个时候就需要通过序列化器把Java中对象转换为字符串进行存储。

2.1 JdkSerializationRedisSerializer

是RedisTemplate类默认的序列化方式。JdkSerializationRedisSerializer使用JDK自带的序列化方式。要求被序列化的对象必须实现java.io.Serializable接口,而且存储的内容为二进制数据,这对开发者是不友好的。会出现虽然不影响使用,但是直接使用Redis客户端查询Redis中数据时前面出现乱码问题。

2.2 OxmSerializer

以字符串格式的xml存储。解析起来也比较复杂,效率也比较低。已经很少有人在使用该序列化器。

2.3 StringRedisSerializer

只能对String类型序列化操作。

2.4 GenericToStringSerializer

需要调用者给传递一个对象到字符串互转的Converter(转换器),使用比较麻烦。

2.5 Jackson2JsonRedisSerializer

该序列化器可以将对象自动转换为Json的形式存储,效率高且对调用者友好。

优点:

速度快,序列化后的字符串短小精悍,不需要实现Serializable接口。

缺点:

此类的构造函数中有一个类型参数,必须提供要序列化对象的类型信息(.class对象)。如果存储List等带有泛型的类型,此序列化器是无法识别泛型的,会直接把泛型固定设置为LinkedHashMap。

例如:存储时List<People> , 取出时是List<LinkedHashMap>

2.6 GenericJackson2JsonRedisSerializer

与Jackson2JsonRedisSerializer功能相似。底层依然使用Jackson工具包。相比Jackson2JsonRedisSerializer多了_class列,列里面存储类(新增时类型)的全限定路径,从Redis取出时根据_class类型进行转换,解决了泛型问题。

该序列化器不需要指定对象类型信息(.class对象)使用Object作为默认类型。目前都使用这个序列化器。

3. 代码步骤

基于Spring Test 单元测试演示

3.1 添加依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.6.RELEASE</version>
</parent>

<dependencies>
<!-- 为了要在项目中jackson工具包 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
</dependencies>

3.2 配置配置文件

  • spring.redis.host=localhost 默认值
  • spring.redis.port=6379 端口号默认值

如果连接Redis集群,不需要配置host,配置spring.redis.cluster.nodes,取值为redis集群所在ip:port,ip:port。由于word排版问题nodes后面取值没有和nodes在一行。

spring:
  redis:
    host: 192.168.52.133
#    cluster:
#      nodes: 192.168.52.133:7001,192.168.52.133:7002,192.168.52.133:7003,192.168.52.133:7004,192.168.52.133:7005,192.168.52.133:7006

3.3 编写配置类

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        return redisTemplate;
    }
}

3.4 编写代码

3.4.1 编写对象新增

@Autowired
private RedisTemplate<String, Object> redisTemplate;

@Test
public void testString() {
    People peo = new People(1, "张三");
    redisTemplate.opsForValue().set("peo1", peo);
}

3.4.2 编写对象获取

@Test
public void testGetString() {
    People peo = (People) redisTemplate.opsForValue().get("peo1");
    System.out.println(peo);
}

3.4.3 编写List

@Test
public void testList() {
    List<People> list = new ArrayList<>();
    list.add(new People(1, "张三"));
    list.add(new People(2, "李四"));
    redisTemplate.opsForValue().set("list2", list);
}

3.4.4 编写List取值

@Test
public void testGetList(){
    List<People> list2 = (List<People>) redisTemplate.opsForValue().get("list2");
    System.out.println(list2);
}

3.4.5 判断Key是否存在

上面讲解Redis作为缓存工具时,需要判断key是否存在,通过hasKey进行判断。

@Test
void hasKey(){
    Boolean result = redisTemplate.hasKey("name");
    System.out.println(result);
}

3.4.6 根据key删除数据

如果key-value正常被删除,返回true,如果key不存在返回false

@Test
void del(){
    Boolean result = redisTemplate.delete("name");
    System.out.println(result);
}

需要更多Java学习资料的可以到评论区留言或者私信哦,视频、源码、项目,通通都给你

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值