Redis基础入门总结

NoSQL非关系型数据库

NoSQL概念

Not Only SQL:不仅仅是SQL,指的就是非关系型数据库,它是关系型数据库有益的补充。最终的数据还是保存在关系型数据库中。非关系型数据库主要是提升数据库的查询速度,一般做为数据的缓存来使用。

非关系型数据库

在这里插入图片描述

​ 非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合,可以是文档或者键值对等。

优点
  1. 格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。
  2. 速度快:nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘;
  3. 成本低:nosql数据库部署简单,基本都是开源软件。
缺点
  1. 不提供sql支持,学习和使用成本较高;
  2. 数据结构相对复杂,复杂查询方面不方便。

为什么要使用NOSQL

具体表现为对如下三高问题的解决:

High Performance - 数据库高并发访问

​ 在同一个时间点,同时有海量的用户并发访问。往往要达到每秒上万次读写请求。关系数据库应付上万次SQL查询还勉强顶得住,但是应付上万次SQL写数据请求,硬盘IO就已经无法承受了。

  • 如天猫的双11,从凌晨0点到2点这段时间,每秒达到上千万次的访问量。

  • 12306春运期间,过年回家买火车抢票的时间,用户不断查询有没有剩余票。

Huge Storage - 海量数据的存储

​ 数据库中数据量特别大,数据库表中每天产生海量的数据。

​ 类似QQ,微信,微博,每天用户产生海量的用户动态,每天产生几千万条记录。对于关系数据库来说,在一张几亿条记录的表里面进行SQL查询,效率是极其低下乃至不可忍受的。

High Scalability && High Availability- 高可扩展性和高可用性的需求

​ 关系型数据库进行扩展和升级是比较麻烦的一样事,对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移。

​ 非关系型数据库可以通过不断的添加服务器节点来实现扩展,而不需对原有的数据库进行维护。

扫描二维码关注公众号,回复: 12015812 查看本文章

Redis的目录文件

目录或文件 作用
redis-benchmark.exe 用于性能测试一个工具命令
redis-check-aof.exe AOF文件的检查和修复工具 (AOF是它的一种文件存储格式)
redis-check-dump.exe RDB文件的检查和修改工具 (RDB是它的一种文件存储格式)
redis-cli.exe 客户端启动程序
redis-server.exe 服务器端启动程序 (不会自动启动,默认每次都要手动开启)
redis.window.conf 服务器配置文件

string类型的操作命令

Redis的5种数据类型

redis是一种高级的key-value的存储系统,其中value支持五种数据类型,指的是它值的类型,键可以认为是字符串类型。redis不是用Java写的,是C语言写的。

值的数据类型 说明
string类型 字符串
list类型 列表:元素可以重复,元素是有索引号,有先后顺序的
set类型 集合:元素是不可重复的,元素没有索引号,没有先后顺序的
hash类型 值由多个键值对组成
zset类型 集合:元素不可重复的,每个元素有索引号,还有一个分数值,可以根据分数进行排序

字符串类型string

在Redis中以二进制保存,没有编码和解码的过程。

无论存入的是字符串、整数、浮点类型都会以字符串写入。

在Redis中字符串类型的值最多可以容纳的数据长度是512M,这是以后最常用的数据类型。

在这里插入图片描述

常用命令

命令 功能
set 键 值 存入字符串类型的键和值,如果键不存在就是添加,存在就是修改
setnx 键 值 键不存在就是添加,存在不做任何操作,不会覆盖以前的键和值
get 键 通过键获取值
del 键 通过键删除键和值

list类型的操作命令

概述

在Redis中,List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其左部(left)和右部(right)添加新的元素。

在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。

如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。

List中可以包含的最大元素数量是4G个(41亿个)

在这里插入图片描述

常用命令

命令 行为
lpush 键 元素 元素 从左边添加1个或多个元素
rpush 键 元素 元素 从右边添加1个或多个元素
lpop 键 删除最左边的一个元素,并且返回
rpop 键 删除最右边的一个元素,并且返回
lrange 键 开始 结束 查找指定索引范围内元素返回,每个元素有2个索引号
索引号从左向右:0~length-1
索引号从右向左:-1~-length
如果要获取整个列表中所有的元素,索引号范围如何写?0~-1
llen 键 获取列表中有多少个元素

命令演示

在这里插入图片描述

一个Redis服务器可以包括多个数据库,客户端可以只连接Redis中某个数据库,就好比一个mysql服务器中创建多个数据库,客户端连接时指定连接到哪个数据库。

Redis中有db0-db15编号的16个数据库。我们不能创建新的数据库,也不能删除数据库。数据库中也没有表的结构,客户端默认连接第0个数据库。但可以通过配置文件设定有多少个数据库。

