Redis 入门和 RedisTemplate 常用方法(常用命令 + 案例源码)

Posted Yan Yang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 入门和 RedisTemplate 常用方法(常用命令 + 案例源码)相关的知识,希望对你有一定的参考价值。

内容

参考博文:https://www.cnblogs.com/maguanyue/p/12090414.html


一、Redis 概念

Redis 是一个开源的使用 ANSIC 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API;

Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型;

Redis 定位是缓存, 提高数据读写速度, 减轻对数据库存储与访问压力


二、Redis 优缺点

1. 优点

【1】性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s ;

【2】丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作;

【3】原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来;

【4】丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。


2. 缺点

【1】 由于是内存数据库,所以,单台机器,存储的数据量,跟机器本身的内存大小。虽然redis本身有key过期策略,但是还是需要提前预估和节约内存。如果内存增长过快,需要定期删除数据。

【2】如果进行完整重同步,由于需要生成rdb文件,并进行传输,会占用主机的CPU,并会消耗现网的带宽。不过redis2.8版本,已经有部分重同步的功能,但是还是有可能有完整重同步的。比如,新上线的备机。

【3】 修改配置文件,进行重启,将硬盘中的数据加载进内存,时间比较久。在这个过程中,redis不能提供服务。


三、应用场景

适用场景

【1】热点数据的缓存;

【2】限时业务的运用;

【3】计数器相关问题;

【4】排行榜相关问题;

【5】分布式锁;

【6】延时操作;

【7】 Pub/Sub构建实时消息系统;

【8】 构建队列系统;

【9】 缓存;


四、Redis 安装

【1】下载安装包,然后一直下一步,安装到环境变量那一步勾一下,也可以安装完后自己配置,不会就直接百度一下安装教程就好了;

【2】安装完环境变量之后 -> win + R -> 输入 cmd 打开命令窗口 -> 输入 redis-cli (查看 redis 服务是否启动)-> 如果进入了 6379 默认端口或你前面设置的端口则 redis 服务已启动,没启动的话自己去任务管理器服务选项找到 redis 启动即可 -> 在命令窗口的端口号后面输入 ping ,出现 PONG 则 Redis 安装成功。


五、常用命令

1. Redis 字符串(String)

1.1 概念

String类型包含多种类型的特殊类型,并且是二进制安全的.比如序列化的对象进行存储,比如一张图片进行二进制存储.,比如一个简单的。

Map<String,  String>  map;

1.2 常用命令

序号命令作用
1set key value设置指定 key 的值(set name yy)
2get key获取指定 key 的值
3incr key把值递增1
4decr key把值递减1
5del key根据键删除键值对
6setex key timeout value存入键值对,timeout表示失效时间,单位s
7ttl key可以查询出当前的key还剩余多长时间过期
8setnx key value如果key已经存在,不做操作, 如果key不存在,直接添加
9incrby key num偏移值(对值进行加减操作)
10mset k1 v1 k2 v2 …批量存入键值对
11mget k1 k2批量取出键值
12append key ‘value’原值后拼接新内容
13setrange key index value修改键对应的值,index表示开始的索引位置(从0开始)

2. Redis 哈希(Hash)

2.1 概念

Hash类型是String类型的field和value的映射表.或者说是一个String集合.它特别适合存储对象,相比较而言,讲一个对象存储在Hash类型里要比存储在String类型里占用更少的内存空间,并方便存储整个对象。

Map<string, Map<string, ?>> map

2.2 常用命令

序号命令作用
1hset key hashkey hashvalue存入一个hash对象(hset user name yy)
2hget key hashkey根据hash对象键取去值
3hexists key hashkey判断hash对象是含有某个键
4hdel key hashkey根据hashkey删除hash对象键值对
5hincrby key hashkey 递增值递增hashkey对应的值
6hlen key获取hash对象键的数量
7hkeys key获取hash对象的所有键
8hvals key获取hash对象的所有值
9hgetall key获取hash对象的所有数据
10hsetnx key hashkey hashvalue存入键值对,键存在时不存入

3. Redis 列表(List)

3.1 概念

Redis中的List类似Java中的queue,也可以当做List来用;
List类型是一个链表结构的集合,其主要功能有push,pop,获取元素等.更详细的说,List类型是一个双端链表的结构,我们可以通过相关操作进行集合的头部或者尾部添加删除元素,list的设计非常简单精巧,即可以作为栈,又可以作为队列.满足绝大多数需求。

Map<String, List>

3.2 常用命令

