首页 > 数据库 >redis

redis

时间:2023-09-20 16:14:00浏览次数:64  
标签:redis Redis System key println out

前言

原文作者: Kyle Violet

文章链接: Redis 入门 | Kyle's Blog (cyborg2077.github.io)

版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Kyle's Blog

本文章为在原文基础上,进行稍作修改的文章,版权声明如上。


本文为瑞吉外卖项目的后续内容,在此特别感谢黑马程序员的课程

32:16:10 黑马程序员 Java 项目实战《瑞吉外卖》,轻松掌握 springboot + mybatis plus 开发核心技术的真 java 实战项目 259.0 万 7.7 万视频 黑马程序员

Redis 入门

  • Redis 是一个基于内存的key-value结构数据库
    • 基于内存存储,读写性能高
    • 适合存储热点数据(热点商品、咨询、新闻)
  • 官网:https://redis.io/

Redis 简介

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

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

    关系型数据库(RDBMS):MySQL、Oracl、DB2、SQLServer
    非关系型数据库(NoSql):Redis、Mongo DB、MemCached

  • Redis 应用场景:缓存、消息队列、任务队列、分布式锁

下载与安装

Windows 安装 Redis

Linux 安装 Redis

  • Linux 系统安装 Redis 步骤:

    1. 将 Redis 安装包上传到 Linux

    2. 解压安装包,改成你自己的 redis 版本,路径我习惯解压到

      /usr/local
      
      复制成功tar -zxvf redisVersion.tar.gz -C /usr/local
      
    3. 安装 Redis 的依赖环境 gcc,我的云服务器已经装过了,本地的 Linux 还没装

      • 这里需要确保能联网,否则会安装失败 用 ping www.baidu.com 就可以检测出来了。如果不能联网,
      • 就输入: cd /etc/sysconfig/network-scripts/
      • 然后 vim ifcfg-ens33
      • 把里面在前面配置的 static(静态 ip,改成 dhcp 动态 ip)
      • systemctl restart network
      • 即可

      然后继续安装

      复制成功# 安装依赖环境
      yum install gcc-c++
      
    4. 进入

      /usr/local/redis根目录
      

      image-20230712131531500

      进行编译

      # 进入到根目录
      cd /usr/local/redis根目录
      
      # 编译
      make
      
    5. 进入 redis 的 src 目录,进行安装

      # 进入到src目录
      cd /usr/local/redis根目录/src
      # 进行安装
      make install
      

      image-20230712131743606

服务启动与停止

Linux 启动与停止

  • 进入到

    /src
    

    目录下,执行

    redis-server
    

    即可启动服务,默认端口号为

    6379
    
    # 进入到根目录
    cd /usr/local/redis根目录/src
    
    # 执行redis-server
    ./redis-server
    

    or

    [root@localhost ~]# ps -ef | grep redis
    root       7695   7286  0 09:58 pts/0    00:00:00 grep --color=auto redis
    [root@localhost ~]# cd /usr/local/redis-4.0.0/
    [root@localhost redis-4.0.0]# src/redis-server ./redis.conf   #启动redis服务
    

    Linux 设置后台运行

  • 进入到 redis 根目录下,修改配置 redis.conf 文件

    # 进入到redis根目录下
    cd /usr/local/redis根目录
    
    # 修改配置文件
    vim redis.conf
    
  • 找到daemonize no字段,将其修改为daemonize yes

    • 这里需要用/dae 来找
  • 在 redis 根目录以 redis.conf 作为配置文件在后台运行

    src/redis-server ./redis.conf
    

Linux 开启密码校验

  • 还是修改 redis.conf 配置文件,找到requirepass这行,将其注释去掉,并在后面写上自己的密码

  • 然后杀掉原进程再重新启动

  • image-20230712142159011

  • # 重新启动
    src/redis-server ./redis.conf
    
    # 登录时同时进行认证
    src/redis-cli -h localhost -p 6379 -a 密码
    
  • 修改完毕之后还是杀进程,然后重启服务

