Redis——客户端代码

一、使用Jedis连接并操作Redis

1、创建一个springboot项目,导入需要的依赖

<dependency>           
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-redis</artifactId>
    <version>1.4.5.RELEASE</version>
</dependency>

2、使用测试单元测试一下Redis连接

package com.gykalc.testjedis;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import redis.clients.jedis.Jedis;

@SpringBootTest
class TestjedisApplicationTests {

    @Test
    void contextLoads() {
    }

    @Test
    void testJedis() {
        /**
         * 使用Jedis连接redis服务器
         * 首先要注意:要关闭redis服务器的防火墙
         * 关闭防火墙命令:service iptables stop | systemctl stop firewalld.service
         * 查看防火墙状态:service iptables status | systemctl status firewalld.service
         * 启动防火墙命令:setvice iptables start | systemctl start firewalld.service
         * systemctl enable firewalld.service  //设置开机自动启动
         * systemctl disable firewalld.service   //设置关闭开机制动启动
         */
        Jedis jedis = new Jedis("192.168.112.102", 6379);
        // 连接成功之后就可以操作redis了
        // jedis在线文档:https://tool.oschina.net/apidocs/apidoc?api=jedis-2.1.0
        jedis.set("country", "china");
        jedis.close();
    }

}

测试是否成功设置了一个键值对
在这里插入图片描述

二、模拟请求缓存

	/**
     * 模拟用户请求一个商品时,我们使用Jedis缓存
     */
    @Test
    void userRequest() {
        // 假设用户请求一个商品,传来一个商品的id
        String itemId = "1358907";
        Jedis jedis = new Jedis("192.168.112.102", 6379);
        String key = "item_" + itemId;
        Map<String, String> itemInfo = null;
        // 如果存在这个key,那么我们就从缓存中读取数据
        if (jedis.exists(key)) {
            itemInfo = jedis.hgetAll(key);
            System.out.println("从redis中读取的缓存数据");
        }else { // 不存在我们就从数据库读取数据
            // 假设数据库读取数据如下
            itemInfo = new HashMap<>();
            itemInfo.put("id", itemId);
            itemInfo.put("name", "华为P40Pro");
            itemInfo.put("price", "5999");
            // 将从数据库读取的数据存储到redis中
            jedis.hmset(key, itemInfo);
            System.out.println("从数据库读取的数据,并存入缓存");
        }
        System.out.println(itemInfo);
        jedis.close();
    }

三、自定义数据分片计算

        当数据需要存储在不同的redis服务上时,需要代码端完成数据分片存储的计算逻辑;模拟海量数据的key-value对,自定义对key值进行计算,完成分布式存储;(6379、6380、6381各自有一部分数据)

package com.gykalc.testjedis;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import redis.clients.jedis.Jedis;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootTest
class TestjedisApplicationTests {

    private static List<Jedis> JEDISPOOL = new ArrayList<>();

    static {
        Jedis jedis6379 = new Jedis("192.168.112.102", 6379);
        Jedis jedis6380 = new Jedis("192.168.112.102", 6380);
        Jedis jedis6381 = new Jedis("192.168.112.102", 6381);
        JEDISPOOL.add(jedis6379);
        JEDISPOOL.add(jedis6380);
        JEDISPOOL.add(jedis6381);
    }
    @Test
    void contextLoads() {
    }

    @Test
    void testJedis() {
        /**
         * 使用Jedis连接redis服务器
         * 首先要注意:要关闭redis服务器的防火墙
         * 关闭防火墙命令:service iptables stop | systemctl stop firewalld.service
         * 查看防火墙状态:service iptables status | systemctl status firewalld.service
         * 启动防火墙命令:setvice iptables start | systemctl start firewalld.service
         * systemctl enable firewalld.service  //设置开机自动启动
         * systemctl disable firewalld.service   //设置关闭开机制动启动
         */
        Jedis jedis = new Jedis("192.168.112.102", 6379);
        // 连接成功之后就可以操作redis了
        jedis.set("country", "china");
        jedis.close();
    }

