微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Redis

 

问题描述@H_502_5@

spring开发项目的时候 每次访问时 都会查询一次数据库 对于那些不经常修改的数据 每次都查询数据库 性能差 不够优雅 @H_502_5@

1. 缓存

缓存的功能 就是提高性能 减少与数据库的交互 @H_502_5@

1.1. 缓存的思想

核心流程@H_502_5@

1.2. 缓存的弊端

做到数据的实时性 比较麻烦 需要在增删改的时候 清空数据 @H_502_5@

1.3. 使用Map集合作为缓存

2. 什么是Nosql数据库

  Nosql,叫非关系型数据库,它的全名Not only sql。 是针对关系型数据库来说的 @H_502_5@

3. Nosql数据的分类

@H_502_5@@H_502_5@

4. Nosql的好处

为了解决高并发、高可用、高可扩展,大数据存储等一系列问题而产生的数据库解决方案@H_502_5@

5. Nosql和关系型数据库区别

  • 区别一@H_502_5@

    • 关系型数据库是需要依赖数据库的关系的 比如说主外键 数据在硬盘上@H_502_5@

    • 非关系型数据库依赖特殊结果 比如redis是key-value的数据格式 在内存中 可以持久化 @H_502_5@

  • 区别二@H_502_5@

  • 区别三: @H_502_5@

    • 关系型数据库: 操作的是硬盘 效率低 安全性稍微高 @H_502_5@

    • 非关系型数据库(redis) 操作的是内存 效率高 但是不安全 数据可能丢失 @H_502_5@

6. Redis

6.1. 什么是redis

Redis是使用c语言开发的一个性能键值Nosql数据库。Redis可以通过一些键值类型来存储数据@H_502_5@

6.2. Redis的特点

  • 性能,持久存储,适应高并发的应用场景。@H_502_5@

  • 相比许多键值数据存储,Redis拥有一套较为丰富的数据类型@H_502_5@

  • Redis数据库完全在内存中,使用磁盘仅用于持久性。@H_502_5@

  • Redis可以将数据复制到任意数量的从服务器。@H_502_5@

6.3. Redis的优势

  • 异常快速:Redis的速度非常快,支持丰富的数据类型。读的速度是110000次/s,写的速度是81000次/s 。@H_502_5@

  • 操作都是原子性:所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。@H_502_5@

6.4. Redis的作用

  • 缓存@H_502_5@

  • 存临时数据 @H_502_5@

6.5. Redis的下载

github上下载 @H_502_5@

@H_502_5@@H_502_5@

6.6. Redis文件介绍

@H_502_5@@H_502_5@

6.7. Redis的启动

@H_502_5@@H_502_5@

运行成功页面@H_502_5@

@H_502_5@@H_502_5@

6.8. 客户端连接

@H_502_5@@H_502_5@

 @H_502_5@

 

@H_502_5@@H_502_5@

6.9. Redis的Value的取值

注意: Redis存的key-value 但是key只能是字符串 value的取值有如下几个类型@H_502_5@

  • 字符串(string) @H_502_5@

  • 散列(hash)@H_502_5@

  • 列表(list)@H_502_5@

  • 集合(set)@H_502_5@

  • 有序集合(sortedSet)@H_502_5@

@H_502_5@@H_502_5@

 @H_502_5@

 @H_502_5@

6.10. List&Set&sortSet区别

  • list类型: 有顺序 可以重复 @H_502_5@

  • set类型:没有顺序 不能重复@H_502_5@

  • sortedSet: 有顺序 不能重复 @H_502_5@

6.11. String类型的操作

6.11.1. 存取单个数据

  • 存值@H_502_5@

    set key value @H_502_5@

  • 取值@H_502_5@

    get key @H_502_5@

@H_502_5@@H_502_5@

6.11.2. 存取多个数据

  • 存值@H_502_5@

    mset key value key value ....@H_502_5@

  • 取值@H_502_5@

    mget key1 key2 @H_502_5@

    @H_502_5@@H_502_5@

6.11.3. 删除数据

del key @H_502_5@

@H_502_5@@H_502_5@

6.12. hash类型操作

6.12.1. 存取单个属性

  • 存值@H_502_5@

    hset key field fieldValue@H_502_5@

  • 取值@H_502_5@

    hget key field @H_502_5@

    @H_502_5@@H_502_5@

6.12.2. 存取多个属性

  • 存值@H_502_5@

    hmset key field1 field1Value field2 fieldValue2@H_502_5@

  • 取值 @H_502_5@

    hmget key field1 field2 @H_502_5@

    @H_502_5@@H_502_5@

     @H_502_5@

     @H_502_5@

6.12.3 删除属性

  • 语法、@H_502_5@

hdel key field1 field2 @H_502_5@

@H_502_5@@H_502_5@

