1 NoSql数据库简介

1 引出NoSQL

作用:作为缓存库减少IO压力

2 NoSQL概述

  • NoSQL,意为不仅仅是sql,泛指非关系型数据库,NoSQL不依赖业务逻辑方式存储,而以简单的key-value模式存储,大大地增加了数据库的扩展能力
    • 不遵循SQL标准
    • 不支持ACID(原子性,隔离性,持久性,一致性)
    • 远超SQL的性能

3 NoSQL的适用场景

  • 对数据高并发的读写
  • 海量数据的读写
  • 对数据高可扩展性的

4 NoSQL不适用场景

  • 需要事务支持
  • 基于sql的结构化查询存储,处理复杂的关系,需要即席查询
  • 用不着sql的和用了sql也不行的情况,考虑使用Nosql

5 NoSQL数据库家族(了解即可)

1) 键值数据库

  • 这一类数据库主要会使用到一个散列表,这个表中有一个特定的键和一个指针指向特定的数据。
  • 键值模型对于 IT 系统来说,其优势在于简单、易部署。键值数据库可以按照键对数据进行定位,还可以通过对键进行排序和分区,以实现更快速的数据定位。

2) 列族数据库

  • 列族数据库通常用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列,如图所示。

Redis6 - 图1

  • 此列族数据库表中由两行组成,每一行都有关键字 Row Key,每一行由多个列族组成,即 Column-Family-1 和 Column-Family-2,而每个列族由多个列组成。

3) 文档数据库

  • 文档数据库的灵感来自 Lotus Notes 办公软件,它与键值数据库类似。该类型的数据模型是版本化的文档,文档以特定的格式存储,如 JSON。
  • 文档数据库可以看作键值数据库的升级版,允许之间嵌套键值,如图所示。

Redis6 - 图2

  • 文档数据库比键值数据库的查询效率更高, 因为文档数据库不仅可以根据键创建索引,同时还可以根据文档内容创建索引。

4) 图形数据库

  • 图形数据库来源于图论中的拓扑学,以节点、边及节点之间的关系来存储复杂网络中的数据,如图所示。

Redis6 - 图3

  • 这种拓扑结构类似 E-R 图,但在图形模式中,关系和节点本身就是数据,而在 E-R 图中,关系描述的是一种结构。

2 Redis的安装

Linux系统版本:centos7,redis版本:6.0.6

  1. 先使用sftp将安装包传入到linux
    cd和lcd,ls和lls
    上传:put 本地文件路径 远程服务器文件路径
    保存:get 远程服务器文件路径 本地文件路径
  2. 然后在linux安装gcc编译器yum install gcc
  3. 解压文件tar -zxvf tar包
  4. cd到解压文件路径然后使用make(必须)和make install文件安装redis
    • ⚠如果没有c语言环境则make处报错,make是编译阶段

安装redis出现些之前安装不曾出现错误
稳定版6.0.1之后版本都会出现这个问题!!!

Redis6 - 图4

解决办法为:升级 gcc到最新版本

  1. # 稳定版6.0.1之前的版本正常安装步骤如下
  2. [root@localhost ~]# yum install gcc
  3. [root@localhost ~]# cd /usr/local
  4. [root@localhost local]# wget http://download.redis.io/releases/redis-6.0.1.tar.gz
  5. [root@localhost local]# tar -xvf redis-6.0.1.tar.gz
  6. [root@localhost local]# cd /usr/local/redis-6.0.1/
  7. [root@localhost redis-6.0.1]# make PREFIX=/usr/local/redis install
  8. # redis(6.0.6)升级 gcc到最新版本
  9. [root@localhost redis-6.0.1]# gcc -v # 查看gcc版本
  10. [root@localhost redis-6.0.1]# yum -y install centos-release-scl # 升级到9.1版本
  11. [root@localhost redis-6.0.1]# yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
  12. [root@localhost redis-6.0.1]# scl enable devtoolset-9 bash
  13. 以上为临时启用,如果要长期使用gcc 9.1的话:
  14. [root@localhost redis-6.0.1]# echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
  15. # 再执行编译:PREFIX 安装目录
  16. [root@localhost redis-6.0.1]# make install PREFIX=/usr/local/redis
  17. **安装成功会出现:Hint: Its a good idea to run make test **

启动模式:前台启动和后台启动(推荐)

  1. 前台启动:
    • 直接使用redis-server
    • 需要重新开一个终端,不适合连接linux使用
  1. 后台启动
    • 需要在解压目录中找到redis.conf(可以复制一份到etc),然后
vim redis.conf
# /字段 查找字段    i 修改文件内容 :wq 保存退出
daemonize no -> daemonize yes
# 后台启动开启redis服务,cd到安装bin目录
redis-server 已经修改的配置文件路径
然后就可以使用redis-cli了 # ping返回PONG说明正常
redis关闭:
    redis-cli shutdown
    redis-cli -p 6379 shutdown(感觉没啥用🤣🤣🤣 windows徽标+.=表情包)

3 常用的五大数据类型

1 Key(基石)

