分布式文件存储与数据缓存 Redis高可用分布式实践(上)(四)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 分布式文件存储与数据缓存 Redis高可用分布式实践(上)(四)

四、Redis可视化工具:Redis Destktop Manager(带时间)

4.1 下载Redis Desktop Manager

官网RESP.app (formerly Redis Desktop Manager) - GUI for Redis ® available on Windows, macOS, iPad and Linux.

或者使用文章配套的安装包。

4.2 连接Redis服务

关闭防火墙

systemctl stop firewalld.service

在redis配置文件中关闭保护模式

protected-mode no

开启远程访问

redis默认只允许本地访问,要使redis可以远程访问可以修改redis.conf。

注释掉bind 127.0.0.1 可以使所有的ip访问redi

重启redis服务

#查看redis端口
lsof -i:6379
#杀死redis进程
kill -9 PID
#重启reids服务
[root@localhost src]# ./redis-server ../redis.conf

- 出现16个库代表连接成功

五、Java整合Redis

5.1 Jedis操作

什么是Jedis

Jedis是Redis官方推荐的Java连接开发工具。

创建maven工程引入maven依赖

<dependency>
   <groupId>redis.clients</groupId>
   <artifactId>jedis</artifactId>
   <version>3.6.0</version>
</dependency>
<dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.12</version>
   <scope>test</scope>
</dependency>

Jedis连接到redis并操作redis

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import java.util.List;
import java.util.Set;
public class TestJedis {
    Jedis jedis;
    //1.创建连接实例
    @Before
    public void init(){
        /*
         * 第一个参数:redis服务的ip
         * 第二个参数:redis服务的端口
         */
        jedis = new Jedis("192.168.66.100",6379);
    }
    //2.Jedis-API:String
    @Test
    public void stringTest(){
        //设置一个键值对
        jedis.set("k1","v1");
        //通过key获取value
        String k1 = jedis.get("k1");
        System.out.println(k1);
        //对某一个key自增
        Long ires = jedis.incr("k2");
    }
    //2.Jedis-API:Keys
    @Test
    public void keysTest(){
        //返回所有的key
        Set<String> keys = jedis.keys("*");
        //返回该key剩余过期时间
        Long time = jedis.ttl("k1");
    }
    //3.Jedis-API:List
    @Test
    public void listTest(){
        //向list中添加数据
        jedis.lpush("list1","v1","v2","v3");
        //返回list全部数据
        List<String> list = jedis.lrange("list1",0,-1 );
    }
    //4.Jedis-API:Set
    @Test
    public void setTest(){
        //向set中添加数据
        jedis.sadd("set1" ,"v1","v2","v2","v3");
        //查看该集合中有多少个元素
        jedis.smembers("set1");
    }
    //4.Jedis-API:Hash
    @Test
    public void hashTest(){
        //设置一个hash
        jedis.hset("user","age","25");
        //获取该key的所有value
        jedis.hvals("user");
    }
    //4.Jedis-API:Zset
    @Test
    public void zsetTest(){
        //向zset中添加一条数据
        jedis.zadd("zset1",100,"java");
       //获取所有的值
        jedis.zrange("zset1",0,-1);
    }
    //5.Jedis-API:Bitmaps
    @Test
    public void bitmapsTest(){
        //将b1偏移量为0的位设置为1
        jedis.setbit("b1",0, "1");
        //获取b1偏移量为0的位
        jedis.getbit("b1",0);
    }
    //6.Jedis-API:Geospatia
    @Test
    public void geospatiaTest(){
        //添加一条地理信息数据
        jedis.geoadd("chinacity",130,110,"beijing");
    }
    //7.Jedis-API:Hyperloglog
    @Test
    public void hyperloglogTest(){
        //将所有元素参数添加到 Hyperloglog 数据结构中。
        jedis.pfadd("book","c++","java","php");
    }
    @After
    public void close(){
        //1.关闭连接实例
        jedis.close();
    }
}

注意:

其实jedis中的方法基本同redis命令一致。

5.2 Spring-Data-Reids

简介

Spring-Data-Redis是spring大家族的一部分,通过简单的配置访问Redis服务,对Reids底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate提供了Redis各种操作、异常处理及序列化,支持发布订阅。

RedisTemplate介绍

Spring封装了RedisTemplate对象来进行对Redis的各种操作,它支持所有的Redis原生的api。

org.springframework.data.redis.core
Class RedisTemplate<K,V>

注意:

  • K:模板中的Redis key的类型,模板中的Redis key的类型(通常为String)如:RedisTemplate<String, Object>。
  • V:模板中的Redis value的类型

RedisTemplate中定义了对5种数据结构操作

