缓存之Redis

命令参考文档
官网地址
菜鸟教程

一。下载安装

windows: https://github.com/microsoftarchive/redis/releases
Linux:见官网


可视化工具Redis Desktop Manager:https://github.com/uglide/RedisDesktopManager/releases/tag/0.9.3

在这里插入图片描述

二。启动服务端与关闭服务端

启动服务端
	windows:
		打开一个 cmd 窗口,进入D盘目录:    `cd D:\Redis Windows x64\Redis-x64-3.0.504` 
		运行启动命令  `redis-server.exe redis.windows.conf`
	
	linux:先make编译src文件夹里面出现redis-server,然后cd src目录,命令: src/redis-server redis.conf	
		这时候redis服务就启动了,可以用桌面客户端连接。如果桌面客户端无法连接如下操作:
				   1.修改redis.conf配置文件中的bind改为0.0.0.0或者注释掉
	               2.设置为非保护模式 protected-mode设置为no(默认yes)
	               3.阿里云轻量应用服务器防火墙添加6379协议端口
	               4.配置文件启动redis   src/redis-server redis.conf	

	验证redis是否启动成功:
	   方法1:redis连接工具连接
	   方法2(linux): ps -ef | grep redis

关闭服务端:
	windows:
		直接关闭CMD窗口
	linux:
		src/redis-cli shutdown             

在这里插入图片描述

三。客户端登录

另启一个 cmd 窗口,原来的不要关闭,不然就无法访问服务端 也要切换到 redis 目录下运行

windows
	 redis-cli.exe    -h 127.0.0.1  -p 6379              //登录
	 redis-cli        -h 127.0.0.1  -p 6379  shutdown     //退出登录

linux
	src/redis-cli -h 127.0.0.1  -p 6379    //客户端登录
	 ctrl + c                              //客户端退出登录

四.客户端登录的命令

redis-cli.exe    -h 127.0.0.1  -p 6379              //登录
redis-cli        -h 127.0.0.1  -p 6379  shutdown     //退出登录
kill -9    //粗暴杀死redis进程
set myKey abc   //设置值 (区分大小写)
get myKey       //取值(区分大小写)
keys *    //查看所有key
keys *e*  //查看所有匹配的key

Redis NOAUTH Authentication required的解决办法:
  没有权限,输入   auth 密码    即可

五。Redis持久化的两种机制 RDB 和 AOF

RDB持久化配置:安装目录下的 redis.windows.conf 文件

save 900 1
save 300 10     //每隔300s有10个key发生变化就生成一个新的快照
save 60 10000  

在这里插入图片描述

六 java代码连接redis

单节点架构或者主从架构
1、Jedis方式连接单节点架构
1.pom引入jedis依赖包
	    <!--jedis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.8.0</version>
        </dependency>

2.使用
	@GetMapping("/jedis")
    public void testJedis() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(20);
        jedisPoolConfig.setMaxIdle(10);
        jedisPoolConfig.setMinIdle(5);

        //连接池
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, "192.168.61.148", 6379, 3000, null);
        Jedis jedis = null;
        try {
            //从redis连接池里拿出一个jedis
            jedis = jedisPool.getResource();


            //1.五种数据结构基本操作,客户端api怎么用,这边就怎么用
            //string
            System.out.println(jedis.set("single", "zhuge"));
            System.out.println(jedis.get("single"));
            //hash
            Map map = new HashMap();
            map.put("name", "zhangsan");
            map.put("age", "5");
            System.out.println(jedis.hmset("hashkey2", map));
            System.out.println(jedis.hgetAll("hashkey2"));

            //2.管道操作实例(多条命令一次性发送进行执行 管道不具有原子性)
            Pipeline pipelined = jedis.pipelined();
            for (int i = 1; i <= 10; i++) {
                pipelined.set("zhuge" + i, "zhuge");
            }
            List<Object> result = pipelined.syncAndReturnAll();
            System.out.println(result);

            //3.lua脚本实例
            jedis.set("product_stock_10016", "15");
            String script = " local count = redis.call('get',KEYS[1] ) " +
                    " redis.call('set',KEYS[1], count-ARGV[1]) ";
            Object luaResult = jedis.eval(script, Arrays.asList("product_stock_10016"), Arrays.asList("10"));
            System.out.println(luaResult);


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ///注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。
            if (jedis != null) {
                jedis.close();
            }
        }
    }
