Redis学习笔记

48 阅读7分钟

一、Redis概述

Redis是一个基于内存的key-value结构数据库。

  • 基于内存存储,读写性能高
  • 适合存储热点数据(热点商品、资讯、新闻)

1.简介

​ Redis是一个开源的内存中的数据结构存储系统,它可以用作:数据库、缓存和消息中间件。官网:redis.io

​ Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。它存储的value类型比较丰富,也被称为结构化的NoSql数据库。

​ NoSql(Not Only SQL),不仅仅是SQL,泛指非关系型数据库。NoSql数据库并不是要取代关系型数据库,而是关系型数据库的补充。

2.数据库种类

关系型数据库(RDBMS)非关系型数据库(NoSql)
MysqlRedis
OracleMongo db
DB2MemCached
SQLServer

3.Redis 应用场景

  • 缓存
  • 任务队列
  • 消息队列
  • 分布式锁

二、Redis入门

Redis 下载与安装

Redis安装包分为windows版和Linux版:

在Linux系统安装Redis步骤:

1.将Redis安装包上传到Linux

2.解压安装包,命令:tar-zxvf redis-4.0.0.tar.gz-C/usr/local

3.安装Redis的依赖环境gcc,命令:yum install gcc-c++

4.进入/usr/local/redis-4.0.0,进行编译,命令:make

5.进入redis的src目录,进行安装,命令:make install

在文件中设置连接密码

vim redis.conf   编辑配置文件,将密码的注释消去
requirepass 123456  设置新密码

ps -ef | grep redis 查询redis的进程
kill -9 31133  沙掉进程,结束redis

src/redis-server ./redis.conf  启动服务前重新加载配置文件

src/redis-cli -h localhost -p 6379 启动客户端
操作时会要求输入密码
auth 123456

exit 退出redis服务

配置文件中
bind 127.0.0.1 设置只有本地能连接(注释掉才能运行远程连接)

连接远程redis服务
./redsi-cli.exe -h 192.168.138.100 -p 6379 -a 123456

三、数据类型

Redis存储的是key-valye结构的数据,其中key是字符串类型,value有5种常用的数据类型:

数据类型
string字符串
hash哈希
list列表
set集合
sorted set有序集合---每个元素都有分值,可以做排行榜

四、常用命令

1.字符串 string 操作命令

Redis 中字符串类型常用命令:

常用命令备注
SET key value设置指定key的值
GET key获取指定key的值不存在时,返回nil,相当于null
SETEX key seconds value设置指定key的值,并将key的过期时间设为 seconds 秒用于设置限时过期的验证码
SETNX key value只有在 key 不存在时设置 key的值分布式锁

更多命令可以参考Redis中文网:www.redis.net.cn

2.哈希hash操作命令

​ Redis hash是一个string类型的field和value 的映射表,hash特别适合用于存储对象,常用命令:

命令
HSET key field value将哈希表key 中的字段field的值设为value(修改key对应内容v)
HGET key field获取存储在哈希表中指定字段的值
HDEL key field删除存储在哈希表中的指定字段
HKEYS key获取哈希表中所有字段
HVALS key获取哈希表中所有值
HGETALL key获取在哈希表中指定key的所有字段和值

3.列表list操作命令

​ Redis 列表是简单的字符串列表,按照插入顺序排序,常用命令:

  • LPUSH key value1 [value2] 将一个或多个值插入到列表头部
    • key是listName
  • LRANGE key start stop 获取列表指定范围内的元素
    • LRANGE myList 0 -1查询从开始到结束,全部元素,倒序cba
  • RPOP key 移除并获取列表最后一个元素
  • LLEN key 获取列表长度
  • BRPOP key1 [key2] timeout
    • 移出并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
    • 实现任务队列

4.集合set 操作命令

​ Redis set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据,常用命令:

  • SADD key member1 [member2] 向集合添加一个或多个成员
    • key是set集合的名称
  • SMEMBERS key 返回集合中的所有成员
  • SCARD key获取集合的成员数
  • SINTER key1 [key2]返回给定所有集合的交集
  • SUNION key1 [key2]返回所有给定集合的并集
  • SDIFF key1 [key2]返回给定所有集合的差集
    • 有前后顺序区别,结果是前者的独有数据
  • SREM key member1 [member2]移除集合中一个或多个成员

5.有序集合 sorted set 操作命令

​ Redis sorted set有序集合是string类型元素的集合,且不允许重复的成员。每个元素都会关联一个double类型的分数(score)。redis正是通过分数来为集合中的成员进行从小到大排序。有序集合的成员是唯一的,但分数却可以重复。

常用命令:

  • ZADD key score1 member1 [score2 member2]向有序集合添加一个或多个成员,或者更新已存在成员的分数
  • ZRANGE key start stop [WITHSCORES]通过索引区间返回有序集合中指定区间内的成员
    • withscores :返回分数
  • ZINCRBY key increment member有序集合中对指定成员的分数加上增量
  • incrementZREM key member [member ...]移除有序集合中的一个或多个成员

6.通用命令

  • KEYS pattern查找所有符合给定模式(pattern)的 key
  • EXISTS key检查给定key是否存在
  • TYPE key返回 key 所储存的值的类型
  • TTL key返回给定 key的剩余生存时间(TTL,time to live),以秒为单位
    • -1 存活时间永久
  • DEL key该命令用于在key存在是删除key

五、在Java中操作Redis

