Redis的简单学习(一文学会Redis!)

一,Redis的介绍(中文官网)(官网

建议进官网里学一学!讲的挺详细的,小编就仅仅展示以下自己的学习流程
下载的话建议github:github地址
在这里插入图片描述
Redis(REmote DIctionary Server) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库;是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API,内部采用单线程多路IO复用技术,一般做为缓存数据库辅助持久化的数据库,具有高性能的特点;
缓存:一般指高速访问的用于临是存储的数据存储区,适用于高并发,直接从缓存中取数据,效率高;
NOSQL:泛指非关系型数据库;不支持sql语句,不支持ACID;性能高;适用于高并发读取,海量读取;如:Redis,MongoDB,HBase

二,新建服务器和Redis的基本配置

原始服务器

找到你的redis文件夹(我这里是没有配置全局Redis,所以在文件下进入,下面将doc进入)
在这里插入图片描述

新建服务器

在这里插入图片描述

  1. 打开doc:windoc键+R,输入cmd,进入
  2. 进入文件夹:cd 我的Redis文件夹地址;(我这里因为没有配全局path,所以这样)
  3. 打开客户端:redis-server 我的配置文件位置(我这里是Redis文件夹下的conf文件夹下的redis.service-6380.conf文件,配置了再打开客户端,后面有配置)(运行客户端期间,服务端不能关闭)
  4. 打开服务端:重新进入doc下,cd进入文件夹,redis-cli -p端口号

配置redis.service-6380.conf文件(配置我们新端口的文件,可以借鉴原来的端口配置文件)

#绑定服务器地址(地址固定,且默认)
bind 127.0.0.1
#绑定服务器端口号(端口号自定义)
port 6380
#设置redis中的数据库的数量(默认16,可更改)
databases 16

控制台输出图
在这里插入图片描述
配置Redis的日志输出

#配置redis的日志文件,将控制台的信息输入在日志文件中,控制台不输出(我这里是log文件夹下的log-service-6380文文件)
logfile C:/Redis/log/log-service-6380

文件日志输出图
在这里插入图片描述
配置redis守护线程(window没有)

#设置
# redis是否使用守护线程,no表示不使用,启动时会在控制台上打印启动信息
# yes表示使用守护线程,后台启动,不打印启动信息(该配置在windows上不支持)
daemonize no

其他配置

# 指定存储到本地时是否对数据进行压缩,默认为yes,采用LZF压缩
rdbcompression yes

# 设置是否对rdb文件格式进行校验,该校验在写文件和读文件时均会进行,默认为yes(一般开启,如果设置为no读写性能会提升但存在数据损坏风险)
rdbchecksum yes

# 当后台保存数据时如果出现错误是否停止保存操作
stop-writes-on-bgsave-error yes

三,Redis的基本使用

基本指令
1.select index:切换数据库(index指具体值)

2.clear:清屏命令

3.keys pattern:获得当前库中的key("*"匹配任意数量的任意字符 "?"匹配任意一个字符 "[]"匹配其中的任意一个字符)
  keys * (获得所有的key)
  keys r* (获得所有以r开头的key)
  keys *is (获得所有以is结尾的key)
  keys ?ava (获得前面有一个任意字符,并且以ava结尾的key)
  keys u[se]r (获得前面第一个字符是u,第二个字符是s或e,结尾为r的key)
  
4.exists key:判断key是否存在

5.type key:判断key是什么类型

6.del key:删除指定的key

7.ttl key:查看过期剩余时间(-1表示永不过期,-2表示已过期)

8.dbsize:查看库中key的数量

9.flushdb:清楚当前库的所有key

10.sort key:对key中的数据进行排序,只针对集合类型(list,set)

11.sort list [asc|desc] :对key为list的集合进行排序(注意不改变原始数据)

12.flushall:清楚所有库的所有数据命令

13.quit/ exit/ ESC键:退出命令

14.ping:检测客户端与服务器连通命令

15.echo message:控制台打印命令

16.info:获得当前Redis的运行属性值

17.设置key的过期时间
expire key 1 (秒为单位)
pexpire key 1 (毫秒为单位)
persist key(永不过期)

18.修改key的名字
rename key newkey (key:旧key;newkey:新key)
renamenx str str1 #将str的key改名为str1,如果str1不存在则修改,如果存在则修改失败

19.数据在不同的库中移动
move key db
move name 1 (将当前库中的name数据移动到1号库中(注意:当前库中存在name数据,1号库中不存
在同名的数据))
数据类型

Redis自身是一个map,其中所有的值都是key-values的形式存储;key是一个字符串,values是具体的数据;
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合);操作过多!传送门:菜鸟教程