序号命令作用
1rpush key value [value …]往列表右边添加数据(rpush hobby java C++ C C# Python)
2lrange key start end范围显示列表数据,全显示则设置0 -1
3lpush key value [value …]往列表左边添加数据
4lpop key弹出列表最左边的数据
5rpop key弹出列表最右边的数据
6llen key获取列表长度
7linsert key before/after refVal newVal参考值之前/后插入数据
8lset key index value根据索引修改数据(索引从0开始)
9lrem key count value在列表中按照个数删除数据
10ltrim key start end范围截取列表(LTRIM list 0 2,保留前3个元素,-1表示最后一个元素,-2倒数第二个元素)
11lindex key index根据索引取列表中数据

4. Redis 集合(Set)

4.1 概念

Set集合是string类型的无序集合,set是通过hashtable实现的,对集合我们可以取交集,并集,差集。


4.2 常用命令

序号命令作用
1sadd key value往set集合中添加元素(sadd myset aa bb cc dd)
2smembers key列出set集合中的元素
3srem key value删除set集合中的元素
4spop key count随机弹出集合中的元素
5sdiff key1 key2返回key1中特有元素(差集)
6sdiffstore var key1 key2返回key1中特有元素存入另一个set集合
7sinter key1 key2返回两个set集合的交集
8sinterstore var key1 key2返回两个set集合的交集存入另一个set集合
9sunion key1 key2返回两个set集合的并集
10sunionstore var key1 key2返回两个set集合的并集存入另一个set集合
11smove key1 key2 value把key1中的某元素移入key2中
12scard key返回set集合中元素个数
13sismember key value判断集合是否包含某个值
14srandmember key count随机获取set集合中元素

5. Redis 有序集合(sorted set)

5.1 概念

【1】Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员;

【2】不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序;

【3】有序集合的成员是唯一的,但分数(score)却可以重复。

5.2 常用命令

序号命令作用
1zadd key score name存入分数和名称(zadd contest 100 play1
zadd contest 90 play2)
2zincrby key score name偏移名称对应的分数
3zrange key start end在指定分数区间内按照分数升序输出名称
4zrevrange key start end在指定分数区间内按照分数降序输出名称
5zrank key name升序返回排名(0开始)
6zrevrank key name降序返回排名(0开始)
7zcard key返回元素个数
8zrangebyscore key min max [withscores]按照分数范围升序输出名称
9zrevrangebyscore key max min [withscores]按照分数范围降序输出名称
10zrem key name删除名称和分数
11zremrangebyscore key min max [withscores]根据分数范围删除元素
12zremrangebyrank key start end根据排名删除元素
13zcount key min max按照分数范围统计个数

六、Redis 进阶

1. 全局命令

序号命令作用
1keys * (可以模糊查询)返回满足的所有键
2exists key [key …]是否存在指定 key,返回存在的 key 的个数
3expire key seconds设置某个key的过期时间.使用ttl查看剩余时间
4persist key在时间结束之前取消过期时间
5flushdb清空当前数据库,flushall清空所有数据库
6select 选择数据库选择数据库 数据库为0到15(一共16个数据库) 默认进入的是0数据库
7move [key] [数据库下标将当前数据中的key转移到其他数据库中
8randomkey随机返回数据库里的一个key
9rename重命名key
10echo打印名
11dbsize查看数据库的key数量
12info获取数据库信息
13config get实时传储收到的请求(返回相关的配置信息)
14config get *返回所有配置

2. Redis 安全

因为redis速度非常快,所以在一台比较好的服务器下,一个外部用户在一秒内可以进行15w次的密码尝试,这意味你需要设定非常强大的密码来来防止暴力破解。

2.1. 修改密码

【1】vi编辑 redis.conf 文件,找到 requirepass [密码] 进行保存修改;
【2】重启服务器 pkill redis-server;
【3】再次进入127.0.01:6379>keys *,出现: (error)NOAUTH Authentication required;
【4】会发现没有权限进行查询auth [密码];
【5】输入密码则成功进入;
【6】每次进入的时候都需要输入免密,还有种简单的方式:redis-cli -a [密码]


3. Redis 事务

3.1 概念

【1】Redis会将一个事务中的所有命令序列化,然后按顺序执行;

【2】单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的;

【3】事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。


3.2 事务命令

序号命令作用
1MULTI标记一个事务块的开始
2EXEC执行所有事务块内的命令
3UNWATCH取消 WATCH 命令对所有 key 的监视
4DISCARD取消事务,放弃执行事务块内的所有命令
5WATCH key [key …]监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断

3.3 案例

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name yy
QUEUED
127.0.0.1:6379> get name
QUEUED
127.0.0.1:6379> set message "my name is yy"
QUEUED
127.0.0.1:6379> get message
QUEUED
127.0.0.1:6379> exec
1) OK
2) "yy"
3) OK
4) "my name is yy"