Redis 的Java 客户端很多,官方推荐的有三种:

  • Jedis
  • Lettuce
  • Redisson

Spring 对Redis 客户端进行了整合,提供了Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即spring-boot-starter-data-redis

1.Jedis

Jedis的maven坐标:

<dependency>
    <groupld>redis.clients</groupld>
    <artifactld>jedis</artifactld>
    <version>2.8.0</version>
</dependency>
import org.junit.Test;
import redis.clients.jedis.Jedis;
import java.util.Set;

/**
 * 通过Jedis连接redis
 */
public class Jedis_Test {

    @Test
    public void testRedis(){
        Jedis localhost = new Jedis("localhost", 6379);
        //添加
        localhost.set("username","wind");

        //String username = localhost.get("username");
        //System.out.println(username);

        //删除
        //localhost.del("username");

        //hash
        localhost.hset("myhash","addr","obj");
        localhost.hset("myhash","name","wind");

        String hget = localhost.hget("myhash", "addr");

        //获取所有的键值
        Set<String> keys = localhost.keys("*");
        for (String key : keys) {
            System.out.println(key);
        }

        localhost.close();
    }
}

2.Spring Data Redis

在Spring Boot项目中,可以使用Spring Data Redis来简化Redis操作,maven坐标:

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

Spring Data Redis中提供了一个高度封装的类:RedisTemplate, 针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:

分类操作接口
ValueOperations简单K-V操作
SetOperationsset类型数据操作
ZSetOperationszset类型数据操作
HashOperations针对map类型的数据操作
ListOperations针对list类型的数据操作
server:
  port: 8080
spring:
  application:
    #应用名称,可选项(默认工程名)
    name: jedis_demo
    #Redis相关配置
    redis:
      host: localhost
      port: 6379
      #password: 123456
      database: 0 #0号数据库,有0-15
      jedis:
          #Redis连接池配置
        pool:
          max-active: 8 #最大连接数
          max-wait: 1ms #连接池最大阻塞等待时间
          max-idle: 4 #连接池中的最大空闲连接
          min-idle: 0 #连接池中的最小空闲连接

3.SpringBoot

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.*;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@SpringBootTest
@RunWith(SpringRunner.class)
public class SpringBootDataRedisTest {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 操作String类型数据
     */
    @Test
    public void testString(){
        redisTemplate.opsForValue().set("home","home");

        //key, v,time,单位
        redisTemplate.opsForValue().set("home1","home1",10l, TimeUnit.SECONDS);

        //如果有,不操作;没有,创建
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("city10086", "annan");
    }

    /**
     * 操作Hash类型数据
     */
    @Test
    public void testHash(){
        HashOperations hashOperations = redisTemplate.opsForHash();
        //存值
        hashOperations.put("001","name","wind");
        hashOperations.put("001","age","15");

        //取字段值
        String name = (String) hashOperations.get("001", "name");
        System.out.println(name);

        //取所有字段
        Set keys = hashOperations.keys("001");
        for (Object key : keys) {
            System.out.println(key);
        }

        //取所有值
        List values = hashOperations.values("001");
        for (Object value : values) {
            System.out.println(value);
        }
    }

    /**
     * 操作List类型数据
     */
    @Test
    public void testList(){
        ListOperations listOperations = redisTemplate.opsForList();
        //存
        listOperations.leftPush("myList","a");
        listOperations.leftPushAll("myList","b","c","d");

        //取,0,-1 全部
        List<String> myList = listOperations.range("myList", 0, -1);
        myList.forEach(o -> {
            System.out.println(o);
        });

        System.out.println("弹出==================");
        //获得列表长度
        Long size = listOperations.size("myList");
        int LSize = size.intValue();
        for (int i = 0; i < LSize; i++) {
            //出队列
            String element = (String) listOperations.rightPop("myList");
            System.out.println(element);
        }

    }

    /**
     * 操作Set类型数据
     */
    @Test
    public void testSet(){
        SetOperations setOperations = redisTemplate.opsForSet();

        setOperations.add("mySet","a","b","v","p","v");

        //取出全部
        Set<String> mySet = setOperations.members("mySet");
        for (String s : mySet) {
            System.out.println(s);
        }

        //删除
        setOperations.remove("mySet","b","v");
    }

    /**
     * 操作Zset类型数据
     */
    @Test
    public void  testZset(){
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        zSetOperations.add("myZset","a",9.9);
        zSetOperations.add("myZset","b",19.9);
        zSetOperations.add("myZset","c",0.9);

        Set<String> myZset = zSetOperations.range("myZset", 0, -1);
        for (String s : myZset) {
            System.out.println(s);
        }

        //修改分数
        zSetOperations.incrementScore("myZset","a",10.0);
        Set<String> myZset01 = zSetOperations.range("myZset", 0, -1);
        for (String s : myZset01) {
            System.out.println(s);
        }

        //移除
        zSetOperations.remove("myZset","b");
    }

    /**
     * 通用操作命令
     */
    @Test
    public void testCommon(){
        //获取所有key
        Set keys = redisTemplate.keys("*");

        //判断某个key是否存在
        Boolean myZset = redisTemplate.hasKey("myZset");
        // 删除指定key
        Boolean myZset1 = redisTemplate.delete("myZset");
        // 获取指定key对应的value类型
        DataType dataType = redisTemplate.type("mySet");
        System.out.println(dataType.name());
    }
}

Record Date:2023/03/23