代码 功能
key * 查看所有的key
exists key名 判断是否存在该key
del/unlink key名 删除key,前者统一,后者异步删除
exprie key名 10 设置过期时间为10s
ttl key名 看还有多少秒过期,-1永不过期,-2已过期
select 数字 选择几号库
dbsize 数字 查看数据库中的key的量
flushdb 清空当前库
flushall 通杀全部库

2 字符串(String)

1 简介

  • String是Redis最基本的类型
    • String类型是🧨二进制安全🧨的,意味着Redis的String类型可以存储任何的数据,包含图片和视频
    • 一个Redis中字符串的key和value最多为512M

2 基本命令

代码 功能
(m)set/(m)get key1,(key2,key3…)名 值1,(值2..) (批量)设置(如果有key则会覆盖)和(批量)查看
append key名 值 追加,有无key都追加,返回追加后的长度
strlen key名 获取值的长度
(m)setnx
key value
在key无时(批量)设置key的值,否则返回0
incr/decr key名 对应value(必须是数字)的值 +1 / -1
incr/decrby key名 step步长 对应value(必须是数字)的值 +step / -step
get/setrange key名 起始值(默认为0) 终值 获取/设置key的value的指定位置范围数据
setex key名 过期时间(int) 设置键值时设置过期时间,s

原子性,多线程一个错误全部都错

3 Redis列表(List)

1 简介

  1. 单键多值
  2. 按照插入顺序排序
  3. 底层是一个双向链表,对两端的操作性能很高,通过索引操作中间节点的性能较差
  4. 值在键在,值光键亡

2 常用指令

代码 功能
l/rpush key value1,value2,value3… 左/右插入值
l/rpop key 从👈/👉1次取一个值
r + pop+ l + push key1 key2 从key1列表右边取值插入到key2列表的左边
lrange key start stop 按照索引下标取元素(从左到右)
linsert key before/after 已知值 新值 在已知值之前/之后加值
lrem key count Value
lset key index value(修改值)
- count > 0 : 从表头开始向表尾搜索,移除与 Value 相等的元素,数量为count
- count > 0 : 从表尾开始向表头搜索,移除与 Value 相等的元素,数量为|count|
- count = 0:删除所有和Value相等的值

4 Redis集合(Set)

1 简介

  • 排重
  • 底层是一个value为null的hash表,所以添加,查询,删除复杂度都是O(1)

2 常用命令

代码 功能
sadd key value1 value2 … 添加
smember key 取出该集合的所有值
sismember key value 判断集合key是否含有该value
scard key 返回该集合的元素个数
srem key value1 value2 删除集合中的某个元素
spop key 从key集合中随机吐出一个值
srandmember key n 随机从该集合中取出n个值,但是不会删除
smove source destination value 两个集合中的值转移
sinter key1 key2 返回两个集合的交集元素
sunion key1 key2 返回两个集合的并集元素
sdiff key1 key2 返回两个集合中的差集元素(key1中的,不包含key2中的)

5 Redis哈希(Hash)

1 简介

  • 好像yml的树形结构

image.png

2 常用命令

代码 功能
h(m)set key field value (批量)给key集合中的field键赋值value
hget key field 从key集合中获取field字段的值
hexists key field 查看哈希表key中的field是否存在
hkeys key 列出所有的field
hvals key 列出所有的value
hincrby key field increment 为哈希表key中的field的值加一
hsetnx key field value 将不存在的key的field值设置为value,key存在则报错

3 数据结构

image.png

6 Redis有序集合(Zset)

4 Redis6配置文件详解

1 NETWORK

image.png

image.png

5 Redis的发布和订阅

6 Redis6新数据类型

1 Bitmaps

1 简介

  • 合理地使用操作位能够有效地提高内存使用率和开发效率
  • Redis提供了Bitmaps这个”数据类型”可以实现对位地操作
    • Bitmaps本身不是一种数据类型,实际上它就是字符串,但是它可以对字符串地位进行操作
    • Bitmaps单独提供了一套指令,所以在Redis中使用Bitmaps和使用字符串地方法不太相同,可以把Bitmaps想象成一个以位为单位的数组,数组的每个单元(value)都是只能存储0和1,数组的下标在Batmaps中叫做偏移量

2 常用命令

代码 功能
set/getbit key offset (value) 设置某个偏移量的值(0或者1)
bitcount key start end 统计key中在[start,end]中的value为1的数量
bitop and(or/not/xor) destkey key 做and(交集)/or(并集)/not(非)/xor(异或)操作并将结果保存到destkey

Bitmaps和set的比较

2 HyperLogLog

1 简介

3 Geospatial

7 Jedis操作Redis6

1 简介以及环境

Jedis就是通过java代码来使用redis

  1. 创建maven项目导入依赖包jedis
  2. 创建jedis类
  3. 执行报错:image.png
  4. 考虑以下问题
