redis的数据类型及操作

redis

  1. Redis的概念

    Redis是一款由C语言编写, 基于内存的持久化的数据库, 其中数据是以KEY-VALUE的形式存储的, Redis提供了丰富的数据类型

  2. Redis的特点

    1. Redis将数据存储到内存当中, 所以Redis的读写效率非常高: 读 11w/s 写 8w/s
    1. redis提供了丰富的数据类型: string , hash , list ,set , sortedSet
    • 注意: redis中数据类型, 主要是描述的key-value中value的数据类型, 而key只有string
    1. Redis数据的移植非常快的
    1. redis中所有的操作都是原子性的, 保证数据的完整性的
  1. redis数据类型的使用场景和特点
  • string: 可以使用json转换对象, 存储
    • 特点: 和 java中 string是类似的, 表示的就是字符串
    • 使用场景: 做缓存
  • hash: 存储对象是比较方便的
    • 特点: 和 java中 hashMap是类似的
    • 使用场景: 做缓存 (hash使用较少)
  • list:
    • 特点: 和 java中 linkedList是类似, 可以看做是队列(FIFO)先进先出
    • 使用场景: 任务队列
  • set :
    • 特点: 和 java中set集合是类似的 去重 无序
    • 使用场景: 去重业务
  • sortedSet
    • 特点: 和 java中 sortedSet(TreeSet)类型 有序 去重
    • 使用场景: 排序操作(排行榜)
  1. redis安装

见课件安装即可

  1. redis的客户端工具: jedis

    jedis是一款java连接redis客户端工具包, jedis提供了一套非常省力的API, jedis中最大的特点就是其API和redis中命令都是一样的, 大大的降低了学习成本, 只需要学习其中的一个就可以了

如果想要使用jedis, 首先先进行导包操作

	<dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
  • jedis的入门程序

    @Test
    public void jedisTest01(){
    //1. 创建 jedis对象: 指定redis的ip地址 和 端口号
    // Jedis 可以将看做是 connection连接对象
    Jedis jedis = new Jedis(“192.168.72.142”,6379);

          //2. 执行相关的操作
          String pong = jedis.ping();
          System.out.println(pong);
    
          //3. 释放资源
          jedis.close();
    
      }
    

    出现的原因主要有以下几个:
    1) 防火墙没有关闭, 或者没有开放6379端口号
    2) redis没有开启
    3) 代码中ip地址或者端口号写错了

5.1 jedis操作redis – string

//2. 使用jedis操作Redis --->  string

    @Test
    public void jedisTest02() throws InterruptedException {
        //1. 创建 jedis对象
        Jedis jedis = new Jedis("192.168.72.142",6379);

        //2. 执行相关操作
        //2.1 进行赋值操作: name :  隔壁老王
        jedis.set("name","隔壁老王");

        //2.2 取值操作
        String name = jedis.get("name");
        System.out.println(name);

        //2.3 想让 某一个key的值 ++  或者 --操作
        jedis.set("age","18");

        Long incr = jedis.incr("age");
        System.out.println(incr); //19

        Long decr = jedis.decr("age");
        System.out.println(decr);  //18

        //2.4 设置一个nickName的key, 要求: 这个key只能存活5秒, 5秒后消失
        jedis.setex("nickName",5,"给别人戴帽子");

        while(jedis.exists("nickName")){

            // 获取一下还剩下多少时间
            // 如果返回的是正数, 表示还剩下多少时间
            // 如果返回的-2 表示的当前这个key已经不存在了
            // 如果返回的是-1  表示的当前这个key是一个永久有效的key
            Long time = jedis.ttl("nickName");
            System.out.println(time);
            Thread.sleep(1000);
        }
        //2.5 给已经存在的key设置有效时间
        jedis.expire("age",5);

        while(jedis.exists("age")){

            // 获取一下还剩下多少时间
            // 如果返回的是正数, 表示还剩下多少时间
            // 如果返回的-2 表示的当前这个key已经不存在了
            // 如果返回的是-1  表示的当前这个key是一个永久有效的key
            Long time = jedis.ttl("age");
            System.out.println(time);
            Thread.sleep(1000);
        }

        //2.6 如何拼接字符串:  name  隔壁老王+隔壁老张
        jedis.append("name","隔壁老张");

       name = jedis.get("name");
        System.out.println(name);

        //2.7 通用的删除某一个key
        jedis.del("name");

        //3. 释放资源

        jedis.close();

    }