Linux 开启远程连接

  • 还是修改 redis.conf 配置文件,找到bind 127.0.0.1这行,把这行注释掉

  • 之后设置防火墙,开启 6379 端口

    # 开启6379端口
    firewall-cmd --zone=public --add-port=6379/tcp --permanent
    
    # 设置立即生效
    firewall-cmd --reload
    
    # 查看开放的端口
    firewall-cmd --zone=public --list-ports
    

    img

    • 居然还是拒绝
      • image-20230712144411902
      • 原因是忘记杀进程重启了,再杀进程重启就行

    云服务器开放端口,需要进入后台手动开启,通过命令行开启的端口无效,查看开放的端口确实有 6379,但是实际上是没开放的,我昨天因为这个,连不上 MySQL(3306 端口没开,我以为开了),找了俩小时的原因

    img

  • 最后在 Windows 的 redis 根目录下,按住 Shift+右键打开 PowerShell 窗口,连接 Linux 的 Redis

    .\redis-cli.exe -h 服务器地址 -p 6379 -a 密码
    

Redis 数据类型

介绍

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

  • 字符串:String
  • 哈希:Hash
  • 列表:List
  • 集合:Set
  • 有序集合:Sorted Set

字符串(String)常用命令

命令 描述
SET key value 设置指定 key 的值
GET key 获取指定 key 的值
SETEX key seconds value 设置指定 key 的值,并将 key 的过期时间设为 seconds 秒
SETNX key value 只有在 key 不存在时设置 key 的值

哈希(Hash)常用命令

Redis Hash是一个String类型的FieldValue的映射表,Hash特别适合用于存储对象

命令 描述
HSET key field value 将哈希表 key 中的字段 field 的值设为 value
HGET key field 获取存储在哈希表中指定字段的值
HDEL key field 删除存储在哈希表中的指定字段
HKEYS key 获取哈希表中所有字段
HVALS key 获取哈希表中所有值
HGETALL key 获取在哈希表中指定 key 的所有字段和值

列表(List)常用命令

Redis List是简单的字符串列表,按照插入顺序排序

命令 描述
LPUSH key value1 [value2] 将一个或多个值插入到列表头部
LRANGE key start stop 获取列表指定范围内的元素
RPOP key 移除并获取列表最后一个元素
LLEN key 获取列表长度
BRPOP key1 [key2] timeout 移出并获取列表的最后一个元素 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止

集合(Set)常用命令

Redis setString类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据

命令 描述
SADD key member1 [member2] 向集合添加一个或多个成员
SMEMBERS key 返回集合中的所有成员
SCARD key 获取集合的成员数
SINTER key1 [key2] 返回给定所有集合的交集
SUNION key1 [key2] 返回所有给定集合的并集
SDIFF key1 [key2] 返回给定所有集合的差集
SREM key member1 [member2] 移除集合中一个或多个成员

有序集合(Sorted Set)常用命令

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

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

通用命令

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

更多详细的命令可以查看官方文档:https://www.redis.net.cn/order/

在 Java 中使用 Redis

简介

  • Redis 的 Java 客户端有很多,官方推荐的有三种
    • Jedis
    • Lettuce
    • Redisson
  • Spring 对 Redis 客户端进行了整合,提供了 SpringDataRedis,在 Spring Boot 项目中还提供了对应的 Starter,即spring-boot-starter-data-redis