6.13. list集合操作

有顺序 可以重复@H_502_5@

6.13.1. 右压栈和左弹栈

右压栈 是指 数据从头添加 数据顺序往后排 类似数据往右压 右压栈 @H_502_5@

左弹栈 是指 数据从左边弹出 @H_502_5@

  • 右压栈@H_502_5@

    lpush key value1 value2 value3 @H_502_5@

  • 左弹栈@H_502_5@

    lpop key (从左边弹出第一个)@H_502_5@

@H_502_5@@H_502_5@

6.13.2. 左压栈和右弹栈

左压栈: 表示数据从后添加 @H_502_5@

右弹栈: 表示数据从后弹出 @H_502_5@

  • 左压栈 @H_502_5@

    rpush key value1 value2 value3 @H_502_5@

  • 右弹栈 @H_502_5@

    rpop key (从右边弹出一个)@H_502_5@

    @H_502_5@@H_502_5@

6.13.3. 查看数据

@H_502_5@@H_502_5@

6.14. 操作set集合

不能重复 没有顺序@H_502_5@

6.14.1. 存取数据

  • 存数据@H_502_5@

    sadd key value1 value2 value3 @H_502_5@

  • 取数据@H_502_5@

    smembers key @H_502_5@

@H_502_5@@H_502_5@

 @H_502_5@

 @H_502_5@

6.14.2. 删除数据

  • 语法@H_502_5@

    srem key value @H_502_5@

@H_502_5@@H_502_5@

6.15. 操作sortedSet

有序 不能重复 @H_502_5@

注意:每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。@H_502_5@

6.15.1 存取值

当endindex等于-1时 表示查询所有@H_502_5@

@H_502_5@@H_502_5@

6.15.2. 删除

  • 语法@H_502_5@

    zrem key value @H_502_5@

    @H_502_5@@H_502_5@

6.16. Redis的通用指令

key* 获得所有的key @H_502_5@

key list* 获得以list开头的key@H_502_5@

6.17. Redis的持久化

redis是把数据存在内存中的 如果我们的服务器关机 这个时候内存中的数据将不存在 所以呢要做持久化 @H_502_5@

当服务器再次启动的时候 redis就会把本地数据加载到内存中 @H_502_5@

6.17.1. RDB的方式

这种持久化的方式 是认的 不用任何配置 @H_502_5@

  • 它的规则@H_502_5@

@H_502_5@@H_502_5@

6.17.2. AOF的方式

每一次操作或者每一秒 都会把记录持久化到硬盘中 (费资源) 到底是每一次还是每一秒 取决于配置 @H_502_5@

  • 开启方式、@H_502_5@

    @H_502_5@@H_502_5@

@H_502_5@@H_502_5@

6.18. java操作Redis

  • Jedis的方式@H_502_5@

  • springdataRedis的方式 @H_502_5@

6.18.1.Jedis单独的方式

  • 创建java工程@H_502_5@

  • 导入jar@H_502_5@

    commons-pool2-2.3.jar@H_502_5@

​   jedis-2.7.0.jar@H_502_5@

  • 创建测试类@H_502_5@

  • 注意: junit测试包 通过idea导入@H_502_5@

  • 对String的操作@H_502_5@

    @H_502_5@@H_502_5@

     @H_502_5@

     @H_502_5@

  • 对hash的操作@H_502_5@

    @H_502_5@@H_502_5@

     @H_502_5@

     @H_502_5@

  • 对List的操作@H_502_5@

    @H_502_5@@H_502_5@

     @H_502_5@

     @H_502_5@

  • 对set的操作@H_502_5@

    @H_502_5@@H_502_5@

  • sortedSet的操作@H_502_5@

    @H_502_5@@H_502_5@

  • 所有的代码@H_502_5@

    package com.shangma.cn;
      ​
      import org.junit.Test;
      import redis.clients.jedis.Jedis;
      ​
      import java.util.List;
      import java.util.Set;
      ​
      public class RedisTest1 {
      ​
          @Test
          public void fun() {
              //如果不写 域名端口 认就是 本机 认端口就是6379
      //        Jedis jedis  = new Jedis();
              Jedis jedis = new Jedis("localhost", 6379);
              jedis.set("name", "huige");
              String name = jedis.get("name");
              System.out.println(name);
              jedis.close();//释放资源
          }
          
          //  @Test
        public void fun1() {
            Jedis jedis = new Jedis();
            jedis.hset("wife", "name", "高圆圆");
            String name = jedis.hget("wife", "name");
            System.out.println(name);
            jedis.close();//释放资源
        }
          
          
       //     @Test
        public void fun2() {
            Jedis jedis = new Jedis();
            //右压栈
              //jedis.lpush("s1", "aaa", "bbb", "cccc");
            // 左压栈
            jedis.rpush("s1", "ddd", "eee");
            List<String> si = jedis.lrange("s1", 0, -1);
            si.forEach(System.out::println);
            jedis.close();//释放资源
      ​
        }
          
       //  @Test
            public void fun3() {
            Jedis jedis = new Jedis();
            jedis.sadd("s2", "zs", "ls", "ww");
            Set<String> s2 = jedis.smembers("s2");
            s2.forEach(System.out::println);
            jedis.close();//释放资源
        }
      ​
       // @Test
        public void fun4() {
            Jedis jedis = new Jedis();
            jedis.zadd("mv",20,"如花");
            Set<String> mv = jedis.zrange("mv", 0, -1);
            mv.forEach(System.out::println);
      ​
            jedis.close();//释放资源
        }
            }

     @H_502_5@