redisTemplate.opsForValue();//操作字符串

redisTemplate.opsForHash();//操作hash

redisTemplate.opsForList();//操作list

redisTemplate.opsForSet();//操作set

redisTemplate.opsForZSet();//操作有序set

StringRedisTemplate与RedisTemplate

  • 两者的关系是StringRedisTemplate继承RedisTemplate。
  • 两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。
  • SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。
    StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。
    RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。

创建springboot项目并添加依赖

<dependencies>
     <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
     </dependency>
     <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <optional>true</optional>
     </dependency>
     <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>io.projectreactor</groupId>
       <artifactId>reactor-test</artifactId>
       <scope>test</scope>
     </dependency>
   </dependencies>

在application.properties中配置

#Redis服务器连接地址
spring.redis.host=192.168.56.31
#Redis服务器连接端口
spring.redis.port=6379
#连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.pool.max-idle=8
#连接池中的最小空闲连接
spring.redis.pool.min-idle=0
#连接超时时间(毫秒)
spring.redis.timeout=30000

自定义序列化

RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。该配置是将其序列化的方式改为json序列化。

package com.zj.redis.conf;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
 * 自定义序列化方式
 */
@Configuration
public class RedisConfig {
   @Bean
   public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
     RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
     redisTemplate.setKeySerializer(new StringRedisSerializer());
     redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
     redisTemplate.setHashKeySerializer(new StringRedisSerializer());
     redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
     redisTemplate.setConnectionFactory(redisConnectionFactory);
     return redisTemplate;
   }
}

没有配置自定义序列化之前:

配置自定义序列化之后:注意此时是json类型