Jedis

  • 使用 Jedis 的步骤

    1. 获取连接
    2. 执行操作
    3. 关闭连接
  • 在此之前我们需要导入一下 Jedis 的 maven 坐标

    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.8.0</version>
    </dependency>
    
  • 编写测试类

    @SpringBootTest
    class RedisTestApplicationTests {
    
        @Test
        void contextLoads() {
            //1. 获取连接
            Jedis jedis = new Jedis("localhost", 6379);
            //2. 执行具体操作
            jedis.set("name", "Hades");
    
            jedis.hset("stu", "name", "Jerry");
            jedis.hset("stu", "age", "18");
            jedis.hset("stu", "num", "4204000400");
    
            Map<String, String> map = jedis.hgetAll("stu");
            Set<String> keySet = map.keySet();
            for (String key : keySet) {
                String value = map.get(key);
                System.out.println(key + ":" + value);
            }
            String name = jedis.get("name");
            System.out.println(name);
            //3. 关闭连接
            jedis.close();
        }
    
    }
    
  • 输出结果

    num:4204000400
    name:Jerry
    age:18
    Hades

  • Jedis 我们了解一下即可,大多数情况下我们还是用 SpringDataRedis 的

Spring Data Redis

  • SpringBoot 项目中,可以使用 SpringDataRedis 来简化 Redis(常用)

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

    • ValueOperations:简单 K-V 操作
    • SetOperations:set 类型数据操作
    • ZSetOperations:zset 类型数据操作
    • HashOperations:针对 map 类型的数据操作
    • ListOperations:针对 list 类型的数据操作
  • 使用 SpringDataRedis,我们首先需要导入它的 maven 坐标

    <!--Spring Boot-redis的依赖包-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
  • 之后重新设置一下序列化器,防止出现乱码,在 config 包下创建

    RedisConfig
    

    配置类

    @Configuration
    public class RedisConfig extends CachingConfigurerSupport {
        @Bean
        public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
    
            RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
    
            //默认的Key序列化器为:JdkSerializationRedisSerializer
            redisTemplate.setKeySerializer(new StringRedisSerializer());
            redisTemplate.setHashKeySerializer(new StringRedisSerializer());
    
            redisTemplate.setConnectionFactory(connectionFactory);
    
            return redisTemplate;
        }
    }
    
  • 随后配置一下连接 redis 的相关配置

    spring:
      redis:
        host: localhost
        port: 6379
        #password: root
        database: 0 #操作的是0号数据库
        jedis:
          #Redis连接池配置
          pool:
            max-active: 8 #最大连接数
            max-wait: 1ms #连接池最大阻塞等待时间
            max-idle: 4 #连接池中的最大空闲连接
            min-idle: 0 #连接池中的最小空闲连接
    
  • String类型数据操作

    @Test
    void stringTest() {
        //获取对象
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //设置name为Hades
        valueOperations.set("name","Hades");
        String name = (String) valueOperations.get("name");
        System.out.println(name);
        //设置age为9527,有效时间10秒
        valueOperations.set("age", "9527", 10, TimeUnit.SECONDS);
        String age = (String) valueOperations.get("age");
        System.out.println(age);
        //如果不存在,则设置name为Kyle
        Boolean aBoolean = valueOperations.setIfAbsent("name", "Kyle");
        System.out.println(aBoolean);
    }
    

    输出结果如下,由于 name 已经存在,故 Kyle 设置失败,最后返回 false,10 秒过后,我们再去 redis 中 get name,则输出nil,表示不存在

    Hades
    9527
    false

  • Hash
    

    类型数据操作

    @Test
    void hashTest() {
        HashOperations hashOperations = redisTemplate.opsForHash();
        hashOperations.put("4204000400", "name", "Hades");
        hashOperations.put("4204000400", "age", "18");
        hashOperations.put("4204000400", "hobby", "Apex");
        //获取map集合
        Map<String, String> map = hashOperations.entries("4204000400");
        Set<String> keySet = map.keySet();
        for (String hashKey : keySet) {
            System.out.println(hashKey + ":" + map.get(hashKey));
        }
        System.out.println("$$$$$$$$$$$$$$$");
        //只获取keys
        Set<String> keys = hashOperations.keys("4204000400");
        for (String key : keys) {
            System.out.println(key);
        }
        System.out.println("$$$$$$$$$$$$$$$");
        //只获取values
        List<String> values = hashOperations.values("4204000400");
        for (String value : values) {
            System.out.println(value);
        }
    }
    

    输出结果如下

    name:Hades
    age:18
    hobby:Apex

    Hades
    18
    Apex

  • List类型数据操作

    @Test
    void listTest() {
        ListOperations listOperations = redisTemplate.opsForList();
        //存数据
        listOperations.leftPush("testData", "A");
        listOperations.leftPushAll("testData", "B", "C", "D");
        List<String> testDatas = listOperations.range("testData", 0, -1);
        //遍历
        for (String tableData : testDatas) {
            System.out.print(tableData + " ");
        }
        System.out.println();
        //获取当前list长度,用于遍历
        Long size = listOperations.size("testData");
        int value = size.intValue();
        //遍历输出并删除
        for (int i = 0; i < value; i++) {
            System.out.print(listOperations.leftPop("testData") + " ");
        }
        //最后输出一下当前list长度
        System.out.println();
        System.out.println(listOperations.size("testData"));
    }
    

    输出结果如下

    D C B A
    D C B A
    0

  • Set类型数据操作

    @Test
    void setTest() {
        SetOperations setOperations = redisTemplate.opsForSet();
        //存数据,这里存了两个a
        setOperations.add("tmp", "a", "b", "c", "d", "a");
        遍历输出
        Set<String> tmpData = setOperations.members("tmp");
        for (String value : tmpData) {
            System.out.print(value + " ");
        }
        System.out.println();
        System.out.println("$$$$$$$$$$$$$$$$$$$");
        //删除bc
        setOperations.remove("tmp", "b", "c");
        //再次遍历输出
        tmpData = setOperations.members("tmp");
        for (String value : tmpData) {
            System.out.print(value + " ");
        }
    }
    

    输出结果如下,符合预期

    d b c a

    d a

  • ZSet类型数据操作

    @Test
    void zsetTest() {
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        //存值
        zSetOperations.add("myZset", "a", 0.0);
        zSetOperations.add("myZset", "b", 1.0);
        zSetOperations.add("myZset", "c", 2.0);
        zSetOperations.add("myZset", "a", 3.0);
        //取值
        Set<String> myZset = zSetOperations.range("myZset", 0, -1);
        for (String s : myZset) {
            System.out.println(s);
        }
        //修改分数
        zSetOperations.incrementScore("myZset", "b", 4.0);
        //取值
        System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$");
        myZset = zSetOperations.range("myZset", 0, -1);
        for (String s : myZset) {
            System.out.println(s);
        }
        //删除成员
        zSetOperations.remove("myZset", "a", "b");
        //取值
        System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$");
        myZset = zSetOperations.range("myZset", 0, -1);
        for (String s : myZset) {
            System.out.println(s);
        }
    }
    

    输出结果如下
    b
    c
    a

    c

  • 通用的数据类型操作

    @Test
    void commonTest() {
        //查看所有key
        Set<String> keys = redisTemplate.keys("*");
        for (String key : keys) {
            System.out.println(key);
        }
        //查看是否存在指定key
        System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$");
        System.out.println(redisTemplate.hasKey("Random"));
        System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$");
        //删除指定key,并再次查看
        redisTemplate.delete("myZset");
        keys = redisTemplate.keys("*");
        for (String key : keys) {
            System.out.println(key);
        }
        System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$");
        //输出指定key的类型
        System.out.println(redisTemplate.type("tmp"));
    }
    

    输出结果如下

    tmp
    name
    4204000400
    stu
    myData

    tmp
    name
    4204000400
    stu
    myData

    SET