4. redis 持久化机制

4.1 RDB 方式

snapshotting(快照) 默认方式.将内存中以快照的方式写入到二进制文件中,默认为 dump.rdb,可以配置设置自动做快照持久化方式,我们可以配置 redis 在 n 秒内如果超过 m 个 key 就修改自动做快照。

Snapshotting设置:
save 900 1 # 900秒内如果超过 1 个 Key 被修改则发起快照保存;
save 300 10 # 300秒内如果超过 10 个 key 被修改,则发起快照保存;
save 60 10000 # 60秒内如果超过 10000 个 key 被修改,则发起快照保存;


4.2 AOF 方式

append-only file (缩写aof) 的方式,由于快照方式是在一定时间间隔做一次,所以可能发生 reids 意外 down 的情况就会丢失最后一次快照后的所有修改的数据。aof 比快照方式有更好的持久化性,是由于在使用aof时,redis会将每一个收到的写命令都通过write函数追加到命令中,当redis重新启动时会重新执行文件中保存的写命令来在内存中重建这个数据库的内容。这个文件在bin目录下:appendonly.aof。
aof不是立即写到硬盘中,可以通过配置文件修改强制写到硬盘中。

aof设置:

appendonly yes //启动aof持久化方式有三种修改方式
#appendfsync always//收到命令就立即写到磁盘,效率最慢.但是能保证完全的持久化
#appendfsync everysec//每秒写入磁盘一次,在性能和持久化方面做了很好的折中
#appendfsync no //完全以依赖os 性能最好,持久化没保证


5. Redis内存淘汰机制及过期Key处理

5.1 内存淘汰机制

Redis内存淘汰机制是指当内存使用达到上限(可通过maxmemory配置,0为不限制,即服务器内存上限),根据一定的算法来决定淘汰掉哪些数据,以保证新数据的存入。

  • 常见的内存淘汰机制分为四大类
      1. LRU:LRU是Least recently used,最近最少使用的意思,简单的理解就是从数据库中删除最近最少访问的数据,该算法认为,你长期不用的数据,那么被再次访问的概率也就很小了,淘汰的数据为最长时间没有被使用,仅与时间相关。
      2. LFU:LFU是Least Frequently Used,最不经常使用的意思,简单的理解就是淘汰一段时间内,使用次数最少的数据,这个与频次和时间相关。
      3. TTL:Redis中,有的数据是设置了过期时间的,而设置了过期时间的这部分数据,就是该算法要解决的对象。如果你快过期了,不好意思,我内存现在不够了,反正你也要退休了,提前送你一程,把你干掉吧。
      4. 随机淘汰:生死有命,富贵在天,是否被干掉,全凭天意了。

  • 通过maxmemroy-policy可以配置具体的淘汰机制
      1. volatile-lru -> 找出已经设置过期时间的数据集,将最近最少使用(被访问到)的数据干掉。
      2. volatile-ttl -> 找出已经设置过期时间的数据集,将即将过期的数据干掉。
      3. volatile-random -> 找出已经设置过期时间的数据集,进行无差别攻击,随机干掉数据。
      4. volatile-lfu -> 找出已经设置过期时间的数据集,将一段时间内,使用次数最少的数据干掉。
      5. allkeys-lru ->与第1个差不多,数据集从设置过期时间数据变为全体数据。
      6. allkeys-lfu -> 与第4个差不多,数据集从设置过期时间数据变为全体数据。
      7. allkeys-random -> 与第3个差不多,数据集从设置过期时间数据变为全体数据。
      8. no-enviction -> 什么都不干,报错,告诉你内存不足,这样的好处是可以保证数据不丢失,这也是系统默认的淘汰策略。


5.2 Redis过期Key清除策略

Redis中大家会对存入的数据设置过期时间,那么这些数据如果过期了,Redis是怎么样把他们消灭掉的呢?我们一起来探讨一下。下面介绍三种清除策略:

  1. 惰性删除:当访问Key时,才去判断它是否过期,如果过期,直接干掉。这种方式对CPU很友好,但是一个key如果长期不用,一直存在内存里,会造成内存浪费。

  2. 定时删除:设置键的过期时间的同时,创建一个定时器,当到达过期时间点,立即执行对Key的删除操作,这种方式最不友好。

  3. 定期删除:隔一段时间,对数据进行一次检查,删除里面的过期Key,至于要删除多少过期Key,检查多少数据,则由算法决定。举个例子方便大家理解:Redis每秒随机取100个数据进行过期检查,删除检查数据中所有已经过期的Key,如果过期的Key占比大于总数的25%,也就是超过25个,再重复上述检查操作。