Jedis类常用方法

  1. 每个方法就是redis中的命令名,方法的参数就是命令的参数。

  2. 每个Jedis对象似于JDBC中Connection对象,获取一个Jedis对象本质上就是获取一个连接对象。

连接和关闭 功能
new Jedis(String host, int port) 创建一个连接对象
参数1:主机名
参数2:端口号 6379
void close() 关闭连接
对string操作的方法 说明
set(String key,String value) 添加字符串类型的键和值
String get(String key) 通过键获取值
del(String … keys) 删除一个或多个键和值
对list操作的方法 说明
lpush(String key,String…values) 从左边添加1个或多个元素
List<String> lrange(String key,long start,long end) 获取一个范围内所有的元素

代码

package com.itheima;

import redis.clients.jedis.Jedis;

/**
 * Jedis的基本使用
 */
public class Demo1Base {
    
    

    public static void main(String[] args) {
    
    
        //1.创建Jedis连接对象
        Jedis jedis = new Jedis("localhost", 6379);
        //2.向服务器添加1个字符串类型的键和值
        jedis.set("book","人鬼情喂鸟");
        //3.从服务器中通过键获取值
        String book = jedis.get("book");
        //4.关闭连接
        jedis.close();
        //5.打印输出到控制台
        System.out.println(book);
    }

}

Jedis连接池的使用

在这里插入图片描述

​ jedis连接资源的创建与销毁是很消耗程序性能,所以jedis为我们提供了jedis的连接池技术,jedis连接池在创建时初始化一些连接对象存储到连接池中,使用jedis连接资源时不需要自己创建jedis对象,而是从连接池中获取一个资源进行redis的操作。使用完毕后,不需要销毁该jedis连接资源,而是将该资源归还给连接池,供其他请求使用。

Jedis连接池API

用于创建连接池的配置信息

JedisPoolConfig配置类 功能说明
JedisPoolConfig() 构造方法,创建一个配置对象
void setMaxTotal() 连接池中最大连接数
void setMaxWaitMillis() 设置最长等待时间,单位是毫秒
JedisPool连接池类 说明
JedisPool(配置对象,服务器名,端口号) 构造方法,创建连接池的类
参数1:上面的配置对象
参数2:服务器名
参数3:端口号
Jedis getResource() 从连接池中获取一个创建好的连接对象,返回Jedis对象

JedisPool的基本使用

需求:

​ 使用连接池优化jedis操作,从连接池中得到一个创建好的Jeids对象,并且使用这个Jedis对象。向Redis数据库写入一个set集合,并且取出集合。打印到控制台,并且查看数据库中信息。

开发步骤

  1. 创建连接池配置对象,设置最大连接数10,设置用户最大等待时间2000毫秒
  2. 通过配置对象做为参数,创建连接池对象
  3. 从连接池里面获取jedis连接对象,执行redis命令。
  4. 执行redis命令写入list集合
  5. 执行redis命令读取list集合
  6. 输出读取的数据
  7. 关闭连接对象(通常连接池不关闭)

执行代码

package com.itheima;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.List;

/**
 * Jedis连接池的基本使用
 */
public class Demo2Pool {
    
    

    public static void main(String[] args) {
    
    
        //1.创建连接池的配置对象
        JedisPoolConfig config = new JedisPoolConfig();
        //2.设置连接池的参数
        config.setMaxTotal(10);  //最大连接数
        config.setMaxWaitMillis(2000);  //最长等待时间为2秒钟
        //3.创建连接池,使用上面配置对象
        JedisPool pool = new JedisPool(config,"localhost", 6379);
        //4.从连接池中获取连接对象
        Jedis jedis = pool.getResource();
        //5.使用连接对象
        jedis.lpush("students", "孙悟空", "猪八戒", "白骨精");
        List<String> students = jedis.lrange("students", 0, -1);
        System.out.println(students);
        //6.关闭连接对象
        jedis.close();
    }

}

小结

JedisPool连接池类 作用
JedisPool(配置对象,服务器名,端口号) 创建连接池
参数1:配置对象
参数2:服务器名
参数3:端口号
Jedis getResource() 从连接池中获取连接对象
void close() 关闭连接池

ResourceBundle类的使用

代码

jedis.properties的内容

# 连接池的最大连接数
maxTotal=10
# 最长等待时间为2秒钟
maxWaitMillis=2000
# 服务器名字
host=localhost
# 端口号
port=6379

使用ResourceBundle类:

package com.itheima;

import java.util.ResourceBundle;

public class Demo3Resource {
    
    

    public static void main(String[] args) {
    
    
        //1. 通过静态方法读取属性文件,参数是:属性文件的主文件名,没有扩展名
        ResourceBundle bundle = ResourceBundle.getBundle("jedis");
        //2. 获取属性值,通过键获取值
        String host = bundle.getString("host");
        //3.输出值
        System.out.println(host);
    }
}

小结