5.2 jedis操作redis – list

@Test
    public void jedisTest03(){
        //1. 创建jedis对象
        // 在使用list想相关的API的时候, 建议从左侧添加, 从右侧弹出, 或者 从右侧添加从左侧 弹出
        Jedis jedis = new Jedis("192.168.72.142",6379);
        //2. 执行相关的操作
        //0 清空数据
        jedis.del("list1");
        //2.1 从左侧添加数据, 从右侧弹出数据
        jedis.lpush("list1","a","b","c","d");

        String rpop = jedis.rpop("list1");
        System.out.println(rpop); // a
        //2.2  查看列表
        List<String> list = jedis.lrange("list1", 0, -1);
        System.out.println(list); // [b c d]  [d c b ]

        //2.3 获取集合的个数
        Long size = jedis.llen("list1");
        System.out.println(size);

        //2.4 想在 c这个元素的前面添加一个 数字 0
        //  参数1:  在那个key中操作
        // 参数2:  添加到哪里去  before after
        // 参数3:  在谁的前面或者后面
        // 参数4:  添加的元素内容
        jedis.linsert("list1", BinaryClient.LIST_POSITION.BEFORE,"c","0");

        list = jedis.lrange("list1", 0, -1);
        System.out.println(list);

        //2.5 从右侧弹出一个元素, 将弹出的这个元素在添加到这个集合的头部
        String key1 = jedis.rpoplpush("list1", "list1");
        System.out.println(key1);


        list = jedis.lrange("list1", 0, -1);
        System.out.println(list);

        //3. 释放资源
        jedis.close();


    }

5.3 jedis操作redis – set

 //4. 使用jedis 操作 redis --- set
    // set特点:  无序  去重

    @Test
    public void jedisTest04(){
        //1. 创建 jedis对象
        Jedis jedis = new Jedis("192.168.72.142",6379);

        //2. 执行相关的操作
        //2.1  添加元素:
        jedis.sadd("set1","q","w","e","r","w","q");
        //2.2 遍历出来
        Set<String> set = jedis.smembers("set1");
        System.out.println(set);
        //2.3  判断某一个元素在set集合是否存在
        // 如果值存在的, 返回true , 如果不存在, false
        Boolean flag = jedis.sismember("set1", "d");

        System.out.println(flag);

        //2.4 获取set集合中数量
        Long size = jedis.scard("set1");
        System.out.println(size);


        //3. 释放资源
        jedis.close();

    }

5.4 jedis操作redis – sortedSet

@Test
    public void jedisTest05(){
        //1. 创建 jedis对象
        Jedis jedis =  new Jedis("192.168.72.142",6379);

        //2. 执行相关的操作
        //2.1 添加元素:
        jedis.zadd("bookList",95,"斗破苍穹");
        jedis.zadd("bookList",85,"斗罗大陆");
        jedis.zadd("bookList",500,"西游记");
        jedis.zadd("bookList",436,"红楼梦");
        jedis.zadd("bookList",147,"水浒传");
        jedis.zadd("bookList",800,"三国演义");

        //2.2  从大到小进行遍历
       // Set<String> set = jedis.zrevrange("bookList", 0, -1);
        Set<Tuple> bookList = jedis.zrevrangeWithScores("bookList", 0, -1);
        for (Tuple tuple : bookList) {
            String book = tuple.getElement();
            double score = tuple.getScore();
            System.out.println(book +"  "+ score);
        }
        //2.3  想要看一下红楼梦这本书从大到小排名第几
        Long rank = jedis.zrevrank("bookList", "红楼梦");
        System.out.println(rank);  // 2  因为 从0开始


        //2.4  返回某个分数范围元素一共有多少个

        Long size = jedis.zcount("bookList", 450, 1000);
        System.out.println(size);
        //3. 释放资源
        jedis.close();

    }
  1. jedis连接池

    jedis看做是一个连接对象, 频繁的创建一个连接, 比较耗时耗资源的 通常情况, 采用连接池的技术, 提前的创建好一部分的连接对象, 放置到容器中, 反复的使用即可

  • jedis的连接池基本使用

    //6. jedis连接池技术
    @Test
    public void jedisTest06(){
    //1. 创建一个连接池对象
    JedisPoolConfig config = new JedisPoolConfig();
    config.setMaxTotal(100); //最大连接数
    config.setMaxIdle(50); // 最大闲时的数量
    config.setMinIdle(25); // 最小闲时的数量

          JedisPool jedisPool = new JedisPool(config,"192.168.72.142",6379);
    
          //2. 从连接池中获取连接对象: jedis对象
          Jedis jedis = jedisPool.getResource();
    
          //3. 执行相关的操作
          String pong = jedis.ping();
          System.out.println(pong);
    
          //4. 释放资源(归还)
    
          jedis.close();
    
      }
    
  • 提取成工具类

    package com.itheima.jedis;

    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    import redis.clients.jedis.JedisPoolConfig;

    public class JedisUtils {
    private static JedisPool jedisPool;
    // 什么加载: 随着类的加载而加载, 一般只会加载一次
    static {
    JedisPoolConfig config = new JedisPoolConfig();
    config.setMaxTotal(100); //最大连接数
    config.setMaxIdle(50); // 最大闲时的数量
    config.setMinIdle(25); // 最小闲时的数量
    // 注意: 千万别在等号左侧 写上 "JedisPool jedisPool " 而应该写成 “jedisPool”
    jedisPool = new JedisPool(config,“192.168.72.142”,6379);
    }

      // 获取连接的方法
    
      public static Jedis getJedis(){
    
    
          return jedisPool.getResource() ;
      }
    

    }

  1. redis的持久化