# 1 配置文件没有将network中的bind那一行注释掉,也没有将protect-mode设置为no
# 2 配置文件在修改之后未重启redis-server 配置文件,导致加载的配置没有改变
# 3 未将linux中的6379端口打开
firewall-cmd --zone=public --add-port=6379/tcp --permanent
firewall-cmd --permanent --add-port=6379/tcp
firewall-cmd --reload
firewall-cmd --query-port=6379/tcp
# 4 实在不行的话就把conf文件中的bind写死了
任意接口:bind 0.0.0.0(把所有的redis先关了,在虚拟机上改)🧨🧨🧨亲测有效🧨🧨🧨
Linux端口号操作
1、查看防火墙状态
systemctl status firewalld

2、如果不是显示active状态,需要打开防火墙
systemctl start firewalld

3、# 查看所有已开放的临时端口(默认为空)
# firewall-cmd --list-ports
# 查看所有永久开放的端口(默认为空)
# firewall-cmd --list-ports --permanent
# 添加临时开放端口(例如:比如我修改ssh远程连接端口是223,则需要开放这个端口)
# firewall-cmd --add-port=223/tcp
# 添加永久开放的端口(例如:223端口)
# firewall-cmd --add-port=223/tcp --permanent
# 关闭临时端口
# firewall-cmd --remove-port=80/tcp
# 关闭永久端口
# firewll-cmd --remove-port=80/tcp --permanent
# 配置结束后需要输入重载命令并重启防火墙以生效配置
# firewall-cmd --reload
# systemctl restart firewalld
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.3.0</version>
</dependency>
public class FirstPro {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("192.168.186.100", 6379);
        String s = jedis.ping();
        System.out.println("s = " + s);
    }
}
# 1 配置文件没有将network中的bind那一行注释掉,也没有将protect-mode设置为no
# 2 配置文件在修改之后未重启redis-server 配置文件,导致加载的配置没有改变
# 3 未将linux中的6379端口打开
firewall-cmd --zone=public --add-port=6379/tcp --permanent
firewall-cmd --permanent --add-port=6379/tcp
firewall-cmd --reload
firewall-cmd --query-port=6379/tcp
# 4 实在不行的话就把conf文件中的bind写死了
任意接口:bind 0.0.0.0(把所有的redis先关了,在虚拟机上改)🧨🧨🧨亲测有效🧨🧨🧨

2 Jedis示例-手机验证码

image.png

8 Redis6与SpringBoot的整合

1 引入依赖包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-redis</artifactId>
    <version>1.4.7.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

2 配置文件

spring:
  redis:
    host: 192.168.186.100
    port: 6379
    database: 0
    # 连接超时时间
    timeout: 1800000
    lettuce:
      pool:
        # 连接池最大连接数
        max-active: 20
        # 最大堵塞等待时间(负数表示没有限制)
        max-wait: -1
        # 连接池中的最大空闲连接
        max-idle: 5
        # 最小空闲连接
        min-idle: 0

3 配置类

4 Controller

9 事务

1 基本操作

image.png

2 事务的错误处理

  • 就像王者组队
    • 只要有一个人不点匹配成功(组队失败),就无法进入游戏(无法进入执行阶段)
    • 而进入游戏之后,就算有个人挂机了(执行失败),其他人也得接着往下打(执行)

3 事务冲突

1 为什么要做成事务❓

  • 有很多人有你的账户(10000),同时去参加双十一抢购
    • 1号:买东西花8000
    • 2号:买东西花5000
    • 3号:买东西花1000

2 悲观🔒和乐观🔒

  1. 悲观锁:就是很悲观,每次拿数据的时候都认为别人会修改,所以每次拿的时候都会加锁,这样别人想要拿这个数据的话就会block直到它拿到锁.传统的关系型数据库里面就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在操作之前上锁
  2. 乐观锁:就是很乐观,每次拿数据时都认为别人不会修改,但是在更新的时候会判断以下在此期间别人有没有去更新数据,可以使用版本号等机制.乐观锁适用于多读的应用类型,这样可以提高吞吐量,Redis就是利用的这种check-and-set机制实现事务

image.png

3 Watch key [key …]/Unwatch乐观🔒

在执行multi之前,先执行watch key1 [key2 …],可以监视一个(多个)的key,如果在事务执行这个(这些)key被其他命令所改动,那么事务将会被打断

4 Redis事务三特性

  1. 单独的隔离操作
    • 事务中的所有命令都会被序列化,按顺序的执行,事务在执行的过程中,不会被其它客户端发送来的命令请求所打断
  2. 没有隔离级别的概念
    • 队列中的命令没有提交之前都不会被实际执行,因为事务提交前任何命令豆瓣不会被实际执行
  3. 不保证原子性
    • 事务中如果有一个指令执行失败,其后的指令仍然会被执行,且没有回滚

11 Redis事务秒杀案例

回来再看

12 Redis持久化之RDB

1 备份

  • Redis会单独的创建(fork)一个子线程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程解释,再用临时文件替换掉之前已持久化的文件
  • 整个过程中,主进程不进行IO操作,确保了极高的性能,如果需要大规模的数据的恢复,且对于数据恢复的完整性不是非常敏感,那么RDB方式要比AOF更加地高效
  • RDB地缺点就是最后一次地持久化后的数据可能会丢失

2 进行相关的配置

查找conf中的snap