java.util.ResourceBundle类 功能
static ResourceBundle getBundle(“配置文件基名”) 读取配置文件,得到对象。参数是主文件名
String getString(“键名”) 通过键获取值

Jedis连接池工具类的实现

jedis.properties配置文件

# 主机名
host=localhost
# 端口号
port=6379
# 最大连接数
maxTotal=20
# 最长等待时间
maxWaitMillis=3000

JedisUtils.java

package com.itheima.utils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.ResourceBundle;

/**
 * Jedis连接池工具类
 */
public class JedisUtils {
    
    

    private static JedisPool pool;

    //在静态代码块中创建连接池
    static {
    
    
        //读取配置文件
        ResourceBundle bundle = ResourceBundle.getBundle("jedis");
        //读取属性值
        int maxTotal = Integer.parseInt(bundle.getString("maxTotal"));
        int maxWaitMillis = Integer.parseInt(bundle.getString("maxWaitMillis"));
        int port = Integer.parseInt(bundle.getString("port"));
        String host = bundle.getString("host");

        //创建连接池配置对象
        JedisPoolConfig config = new JedisPoolConfig();
        //设置连接池的参数
        config.setMaxTotal(maxTotal);
        config.setMaxWaitMillis(maxWaitMillis);
        //创建连接池
        pool = new JedisPool(config, host, port);
    }

    /**
     * 获取连接对象
     */
    public static Jedis getJedis() {
    
    
        return pool.getResource();
    }

}

使用工具类

package com.itheima;

import com.itheima.utils.JedisUtils;
import redis.clients.jedis.Jedis;

//使用连接池工具类
public class Demo4Use {
    
    

    public static void main(String[] args) {
    
    
        //从连接池中获取连接对象
        Jedis jedis = JedisUtils.getJedis();
        //添加键和值
        jedis.set("car", "BWM");
        //取出
        String car = jedis.get("car");
        //输出
        System.out.println(car);
        //关闭连接
        jedis.close();
    }
}

持久化

利用永久性存储介质将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制称为持久化 持久化用于防止数据的意外丢失,确保数据安全性

永久化介质保存数据,存在硬盘

RDB

直接拷贝数据从内存到磁盘上

RDB优点

  • RDB是一个紧凑压缩的二进制文件,存储效率较高

  • RDB内部存储的是redis在某个时间点的数据快照,非常适合用于数据备份,全量复制等场景

  • RDB恢复数据的速度要比AOF快很多

  • 应用:服务器中每X小时执行bgsave备份,并将RDB文件拷贝到远程机器中,用于灾难恢复。

RDB缺点

  • RDB方式无论是执行指令还是利用配置,无法做到实时持久化,具有较大的可能性丢失数据

  • bgsave指令每次运行要执行fork操作创建子进程,要牺牲掉一些性能

  • Redis的众多版本中未进行RDB文件格式的版本统一,有可能出现各版本服务之间数据格式无法兼容现象

AOF

  • AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令 达到恢复数据的目的。与RDB相比可以简单理解为由记录数据改为记录数据产生的变化

  • AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式

AOF写数据三种策略(appendfsync)

  • always(每次):每次写入操作均同步到AOF文件中 数据零误差,性能较低,不建议使用。

  • everysec(每秒):每秒将缓冲区中的指令同步到AOF文件中,在系统突然宕机的情况下丢失1秒内的数据 数据准确性较高,性能较高,建议使用,也是默认配置

  • no(系统控制):由操作系统控制每次同步到AOF文件的周期 整体过程不可控

RDB VS AOF

在这里插入图片描述

RDB与AOF的选择之惑

  • 对数据非常敏感,建议使用默认的AOF持久化方案

  • AOF持久化策略使用everysecond,每秒钟fsync一次。该策略redis仍可以保持很好的处理性能,当出 现问题时,最多丢失0-1秒内的数据。

  • 注意:由于AOF文件存储体积较大,且恢复速度较慢

  • 数据呈现阶段有效性,建议使用RDB持久化方案

  • 数据可以良好的做到阶段内无丢失(该阶段是开发者或运维人员手工维护的),且恢复速度较快,阶段 点数据恢复通常采用RDB方案

  • 注意:利用RDB实现紧凑的数据持久化会使Redis降的很低,慎重总结:

  • 综合比对

  • RDB与AOF的选择实际上是在做一种权衡,每种都有利有弊 如不能承受数分钟以内的数据丢失,对业务数据非常敏感,选用AOF

  • 如能承受数分钟以内的数据丢失,且追求大数据集的恢复速度,选用RDB

  • 灾难恢复选用RDB

  • 双保险策略,同时开启RDB 和 AOF,重启后,Redis优先使用AOF 来恢复数据,降低丢失数据的量

以上内容有失偏颇处,欢迎指正!

猜你喜欢

转载自blog.csdn.net/weixin_47785112/article/details/107103980