Redis的使用

redis

  • 关于redis的要点

    • redis是以key-value形式存储的非关系型数据库,直接在内存中操作数据
    • 它的定位是缓存,存储临时数据,提高数据的读写速度,减轻数据库的压力
    • 它是单线程操作的,所以不存在高并发访问问题
  • redis常用命令

    • key不能重复,是唯一的,如果存入相同的key会覆盖前面存入的key
    • value存储String类型,Map<String, String>
      # 存入key-value数据
      set key value
      # 根据key取出value
      get key
      # 将value值递增1,如果没有该key,会创建并设置value为1
      incr key
      # 将value值递减1,如果没有该key,会创建并设置value为-1
      decr key
      # 删除key
      del key
      # 存入key-value,timeout是存活时间(s)
      setex key timeout value
      # 查询指定key的存活时间
      ttl key
      # 添加数据之前判断key是否已存在,存在则添加
      setnx key value
      
    • value存储Hash类型,Map<String, Map>
      # 存入key-(hkey - hvalue)数据
      hset key hkey hvalue
      # 根据key和hkey取出hvalue
      hget key hkey
      # 判断hash对象中hkey是否存在
      hexists key hkey
      # 根据hkey删除一个hkey-hvalue
      hdel key hkey
      # 列出所有hkey-hvalue值
      hgetall key
      # 列出所有hkey
      hkeys key
      # 列出所有hvalue
      hvals key
      
    • value存储List类型,Map<String, List>,存储的元素是有序的,可重复
      # 从左边存入集合数据,key后面是存入的多个值
      lpush key value1 value2 value3...
      # 从右边存入集合数据,key后面是存入的多个值
      rpush key value1 value2 value3...
      # 从左到右列出指定索引段的List值,含头含尾,如果是列出全部值,则 lrange key 0 -1
      lrange key start stop
      # 移除List集合最左边的值,比如[1,2,3,4],移除1
      lpop key
      # 移除List集合最右边的值,比如[1,2,3,4],移除4
      rpop key
      # 获取List集合的元素个数
      llen key
      
    • value存储Set集合类型,Map<String, Set>,存储的元素是无序的,能对Set进行并集、交集、差集操作
      # 存入Set集合,key后面是存入的多个值
      sadd key value1 value2 value3...
      # 列出Set集合中所有元素
      smembers key
      # 删除指定的Set元素
      srem key value
      # 随机删除Set元素,count是随机删除的元素的个数
      spop key count
      # 列出key2中没有的元素,key1和key2的差集
      sdiff key1 key2
      # 列出key1和key2的Set集合中共有的元素,交集
      sinter key1 key2
      # 列出所有key1和key2的Ser集合中元素,并集
      sunion key key2
      # 获取Set集合中元素个数
      scard key
      
    • value存储ZSet集合和score,能根据score将ZSet值排序,升序或倒序
      # 存入Set集合和score,score value 能有多个
      zadd key score1 value1 score2 value2...
      # 按照分数升序列出value,含头含尾,如果是列出全部值,zrange key 0 -1
      zrange key start stop
      # 按照分数降序列出value,含头含尾,如果是列出全部值,zrange key 0 -1
      zrevrange key start stop
      # 升序后返回指定value的排名,从0开始
      zranke key value
      # 降序后返回指定value的排名,从0开始
      zrevranke key value
      # 将指定value的分数递增score分
      zincrby key score value
      # 获取Set集合中元素个数
      zcard key
      
  • key的设计

    • 唯一性:key是唯一的
    • 可读性:key的名称要有意义,达到见名知意的效果
    • 灵活性:key的名称不要太长,易操作
    • 时效性:有些key需要给定存活时间,以防长期不用导致内存积满,比如登录用户的Session信息
  • redis的全局命令

    • 列出当前数据库中所有符合条件的key,可以模糊查询
      # 查询所有的key
      keys *
      # 查询以a开头的key
      keys a*
      # 查询以d结尾的key
      keys *d
      
    • 判断指定key是否存在,存在返回1,不存在返回0
      exists key
      
    • 给key设置存活时间,单位s
      # 与setex的区别,该命令是后期给key设置时间,不会覆盖key的数据,而后期给key设置时间使用setex命令,会覆盖key
      expire key seconds
      
    • 取消给key设置的存活时间
      persist key
      
    • 查看key存储值的数据类型
      type key
      
  • redis事务

    • 使用事务,先执行multi命令,然后执行操作数据命令,最后执行exec命令,取消事务使用discard命令
    • redis是不支持真正的事务的,这里说的事务只是将操作数据的命令统一执行,中间有命令出错并不会让数据回滚,而是命令继续执行
  • redis持久化策略

    • redis的定位是缓存,数据只存在内存中,只存储临时数据,因为数据易丢失,所以需要隔一段时间将redis中数据保存到硬盘中,而由于与硬盘交互过程相对于内存较慢,所以需要采取折中的方式达到数据访问速度与数据安全的平衡
    • RDB策略,也称快照策略
      • redis将某一时间点的数据全部打包生成一个.rdb的文件,保存在磁盘中,当我们重启redis服务的时候,将会读取该rdb文件恢复数据库中的数据
      • 在redis安装根目录下打开redis.windows.conf文件,在194行找到下列代码,默认使用RDB策略,可以更改配置
        # 距离上一次执行rdb快照时间超过900秒,并且至少有1个键发生了改变,便会触发备份操作
        save 900 1
        # 距离上一次执行rdb快照时间超过300秒,并且至少有10个键发生了改变,便会触发备份操作
        save 300 10
        # 距离上一次执行rdb快照时间超过60秒,并且至少有1000个键发生了改变,便会触发备份操作
        save 60 10000
        
    • AOF策略,命令日志策略
      • redis会将被执行的写命令添加到aof文件的末尾,该文件被保留在磁盘中。当重启redis服务的时候会优先(相对于rdb文件而言)读取aof文件,完成对redis数据的恢复
      • 在redis安装根目录下打开redis.windows.conf文件,在581行找到找到appendonly no,将no改成yes即可使用此策略,在609行更改策略配置
      • appendonly,该选项决定了是否开启aof持久化策略
        配置名称 配置选项 解释说明
        appendonly yes / no 决定是否开启aof策略,默认情况下是no
      • appendfsync, 该选项决定了写入aof文件的频率
        配置名称 配置选项 解释说明
        appendfsync always 每一个redis写命令时都会被写入到aof文件中,这样会严重降低redis的速度
        appendfsync everysec 每秒钟执行一次同步,将这一秒钟之内接受到的命令写入aof文件中
        appendfsync no 并不是不进行aof持久化,而是让操作系统决定什么时候将命令写入aof文件中,这样我们丢失的数据将不可控
  • redis内存淘汰机制及过期Key处理

    • redis内存淘汰机制
      • 指当内存使用达到上限(可通过maxmemory配置,0为不限制,即服务器内存上限),根据一定的算法来决定淘汰掉哪些数据,以保证新数据的存入
      • 在redis安装根目录下打开redis.windows.conf文件,在525行找到maxmemory <bytes>,更改redis内存上限大小
      • LRU:LRU是Least recently used,最近最少使用的意思,简单的理解就是从数据库中删除最近最少访问的数据,该算法认为,你长期不用的数据,那么被再次访问的概率也就很小了,淘汰的数据为最长时间没有被使用,仅与时间相关
      • LFU:LFU是Least Frequently Used,最不经常使用的意思,简单的理解就是淘汰一段时间内,使用次数最少的数据,这个与频次和时间相关
      • TTL:Redis中,有的数据是设置了过期时间的,而设置了过期时间的这部分数据,就是该算法要解决的对象。如果你快过期了,不好意思,我内存现在不够了,反正你也要退休了,提前送你一程,把你干掉吧
      • 随机淘汰:生死有命,富贵在天,是否被干掉,全凭天意了
      • 通过maxmemroy-policy可以配置具体的淘汰机制,系统默认的淘汰机制是no-enviction,什么都不干,报错,告诉你内存不足,这样的好处是可以保证数据不丢失
      • 在redis安装根目录下打开redis.windows.conf文件,在548行找到maxmemory-policy noeviction,更改maxmemroy-policy配置
    • redis过期Key处理
      • 给key设置存活时间,当时间到了之后,redis清除key的策略
      • 惰性删除:当访问Key时,才去判断它是否过期,如果过期,直接干掉。这种方式对CPU很友好,但是一个key如果长期不用,一直存在内存里,会造成内存浪费
      • 定时删除:设置键的过期时间的同时,创建一个定时器,当到达过期时间点,立即执行对Key的删除操作,这种方式最不友好
      • 定期删除:隔一段时间,对数据进行一次检查,删除里面的过期Key,至于要删除多少过期Key,检查多少数据,则由算法决定。例如:Redis每秒随机取100个数据进行过期检查,删除检查数据中所有已经过期的Key,如果过期的Key占比大于总数的25%,也就是超过25个,再重复上述检查操作
      • Redis服务器实际使用的是惰性删除和定期删除两种策略:通过配合使用这两种删除策略,可以很好地在合理使用CPU和避免浪费内存之间取得平衡
  • 使用Jedis工具包操作Redis,非SpringBoot项目

    • 添加Jedis依赖
      <dependency>
          <groupId>redis.clients</groupId>
          <artifactId>jedis</artifactId>
      </dependency>
      
    • 代码编写
      @Test
      public void testString(){
          //创建Jedis连接池,配置连接地址及端口号
          JedisPool jedisPool = new JedisPool("localhost", 6379);
          //获取Jedis连接对象
          Jedis jedis = jedisPool.getResource();
          //配置连接redis的密码,默认没有密码,如果在配置文件中配置了密码,需要在此配置
          //jedis.auth("root");
      
          //使用Jedis连接对象操作Jedis数据库,这里的方法名与redis命令一样
          //获取当前数据库中所有的key
          Set<String> keys = jedis.keys("*");
          keys.forEach(System.out::println);
      
          //获取key为student存储值的类型
          String type = jedis.type("student");
          System.out.println("type = " + type);//zset
      
          //清空当前数据库中所有数据
          String s = jedis.flushDB();
          System.out.println(s);//OK
      }
      
  • 使用Lettus工具包操作Redis,SpringBoot项目

    • 添加Lettus依赖
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-redis</artifactId>
      </dependency>
      
    • 代码编写
      @Autowired
      private StringRedisTemplate template;
      
      @Test
      public void testString(){
          ValueOperations<String, String> stringTem = template.opsForValue();
      
          //清除当前数据库所有key-value
          template.delete(template.keys("*"));
      
          // 存入key-value数据
          stringTem.set("user", "禹王穆");
          stringTem.set("age", "18");
      
          // 根据key取出value
          System.out.println("stringTem.get(\"user\") = " + stringTem.get("user"));
          String user = stringTem.get("user", 0, -1);
          System.out.println("user = " + user);
      
          // 将value值递增1,如果没有该key,会创建并设置value为1
          System.out.println("stringTem.increment(\"age\") = " + stringTem.increment("age"));
      
          // 将value值递减1,如果没有该key,会创建并设置value为-1
          System.out.println("stringTem.decrement(\"age\") = " + stringTem.decrement("age"));
      
          // 删除key
          Boolean delete = template.delete("age");
          System.out.println("delete = " + delete);
      
          // 存入key-value,timeout是存活时间(s)
          stringTem.set("a","1", Duration.ofSeconds(100L));
      
          // 查询指定key的存活时间
          System.out.println("template.getExpire(\"a\") = " + template.getExpire("a"));
      
          // 添加数据之前判断key是否已存在,存在则添加
          Boolean absent = stringTem.setIfAbsent("b", "3");
          System.out.println("absent = " + absent);
      }
      
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 目录: 1 Redis初识 1.1 Redis介绍 1.2 Redis功能特性介绍 1.3 Redis...
    莎莎1990阅读 719评论 0 2
  • Redis的安装 一、Redis的安装 Redis是c语言开发的。安装redis需要c语言的编译环境。如果没有gc...
    a86e8e27fc21阅读 627评论 0 0
  • 上一篇简单介绍了Redis,本文介绍一下如何操作Redis。对于现有的操作Redis比较知名的框架有Jedis(历...
    不知名的程序员阅读 665评论 0 0
  • 介绍 redis是键值对的数据库,常用的五种数据类型为字符串类型(string),散列类型(hash),列表类型(...
    潇豪阅读 285评论 0 1
  • redis 使用历程 为什么使用redis缓存? 答:之前是没有使用redis的,直接用Java代码写类缓存功能,...
    todobugs阅读 256评论 0 1