redis实例基础

假如你是一个java用户,请定义一个用户信息结构体,然后使用fastjson对用户信息对象进行序列化,然后将序列化的对象用jedis存入redis中。
接着用jedis将刚刚存入的用户信息从redis中取出,再经过fastjson反序列化后输出到控制台上!

  1. 先导入环境依赖。
<dependency>
     <groupId>redis.clients</groupId>
     <artifactId>jedis</artifactId>
     <version>2.8.0</version>
 </dependency>
 <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>fastjson</artifactId>
     <version>1.2.75</version>
 </dependency>
  1. 定义一个User类。
public class User {
    private String name;
    private Integer age;
    private String sex;
    //以下省略构造函数,getset方法,以及toString方法
}
  1. 在建立连接redis的jedis环境⭐
public class JedisConfig{
 state{
 JedisPoolConfig config=new JedisPoolConfig();
 config.setMaxTotal(100);
 config.setMaxIdle(50);
 config.setMaxWaitMillis(3000);
        config.setTestOnBorrow(true);
        config.setTestOnReturn(true);
        JedisShardInfo jedisShardInfo = new JedisShardInfo("120.55.36.148", 6379);
        jedisShardInfo.setPassword("123456");
        List<JedisShardInfo> list = new LinkedList<JedisShardInfo>();
        list.add(jedisShardInfo);
        pool = new ShardedJedisPool(config,list);
 }
}
  1. 最后在该类中创建一个main方法实现业务。⭐
public static void main(String[] args) {
        User user = new User();
        user.setName("chenhang");
        user.setAge(1);
        user.setSex("man");
        //序列化后存入redis
        String s = JSON.toJSONString(user);
        ShardedJedis jedis = pool.getResource();
        jedis.set(user.getName(),s);
        //反序列化
        String user2 = jedis.get(user.getName());
        User user1 = JSON.parseObject(user2, User.class);
        System.out.println(user1.toString());
    }

Redis下载和安装(linux)

# 联网情况下,执行如下命令进行下载
wget http://download.redis.io/releases/redis-6.0.10.tar.gz
# 一般都在usr下创建一个目录,方便管理
mkdir /usr/local/src/redis
# 切换到下载的目录,进行解压缩
tar -zxvf redis-4.0.2.tar.gz
# 将解压缩的redis移到到/usr/local/src/redis
mv redis-6.0.10 /usr/local/src/redis
# 进入文件夹内,进行编译并安装
make
make install
# 启动redis
redis-server
# 连接redis
redis-cli

SpringBoot整合Redis⭐

  • 配置Redis的redis.conf
## 确保客户端可以访问到redis
    bind 0.0.0.0
    protected-mode no
    daemonize yes
  • SpringBoot中关于redis的配置
# redis配置
Spring:
  redis:
    host: Redis所在的ip地址
    port: 端口号
    database: 选择的数据库
  • 具体操作如下:
@SpringBootTest
class Boot06RedisApplicationTests {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    // 操作stringRedisTemplate字符串
    void test1() {
        //对于key、value都是String时,可以使用StringRedisTemplate
        stringRedisTemplate.opsForValue().set("age", "32");
        stringRedisTemplate.opsForValue().set("name", "李哥");
        stringRedisTemplate.opsForList().leftPushAll("lists", "java", "python", "golang", "c++");
        stringRedisTemplate.opsForHash().put("mainKey", "secondKey", "value");
        stringRedisTemplate.opsForSet().add("city", "beijing", "xian", "shanghai");
        stringRedisTemplate.opsForZSet().add("score", "lige", 100);
    }
	@Test
    // 操作redisTemplate字符串
    void test2() {
 // 将key和hashKey的序列化方式设置位String,防止乱码,默认是JdkSerializationRedisSerializer
        // 对于key、value存在对象时,可以使用RedisTemplate
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.opsForValue().set("user", new User(1, "lige", "陕西省"));
        // 其余操作都类似于StringRedisTemplate
        redisTemplate.opsForValue().set("age", "32");
        redisTemplate.opsForList().leftPushAll("lists", "java", "python", "golang", "c++");
        redisTemplate.opsForHash().put("mainKey", "secondKey", "value");
        redisTemplate.opsForSet().add("city", "beijing", "xian", "shanghai");
        redisTemplate.opsForZSet().add("score", "lige", 100);
    }
	@Test
    // 对同一个key多次操作时,可以使用boundXxxOps绑定一个key
    void test3() {
        BoundValueOperations name = redisTemplate.boundValueOps("name");
        name.set("changed lige");
        name.append("zhenshuai");
    }
}

实战应用

  • 利用mybatis自身本地缓存结合redis实现分布式缓存
    mybatis中应用级缓存(二级缓存) SqlSession级别缓存 所有会话共享
  • 开启二级缓存
  • xxxMapper.xml中加入标签
  • cache标签底层默认使用org.apache.ibatis.cache.impl.PerpetualCache
  • 将缓存的type属性更改自定义RedisCache
  • 通过mybatis默认cache源码可知,可以使用自定义cache类实现Cache接口,并对其方法进行实现

自定义Cache类:

@SuppressWarnings("all")
public class RedisCache implements Cache {
    
