教程(Redis框架从入门到学精(全)_redis学习_码农研究僧的博客-优快云博客)
在linux上安装redis
先装一个gcc
yum install gcc
用xftp7将安装包传到虚拟机或者服务器中
解压
tar -zxvf redis
进入解压文件
make
make install
两种启动方法推荐使用后台启动
进redis文件把redis.conf复制一份
cp redis.conf /etc/redis.conf
远程连接
修改etc目录下的redis.conf的daemonnize的no改成yes,将bind 127.0.0.1注释,将protected-mode改为no
进入、usr/local/bin
启动redis命令
redis-server /etc/redis.conf
查看启动成功没
ps -ef | grep redis
通过客户端连接redis
redis-cli
redis的关闭
第一直接把进程杀掉
第二连接redis用shutdown
查看有没有启动Redis服务器。
在ider连接redis是,连接不上,下面的是解决问题
redis的配置application.yml(或application.properties)中 spring.redis.timeout连接超时时间(毫秒)中设置不能为0, 一般修改如下:spring.redis.timeout=5000。
找到redis的配置文件 redis.conf : 执行 vim redis.conf 3.1 protected-mode yes 改为 protected-mode no (即该配置项表示是否开启保护模式,默认是开启,开启后Redis只会本地进行访问,拒绝外部访问)。 3.2 注释掉 bin127.0.0.1 即 #bin 127.0.0.1 (ps: 不注释掉,表示指定 redis 只接收来自于该 IP 地址的请求,注释掉后,则表示将处理所有请求)。
如果在Redis中没有配置requirepass ,那么在application.properties(或application.yaml)中就不要写spring.redis.password。
常用数据类型
redis键(key)常用命令
keys* 查看当前库的所有key
EXISTS k1 判断k1存在不存在
type k1 查看时什么类型的
del k3 把k3 删除
unlink k3 也是把k3删除 但是时异步操作
expire k3 10给k3设置一个过期时间为10秒
ttl k3 查看k3 过期了没
select 参数 切换数据库
dbsize 查看当前数据库的key的数量
flushdb 清空当前库
flushall 通杀全部库
redis字符串
String类型时二进制安全的,意味着redis的String可以包含任何数据
string类型时redis最基本的数据类型,一个字符串中最多存512M
set <key> <value> 添加一个数据
get <key> 获取键值
append <key> 参数 在key后面追加参数
strlen <key> 获取值的长度
setnx <key> <value> 当key不存在时才能设置
incr <key> 将key中的储存值加1,只能对数字进行操作
decr <key> 将值减1
incrby <key> 参数 将数字值加上参数
mset <key> <value> <key> <value> <key> <value> 可以设置多个值
mget k1 k2 k3 获取多个键的值
getrange <key> 0-n 获取范围值
setrange <key> 0-n 覆盖范围值
setex <key> <过期时间> <value> 设置键值并设置过期时间
getset <key> <value> 设置新值获取旧值
redis列表
底层时双向链表
lpush/rpush <key><value1><value2><value3> 从左边/右边放值
lpop/rpop <key> 从左边或者右边拿出一个值
rpop|push <key1><key2>从<key1>列表中取一个值查到<key2>的左边
lrange mylist 0-1 获取所有value
lindex <key><index>按照索引下标获得元素(从左到右)
llen<key> 获取列表长度
linsert <key> before <value> <newvalue> 在<value>的后面插入<newvalue>插入值
lrem <key><n> <value>从左边删除n个value(从左到右)
lset<key> <index><value>将列表下标为nidex的值替换成value
redis将lian表和ziplist结合起来组成quicklist.也就是将多个zip使用双向指针穿起来使用。这样既满足了快速的插入删除性能,又不会出现太多数据冗余
redis集合(Set)
set可以自动排重
redis的set 时string类型的无序集合。它的底层其实时一个value为null的hash表,所以添加,删除,查找的复杂度都是o(1)
常用命令
sadd <key> <value1><value1><value1> 将一个或多个元素加入到集合key中,已存在的元素被忽略
smembers <key> 取出该集合的所有元素
sismember <key> <value>判断<key>是否有这个value 有1没有0
scard <key> 返回该集合的元素个数
srem <key><value1><value2>...删除集合中 的某个元素
spop <key>随机从集合中吐出一个值
srandmenber <key><n>随机从该集合中取出n 个值,不会从集合比重删除
smove <source><destination> value 把集合中一个值从一个集合中移动到另一边
sinter <key1> <key2>返回两个集合的交集元素
sunion <key1><key2>返回两个集合的并集元素
sdiff <key1><key2>返回两个集合的差集元素(key1中的,不包含key2)
Set数据结构是dict字典,字典是用哈希表实现
redis哈希
redis hash是一个键值对集合
redis hash是一个string类型的field和value 的映射表,hash特别适合用于存储对象
类似与java里面的Map<String,Object>
常用命令
hset <key><field><value>给<key>集合中的<field>键赋值<value>
hget <key1><field>从<key1>集合<field>取出value
hmset <key1><field1><value1><field2><value2>批量设置hash的值
hexists <key1><field>查看哈希表key中,给定域field是否存在
hkeys <key>列出该hash集合的所有field
hvals <key>列出该hash集合的所有value
hincrby <key><field><increment>为哈希表key中的域filed的值加上增量1 -1
hsetnx <key><field><value>将哈希表key中的域field的值设置为value,当且仅当域field不存在
redis有序集合zset
zset跟set相似
不同的是有序集合的每个成员都关联了一个评分,这个评分被用来按照从最低分到最高分的方式排序集合中的成员,集合的成员是唯一的,但是评分可以是重复的
常用命令
zadd <key><score1><value1><score2><value2>
将以恶搞或多个member元素及其score值加入到有序集key当中
zrange <key><start><stop> [WITHSCORES]
返回有序集key中,下标在<start><stop>之间的元素加入中后面的可以把值也显示出来
zrangebyscore key min max [WITHSCORES] [limit offser count]
返回有序集,score范围在min到max之间
zrevrangebyscore key min max [WITHSCORES] [limit offser count]
默认从小到大排序,,这个是从大到小
zincrby <key><increment><value>为元素的score加上数量
zrem <key><value>删除该集合下,指定值的元素
zcount <key><min><max>统计该集合,分数区间内的元素个数
zrank <key><value>返回该值在集合中的排名,从0开始
底层有跳跃表
配置文件详解
发布和订阅
redis新数据类型
Bitmaps命令
假设0表示没有1表示有
setbit <key> <offset> <标志数> 存
getbit <key> <offset>取出
bitcount <key> 计算出标志数是1 的数量
可以查两天都访问过的人的数量
HyperLogLog
统计集合中不重复的元素
pfadd <key><element> [element...]添加元素
pfcount <key> 统计出基数的数量
Geospatial
提供地理位置距离的长度
redis-jedis
用jedis操作redis,要将配置文件里面的#bind 127.0.0.1 -::1注释和protected-mode yes改成no在把防火墙关掉
redis事务和锁机制
会序列化,按顺序执行,防止插队
命令
multi 进去队列状态
exec 执行队列的语句
discard 放弃组队
如果在组队中有命令错误。就会报错所有的命令都不会执行
组队成功,执行那个命令失败,剩下的成功
悲观锁
每次操作都先上锁,操作完了释放锁,下一个人才能进行操作
乐观锁
给一个版本号,操作之前先检查版本号和数据库的一致吗,不一致不能操作,操作过后版本会变
watch key 在事务multi执行之前,先执行watch key(可以监视多个)key,如梭事务执行之前这个key被其他命令改动,那么事务将被打断
nuwatch 取消监视
redis事务三大特性
1.单独的隔离操作
按顺序执行,不会被其他客户端发送来的命令打断
2.没有隔离级别的概念
队列中的命令没有体检之前都不会实际被执行,事务体检之前任何指令都不会被执行
3.不保证原子性
有一天指令失败,其后的命令任然会被执行,没有回滚
模拟并发
yum install httpd-tools 安装工具
ab -n 1000 -c 100 -p postfile -T application/x-www-form-urlencoded http://192.168.1.106:8080/Miaosha1/doseckill
超时用连接池解决
超卖用乐观锁解决
解决库存遗留问题用脚本LUA
redis持久化
RDB 先将数据放到暂时存储区,保存时用暂时存储区的文件替换,实质上是备份和恢复数据
优势
适合大规模的数据恢复
对数据完整性和一致性要求不高哼适用
节省磁盘空间
恢复速度快
RDB的缺点就是最后一次持久化后的数据可能丢失
RDB恢复数据
将生成的dump.rdb文件复制一份,当数据丢失时,只需要将复制的文件复制一份到dump.rdb原来的位置并且名字一样
AOF
以日志形式来记录每个写操作,只记录写操作不记录读操作,只允许追加不可以改写文件
需要手动开启,在启动文件中找到appendonly 该成yes
AOF和RDB同时开启,体统默认取AOF的数据
AOF的数据恢复和RDB一样
修复异常appendonly.aof用redis-check-aof --fix appendonly.aof
AOF同步设置,根据需要设置
redis_主从复制
主机数据更新后根据配置和策略,走动同步到备机的master/slaver机制 ,master以写为主,slave以读为主
读写分离,性能扩展
容灾快速恢复
创建主从机
1.创建/myredis文件夹
2.复制redis.conf配置文件到文件夹中
3.配置一主两从,创建三个配置文件
*redis6379.conf
*redis6380.conf
*redis6381.conf
4.在三个配置文件中写入内容
include /myredis/redis.conf
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb
5.启动三个redis服务
redis-server redis6379.conf
查看当前主机运行状况
info replication
*在从机上执行slaveof 主机ip 端口号
常用三招
1.一主两仆
当从服务器连上主服务器后,从服务器向主服务器发送进行数据同步信息
主服务器接到从服务器发送过来同步信息,把主服务器数据进行持久化,rdb文件,把rdb文件发送从服务器,从服务器拿到rdb进行读取
2.薪火相传
从机可以变成别的从机的主机
3.反客为主
从机变成主机
slaveof no one
哨兵模式
反客为主的自动版,能够后台监控主机是否故障,如果故障了根据票数自动将从库转换为主库
1.在myredis中新建sentinel.conf (名字不能错)
2.在sentinel.conf写入sentinel monitor mymaster 127.0.0.1 6379 1
3.启动哨兵redis-sentinel sentinel.conf
从机中选一个作为主机
1.选择优先级靠前的
2.选择偏移量最大的
3.选择rundi最小从服务
redis集群
redis3.0开始使用无中心化集群
创建集群
先在myredis中创建6个配置文件redis6379.conf到redis6384.conf
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
全部启动
然后进入
cd /opt/redis加上自己ide版本/src
把六个节点合成一个集群
create --cluster-replicas 1 表欧式创建一个一台主机一台从机的简单集群
redis-cli --cluster create --cluster-replicas 1 192.168.63.128:6379 192.168.63.128:6380 192.168.63.128:6381 192.168.63.128:6389 192.168.63.128:6390 192.168.63.128:6391
All 16384 slots covered.
连接集群,用那个端口都行
redis-cli -c -p 6379
查看节点信息
cluster nodes
分配原则
每个主库和从库都应该在不同的主机中
插槽的概念一个集群中有16384个插槽,如果有三个主机那么每个主机中都有一部分插槽,都有一个范围值比如主机一的插槽在0-5000中那么我写入一个值这个值插入6000这个槽中那么redis就会切换主机完成操作
查看插槽中有那么数据
cluster countkeysinslot <插槽号>
只能查看自己插槽中的值
故障恢复
加入在运行中主机挂掉,那么从机会马上替代主机,变成主机,那么之前的主机重新启动之后,就会变成从机
redis集群的好处
实现扩容
分摊压力
无中心配置相对简单
redis集群的不足
多见操作不被支持
多见的redis事务不被支持
redis缓存穿透
1.redis查询不到数据库
2.出现很多非正常访问
3.服务器压力变大
解决方法
1.对空值缓存
2.设置可访问的名单(白名单)
3.采用布隆过滤器
4.进行实时监控
缓存击穿
现象
-
数据库访问压力瞬时增加
-
redis里面没有出现大量key过期
-
redis正常运行
排查
-
redis某个key过期了,大量访问这个key
解决方案
-
预先设置热门数据:在redis高峰访问之前,把一些热门数据提前存入到redis里面,加大这些热门数据key的时长
-
实时调整:现场监控哪些数据热门,实时调整key的过期时长
-
使用锁
-
就是子缓存失效的时候,不是立即取load db
-
先使用缓存工具的某些带成功操作返回值
-
缓存雪崩
数据库压力变大造成服务器崩溃
1.在极少时间段,查询大量key的集中过期情况
解决方案
-
构建多级缓存架构:nginxhuancun+redis缓存+其他缓存
-
使用锁或队列(不适合高并发)
-
设置过期标志更新缓存
-
将缓存失效时间分散开
redis分布式锁
设置锁
setnx <key> <value>
释放锁
del <key>
设置锁的过期时间
expire <key> 10秒
上锁同时设置过期时间 nx表示上锁ex表示设置过期时间
set <key> <value> nx ex 12
上锁的时候设置一个uuid,释放锁时先判断这个uuuid是不是自己的(防止误删锁)
通过lua脚本实现删除的原子性操作
使用分布式锁要满足一下四个条件
-
互斥性,在任何时刻,只有一个客户端能持有锁
-
不会发生死锁
-
解铃还须系铃人
-
加锁和解锁必须具有原子性
新功能
acl list 查看用户和权限
acl setuser <用户名>
acl whooami 查看当前那个用户在操作
acl setuser <用户名> on >密码 <权限> on表示看登录
auth <用户名> <密码>切换用户