小结Redis服务器实际使用的是惰性删除和定期删除两种策略:通过配合使用这两种删除策略,可以很好地在合理使用CPU和避免浪费内存之间取得平衡。


七、Redis 的使用

1. Redis 和 RedisTemplate 的区别

Jedis是Redis官方推荐的面向Java的操作Redis的客户端,一般我们不直接使用 Redis,而是在 Redis 上面封装一层,直接操作其业务;RedisTemplate就是SpringDataRedis中对JedisApi的高度封装
SpringDataRedis相对于Jedis来说可以方便地更换Redis的Java客户端,比Jedis多了自动管理连接池的特性,方便与其他Spring框架进行搭配使用如:SpringCache。


2. 引入依赖

<packaging>jar</packaging>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.3</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

3. Jedis基本使用

3.1 API 的使用(同 redis 命令一致)

package com.yy.redis;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

@SpringBootTest
public class JedisTest {

    @Test
    public void testJedisPool() {
        // 1:创建Jedis连接池
        JedisPool pool = new JedisPool("localhost", 6379);
        // 2:从连接池中获取Jedis对象
        Jedis jedis = pool.getResource();
        System.out.println("jedis = " + jedis);
        // 3、设置密码
        // edis.auth(密码);

        // 4、API 的使用,只列出一个,替他同操作命令相同
        jedis.set("name", "yy");
        System.out.println("name = " + jedis.get("name"));

        // 5、关闭资源
        jedis.close();
        pool.destroy();
    }
}

3.2 项目开发设置

@Test
public void testTool(){
    GenericObjectPoolConfig config = new GenericObjectPoolConfig();
    // 最大连接数, 默认8个
    config.setMaxTotal(100);
    // 最大空闲连接数, 默认8个
    config.setMaxIdle(20);
    // 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
    config.setMaxWaitMillis(-1);
    // 在获取连接的时候检查有效性, 默认false
    config.setTestOnBorrow(true);
    JedisPool pool = new JedisPool(config,"192.168.122.128",6379,5000,"wolfcode");
    Jedis j = pool.getResource();
    String name = j.get("name");
    System.out.println(name);
    j.close();
    pool.close();
    pool.destroy();
}

4. 集成SpringBoot(同 redis 命令全称)

4.1 application.properties 配置文件

#application.properties
spring.redis.host=127.0.0.1
spring.redis.port=6379
#spring.redis.password=admin

4.2 App 启动类

package com.yy.redis;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

4.3 TestTemplate 测试类

package com.yy.redis;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;

@SpringBootTest
public class TestTemplate {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Test
    public void testRedisTemplate() {
        // 操作字符串 String
        redisTemplate.opsForValue().set("name", "yy");
        System.out.println("name = " + redisTemplate.opsForValue().get("name"));
        /*// 操作 hash
        redisTemplate.opsForHash().xx();
        // 操作 list
        redisTemplate.opsForList().xx();
        // 操作 set
        redisTemplate.opsForSet().xx();
        // 操作有序 zset
        redisTemplate.opsForZSet().xx();*/
    }
}

八 RedisTemplate 常用方法

博客地址:RedisTemplate 常用方法


九、案例

1. 需求

需求:页面上有一篇文章, 访问(刷新)一次,阅读数+1


2. 项目准备

2.1 项目结构

在这里插入图片描述


2.2 pom.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.yy..redis</groupId>
    <artifactId>redis-demo</artifactId>
    <version>1.0.1</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
        <relativePath/>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

2.3 application.properties 配置文件

#application.properties
spring.redis.host=127.0.0.1
spring.redis.port=6379
#spring.redis.password=admin

2.4 App 启动类

package com.yy.redis;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
    public static 以上是关于Redis 入门和 RedisTemplate 常用方法(常用命令 + 案例源码)的主要内容,如果未能解决你的问题,请参考以下文章

使用RedisTemplate实现Redis分布式锁出现的一些列问题(避坑)

Redis# 常见报错Unsatisfied dependency设置密码主从配置

Redis 数据类型操作指令以及对应的RedisTemplate方法

Redis系列--7RedisTemplate和 Serializer详解

redis的lua脚本快速入门

关于RedisTemplate和StringRedisTemplate(转)