Redis
网课链接
https://www.bilibili.com/video/BV1Rv41177Af?from=search&seid=330356149089765548
相关代码
https://gitee.com/userwhz/redis-sgg
1.NoSQL数据库简介
Redis解决性能问题 如
分布式 集群 session问题 session共享问题
常用解决方法
信息存储到客户端cookie 安全问题
session复制 浪费空间
存储到文件服务器或者数据库 IO效率问题
存储到Redis数据库 不需要经过IO 直接在内存中,速度快(好处)
NoSQL = Not Only SQL 非关系型数据库
key - value 增加数据库的扩展能力
不遵循SQL标准
不支持ACID
远超于SQL的性能
适用场景
1)高并发数据的读写
2)海量数据的读写
3)对数据的高可扩展性
不适合的场景
1)需要事务支持
2)基于SQL的结构化查询存储 处理复杂关系
Nosql
1)Memcache
数据都在内存 不能持久化
支持类型单一
辅助关系型数据库
2)redis
数据都在内存 支持持久化
支持多种数据
辅助关系型数据库
3)MongoDB
文档型数据库
数据在内存 可以持久化
支持二进制以及大型对象
行式数据库
不适合用于大数据
像SQL server,Oracle,mysql等传统的是属于行式数据库范畴。
列式数据库
统计方便
2.Redis6概述和安装
value
String list set zset有序集合 hash
特点
1)原子性操作
2)支持排序
3)数据缓存在内存中
4)可以周期性将数据写入磁盘中
5)实现主从同步 master-slave
作用
1)配合关系型数据库做高速缓存
2)热点数据 session共享
3)多样的数据结构存储持久化数据
4)最新N个数据 通过list实现时间排序
5)排行版 zset
6)时效性 expire过期
7)计数器秒杀 原子性 自增方法INCR DECR
8)去除大量重复数据 利用Set集合
9)构建队列 list集合
10)发布订阅消息 pub/sub模式
下载
/opt 有最初的conf
/etc/redis.conf 复制后的conf
/usr/local/bin/ 启动文件
ps -ef |grep redis 查找进程
常用防火墙命令
systemctl status firewalld 防火墙状态
systemctl stop firewalld 关闭防火墙
systemctl start firewalld 开启防火墙
linux下安装redis
/opt
解压 tar -zxvf
中有conf
gcc
make
make install
usr/local/bin 存放redis运行文件
redis-benchmark 性能测试工具,可以在自己本子运行,看看自己本子性能如何
redis-check-aof 修复有问题的AOF 文件,rdb和aof后面讲·
redis-check-dump 修复有问题的 dump.rdb文件
redis-sentinel Redis集群使用
redis-server Redis服务器启动命令
redis-cli 客户端,操作入口
前台启动 不推荐
redis-server
后台启动
修改redis.conf 中的deamonize的no为yes 守护进程
后台启动 修改后的配置文件地址
客户端
redis-cli
ping pong
关闭整个redis
shutdown
kill进程
redis 端口号 6379
默认16个数据库
默认适用0号库
使用select 号码 切换数据库
redis串行操作 是单线程+多路IO复用技术
memcached 多线程加锁
3.常用五大数据类型
key操作
keys * 查看所有key
匹配 keys *key的部分匹配
exists key 判断是否存在
del key 删除key
unlink key 也是删除 根据value选择非阻塞删除
仅将keys从keyspace元数据中删除 真正的删除在后续异步操作
type key key的类型
expire key 10 设置key的过期时间
ttl key查看还有多少秒过期 -1 表示永不过期 -2表示已过期
gbsize 当前库key的数量
flushdb 清空当前库
flushall 通杀所用库
Sting基本操作
二进制安全 可以包含任何数据
一个字符串value最多可以是512M
set 添加键值对 set key value
get key 取到key对应的值
append 追加 append k1 追加的东西
strlen key 长度
setnx 设置值 只有key不存在 才能设置成功
incr key 增1
decr key 减1
incrby/decrby key 步长
原子操作 不会被线程机制打断的操作 单线程
java中的i++不是原子操作
i=0 两个线程对i++100次 值是多少 答案范围 2-200
取值 ++ 赋值
mset kv kv 设置一个或多个key-value
mget k k k 取到多个value
msetnx kv kv 如果已经设置 则不成功
getrange k 起始位置 终止位置 取部分
setex key 过期时间 value
getset key value 用新值换旧值
string 数据结构为简单动态字符串 SDS
扩容机制 加倍 超过1M 只会多扩1M 总的不超过512M
List列表
单键多值 底层双向链表
头部添加 尾部添加
lpush/rpush key v v v v v v 左边或者右边插入一个或者多个值 左边放都放最左边 懂得都懂
lpop/rpop k 左边或者右边吐出一个值 值在键在 值光键完
lrange k 0 -1 表示取所有的值
lindex k index
llen k 列表长度
底层数据结构 quickList
元素较少 使用连续的内存存储 结构为ziplist 压缩列表
元素较多 变成quicklist 链表和压缩链表结合
Set集合 相对list有自动排重的功能 即不能重复
无序集合 底层是一个value为null的hash表 添加查询删除的复杂度都是1
sadd k v v v
smembers k 取出集合的所有值
sismember k v 为1表示k中存在v
scard k 元素个数
srem k v v 删除集合中的元素
spop k 随机吐出值
srandmember k n 随机从集合中取出n个值 但不会删除
smove k k v 把v从k弄到k
sinter k k 返回交集
sunion k k 返回并集
sdiff k k 返回差集k1中的不含k2中的
set底层数据结构是字典 字典是用哈希表实现的
Hash 哈希
键值对集合
适合存储对象
hset k field value
hget k field 取v
gmset k fv fv
hexists k f 看k中f是否存在
hkeys 列出所有的f
hvals 列出所有的value
数据结构
ziplist 长度短 个数少
hashtable
zset有序集合
没有重复元素 成员唯一 评分可以相同
zadd k score v score v
zrange key start end
zrangebyscore key scmin scmax
底层数据结构
hash
跳跃表
4.Redis配置文件
内容解析 可以自行查找更加详细的说明
只支持bytes
bind 访问权限
保护模式
端口号
tcp-bcaklog 最大队列总和 = 未完成三次握手 + 已经完成三次握手
高并发需要适当调高
timeout 客户端空闲超过timeout,服务端会断开连接
tcp-keepalive 定时给对端发送ack。检测到对端关闭需要两倍的设置值
loglevel 日志级别
debug
verbose
notice 默认
warning
密码设置
maxclients 客户端的最大连接数
内存淘汰策略 maxmemory-policy
1. noeviction:当内存使用超过配置的时候会返回错误,不会驱逐任何键
2. allkeys-lru:加入键的时候,如果过限,首先通过LRU算法驱逐最久没有使用的键
3. volatile-lru:加入键的时候如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的键
4. allkeys-random:加入键的时候如果过限,从所有key随机删除
5. volatile-random:加入键的时候如果过限,从过期键的集合中随机驱逐
6. volatile-ttl:从配置了过期时间的键中驱逐马上就要过期的键
7. volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键
8. allkeys-lfu:从所有键中驱逐使用频率最少的键
5.Redis的发布和订阅
发送者发布消息 pub
订阅者接收消息 sub
Redis客户端可以订阅任意数量的频道
一个发布者可以发布多个频道
subscribe channelX
publish channelX message
6.Redis新数据类型
Bigmaps
实际上为字符串 但是可以对字符串进行位操作
偏移量 offset
setbit <key> <offset> <value>
getbit <key> <offset>
bitcount 取数量
bitop and 合并后的目标 合并集1 合并集2
HyperLogLog
统计网站PV(pageView页面访问量)
用incr 和 incrby都可
但UV(UniqueVisitor 独立访客) 独立IP数 搜索记录数 需要去重和计数存在问题
集合中不重复元素个数的问题称为基数问题
解决基数(不重复元素)问题
MySQL distinct count
Redis hash set bigmaps
缺点空间浪费大
pfadd <key> <element> [element] 可多个
pfcount 数量
pfmeage 内容合并
Geospatial
提供经纬度设置 查询 范围查询 距离查询
geoadd <key> <longitude> <latitude> <member> [longitude latitude member]
geopos <key> <member> 取值
geodist <key> <member1> <member2> 单位 两地方的直线距离
georedis <key> <logitude> <latitude> radius 单位 以某一坐标为中心取半径内的元素
7.Jedis操作Redis
连接注意配置文件
开放组
防火墙
常用操作
API自己查 自行寻找资料
key string list set zset hash
模拟验证码
输入手机号 随机发送6位验证码 2分钟有效
输入验证码 点击验证 返回成功或者失败
每个手机号每天只能输入三次
8.Redis整合SpringBoot
整合依赖
配置文件配置redis
config
9.Redis的事务操作
事务作用 串联多个命令 防止别的命令插队
Multi 开启事务
Exec 类似提交
discard 类似回滚
组队时命令出现错误 执行所有命令都错误
执行出现错误 错误的不执行 其他正常执行
事务冲突问题
悲观锁 老悲观了
乐观锁 加版本号
watch key
事务中key被修改 则事务不成功
unwatch取消监视
事务三特性
1)单独的隔离操作
2)没有隔离级别的概念
3)不保证原子性
秒杀案例
商品减1 人数加1
压力检测 用下载一个工具Linux 一般应该是运维人员的工作
yum install httpd-tools
ab -n 1000 -c 100
1000个请求 100个并发
-T -p postfile 最后加请求路径
连接超时 用 Jedis连接池
超买超卖 加乐观锁 watch
库存遗留问题 乐观锁造成的
解决 Lua脚本
10.Redis持久化之RDB
RDB Redis DataBase
指定的时间间隔将内存数据集快照写入磁盘
snapshotting
默认开启 文件名称dump.db
配置文件可以修改时间间隔
save 手动持久化操作
bgsave后台持久化操作 异步快照 快照同时可以响应客户端操作
stop-writes-on-bgsave-error 磁盘满了关闭redis写操作
如何持久化
创建(fork)一个子进程进行持久化 先将数据写入一个临时文件中 持久化结束后 用临时文件替换上次持久化的文件
整个过程 主进程不进行IO操作 对于大规模数据的恢复,且数据恢复的完整性不是非常敏感 RDB更高效
优点
1)适合大规模的数据恢复
2)节省磁盘空间
3)恢复速度快
缺点
1)内存数据被克隆
2)最后一次持久化的数据可能丢失 (因为按一定规则进行的持久化,没有达到要求的不进行持久化)
RDB恢复备份
将备份的文件名称改为dump.rdb
启动redis时会自动恢复数据
11.Redis持久化之AOF
AOF Append Only File
以日志形式来记录每一个写操作 读操作不记录
只许追加文件但不可以改写文件
AOF默认不开启 appendonly no
appendonly.aof
在conf中开启
AOF和RDB同时开始 以AOF数据为基准(重要)
AOF持久化流程
将备份数据文件改为appendonly.aof
启动redis时会自动恢复数据
异常恢复
遇到APF文件损坏,通过usr/local/bin/redis-check-aof--fix appendonly.aof进行恢复
备份损坏的AOF
重启redis
AOF同步配置频率设置
appendfsync always
appendfsync everysec 宕机可能丢失一秒数据
appendfsync no
Rewrite 压缩
避免AOF文件过大
实现
fork
触发条件
auto-aof-rewrite-percentage设置重写基准值
指当前aof文件比上次重写的增长比例大小
最小文件64M
比如设置值为100% 则在128M时发生变化
优点
1)备份更稳健
2)可读的日志
缺点
1)磁盘空间大
2)恢复备份速度慢
写时复制???
12.Redis的主从复制
主机数据更新后,自动同步到备机的行为
master写为主
slave读为主
一般一主多从
作用
1)读写分离
2)容灾快速恢复
一主两从配置案例
mkdir /myredis
复制配置文件到文件夹中 cp /etc/redis.conf /myredis/redis.conf
创建三个配置文件
redis6379.conf
redis6380.conf
redis6381.conf
include /myredis/redis.conf 公共部分
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb
info replication 打印主从复制相关信息
redis-cli -p 6379
从服务器执行 slaveof 主机ip 主机端口号
主服务器可以做写操作 从服务器不可以写
主从复制问题
从服务器挂掉 重启则为主服务器 重新为从服务器时 数据不会丢失
申请为从服务器是否直接获取主服务器所有数据??
自带的数据问题??
主服务器挂掉后 从服务器仍然为从服务器
主从复制原理
从连接上主 向主发送数据同步消息
主接收消息 主数据持久化RDB
从拿到RDB 读取数据 从需要flushdb??
主写操作 和从数据同步
套娃 仆有仆
二叉树结构
主机宕机后 从机变主机
salveof no one
哨兵模式
自动化反客为主
sentinel.conf 配置文件
sentinel monitor mymaster 127.0.0.1 6379 1
mymaster监控对象的名称
1表示至少有多少个哨兵同意
启动哨兵配置文件
redis-sentinel /myredis/sentinel.conf
26379 默认端口
选举条件
1)优先级靠前 conf replica-priority 值越小 优先级越高
2)偏移量最大的 即是同步量更大的
3)runid最小的 随机生成40位的runid
主挂掉 从变主 主变从
缺点 复制延迟
java实操 自行了解
13.Redis 集群
原因
容量不够
并发写操作
ip地址变化解决
早期通过代理主机解决 类似nginx
后来采用无中心化集群配置
集群实现水平扩容 1/N
搭建redis集群
配置基本信息
include /myredis/redis.conf 公共部分
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb
cluster-enabled yes 集群模式
cluster-config-file nodes-6379.conf 设置节点配置文件名
cluster-node-timeout 15000 设定节点失联时间 毫秒 超过自动主从切换
启动redis实例
合体 cd /opt/redis-6.2.1/src
redis-cli --cluster create-replicas 1 主机ip:6379 主机ip:6380 主机ip:6381 主机ip:6389 主机ip:6390 主机ip:6391
1表示以最简单的方式配置 一台主机 一台从机
连接
redis-cli -c -p 6379
cluster nodes集群节点信息
分配原则
尽量都在不同服务器、
slots 插槽
16384
计算分配数据库
计算插槽值
cluster keyslot key
计算插槽值中的key个数
cluster countkeysinslot 插槽值
返回插槽中的值
cluster getkeysinslot 插槽值 个数
故障恢复
主服务器挂掉再启动 主变从 从变主
cluster-require-full-coverage yes 一段插槽主从都挂 则全挂
no则就挂那一个
java实操 自行了解
缺点
1)不支持多键操作
2)不支持多键redis事务
3)不支持lua脚本
14.Redis应用问题解决
缓存穿透
出现非正常URL访问
Redis中大面积出现未命中 一般应该是黑客攻击
解决
1)对空值缓存
查询缓存的数据为空(不管数据存不存在) 把空结果进行缓存 设置过期时间也很短 最长不超过5分钟
2)设置可访问的名单(白名单)
使用bitmaps类型定义一个可访问的名单 id作为偏移量
效率低
3)采用布隆过滤器
4)进行实时监控
缓存击穿
redis某个key过期
大量访问这个key 热点数据
解决
1)预先设置热门数据
2)实时调整
调整过期时间
3)使用锁
效率低
缓存雪崩
大量key同时过期
解决
1)构建多级缓存架构
nginx缓存 redis缓存 其他缓存
2)使用锁或队列
不适用高并发
3)设置过期标志更新缓存
4)将缓存失效时间分散
15.分布式锁
分布式锁的主流方案
1)基于数据库实现分布式锁
2)基于缓存(Redis等)
3)基于Zookeeper
redis性能最高
zookeeper可靠性最高
redis实现分布式锁
setnx
del 删除锁
设置过期时间防止死锁
上锁后出现异常 无法设置过期时间
上锁同时设置过期时间 set users 10 nx ex 12
使用UUID防止误删
set lock uuid nx ex 10
释放时判断当前uuid和要释放锁uuid是否一样
原子性 导致a删了b的锁
通过lua脚本
16.Redis6新功能
ACL 访问控制列表
设置权限
acl list 展示用户权限列表
acl cat 查看操作命令
运维了解
支持 Cluster