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

- 此列族数据库表中由两行组成,每一行都有关键字 Row Key,每一行由多个列族组成,即 Column-Family-1 和 Column-Family-2,而每个列族由多个列组成。
3) 文档数据库
- 文档数据库的灵感来自 Lotus Notes 办公软件,它与键值数据库类似。该类型的数据模型是版本化的文档,文档以特定的格式存储,如 JSON。
- 文档数据库可以看作键值数据库的升级版,允许之间嵌套键值,如图所示。

- 文档数据库比键值数据库的查询效率更高, 因为文档数据库不仅可以根据键创建索引,同时还可以根据文档内容创建索引。
4) 图形数据库
- 图形数据库来源于图论中的拓扑学,以节点、边及节点之间的关系来存储复杂网络中的数据,如图所示。

- 这种拓扑结构类似 E-R 图,但在图形模式中,关系和节点本身就是数据,而在 E-R 图中,关系描述的是一种结构。
2 Redis的安装
Linux系统版本:centos7,redis版本:6.0.6
- 先使用sftp将安装包传入到linux
cd和lcd,ls和lls
上传:put 本地文件路径 远程服务器文件路径
保存:get 远程服务器文件路径 本地文件路径- 然后在linux安装gcc编译器
yum install gcc- 解压文件
tar -zxvf tar包- cd到解压文件路径然后使用make(必须)和make install文件安装redis
- ⚠如果没有c语言环境则make处报错,make是编译阶段
安装redis出现些之前安装不曾出现错误
稳定版6.0.1之后版本都会出现这个问题!!!

解决办法为:升级 gcc到最新版本
# 稳定版6.0.1之前的版本正常安装步骤如下[root@localhost ~]# yum install gcc[root@localhost ~]# cd /usr/local[root@localhost local]# wget http://download.redis.io/releases/redis-6.0.1.tar.gz[root@localhost local]# tar -xvf redis-6.0.1.tar.gz[root@localhost local]# cd /usr/local/redis-6.0.1/[root@localhost redis-6.0.1]# make PREFIX=/usr/local/redis install# redis(6.0.6)升级 gcc到最新版本[root@localhost redis-6.0.1]# gcc -v # 查看gcc版本[root@localhost redis-6.0.1]# yum -y install centos-release-scl # 升级到9.1版本[root@localhost redis-6.0.1]# yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils[root@localhost redis-6.0.1]# scl enable devtoolset-9 bash以上为临时启用,如果要长期使用gcc 9.1的话:[root@localhost redis-6.0.1]# echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile# 再执行编译:PREFIX 安装目录[root@localhost redis-6.0.1]# make install PREFIX=/usr/local/redis**安装成功会出现:Hint: It’s a good idea to run ‘make test’ **
启动模式:前台启动和后台启动(推荐)
- 前台启动:
- 直接使用redis-server
- 需要重新开一个终端,不适合连接linux使用
- 后台启动
- 需要在解压目录中找到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 简介
- 单键多值
- 按照插入顺序排序
- 底层是一个双向链表,对两端的操作性能很高,通过索引操作中间节点的性能较差
- 值在键在,值光键亡
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的树形结构

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 数据结构

6 Redis有序集合(Zset)
4 Redis6配置文件详解
1 NETWORK


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
- 创建maven项目导入依赖包jedis
- 创建jedis类
- 执行报错:
![]()
- 考虑以下问题
# 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示例-手机验证码

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 基本操作

2 事务的错误处理
- 就像王者组队
- 只要有一个人不点匹配成功(组队失败),就无法进入游戏(无法进入执行阶段)
- 而进入游戏之后,就算有个人挂机了(执行失败),其他人也得接着往下打(执行)
3 事务冲突
1 为什么要做成事务❓
- 有很多人有你的账户(10000),同时去参加双十一抢购
- 1号:买东西花8000
- 2号:买东西花5000
- 3号:买东西花1000
2 悲观🔒和乐观🔒
- 悲观锁:就是很悲观,每次拿数据的时候都认为别人会修改,所以每次拿的时候都会加锁,这样别人想要拿这个数据的话就会block直到它拿到锁.传统的关系型数据库里面就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在操作之前上锁
- 乐观锁:就是很乐观,每次拿数据时都认为别人不会修改,但是在更新的时候会判断以下在此期间别人有没有去更新数据,可以使用版本号等机制.乐观锁适用于多读的应用类型,这样可以提高吞吐量,Redis就是利用的这种check-and-set机制实现事务

3 Watch key [key …]/Unwatch乐观🔒
在执行multi之前,先执行watch key1 [key2 …],可以监视一个(多个)的key,如果在事务执行这个(这些)key被其他命令所改动,那么事务将会被打断
4 Redis事务三特性
- 单独的隔离操作
- 事务中的所有命令都会被序列化,按顺序的执行,事务在执行的过程中,不会被其它客户端发送来的命令请求所打断
- 没有隔离级别的概念
- 队列中的命令没有提交之前都不会被实际执行,因为事务提交前任何命令豆瓣不会被实际执行
- 不保证原子性
- 事务中如果有一个指令执行失败,其后的指令仍然会被执行,且没有回滚
11 Redis事务秒杀案例
回来再看
12 Redis持久化之RDB
1 备份
- Redis会单独的创建(fork)一个子线程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程解释,再用临时文件替换掉之前已持久化的文件
- 整个过程中,主进程不进行IO操作,确保了极高的性能,如果需要大规模的数据的恢复,且对于数据恢复的完整性不是非常敏感,那么RDB方式要比AOF更加地高效
- RDB地缺点就是最后一次地持久化后的数据可能会丢失
2 进行相关的配置
查找conf中的snap