四,Redis的持久化

持久化:(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等。持久化是将程序数据在持久状态和瞬时状态间转换的机制。JDBC就是一种持久化机制。文件IO也是一种持久化机制。
redis的持久化:将redis的数据存在磁盘上,在需要时进行恢复,通过RBDAOF方式

当Redis启动时会自动读取rdb文件,将已存储的数据恢复
RDB方式(快照方式):

该方法用于备份数据,可以将redis中的数据一次性备份,关注点在数据,当数据大时耗时间,(每次存储还会再次存储上一次备份的数据);
优点
RDB得到的是一个紧凑压缩的二进制文件,存储效率比较高
RDB内部存储的是数据快照,非常适用于数据备份,数据整体复制等场景
RDB恢复数据的速度要比AOF快
缺点
RDB方式基于快照思想,每次读写全部数据,当数据量巨大时效率低、IO读写性能低下
RDB方式无法实时备份数据,数据丢失的可能性大
bgSave指令每次执行要创建子进程,内存会产生额外的消耗

设置日志文件,保存RDB方式所保存的内容
在这里插入图片描述
save方式存储数据:该方式会和其它操作一起进行,当存储数据多时,存储效率低,导致redis卡顿;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
控制台显示
在这里插入图片描述

save配置要根据实际使用场景进行使用,频度过高或过低都会给性能造成影响
调用debug reload指令重启服务器时会自动保存数据
服务器关闭时(shutdown指令关闭)会自动保存数据

bgsave存储方式:在新的进程下进行持久化存储,不会影响其他操作;(可以在任务管理器下看到进程的出现,但是由于数据小,只是一瞬)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
控制台显示
在这里插入图片描述
自动保存快照的配置,不设置该配置则不会自动保存

# 该配置表示开启自动备份功能,如果该配置不设置则不会自动备份数据当调用shutdown指令时不会自动备份数据
# 设置Redis后台自动保存数据间隔时间和数据变化量,Redis会根据以下配置自动执行bgsave命令保存数据
# 3600秒内有1个数据发生改变就自动保存
#save 3600 1
# 300秒内有100个数据发生改变就自动保存
save 300 100
# 60秒内有10000个数据发生改变就自动保存
#save 60 10000

区别

save直接调用rdbSave函数,会阻塞Redis的主进程,直到保存完成为止;
bgsave则调用fork函数生成一个子进程,子进程负责调用rdbSave函数,并在存储完成后向主进程发送信号;
两者都将日志文件存储在我们指定的rdb文件中,默认为dump.rdb文件;
AOF方式(日志方式):

Redis的主流存储方式以日志的方式将每次的写操作记录下来,只记录写操作,关注操作,需要时根据记录一步步恢复;
AOF写数据的过程:1. 将写命令写入AOF缓存区;2.到达指定时机一次写入文件;
配置AOF

#是否使用AOF方式,默认no;开启之后aof优先于rdb
appendonly yes
#写入的三种策略,配置AOF存储的写入策略
#每次写入
# appendfsync always
#每秒写入
appendfsync everysec
#系统写入
# appendfsync no

重启服务器得到
在这里插入图片描述
测试存储:
在这里插入图片描述
查看文件
在这里插入图片描述
再次测试
在这里插入图片描述
查看文件(只有age但是剩下都存储了,动作赘余了)
在这里插入图片描述
在这里插入图片描述
AOF重写

降低磁盘占用量,提高磁盘使用率,提高持久化效率,降低持久化写时间,提高IO性能提高数据恢复效率
超时数据不再写入文件
忽略无效指令、重写时使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令

自动化重写规则(可以通过info指令查看)

# AOF自动触发百分比
auto-aof-rewrite-percentage 100
# AOF自动触发最小尺寸
auto-aof-rewrite-min-size 64mb

# AOF自动触发参考值
aof_current_size:60 #当AOF触发条件的最小尺寸大于该值自动执行AOF重写
aof_base_size:60 #AOF触发基础尺寸
# 当前使用百分比大于或等于自动触发百分比时会自动执行AOF重写
# 公式:aof_current_size - auto-aof-rewrite-min-size / aof_base_size >= auto_aof-rewrite-percentage

避免大多数无效步骤,占用内存,我们对其进行了手动重写以展示效果,输入bgrewriteaof
在这里插入图片描述
控制台出现
在这里插入图片描述
文件改变
在这里插入图片描述
字节减少
在这里插入图片描述

五,Redis中的事务

当Redis执行多条命令时,可能会被其它的命令插队,从而影响结果;为了保证完成某个功能的系列操作不被其它操作指令影响,Redis提供了事务处理机制
传统的事务
多个操作不可分割,同时成功,同时失败,可通过commit提交,rollback回滚,具有四个特性:原子性,一致性,隔离性,持久性;
Redis的事务
一个指令执行队列,将一系列的操作指令包装成一个整体(队列),当执行时,将队列中的指令按照既定的顺序执行,在执行过程中不允许其它命令执行,具有排他性,Redis中没有事务回滚的概念;

开启事务:multi指令:该指令用于设置事务的开始位置,该指令后的所有指令都将加入到Redis的事务中,形
         成一个指令队列,直到exec指令或者discard指令结束
执行事务(结束事务):exec指令:该指令用于执行事务,表示事务结束并执行事务队列中的指令,
                     它与multi成对使用
取消事务:discard指令:取消事务
监控锁:watch指令 取消监控:unwatch

在这里插入图片描述
doc命令解释事务:
在这里插入图片描述
指令语法错误,则会自动取消当前事务
在这里插入图片描述
出现执行错误,则事务不会停止也不会回滚,依然执行
在这里插入图片描述

六,Redis中的锁

分布式锁

当多个线程需要同时操作一个数据时,为避免出现数据异常,我们要将数据锁起来,使用结束后在
将锁打开,此时其他线程才可以继续访问该数据,Redis中使用分布式锁实现此场景
Redis中并没有分布式锁的实现,我们可以通过setnx来设计一个分布式锁
setnx lock 1:设置锁
del lock:删除锁
在这里插入图片描述
死锁
通过分布式锁的机制可以实现数据的排他性,但是如果一个人设的锁,这个人不解锁,那么就会出现死锁现象,在设计分布式时,不允许出现死锁;可以通过设置时效性的锁来预防出现死锁
定时分布式锁
在这里插入图片描述在这里插入图片描述在这里插入图片描述
watch监控锁
当一个数据需要改变时,可能会有很多条指令改变它,则其他人就不能再改变(数据只能被改变一次),此时我们就需要使用监控锁,对要修改的数据监控起来,
在执行事务前如果key的值发生改变,自动终止事务的执行
在这里插入图片描述

七,Judis的简单学习

Jedis是Redis官方推荐的Java连接开发工具。要在Java开发中使用好Redis中间件,必须对Jedis熟悉;简单学习传送门:菜鸟教程
jedis的maven依赖:

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

八,Redis与springboot整合

Spring使用Spring Data与Redis进行整合,在SpringData中提供了一个模板类RedisTemplate来实现
redis的相关操作
建立springboot项目的maven依赖:
spring-boot-starter-parent
spring-boot-starter-web
spring-boot-devtools
lombok(上面的应该都知道吧!不知道的进maven官网
spring-boot-starter-data-redis依赖(主角登场)

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

还需要配置的yml文件:
在这里插入图片描述
操作类

package com.jazhong.redis.dao.impl;

import com.jazhong.redis.dao.RedisDao;
import com.jazhong.redis.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Set;

@Component//交给spring管理
public class RedisDaoImpl implements RedisDao {
    @Autowired//注入redis支撑类
    private RedisTemplate redisTemplate;

    /**
     * 存入key和value
     */
    @Override
    public void save(String key, String value) {
        //通过redisTemplate模板对象,获得一个操作redis字符串的对象ValueOperations
        ValueOperations valOps = redisTemplate.opsForValue();
        valOps.set(key,value);
    }

    /**
     * 存入key和value(数字)
     */
    @Override
    public void save(String key, Integer value) {
        //通过redisTemplate模板对象,获得一个操作redis字符串的对象ValueOperations
        ValueOperations valOps = redisTemplate.opsForValue();
        valOps.set(key,value);
    }

    /**
     * 得到key对应的value(字符串)
     */
    @Override
    public String get(String username) {
        ValueOperations valOps = redisTemplate.opsForValue();
        String string = (String)valOps.get(username);
        return string;
    }

    /**
     *得到key对应的value(数字)
     */
    @Override
    public Integer getInt(String age) {
        ValueOperations valOps = redisTemplate.opsForValue();
        Integer integer = (Integer) valOps.get(age);
        return integer;
    }

    /**
     * 存入user对象(涉及到存储到磁盘中,该实体类需要序列化)
     * @param user
     */
    @Override
    public void saveObj(User user) {
        ValueOperations valOps = redisTemplate.opsForValue();
        valOps.set("user",user);
    }

    /**
     * 得到user对象
     */
    public User get(){
        ValueOperations valOps = redisTemplate.opsForValue();
        User user = (User) valOps.get("user");
        return user;
    }

    /**
     * 简单操作list
     */
    @Override
    public void opsList() {
        //获得操作list的
        ListOperations ops = redisTemplate.opsForList();
        Long aLong = ops.leftPush("list", "aaa");
        ops.leftPushAll("list","aaaa","bbbb","cccc");
        List<String> list = ops.range("list", 0, -1);
        System.out.println(list);
        for (String s : list) {
            System.out.println(s);
        }
    }

    /**
     * 简单操作set集合
     */
    @Override
    public void opsSet() {
        SetOperations ops = redisTemplate.opsForSet();
        ops.add("set","aaa","bb","cc");
        Set<String> set = ops.members("set");
        System.out.println(set);
        for (String s : set) {
            System.out.println(s);
        }
    }

    /**
     * 简单操作zset集合(有序的set)
     */
    @Override
    public void opsZset() {
        ZSetOperations ops = redisTemplate.opsForZSet();
        ops.add("zset","小明",100);
        ops.add("zset","小n",200);
        ops.add("zset","小hua",40);
        ops.add("zset","小u",500);
        Set zset = ops.rangeWithScores("zset", 0, -1);
        for (Object s : zset) {
            System.out.println(s);
        }
    }

    /**
     * 删除方法
     */
    public void del(){
        redisTemplate.delete("zset");
    }

    /**
     * 简单操作map集合
     */
    @Override
    public void opsHash() {
        HashOperations ops = redisTemplate.opsForHash();
        ops.put("user1","userId1",(Object) "1171");
        ops.put("user1","username","yyx1");
        ops.put("user1","userage","201");
        ops.put("user1","userpassword","1231");
        String s= (String)ops.get("user1", "userId1");
        System.out.println(s);
    }
}

控制类:

package com.jazhong.redis.controller;


import com.jazhong.redis.model.User;
import com.jazhong.redis.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/redis")
public class RedisController {
    @Autowired
    private RedisService redisService;
    @GetMapping("/save")
    public String saveStr(String key,String value){
        redisService.save(key,value);
        return "ok";
    }
    @GetMapping("/saveint")
    public String saveInt(String key,Integer value){
        redisService.save(key,value);
        return "ok!int";
    }
    @GetMapping("/get")
    public String get(){
//       return redisService.get("username");
        Integer age = redisService.getInt("age");
        return age+"";
    }
    @GetMapping("saveobj")
    public String saveObj(@RequestBody User user){
        redisService.saveObj(user);
        return "ok!obj";
    }
    @GetMapping("/getUser")
    public User getUser(){
        User user = redisService.get();
        System.out.println(user);
        return user;
    }
    @GetMapping("/opsList")
    public String opsList(){
        redisService.opsList();
        return "ok!list";
    }
    @GetMapping("/opsSet")
    public String opsSet(){
        redisService.opsSet();
        return "ok!Set";
    }
    @GetMapping("/opsZset")
    public String opsZset(){
        redisService.opsZset();
        return "ok!Zset";
    }
    @GetMapping("/opsHash")
    public String opsHash(){
        redisService.opsHash();
        return "ok!Hash";
    }

    @DeleteMapping("/del")
    public String opsDel(){
        redisService.del();
        return "ok!del";
    }
}

这里使用postman应用测试传入数据(省去了在页面测试的麻烦)
即在postman服务端,根据url地址和类型,传入数据,通过IDEA存入redis;当然可以通过redis客户端得到存入的数据;
可以去应用商店下载
在这里插入图片描述
这里要注意
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值