    /**
     * 模拟用户请求一个商品时,我们使用Jedis缓存
     */
    @Test
    void userRequest() {
        // 假设用户请求一个商品,传来一个商品的id
        String itemId = "1358907";
        Jedis jedis = new Jedis("192.168.112.102", 6379);
        String key = "item_" + itemId;
        Map<String, String> itemInfo = null;
        // 如果存在这个key,那么我们就从缓存中读取数据
        if (jedis.exists(key)) {
            itemInfo = jedis.hgetAll(key);
            System.out.println("从redis中读取的缓存数据");
        }else { // 不存在我们就从数据库读取数据
            // 假设数据库读取数据如下
            itemInfo = new HashMap<>();
            itemInfo.put("id", itemId);
            itemInfo.put("name", "华为P40Pro");
            itemInfo.put("price", "5999");
            // 将从数据库读取的数据存储到redis中
            jedis.hmset(key, itemInfo);
            System.out.println("从数据库读取的数据,并存入缓存");
        }
        System.out.println(itemInfo);
        jedis.close();
    }

    /**
     * 自定义数据分片计算
     */
    @Test
    void autoSharedWrite() {
        // 模拟海量数据插入redis
        for (int i = 0; i < 1000; i ++) {
            String key = "item_1803_cs";
            String value = "item_1803_values_";
            key += i;
            value += i;
            int index = hashShared(key);
            JEDISPOOL.get(index).set(key, value);
        }
    }

    @Test
    void autoSharedRead() {
        // 模拟海量数据读取
        for (int i = 0; i < 1000; i ++) {
            String key = "item_1803_cs";
            key += i;
            int index = hashShared(key);
            String s = JEDISPOOL.get(index).get(key);
            System.out.println(s);
        }
    }

    /**
     * 使用hash散列取余算法计算出使用哪个redis服务
     * 返回0 - jedis连接池中连接数 - 1
     * @param key
     * @return
     */
    public int hashShared(String key) {
        int size = getJedisPoolSize();
        // 因为hashCode可能为负数,所以我们&上Integer.MAX_VALUE
        return (key.hashCode() & Integer.MAX_VALUE) % size;
    }

    public static int getJedisPoolSize() {
        return JEDISPOOL.size();
    }
}

四、Jedis本身的数据分片计算

	/**
     * jedis本身实现了数据分片计算
     */
    @Test
    void jedisShard() {
        List<JedisShardInfo> infoList = new ArrayList<>();
        JedisShardInfo info6379 = new JedisShardInfo("192.168.112.102", 6379);
        JedisShardInfo info6380 = new JedisShardInfo("192.168.112.102", 6380);
        JedisShardInfo info6381 = new JedisShardInfo("192.168.112.102", 6381);
        infoList.add(info6379);
        infoList.add(info6380);
        infoList.add(info6381);
        ShardedJedis sJedis = new ShardedJedis(infoList);
        sJedis.set("shardedJedis", "hello world shardedJedis");
    }

五、Jedis的分片连接池

	@Test
    void jedisPool() {
        // 利用节点信息,配置最大连接数、最小连接数、最大空闲数
        // 连接超时、connectTime、socketTime、重连次数等
        List<JedisShardInfo> infoList = new ArrayList<>();
        JedisShardInfo info6379 = new JedisShardInfo("192.168.112.102", 6379);
        JedisShardInfo info6380 = new JedisShardInfo("192.168.112.102", 6380);
        JedisShardInfo info6381 = new JedisShardInfo("192.168.112.102", 6381);
        infoList.add(info6379);
        infoList.add(info6380);
        infoList.add(info6381);
        // 构造一个具有配置条件的配置对象
        GenericObjectPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(8); // 设置最大空闲连接数
        config.setMaxTotal(200); // 设置最大连接数
        // 利用配置对象和连接信息构造连接池
        ShardedJedisPool jedisPool = new ShardedJedisPool(config, infoList);
        ShardedJedis resource = jedisPool.getResource();
        for (int i = 0; i < 100; i++) {
            String key = "item_1803_cs";
            String value = "item_1803_values_";
            key += i;
            value += i;
            resource.set(key, value);
        }
        //可以实现api操作,分布式计算
        jedisPool.returnResource(resource);
    }