6.18.2. Jedis连接池的方式

每次操作redis都会频繁创建和关闭链接 资源浪费 并且性能不好 @H_502_5@

所以我们需要连接池 类似数据库连接一样@H_502_5@

具体代码@H_502_5@

        /**
         * 连接池的使用
         */
    //    @Test
        public void pool() {
            JedisPoolConfig config  = new JedisPoolConfig();
            // 最大空闲数
            config.setMaxIdle(10);
    //        最大连接数
            config.setMaxTotal(50);
  ​
            //通过配置类创建连接池
            JedisPool pool = new JedisPool(config,"localhost",6379);
            // 在连接池中取出Jedis连接
            Jedis jedis = pool.getResource();
            jedis.set("haha","窗前明月光");
            String haha = jedis.get("haha");
            System.out.println(haha);
  ​
        }

 @H_502_5@

6.18.3. 连接池的封装

  • 第一步 :新建一个jedis.properties文件@H_502_5@

      host=localhost
      port=6379
      maxIdle=10
      maxTotal=50

     @H_502_5@

  • 第二步:编写工具类 @H_502_5@

      public class JedisUtil {
      ​
          private static JedisPool jedisPool;
      ​
          static {
              InputStream in = JedisUtil.class.getClassLoader().getResourceAsstream("redis.properties");
              Properties properties = new Properties();
              try {
                  properties.load(in);
                  JedisPoolConfig config = new JedisPoolConfig();
                  // 最大空闲数
                  config.setMaxIdle(Integer.parseInt(properties.getProperty("maxIdle")));
                  // 最大连接数
                  config.setMaxTotal(Integer.parseInt(properties.getProperty("maxTotal")));
                  jedisPool = new JedisPool(config, properties.getProperty("host"), Integer.parseInt(properties.getProperty("port")));
              } catch (IOException e) {
                  throw new RuntimeException("配置文件加载失败");
              }
      ​
          }
      ​
          /**
           * 这个是获得Jedis
           *
           * @return
           */
          public static Jedis getJedis() {
              return jedisPool.getResource();
          }
      ​
          /**
           * 释放资源
           */
          public static void release(Jedis jedis) {
              //这个表示当前jedis链接 放到我们链接池中  并不是关闭了
              jedis.close();
          }
      ​
      }

     @H_502_5@

  • 第三步 测试 @H_502_5@

      @Test
          public void pool1() {
              Jedis jedis = JedisUtil.getJedis();
              jedis.set("haha", "窗前明月光");
              String haha = jedis.get("haha");
              System.out.println(haha);
              JedisUtil.release(jedis);
          }

     @H_502_5@

6.18.4. SpringDataRedis操作

//Todo:等着@H_502_5@

6.19. Redis集群

redis的数据存在内存中 但是如果数据量比较多 内存占用很大 那么一台机器 可能无法满足需求 @H_502_5@

这个时候我们可能要搭建redis集群 @H_502_5@

6.19.1. 集群的搭建

6.19.2. Jedis对集群的操作

      @Test
      public void fun() {
          JedisPoolConfig config = new JedisPoolConfig();
          config.setMaxTotal(50);
          config.setMaxIdle(10);
          JedisShardInfo info1 = new JedisShardInfo("localhost", 6379);
          JedisShardInfo info2 = new JedisShardInfo("localhost", 7777);
          List<JedisShardInfo> list = new ArrayList<>();
          list.add(info1);
          list.add(info2);
          ShardedJedisPool pool = new ShardedJedisPool(config, list);
  ​
          ShardedJedis jedis = pool.getResource();
          for (int i = 0; i <100; i++) {
              jedis.set("name"+i,"huige"+i);
          }
          jedis.close();
      }
  }

6.19.3. SpringDataRedis对集群的操作

//Todo:等着@H_502_5@

6.20. Redis可视化工具

6.20.1. 安装

  双击安装@H_502_5@

6.20.2. 连接Redis

@H_502_5@@H_502_5@

 @H_502_5@

 @H_502_5@

 @H_502_5@

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