文章目录
-
- 1、NoSQL数据库
-
- 1.1 NoSQL数据库概述
- 1.2 NoSQL使用场景
- 1.3 NoSQL不适用场景
- 1.4 常见的NoSQL数据库
-
- 1.4.1 Memcache
- 1.4.2 Redis
- 1.4.3 MongoDB
- 2、Redis概述和安装
-
- 2.1 概述
- 2.2 安装
-
- 2.2.1 Windows版本安装
- 2.2.2 Linux版本安装
- 2.3:redis基础知识
-
- 2.3.1: 端口号
- 2.3.2:数据库
- 2.3.3:基础命令
- 2.3.4:线程
- 3、Redis五大数据类型常用
-
- 3.1. Redis键(key)
- 3.2 Redis字符串
-
- 3.2.1: 常用命令
- 3.3 Redis列表(List)
-
- 3.3.1:常用命令
- 3.4 Redis集合(Set)
-
- 3.4.1:常用命令
- 3.5 Redis哈希(Hash)
- 3.6: Redis有序集合Zset(sorted set)
- 4、Redis介绍配置文件
-
- 4.1:Units单位
- 4.2:INCLUDES包含
- 4.3:NETWORD网路配置
- 4.4:GENERAL通用
- 4.5:限制
- 4.6:SRCURITY安全
- 5、Redis发布和订阅
-
- 5.1:订阅发布消息图
- 5.1:发布订阅命令
- 6、Redsi新数据类型
-
- 6.1、Bitmaps简介
-
- 6.1.1、命令
- 6.2、HyperLogLog简介
-
- 6.2.1、命令
- 6.3、Geospatial简介
-
- 6.3.1、命令
- 7、Redis_Jedis测试
-
- 7.1、步骤
- 7.2、常用API
- 8、SpringBoot整合
-
- 引入所需的依赖性
- 2、添加配置
- 3、封装关于redis的工具类
- 4、进行测试
- 9、Redis事务\_锁机制
-
- 9.1、Redis的事务定义
- 9.2、multi、exex、discard
- 9.悲观锁和乐观锁
- 9.4、Watch监控
- 9.事务的三个特点
- 10、Redis持久化之RDB(Redis DataBase)
-
- 10.1、什么是RBD
- 10.2、什么是Fork
- 10.3、dump.rdb
- 11、Redis持久化之AOF(Append Only File)
-
- 11.1、是什么
- 11.2、配置部分
- 11.3、AOF数据恢复
- 11.4、Rewrite
- 11.5、优缺点
- 12、Redis主从复制
-
- 12.1、概念
- 12.二、主从复制配置
- 12.3、常用三招
-
- 12.3.1、一主二仆
- 12.3.2、薪火相传
- 12.3.3、反客为主
- 12.4、复制原理
- 12.5、哨兵模式
- 13、Redis集群
-
- 13.1、问题
- 13.什么是集群?
- 13.3.准备开始建设集群
- 13.4、什么是slots
- 13.5、-c通过集群策略连接,设置的数据将自动切换到相应的写作主机
- 13.6.查询集群中的值
- 13.7、故障修复
- 13.8、优缺点
- 14、Redis应用问题
-
- 14.1、缓存穿透
- 14.2、缓存击穿
- 14.3、缓存雪崩
- 15、分布式锁
-
- 15.1、概念
- 15.2.分布式锁的主流实现方案
- 15.3、使用redis实现分布式锁
-
- 15.3.1.设置锁和过期时间
- 15.3.2、UUID防止误删
- 15.3.3、LUA确保删除原子性
- 15.3.4.分布式锁的几个必要条件
1、NoSQL数据库
1.1 NoSQL数据库概述
NoSQL(NoSQL = Not Only SQL
), 不仅仅是SQL,泛指非关系数据库
。
NoSQL不依赖业务逻辑存储,只是简单key-value
模式存储大大提高了数据库的扩展能力。
- 不遵循SQL标准。
- 不支持ACID
- 远超于SQL的性能。
1.2 NoSQL使用场景
- 对数据高并发的读写
- 海量数据的读写
- 对数据的高可扩展性
1.3 NoSQL不适用场景
- 需要事物支持
- 复杂关系的查询
1.4 常见的NoSQL数据库
1.4.1 Memcache
- 很早出现的NoSQL数据库
- 数据都在内存中,一般
不持久化
- 支持简单的key-value模式,
支持类型单一
- 一般作为
缓存数据库
辅助持久化数据库
1.4.2 Redis
- 几乎覆盖了Memcached的绝大部分功能
- 数据都在内存中,
支持持久化
,主要用作备份恢复 - 除了支持简单的key-value模式,还支持
多种数据结构的存储,
比如list、set、hash、zset
等。 - 一般作为缓存数据库辅助持久化的数据库
1.4.3 MongoDB
- 高性能、开源、模式自由(schema free)的
文档型数据库
- 数据都在内存中,如果内存不足,把不常用的数据保存到硬盘
- 虽然是key-value模式,但是对value(尤其是
Json
)提供了丰富的查询功能 - 支持二进制数据及大型对象
- 可以根据数据的特点替代
RDBMS
,成为独立的数据库。 或者配合RDBMS,存储特定的数据。
2、Redis的概述和安装
2.1 概述
Redis是什么
Redis: REmote DIctionary Server
(远程字典服务器)
是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行,并支持持久化的NoSQL数据库,是当前最热门的NoSQL数据库之一,也被人们称为数据库结构服务器
Redis与其他key-value缓存产品有以下三个特点
- Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list、set、zset、hash等数据结构的存储。
- Redis支持数据的备份,即
master-slave
(主从)模式的数据备份
Redis能干嘛
- 内存存储和持久化: redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务
- 发布、订阅消息系统
- 地图信息分析
- 定时器、计数器
- 最新n个数据
特性
数据类型、基本操作和配置
持久化和复制,RDB、AOF
事物的控制
常用网站
https://redis.io/ 官网
http://www.redis.cn 中文网
2.2 安装
2.2.1 Windows版本安装
下载地址: https://gitee.com/resource-download/redis/tree/master/
下载完成后解压后即可。
双击启动redis-server.exe
双击启动redis-cli.exe
测试简单的存值取值
127.0.0.1:6379> set name 'Mr Qi'
OK
127.0.0.1:6379> get name
"Mr Qi"
127.0.0.1:6379>
2.2.2 Linux版本安装
官网下载地址 https://redis.io/download/
下载完成后放进我们的linux的/opt
目录下
进入/opt目录
cd /opt
然后进行解压缩
tar -zxvf redis-6.2.6.tar.gz
安装gcc
(gcc是linux下的一个编译程序,是c语言的编译工具)
yum install gcc
然后在解压后的目录下,执行make
(将我们的文件编译成C文件)命令,
cd redis-6.2.6
make
:
emalloc/jemalloc.h: 没有那个文件或目录
我们需要执行以下命令
make distclean
执行完然后再次make
即可。
到这里我们就编译完成了,我们要继续进行安装
make install
安装完成后,它的默认安装位置是usr/local/bin
目录下,进入目录执行ls
命令进行查看.
我们可以看到里面关于redis的有7个文件,各个文件说明如下
redis-benchmark
: 性能测试工具
redis-check-aof
: 修复有问题的aof文件
redis-check-rdb
:修复有问题的rdb文件
redis-server
:redis服务器启动命令
redis-cli
:客户端操作入口
:
执行redis-server
命令
这种方式有个弊端,就是我们只要关闭窗口,则服务就会自动关闭。
:
我们需要修改redis.conf
文件,将里面的daemonize no
改为yes
,为了不破坏原有文件,我们可以复制一份文件进行修改。
进入/opt/redis-6.2.6
目录下执行以下命令
# mycopy 你自己放的具体位置,可自行修改
cp redis.conf /mycopy
进入/mycopy目录下修改redis.conf文件,执行命令如下
cd /mycopy
vi redis.conf
将对应位置修改为yes
即可,退出即可。
:
进入/usr/local/bin
,执行以下命令
redis-server /mycopy/redis.conf
这样redis就在后台启动了,即使关掉窗口redis仍然可以正常使用
我们可以来查看我们的redis进程是否正常启动:
ps -ef | grep redis
启动成功。
:
redis-cli
:
shutdown
exit
2.3:redis基础知识
2.3.1: 端口号
redis默认端口号为6379
:
:6379在是手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字。MERZ长期以来被Redis作者antirez及其朋友当作愚蠢的代名词。后来Redis作者在开发Redis时就选用了这个端口。
# 在redis.conf配置文件中
port 6379
2.3.2:数据库
redis默认16个数据库,类似数组下标从0开始,默认使用零号数据库。redis.conf里面有默认配置。
# Set the number of databases. The default database is DB 0, you can select
# a different one on a per-connection basis using SELECT <dbid> where
# dbid is a number between 0 and 'databases'-1
databases 16
2.3.3:基础命令
select
命令切换数据库
# 不同的库可以存储不一样的数据
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> select 2
OK
dbsize
查看当前库的key数量
127.0.0.1:6379[2]> set name 'qi'
OK
127.0.0.1:6379[2]> dbsize
(integer) 1
127.0.0.1:6379[2]> select 1
OK
127.0.0.1:6379[1]> dbsize
(integer) 0
keys *
可以查看具体的key
127.0.0.1:6379[2]> keys *
1) "name"
flushdb
: 清空当前库
flushall
:清空全部库
127.0.0.1:6379[2]> dbsize
(integer) 1
127.0.0.1:6379[2]> flushdb
OK
127.0.0.1:6379[2]> dbsize
(integer) 0
2.3.4:线程
Redis是单线程+多路IO复用技术
IO多路复用是指使用一个线程来检查多个文件描述符(Socket)的就绪状态,比如调用select和poll函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则阻塞直到超时。
3、Redis常用五大数据类型
3.1. Redis键(key)
命令 | 作用 |
---|---|
keys * | 查看当前库所有key |
exists key | 判断key是否存在 |
type key | 查看key是什么类型的 |
del | 删除指定的key数据 |
expire key 10 | 为key设置过期时间 |
ttl key | 查询还有多久过期(-1:永不过期,-2:已经过期) |
3.2 Redis字符串
- String类型是Redis中最基本的类型,一个Redis中字符串value最多可以是
512M
- String是
二进制安全的
.意味着Redis的String可以包含任何数据,比如jpg图片或者是序列化的对象。 - 一个redis中字符串value最多可以是512M.
3.2.1: 常用命令
set <key> <value>
:存值(key如若已存在则覆盖)
127.0.0.1:6379> set name qi
OK
get <key>
:取值
127.0.0.1:6379> get name
"qi"
append <key> <value>
将给定的value追加到原值的末尾
127.0.0.1:6379> append name jing
(integer) 6
127.0.0.1:6379> get name
"qijing"
strlen <key>
获取值得长度
127.0.0.1:6379> strlen name
(integer) 6
setnx key value
:只有key不存在时,设置key的值
# 存在key则设置不成功
127.0.0.1:6379> setnx name zhang
(integer) 0
# 不存在这个key,成功设置
127.0.0.1:6379> setnx age 10
(integer) 1
incr <key>
: 只能对数字值操作+1,如果为空,新增值为1
# key值不存在,也就是key为空
127.0.0.1:6379> incr k1
(integer) 1
127.0.0.1:6379> get k1
"1"
# key不为空
127.0.0.1:6379> set age 10
OK
127.0.0.1:6379> incr age
(integer) 11
127.0.0.1:6379> get age
"11"
decr <key>
:只能对数字值操作-1,如果为空,则为0
127.0.0.1:6379> set age 10
OK
127.0.0.1:6379> decr age
(integer) 9
127.0.0.1:6379> get age
"9"
incrby <key> <步长>
:可以设置每次增加多少
127.0.0.1:6379> set age 10
OK
127.0.0.1:6379> incrby age 10
(integer) 20
127.0.0.1:6379> get age
"20"
decrby <key> <步长>
:可以设置每次减少多少
127.0.0.1:6379> set age 10
OK
127.0.0.1:6379> decrby age 10
(integer) 0
127.0.0.1:6379> get age
"0"
mset <key1> <value1> <key2> <value2>
:可以设置多个key-value
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> keys *
1) "k1"
2) "k2"
3) "k3"
:msetnx <key1> <value2> <key2> <value2>
:给定所有key都 不存在设置key的值,一个失败都失败
mget <key1> <key2>
:可以获取多个key的value值
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"
getrange <key> <起始位置> <结束位置>
:获取值的范围,类似于java中的substring
127.0.0.1:6379> set name YangLi
OK
127.0.0.1:6379> getrange name 0 3
"Yang"
setrange <key> <起始位置> <value>
: 从key的起始位置加入值
127.0.0.1:6379> setrange name 3 aaa
(integer) 7
127.0.0.1:6379> get name
"123aaa7"
127.0.0.1:6379>
setex <key> <过期时间> <value>
: 设置过期时间
127.0.0.1:6379> setex age 10 21
OK
127.0.0.1:6379> ttl age
(integer) -2
127.0.0.1:6379> get age
(nil)
getset <key> <value>
:设置新值获取旧值
127.0.0.1:6379> getset name MaYangLi
"qijingjing"
127.0.0.1:6379> get name
"MaYangLi"
3.3 Redis列表(List)
- Redis列表是最简单的字符串列表,按照插入顺序,你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
- 它的底层是一个
双向链表
,对两端操作性很高,通过索引下标的操作中间点的性能很差。
3.3.1:常用命令
lpush/rpush <key> <v1> <v2> <v3>
:从左边/右边插入一个或多个值
lrange <key> <开始位置> <结束位置>
:按照索引下标获得元素
127.0.0.1:6379> lpush name qijingjing yangli
(integer) 2
# 0 到 -1 代表全部元素
127.0.0.1:6379> lrange name 0 -1
1) "yangli"
2) "qijingjing"
lpop/rpop <key>
: 从左边/右边取到一个值,取出后即值不存在了
127.0.0.1:6379> rpush name v1 v2 v3
(integer) 3
127.0.0.1:6379> lpop name
"v1"
127.0.0.1:6379> rpop name
"v3"
rpoplpush <key1> <key2>
:从key1列表右边吐出一个值,插到key2列表左边
127.0.0.1:6379> rpush name1 v1 v2 v3
(integer) 3
127.0.0.1:6379> rpush name2 v4 v5 v6
(integer) 3
127.0.0.1:6379> rpoplpush name1 name2
"v3"
127.0.0.1:6379> lrange name1 0 -1
1) "v1"
2) "v2"
127.0.0.1:6379> lrange name2 0 -1
1) "v3"
2) "v4"
3) "v5"
4) "v6"
lindex key <下标>
:按照索引下标获得元素(从左到右)
127.0.0.1:6379> rpush name v1 v2 v3
(integer) 3
127.0.0.1:6379> lindex name 0
"v1"
127.0.0.1:6379> lindex name 2
"v3"
llen <key>
:获得列表长度
127.0.0.1:6379> rpush name v1 v2
(integer) 2
127.0.0.1:6379> llen name
(integer) 2
linsert <key> <before>/<after> <value> <newvalue>
:在value的前面/后面插入newvalue插入值
127.0.0.1:6379> rpush age v1 v2 v3
(integer) 3
127.0.0.1:6379> linsert age before v3 v4
(integer) 4
127.0.0.1:6379> lrange age 0 -1
1) "v1"
2) "v2"
3) "v4"
4) "v3"
lrem <key><n><value>
:从左边删除n个value(从左到右)
127.0.0.1:6379> rpush k11 v1 v2 v3 v3 v3 v4 v5
(integer) 7
127.0.0.1:6379> lrem k11 2 v3
(integer) 2
127.0.0.1:6379> lrange k11 0 -1
1) "v1"
2) "v2"
3) "v3"
4) "v4"
5) "v5"
lset <key> <index> <value>
:在指定下标位置换一个新值
127.0.0.1:6379> rpush key v1 v2 v3
(integer) 3
127.0.0.1:6379> lset key 0 vv
OK
127.0.0.1:6379> lrange key 0 -1
1) "vv"
2) "v2"
3) "v3"
3.4 Redis集合(Set)
-
Redis set 对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以
自动排重
的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择 -
Redis的Set是string类型的无序集合,它底层其实是一个value为null的hash表
3.4.1:常用命令
sadd <key><value1><value2>
:将一个或多个元素加入到集合key中,已经存在的会被忽略
smembers<key>
:取出该集合所有值
127.0.0.1:6379> sadd name qi qi a b c
(integer) 4
127.0.0.1:6379> smembers name
1) "c"
2) "a"
3) "b"
4) "qi"
sismember<key><value>
:判断集合key是否有含value值,有1,没有0
127.0.0.1:6379> sadd name qw df
(integer) 2
127.0.0.1:6379> sismember name qw
(integer) 1
127.0.0.1:6379>
scard<key>
:返回该集合的元素个数。
127.0.0.1:6379> sadd age 1 2 3
(integer) 3
127.0.0.1:6379> scard age
(integer) 3
srem<key><value1><value2>
:删除集合中的某个元素(没有则不做处理)
127.0.0.1:6379> sadd name a b c d
(integer) 1
127.0.0.1:6379> srem name a b
(integer) 2
127.0.0.1:6379> smembers name
1) "c"
2) "d"
spop<key>
:随机从该集合中吐出一个值
127.0.0.1:6379> spop name
"a"
127.0.0.1:6379> smembers name
1) "c"
2) "b"
srandmember<key><n>
:随机从该集合中取出n个值,不会从集合中删除。
127.0.0.1:6379> sadd name a b c d e
(integer) 5
127.0.0.1:6379> srandmember name 3
1) "c"
2) "a"
3) "e"
smove<source><destination><value>
:把一个集合的值移到另一个集合
127.0.0.1:6379> sadd age1 1 2 3 4 5
(integer) 5
127.0.0.1:6379> sadd age2 6 7 8 9 10
(integer) 5
127.0.0.1:6379> smove age1 age2 1
(integer) 1
127.0.0.1:6379> smembers age1
1) "2"
2) "3"
3) "4"
4) "5"
127.0.0.1:6379> smembers age2
1) "1"
2) "6"
3) "7"
4) "8"
5) "9"
6) "10"
sinter<key1><key2>
:返回两个集合的交集
元素
127.0.0.1:6379> sadd age1 1 2 3 4
(integer) 1
127.0.0.1:6379> sadd age2 1 3 567
(integer) 2
127.0.0.1:6379> sinter age1 age2
1) "1"
2) "3"
sunion<key1><key2>
:返回两个集合的并集
元素
127.0.0.1:6379> sadd age1 1 2 3 4
(integer) 4
127.0.0.1:6379> sadd age1 2 3 4 56
(integer) 1
127.0.0.1:6379> sunion age1 age2
1) "1"
2) "2"
3) "3"
4) "4"
5) "56"
sdiff<key1><key2>
:返回两个集合的差集
元素(key1中的,key2中没有的)
127.0.0.1:6379> sadd age1 1 3 5 7
(integer) 4
127.0.0.1:6379> sadd age2 1 2 4 6 7
(integer) 5
127.0.0.1:6379> sdiff age1 age2
1) "3"
2) "5"
3.5 Redis哈希(Hash)
- Redis hash 是一个键值对的集合
- Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。存储部分变更的数据,如用户信息等。
hset <key><field><value>
:给key集合中的field键赋值value
hget <key><field>
:从key集合field取出value。
127.0.0.1:6379> hset user name qijingjing
(integer) 1
127.0.0.1:6379> hget user name
"qijingjing"
hmset <key1><value1><key2><value2>..
:批量设置hash的值
127.0.0.1:6379> hmset user age 1 city beijing
OK
127.0.0.1:6379> hget user age
"1"
127.0.0.1:6379> hget user city
"beijing"
hexists<key1><field>
:查看哈希表key中,给定field是否存在
127.0.0.1:6379> hset user name qijingjing
(integer) 1
127.0.0.1:6379> hexists user name
(integer) 1
hkeys <key>
:列出该hash集合所有的filed
127.0.0.1:6379> hset user name qijing age 1
(integer) 2
127.0.0.1:6379> hkeys user
1) "name"
2) "age"
hvals <key>
:列出hash集合所有的value
127.0.0.1:6379> hmset user age 1 name qijingjing
OK
127.0.0.1:6379> hvals user
1) "1"
2) "qijingjing"
hincrby <key><field><increment>
:为哈希表key中的field的值进行加减操作
127.0.0.1:6379> hset user age 1
(integer) 1
127.0.0.1:6379> hincrby user age 10
(integer) 11
127.0.0.1:6379> hincrby user age -1
(integer) 10
hsetnx <key><field><value>
:将哈希表key中的field的值设置为value,当且仅当field不存在
127.0.0.1:6379> hset user name qijing
(integer) 1
127.0.0.1:6379> hsetnx user age 1
(integer) 1
127.0.0.1:6379> hkeys user
1) "name"
2) "age"
3.6: Redis有序集合Zset(sorted set)
与set相比,sorted set增加了一个权重参数score,使得集合的元素可以按照score进行有序排列,可以用sorted set来做带权重的队列,比如普通消息的score为1,重要消息的score为2,让权重高的先执行即可。可以用于排行榜操作。
zadd <key><score1><value1><score2><value2>...
:将一个或多个元素加入到有序集合key中
zrange<key><start><stop>[WITHSCORES]
:返回有序集合key中,下标在start到stop之间的元素,带WITHS