package com.zj.redis;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.Resource;
import java.util.Set;
@SpringBootTest
class RedisApplicationTests {
    @Resource
    private RedisTemplate redisTemplate;
    /*
    * 使用RedisTemplate实例操作redis
    * */
    //操作字符串
    @Test
    void contextLoads() {
        //添加数据(key是name,value是zhangsan)
        redisTemplate.opsForValue().set("name", "zhangsan");
        //获取数据
        System.out.println(redisTemplate.opsForValue().get("name"));
    }
    //操作list
    @Test
    void contextLoads2(){
        //添加数据
        redisTemplate.opsForList().rightPush("age",23);
        redisTemplate.opsForList().rightPush("age",24);
        redisTemplate.opsForList().rightPush("age",25);
        //获取最右边的数据
        System.out.println(redisTemplate.opsForList().rightPop("age"));
    }
    //操作Hash
    @Test
    void contextLoads3(){
        //添加
        redisTemplate.opsForHash().put("user","name","张三");
        redisTemplate.opsForHash().put("user","age",12);
        redisTemplate.opsForHash().put("user","address","临沂市");
        //获取
        System.out.println(redisTemplate.opsForHash().get("user", "name"));
    }
    //操作set
    @Test
    void contextLoads4(){
        //添加
        redisTemplate.opsForSet().add("verse","两岸猿声啼不住,轻舟已过万重山。","莫愁前路无知己,天下谁人不识君。",
                                                   "大鹏一日同风起,扶摇直上九万里。");
        //获取
        Set verse = redisTemplate.opsForSet().members("verse");
        System.out.println(verse);
        //获取元素长度
        System.out.println(redisTemplate.opsForSet().size("verse"));
    }
    //操作ZSet
    @Test
    void contextLoads5(){
        //添加元素
        redisTemplate.opsForZSet().add("programmer","Dennis MacAlistair Ritchie",100);
        redisTemplate.opsForZSet().add("programmer","Linus Benedict Torvalds",99);
        redisTemplate.opsForZSet().add("programmer","Bjarne Stroustrup ",98);
        redisTemplate.opsForZSet().add("programmer","Brain Wlison Kernighan",97);
        //获取元素
        Set programmer = redisTemplate.opsForZSet().range("programmer", 0, -1);
        System.out.println(programmer);
        //通过分数获取元素
        Set programmer1 = redisTemplate.opsForZSet().rangeByScore("programmer", 90, 100);
        System.out.println(programmer1);
    }
}


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4天前
|
消息中间件 缓存 NoSQL
Redis经典问题:缓存雪崩
本文介绍了Redis缓存雪崩问题及其解决方案。缓存雪崩是指大量缓存同一时间失效,导致请求涌入数据库,可能造成系统崩溃。解决方法包括:1) 使用Redis主从复制和哨兵机制提高高可用性;2) 结合本地ehcache缓存和Hystrix限流降级策略;3) 设置随机过期时间避免同一时刻大量缓存失效;4) 使用缓存标记策略,在标记失效时更新数据缓存;5) 实施多级缓存策略,如一级缓存失效时由二级缓存更新;6) 通过第三方插件如RocketMQ自动更新缓存。这些策略有助于保障系统的稳定运行。
129 1
|
7天前
|
存储 消息中间件 缓存
Redis缓存技术详解
【5月更文挑战第6天】Redis是一款高性能内存数据结构存储系统,常用于缓存、消息队列、分布式锁等场景。其特点包括速度快(全内存存储)、丰富数据类型、持久化、发布/订阅、主从复制和分布式锁。优化策略包括选择合适数据类型、设置过期时间、使用Pipeline、开启持久化、监控调优及使用集群。通过这些手段,Redis能为系统提供高效稳定的服务。
|
13天前
|
存储 缓存 NoSQL
【Go语言专栏】Go语言中的Redis操作与缓存应用
【4月更文挑战第30天】本文探讨了在Go语言中使用Redis进行操作和缓存应用的方法。文章介绍了Redis作为高性能键值存储系统,用于提升应用性能。推荐使用`go-redis/redis`库,示例代码展示了连接、设置、获取和删除键值对的基本操作。文章还详细阐述了缓存应用的步骤及常见缓存策略,包括缓存穿透、缓存击穿和缓存雪崩的解决方案。利用Redis和合适策略可有效优化应用性能。
|
2天前
|
缓存 NoSQL 安全
Redis经典问题:缓存击穿
本文探讨了高并发系统中Redis缓存击穿的问题及其解决方案。缓存击穿指大量请求同一未缓存数据,导致数据库压力过大。为解决此问题,可以采取以下策略:1) 热点数据永不过期,启动时加载并定期异步刷新;2) 写操作加互斥锁,保证并发安全并设置查询失败返回默认值;3) 预期热点数据直接加缓存,系统启动时加载并设定合理过期时间;4) 手动操作热点数据上下线,通过界面控制缓存刷新。这些方法能有效增强系统稳定性和响应速度。
51 0
|
2天前
|
缓存 NoSQL 应用服务中间件
Redis多级缓存
Redis多级缓存
8 0
|
2天前
|
缓存 NoSQL 关系型数据库
Redis 缓存 一致性
Redis 缓存 一致性
6 0
|
3天前
|
缓存 监控 NoSQL
Redis经典问题:缓存穿透
本文介绍了缓存穿透问题在分布式系统和缓存应用中的严重性,当请求的数据在缓存和数据库都不存在时,可能导致数据库崩溃。为解决此问题,提出了五种策略:接口层增加校验、缓存空值、使用布隆过滤器、数据库查询优化和加强监控报警机制。通过这些方法,可以有效缓解缓存穿透对系统稳定性的影响。
78 3
|
4天前
|
缓存 NoSQL 搜索推荐
Redis缓存雪崩穿透等解决方案
本文讨论了缓存使用中可能出现的问题及其解决方案。首先,缓存穿透是指查询数据库中不存在的数据,导致请求频繁到达数据库。解决方法包括数据校验、缓存空值和使用BloomFilter。其次,缓存击穿是大量请求同一失效缓存项,可采取监控、限流或加锁策略。再者,缓存雪崩是大量缓存同时失效,引发数据库压力。应对措施是避免同一失效时间,分散缓存过期。接着,文章介绍了Spring Boot中Redis缓存的配置,包括缓存null值以防止穿透,并展示了自定义缓存过期时间的实现,以避免雪崩效应。最后,提供了在`application.yml`中配置不同缓存项的个性化过期时间的方法。
|
6天前
|
存储 大数据 Apache
深入理解ZooKeeper:分布式协调服务的核心与实践
【5月更文挑战第7天】ZooKeeper是Apache的分布式协调服务,确保大规模分布式系统中的数据一致性与高可用性。其特点包括强一致性、高可用性、可靠性、顺序性和实时性。使用ZooKeeper涉及安装配置、启动服务、客户端连接及执行操作。实际应用中,面临性能瓶颈、不可伸缩性和单点故障等问题,可通过水平扩展、集成其他服务和多集群备份来解决。理解ZooKeeper原理和实践,有助于构建高效分布式系统。
|
8天前
|
缓存 监控 NoSQL
Redis缓存雪崩及应对策略
缓存雪崩是分布式系统中一个常见但危险的问题,可以通过合理的缓存策略和系统设计来降低发生的概率。采用多层次的缓存架构、缓存预热、合理的缓存失效时间等措施,都可以有效应对缓存雪崩,提高系统的稳定性和性能。在实际应用中,及时发现并解决潜在的缓存雪崩问题,是保障系统可用性的关键一环。
39 14