持久化: 从内存到硬盘的过程

序列化: 从内存到硬盘的过程

反序列化 : 从硬盘到内存过程

监听器: setAttribute(String name Object value)

钝化 : 从内存到硬盘的过程

活化: 从硬盘内存过程

我们知道, redis是将数据存储在了内存当中, 那么当关闭服务器, 内存的资源也就会消失了, 这时存储在redis中的数据也会消失, 那么我们应该如何做呢?

  • 在redis中已经提供了两种持久化的方案

    • RDB: redis提供的一种基于快照机制实现的持久化方案, 而快照就类似于照相机, 会将一个服务器某个时刻的一个状态整体保存下来, 快照文件一般都非常的小,只有几kb左右
      • 优点: 由于持久化的文件非常小, 适合于做灾难恢复
      • 缺点: 由于redis中持久化的时机问题, 会存在数据丢失的问题
    • AOF: redis提供的一种基于日志机制实现的持久化方案, 会将用户操作(增 删 改)的所有的命令整体的记录下来保存到日志文件中,一般文件都比较庞大
      • 优点: AOF机制可以让将用户所有的命令都记录下来, 顾其数据保存的比较完整, 不容易丢失
      • 缺点: 持久化的文件比较庞大, 不利于灾难恢复
  • RDB保存机制: redis默认是开启RDB机制

    save 900 1 : 在900秒之内,如果有一个数据进行修改,就会执行一下保存
    save 300 10 : 在300秒之内, 如果有10个以上的数据被修改, 就会执行一下保存
    save 60 10000 : 在60秒之内, 如果有10000个以上的数据被修改. 就会执行一下保存

  • 当服务器宕机, 最大丢失数据量为在不到5分钟的时间里丢掉9999个数据

    • 一般情况下redis的不会出现宕机的现象, 除非redis中的数据将内存撑爆了, 但这个现象在大公司是不会出现的

  • AOF的保存机制:redis默认不开启

如何开启AOF:

  • 打开redis的配置文件,修改下列两个参数即可

    appendonly yes //默认此项是no,没有启动AOF机制
    appendfsync everysec //appendfsync的取值: [always everysec no]

  • always: 总是, 只要有新的命令执行, 就将其保存到文件中

    • 优点: 数据保存最完整, 几乎不会丢掉数据
    • 缺点: 大大降低了redis的性能
  • everysec: 每秒钟执行一次保存

    • 此种保存不会大幅度的降低redis的性能,但是会丢失最大1s的数据
  • no: 不执行保存, 由操作系统自动调用保存(linux一般30分钟刷新一次内存)

    • 一般不使用

开发中:

一般小公司会采用AOF + RDB  大公司只会使用RDB
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值