2.Spring封装的RedisTemplate方式连接单节点架构
//redis的使用 亲测有效
1.依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2.配置文件
# redis数据库(默认为0)
spring:
  redis:
      database: 6
      host: localhost         # Redis服务器地址
      port: 6379              # Redis服务器连接端口
      password:
      pool.max-active: 8      #连接池最大连接数
      pool.max-wait: -1       #连接池最大阻塞等待时间
      pool.max-idle: 8        #连接池中的最大空闲连接
      pool.min-idle: 0        #连接池中的最小空闲连接
      timeout: 5000           #连接超时时间(毫秒)

3.声明
  @Autowired
  private RedisTemplate redisTemplate;


4.使用(具体使用见下面截图)
添加值:redisTemplate.opsForValue().set(key, validCode, DEFAULT_VALID_CODE_TIME_OUT, TimeUnit.MINUTES);
移除值:redisTemplate.delete(key);

redisTemplate.opsForValue();  //操作字符串
redisTemplate.opsForHash();   //操作hash
redisTemplate.opsForList();   //操作list
redisTemplate.opsForSet();   //操作set
redisTemplate.opsForZSet();   //操作有序set
在这里插入图片描述

哨兵架构(注意查看防火墙端口是否允许 26379 26380 26381)
1、Jedis方式连接哨兵架构
 @GetMapping("/jedis")
    public void testJedis() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(20);
        jedisPoolConfig.setMaxIdle(10);
        jedisPoolConfig.setMinIdle(5);

        String masterName = "mymaster"; //和sentinel-26379.conf配置文件里面sentinel monitor mymaster 192.168.0.60 6379 2
        Set<String> sentinels = new HashSet<>();
        sentinels.add(new HostAndPort("192.168.61.148", 26379).toString());
        sentinels.add(new HostAndPort("192.168.61.148", 26380).toString());
        sentinels.add(new HostAndPort("192.168.61.148", 26381).toString());
        //连接池
        JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName, sentinels, jedisPoolConfig, 3000, null);
        Jedis jedis = null;
        try {
            //从redis连接池里拿出一个jedis
            jedis = jedisSentinelPool.getResource();
            jedis.set("aaaakey","aaaavalue");
            System.out.println(jedis.get("aaaakey"));

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ///注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。
            if (jedis != null) {
                jedis.close();
            }
        }
    }
2.Spring封装的RedisTemplate方式连接哨兵架构
配置文件
spring:
  redis:
    database: 7
    timeout: 5000           #连接超时时间(毫秒)
    sentinel:               #哨兵模式
      master: mymaster      #主服务器哨兵名称  和sentinel-26379.conf配置文件里面sentinel monitor mymaster 192.168.0.60 6379 2
      nodes: 192.168.61.148:26379,192.168.61.148:26380,192.168.61.148:26381
    lettuce:
      pool:
        max-idle: 50
        min-idle: 10
        max-active: 100
        max-wait: 1000

七。缓存穿透、缓存雪崩和缓存击穿

参考说明

缓存穿透:指查询一个数据库一定不存在的数据 (传入id为-1,缓存不存在,查数据库,数据库也不存在,这样一直都查询的数据库)
解决办法:数据库也不存在时将id=-1和Null存入缓存,过期设置短一点
布隆过滤器解决缓存穿透

缓存雪崩:缓存集中过期失效 (比如双十一晚上8点迎来一波抢购存入缓存,到了九点全部过期)
解决办法:根据商品的分类设置不同的过期实践

缓存击穿:是指一个key非常热点,在不停的扛着大并发,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库
解决办法:让这个key永不过期
或者互斥锁的办法(此方法只允许一个线程重建缓存, 其他线程等待重建缓存的线程执行完, 重新从缓存获取数据即可)

public void String get(String key) {
	// 从Redis中获取数据
	String value = redis.get(key);
	if (value == null) {
		 String tempKey = "hot:key:" + key;
		 // 只允许第一个线程重建缓存(即从数据库读取数据,其他线程都重新走一遍这个方法)
		 if (redis.set(tempKey, "1", "ex 180", "nx")) {
		 	 // 从数据源获取数据并设置到redis
		 	 value = db.get(key);
		 	 redis.setex(key, timeout, value);
		 	 // 删除临时key
		 	 edis.delete(tempKey );
		 }else{
		 	// 其他线程休息50毫秒后重试
		 	Thread.sleep(50);
		 	get(key);
		 }
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

飘然生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值