标签:redis,Redis,System,key,println,out
From: https://www.cnblogs.com/Lovi/p/17717512.html

相关文章

  • Redis 面试常见问答
    本文出自:https://thinkinjava.cn作者:莫那鲁道1.什么是缓存雪崩?怎么解决?一般而言,我们会利用缓存来缓冲对数据库的冲击,假如缓存无法正常工作,所有的请求便会直接发送至数据库,进而导致数据库崩溃,从而导致整个系统崩溃。如何解决呢?2种策略(同时使用):对缓存做高可用,防止缓......
  • redis cluster三主六从 redis三主三从集群搭建
    转自:https://blog.51cto.com/u_16099166/6885197一、下载安装二、本文架构(三台服务器,每台部署两个节点,主从同步,生产最好是部署六台服务器): 三、进入redis安装目录,复制redis.conf文件,建立从节点配置文件1#进入redis安装目录2cdredis34#复制redis.conf文件5cpredis.......
  • redis三主三从哨兵模式 redis三主三从集群
    转自:https://blog.51cto.com/u_16213559/7033634conf复制/usr/local/src/redis-6.2.6文件夹下redis.conf文件到/usr/local/src/master-slave文件夹中命名为redis6381.conf1#允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不......
  • 解决安装VS2022时,出现未能安装包"Microsoft.VisualCpp.Redist.14,version=14.32.31332
    解决安装VS2022时,出现未能安装包"Microsoft.VisualCpp.Redist.14,version=14.32.31332,chip”=x86"问题描述之前安装过MSSQLServer和VS2022,但是后来又卸载了。现在重装VS2022出现两个报错:无法安装Microsoft.VisualCpp.Redist.14,version=14.32.31332,chip”=x86无法安装Micr......
  • redis和mysql的区别以及它们是如何配合使用的
    redis和mysql的区别:1、从类型上来说,mysql是关系型数据库,redis是缓存数据库。2、mysql用于持久化的存储数据到硬盘,功能强大,但是速度较慢。redis用于存储使用较为频繁的数据到缓存中,读取速度快。3、mysql和redis因为需求的不同,一般都是配合使用。mysql和redis的数据库类型,m......
  • Redis7 10大数据类型(Redis基数统计)
    一、概述用途:统计某个网站的UV,统计某个文章的UV什么是UVUniqueVisitor独立访客,一般理解为客户端ip用户搜索网站关键词的数量统计用户每天搜索不同词条个数去重复统计功能的基数估计算法,就是HyperLogLog基数是一种数据集,去重复后的真实个数案例case基数统计用户统计......
  • 基本环境安装 jdk,mq,redis,nginx
    JDK:解压安装包,命令为tar-zxvfjdk-8u381-linux-x64.tar.gz配置环境变量,使用vim命令(需要安装vim,安装命令为:yuminstallvim)修改/etc/profile文件,在文件末尾加入如下配置 JAVA_HOME=/usr/local/jdk8/jdk1.8.0_381 PATH=$JAVA_HOME/bin:$PATH重新加载profile文件,使更改的配置......
  • 详细解释一下redis的缓存击穿、缓存雪崩的原理,以及如何避免?
    缓存击穿和缓存雪崩是两种常见的缓存问题,它们会对系统性能和可用性产生负面影响。以下是对这两个问题的详细解释以及如何避免它们的方法:缓存击穿(CacheMiss)原理:缓存击穿是指在高并发的情况下,多个请求同时访问缓存,但缓存中不存在所需数据。这些请求会穿透缓存,直接访问底层数据库......
  • redisson 工具类
    importcom.alibaba.fastjson.JSON;importcom.juxiao.xchat.dao.room.dto.CallStatus;importcom.juxiao.xchat.manager.cache.redis.RedissonManager;importlombok.extern.slf4j.Slf4j;importorg.redisson.api.*;importorg.redisson.client.protocol.ScoredEntry;i......
  • Redis面试题
    Redis到底是多线程还是单线程Redis6.0版本之前的单线程指的是其网络I/O和键值对的读写是由一个线程完成的。多线程在Redis6.0中的引入是为了改善一些特定场景下的性能问题,特别是在大型多核系统上。Redis6.0引入了多个I/O线程,这些线程负责处理网络事件的监听和接收。主线程仍......