    private RedisTemplate redisTemplate;
	// id:对应mapper的namespace="com.atlige.boot.mapper.UserMapper"
    private final String id;

    public RedisCache(String id){
        this.id = id;
    }
    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public void putObject(Object key, Object value) {
        // 使用redis里的hash类型作为缓存存储模型,key -- id, hashkey--当前方法key, value -- value
        getRedisTemplate(redisTemplate).opsForHash().put(id.toString(), getKeyToMD5(key.toString()), value);

    }

    @Override
    public Object getObject(Object key) {
        // 根据key从redis的hash类型中获取数据
        return getRedisTemplate(redisTemplate).opsForHash().get(id.toString(), getKeyToMD5(key.toString()));
    }

    /**
     * 根据指定的key删除缓存
     * @param key
     * @return
     */
    @Override
    public Object removeObject(Object key) {
        return null;
    }

    /**
     * 清空缓存
     */
    @Override
    public void clear() {
        // 清空namespace
        getRedisTemplate(redisTemplate).delete(id.toString());
    }

    /**
     * 计算缓存数量
     * @return 缓存数量
     */
    @Override
    public int getSize() {
        // 获取hash中的key、value的数量
        return getRedisTemplate(redisTemplate).opsForHash().size(id.toString()).intValue();
    }
	
    public RedisTemplate getRedisTemplate(RedisTemplate redisTemplate){
        if (redisTemplate == null){
            redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");
        }
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }


    private String getKeyToMD5(String key){
        return DigestUtils.md5DigestAsHex(key.getBytes());
    }
}

注意点:

  • 自定义的RedisCache不是由spring的beanFactory实例化的,而所以不能使用自动注入 @Autowired
  • 编写一个可以获取beanFactory的工具类ApplicationContextUtils来获取
/**
 * @author Jeremy Li
 * @data 2021/1/22 - 22:39
 * 用来获取springboot创建好的工厂
 */
@Component
public class ApplicationContextUtils implements ApplicationContextAware {
    //保留下来的工厂
    @Autowired
    private static ApplicationContext applicationContext;

    // 将创建好的工厂以参数的形式传递给这个类
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextUtils.applicationContext = applicationContext;
    }

    // 提供在工厂中获取对象的方法
    public static <T> T getBean(String beanName, Class<T> requiredType){
        return (T) applicationContext.getBean(beanName);
    }

}

Redis主从复制架构

主从复制架构仅仅用来解决数据的冗余备份,从节点仅仅用来同步数据:

### master 7001 
    bind 0.0.0.0
    port:7001
    daemonize yes
    protected-mode no

### slave1 7002 
    bind 0.0.0.0
    port:7002
    daemonize yes
    protected-mode no
    replicaof 192.168.152.128 7001

### slave2 7003
    bind 0.0.0.0
    port:7003
    daemonize yes
    protected-mode no
    replicaof 192.168.152.128 7001

Redis哨兵机制

Sentinel系统 在被监视的主服务器进行下线状态时,自动将从服务器升级为新的主服务器。

  1. 创建一个sentinel文件夹并创建一个sentinel.conf
sentinel monitor [主从架构名称:mymaster] [主服务器的ip:192.168.152.128] [端口号:7003] [设置哨兵的数量:1]
  1. 使用redis/bin/下的redis-sentinel 加载配置文件并启动哨兵即可在这里插入图片描述

Redis集群

在这里插入图片描述
相关的linux命令:

# 对每一个redis.conf进行修改
bind 0.0.0.0
port xxxx
daemonize yes
pidfile redis_xxxx.pid
logfile redis_xxxx.log
appendonly yes
cluster-enabled yes
cluster-config-file nodes-xxxx.conf
cluster-node-timeout 5000
cluster-slave-validity-factor 10
cluster-migration-barrier 1
cluster-require-full-coverage yes

# 构建集群
redis-cli --cluster create 192.168.152.128:8000 192.168.152.128:8001 192.168.152.128:8002 192.168.152.128:8003 192.168.152.128:8004 192.168.152.128:8005 --cluster-replicas 1

# 查看集群状态
redis-cli --cluster check 192.168.152.128:8001

Redis分布式Session管理

利用spring提供的session管理解决方案,将一个应用session交给redis存储,整个应用中所有的session的请求都会去redis中获取相应的session数据
在这里插入图片描述

  • 引入依赖
<!--springboot-redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring-data-redis session管理-->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>
  • 编写配置类
@Configuration
@EnableRedisHttpSession // 将整个应用中使用session的数据全部交给redis处理
public class RedisSessionManager {
}
  • 测试
@Controller
@RequestMapping("test")
public class TestController {

    @RequestMapping("test")
    public void test(HttpServletRequest request, HttpServletResponse response) throws IOException {
        List<String> list = (List<String>) request.getSession().getAttribute("list");
        if (list == null){
            list = new ArrayList<>();
//            request.getSession().setAttribute("list", list);
        }

        list.add("xxxx");
        request.getSession().setAttribute("list", list); // 每次session变化都要同步session

        response.getWriter().write("size: " + list.size() + "\n");

        response.getWriter().write("sessionId: " + request.getSession().getId());

    }

    @RequestMapping("logout")
    public void testLogout(HttpServletRequest request){
        request.getSession().invalidate();

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gary jie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值