六、springboot整合jedis

1、在application.yaml中进行配置

server:
  port: 8080

mycustom:
  maxIdle: 8 # redis最大空闲数
  maxTotal: 200 # redis最大连接数
  redisinfos: # redis信息
    - host: 192.168.112.102
      port: 6379
    - host: 192.168.112.102
      port: 6380
    - host: 192.168.112.102
      port: 6381

2、创建一个配置类,读取yaml中的配置

package com.gykalc.testjedis.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@ConfigurationProperties(prefix = "mycustom")
public class RedisProperties {

    private List<RedisInfo> redisInfos;

    private Integer maxIdle;

    private Integer maxTotal;

    public static class RedisInfo {
        private String host;
        private Integer port;

        public String getHost() {
            return host;
        }

        public void setHost(String host) {
            this.host = host;
        }

        public Integer getPort() {
            return port;
        }

        public void setPort(Integer port) {
            this.port = port;
        }
    }

    public List<RedisInfo> getRedisInfos() {
        return redisInfos;
    }

    public void setRedisInfos(List<RedisInfo> redisInfos) {
        this.redisInfos = redisInfos;
    }

    public Integer getMaxIdle() {
        return maxIdle;
    }

    public void setMaxIdle(Integer maxIdle) {
        this.maxIdle = maxIdle;
    }

    public Integer getMaxTotal() {
        return maxTotal;
    }

    public void setMaxTotal(Integer maxTotal) {
        this.maxTotal = maxTotal;
    }
}

3、创建一个Redis配置类,注入读取到的类

package com.gykalc.testjedis.config;

import com.gykalc.testjedis.properties.RedisProperties;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedisPool;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class RedisConfig {

    /**
     * 获取到redis配置类
     */
    @Autowired
    private RedisProperties redisProperties;

    /**
     * 使用Bean注解,将连接池对象交给spring进行管理
     * Scope注解singleton:单例
     * @return
     */
    @Bean
    @Scope("singleton")
    public ShardedJedisPool shardedJedisPool() {
        List<JedisShardInfo> infoList = new ArrayList<>();
        List<RedisProperties.RedisInfo> redisInfos = redisProperties.getRedisInfos();
        for (RedisProperties.RedisInfo info: redisInfos) {
            JedisShardInfo jedisShardInfo = new JedisShardInfo(info.getHost(), info.getPort());
            infoList.add(jedisShardInfo);
        }
        // 构造一个具有配置条件的配置对象
        GenericObjectPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(redisProperties.getMaxIdle()); // 设置最大空闲连接数
        config.setMaxTotal(redisProperties.getMaxTotal()); // 设置最大连接数
        // 利用配置对象和连接信息构造连接池
        return new ShardedJedisPool(config, infoList);
    }
}

4、Controller

package com.gykalc.testjedis.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

@RestController
@RequestMapping("/test")
public class JedisController {

    @Autowired
    private ShardedJedisPool shardedJedisPool;

    @RequestMapping(value = "/getData")
    public String getData(String id) {
        String key = "shardedJedisPool_" + id;
        ShardedJedis resource = shardedJedisPool.getResource();
        String result = "";
        if (resource.exists(key)) {
            System.out.println("从redis缓存中获取数据");
            result = resource.get(key);
        }else {
            System.out.println("从数据库中获取数据");
            result = "{id: \"" + id + "\", name: \"gyk\", age: \"24\"}";
            // 存入缓存中
            resource.set(key, result);
        }
        // 关闭资源
        shardedJedisPool.returnResource(resource);
        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值