Redis学习总结(一)
Redis下载
1.将tar.gz压缩包放到服务器
2.使用tar -zxvf 命令解压压缩包
3.进入redis文件夹查看conf文件
4.安装基本环境 yum install gcc-c++
5.make命令
安装6.0.1版本报错解决
升级gcc centos7默认gcc版本为4.8.5
#升级到 5.3及以上版本
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
scl enable devtoolset-9 bash 9版本
退出xshell gcc版本恢复原来版本 gcc版本长期生效语句
echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
gcc -v查版本号
6.make install 安装程序
7.redis默认安装到/usr/local/bin
8.cp /usr/local/redis/redis6.0.6/redis.conf /usr/local/bin/myconfig 拷贝一份conf文件,使用副本保证安全
9.设置后台启动 redis.conf 中 daemonize改为yes
10.启动redis redis-server myconfig/redis.conf 指定启动配置文件
11.连接redis客户端redis-cli -p 6379
12.测试连接 ping->pong
13.连接后shutdown命令关闭redis-server
14.exit退出客户端
15.后面会使用单机多redis集群测试
Redis使用场景
1.集群下的session复用,防止服务模块之间切换导致退出
2.高并发 秒杀
3.高访问量的数据
Redis常用命令
# 添加数据
set k v
# 查询数据
get k
# 查询所有key
keys *
# 删除指定k-v
del k
# 添加过期时间
expire k seconds expire(过期)
# 查询过期时间
ttl k
# 判断key是否存在
exists k
# key的类型
type k
# 异步删除
unlink k
# 选择使用的数据库
select [0-15]
# 查询数据库键对值的数量
dbsize
# 清空当前库
flushdb
# 清空所有库
flushall
Redis学习总结(二)
Redis中的数据类型
string
## 常用命令
# 添加
set k v [NX(当前key不存在时添加)]|[XX(当前key存在时,可以添加)]|[EX(设置过期秒数)]|[PX(超时毫秒数)] NX和XX不能同时使用,EX和PX不能同时使用
# 查询对应键值
get key
# 将给定的<value>追加到原值的末尾
append key value
# 获得值的长度
strlen key
# 只有key不存在时,设置key的值 == set key value NX
setnx key value
# 将key中存储的数字值加1,只能对数值操作,如果为空,新增值为1
incr key
# 将key中存储的数字值减1,只能对数值操作,如果为空,新增值为-1
decr key
# 使key中存储的数值按步长增或减 step步长
incrby/decrby key step
# 同时存储多个键值对
mset key1 value1 key2 value2
# 同时获取多个键值value
mget key1 key2
# 同时设置多个键值对,当且仅当所有给定的key都不存在,有一个失败都失败
msetnx key1 value1 key2 value2
# 获得值的范围,类似java中的subString 前后都包含
getrange key <起始位置><结束位置>
# 从起始位置开始加入value
setrange key <起始位置> value
# 给键对值设置过期时间
setex key <过期时间> value
# 以旧换新 获取旧值,设置新值
getset key value
list
底层是一个双向链表,对两端操作性好,对中间操作灵活性差
# 从列表左边或右边添加一个或多个值
lpush/rpush key value1 value2 value3
# 从列表左边/右边吐出一个值 值在键在,值空键没
lpop/rpop key
# 从key1列表右边取出一个值放到key2的左边
rpoplpush key1 key2
# 按照索引下标获取元素,从左到右 0 -1 表示取出所有
lrange key <start> <stop>
# 按照索引下标获取元素 index元素个数 从左到右
lindex key index
# 获取列表长度
llen key
# 在value的前/后面插入newvalue
linsert key before/after value newvalue
# 从左边删除n个value 从左到右 value要删除的value值
lrem key n value
# 将列表key下标为index的值换成value
lset key index value
set
无序列表,去重,底层是hash表,增删改查快
# 将一个或多个value存到集合中,相同值忽略
sadd key value1 value2
# 取出该集合的所有值
smembers key
# 判断集合key是否含有该value值 ,有1 无0
sismember key value
# 返回该集合的元素个数
scard key
# 删除集合中的某个元素
srem key value1 value2
# 随机吐出集合中的某个值
spop key
# 随机从集合中取出n个值,不会从集合中删除
srandmember key n
# 把source集合中的一个值移动到destination集合
smove source destination value
# 返回两个集合的交集元素
sinter key1 key2
# 返回两个集合中的并集元素
sunion key1 key2
# 返回两个集合中的差集元素 key1-key2 不包含key2-key1
sdiff key1 key2
hash
# 给key集合中的field键赋值
hset <key> <field> <value>
# 从key1集合field中取出value
hget <key1> <field>
# 删除key中指定的field
hdel key field value
# 批量设置value的值
hmset key1 field1 value1 field2 value2
# 查看hash表key中,filed是否存在
hexists key1 field
# 列出该hash集合中的所有field
hkeys key
# 列出该hash集合中的所有value
hvals key
# 为hash表 key的域 field的值上加上增量1 -1
hincrby key field increment
# 将hash表key中的域field的值设置为value,当且仅当field不存在
hsetnx key field value
zset
与set相似,是一个没有重复元素的集合
不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排列集合中的成员。
集合中的成员是唯一的,但是评分可以是重复的。
因为元素是有序的,所以可以根据评分(score)或次序(position)来获取一个范围的元素
访问有序集合的中间元素也是非常快的,因此能够使用有序集合作为一个没有重复元素成员的智能列表
# 将一个或多个member元素及其score值加入到有序集合key中
zadd key score1 value1 score2 value2
# 返回有序集合key中,下标在start和stop中间的元素,WITHSCORES可以让分数和值一起返回到结果集
zrange key start stop [WITHSCORES]
# 返回有序结合key中,所有score值介于min,max之间(包括min和max)的成员,有序集合成员按score值递增(从小到大)排列
zrangebyscore key min max [WITHSCORES] [limit offset count]
# 返回有序结合key中,所有score值介于min,max之间(包括min和max)的成员,有序集合成员按score值递减(从大到小)排列
zrevrangebyscore key max min [WITHSCORES] [limit offset count]
# 为value的score加上增量
zincrby key increment value
# 删除该集合下,指定值的元素
zrem key value
# 统计该集合,分数区间内的元素个数
zcount key min max
# 返回该值在集合中的排名,从0开始
zrank key value
Redis 学习总结(三)
配置文件
###Units 单位###
配置大小单位,开头定义了一些基本的度量单位,只支持byte,不支持bit,大小写不敏感
###INCLUDE###
类似jsp中的include,多实例的情况可以把公用的配置文件提取出来
###NETWORK###
网络相关配置
默认情况下 bind = 127.0.0.1只支持本机访问
外部访问需要将bind = 127.0.0.1注释,并且要将protected-mode改为no
port 默认6379
tcp-backlog 是一个连接队列,backlog队列总和=未完成三次握手队列+已经完成三次握手队列
在高并发环境下需要一个高backlog值来避免慢客户端连接问题
注意Linux内核会将这个值减小到/proc/sys/net/core/somaxconn的值128,所以需要取人增大/proc/sys/net/core/somaxconn和/proc/sys/net/ipv4/tcp_max_syn_backlog 128两个值
timeout 空闲客户端关闭时间 0表示永不关闭
tcp-keepactive 默认300秒检测一次连接是否使用,不使用就断开
###security###
设置密码
命令
config get requirepass //获取密码配置
config set requirepass "123456" //设置密码
auth 123456 //登录
###LIMITS###
maxclients 设置redis同时可以与多少个客户端连接,默认10000,如果达到了限制,会拒绝连接
maxmemory-policy
volatile-lru:使用LRU算法移除key,只对设置了过期时间的键
allkeys-lru:在所有集合key中,使用LRU算法移除key
volatile-random:在过期集合中移除随机的key,只对设置了过期时间的键
allkeys-random:在所有集合key中,移除随机的key
volatile-ttl:移除那些值最小的key,即那些最近要过期的key
noeviction: 不进行移除,针对写操作,只是返回错误信息
发布和订阅
#订阅一个或多个符合给定模式的频道
psubscribe pattern [pattern...]
#查看订阅与发布系统状态
pubsub subcommand [argument[argument...]]
#将信息发送到指定的频道
publish channel message
#退订所有给定模式的频道
punsubscribe [parttern[pattern...]]
#订阅给定的一个或多个频道的信息
subscribe channel [channel...]
#退订给定的频道
unsubscribe channel [channel...]
新数据类型
BitMaps
统计用户信息 活跃/不活跃 、 打卡 、登录/未登录 0|1解决
二进制存储
# 设置BitMaps中的某个偏移量的value(0或1) offset:偏移量从0 开始
setbit key offset value
# 获取bitmaps中偏移量的值 ,offset:偏移量从0 开始
getbit key offset
# 统计字符串从start字节到end字节比特值为1 的数量
bitcount key [start end]
# bitop是一个复合操作,它可以做多个BitMaps的and(交集),or(并集),not(非),xor(异或)操作并将结果保存在destkey中
bitop and(or/not/xor) <destkey> [key...]
使用场景
使用场景
1.日访问量
通过hash也可以进行统计,将日期作为key ,用户id作为field, boolean值作为value
但是当访问量过大时,hash的效率就没有bitMaps高了,因为bitMaps时二进制
将日期作为key 用户id作为偏移量 0/1作为value
但是当访问量小时,不适合用bitMaps 因为用户id可能是随机生成的,跨度比较大
2.点赞
将文章设置成 key 用户id设置为偏移量 0/1 作为value判断是否已经点赞
同样可以使用hash实现
HyperLogLog
基数统计
基数 == 集合中所有不重复的数+重复的数的一个
hyperloglog 的 内存是固定的 12kb 可以存放2^64个数据
#设置值,成功返回1,失败返回0
pfadd key element [element...]
#获取值的数量 计算HLL的近似基数,可以计算多个HLL,比如用HLL存储每天的UV,计算一周的UV可以使用七天的UV合并计算
pfcount key [key...]
#合并多个集合为一个新的集合
pfmerge newkey key [key...]
使用场景
只能统计去重之后的基数,不能知道具体值,可以和bitMaps或set合并使用
1.统计注册 IP 数
2.统计每日访问 IP 数
3.统计页面实时 UV 数
4.统计在线用户数
5.统计用户每天搜索不同词条的个数
Geospatial
地理信息
#设置地理位置 longtitude 经度 latitude 纬度
geoadd key longtitude latitude member
#获取标准的地理空间字符串 没什么用
geohash key member
#获取两地的距离
geodist key member1 member2 m|km|ft(英尺)|mi(英里) 默认m
#获取经纬度
geopos key member [member..]
#查询指定半径内所有空间元素的集合 radius半径
georadius key longtitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]
WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。
WITHCOORD: 将位置元素的经度和维度也一并返回
ASC: 根据中心的位置, 按照从近到远的方式返回位置元素。
DESC: 根据中心的位置, 按照从远到近的方式返回位置元素。
COUNT <count>: 返回指定数量的元素,但执行速度不变,全部查询然后截取的
#查询指定半径内所有空间元素的集合 以member为中心
georadiusbymember key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]
#底层是zset,可以使用zset操作geo
#移除成员
zrem key member
#查看元素 withscores带着score一起输出
zrange key start end [withscores]
使用场景
1.附近的人
2.地图两点距离
Jedis
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.3.0</version>
</dependency>
//创建Jedis对象
Jedis jedis = new Jedis("192.168.*.*",6379);
//ping -- pong
String pong = jedis.ping;
//部分方法
jedis.keys("*")
jedis.set("k","v")
jedis.get("k")
//jedis的事务
multi = jedis.multi();
multi.set().........
关闭连接
jedis.close()
springboot整合redis
关闭防火墙
设置protected-mode = no
<!--springboot redis整合-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring2.x 集成redis所需 依赖-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.0</version>
</dependency>
配置文件
# redis服务器ip
spring.redis.host=192.168.229.128
# redis服务器端口
spring.redis.port=6379
# redis选择数据库
spring.redis.database= 0
# 连接超时时间
spring.redis.timeout=1800000
# 连接池最大连接数 (负数表示没限制)
spring.redis.lettuce.pool.max-active=20
# 最大阻塞等待时间 (负数表示没限制)
spring.redis.lettuce.pool.max-wait=-1
# 连接池中最大空闲连接(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
# 连接池中最小空闲连接(负数表示没限制)
spring.redis.lettuce.pool.min-idle=0
添加配置类
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.io.Serializable;
//配置类专属注解 并且完成自动注入
@Configuration
public class RedisConfig {
@Bean
//配置redisTemplate
// 默认情况下的模板只能支持 RedisTemplate<String,String>,
// 只能存入字符串,很多时候,我们需要自定义 RedisTemplate ,设置序列化器
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<String,Object> template = new RedisTemplate <>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
使用
@Autowired //注入template
RedisTemplate redisTemplate
//使用opsForValue操作
redisTemplate.opsForValue().set()
redisTemplate.opsForValue().get()
注解
@Cacheable(value,cachename)
Redis学习总结(四)最终篇
Redis事务
Redis事务是针对多个命令执行的,单个命令执行时,不用担心事务问题,因为redis是单线程,单个命令执行时不会被打断,但是多个命令可能会被插队
multi exec discard
# multi
multi命令开启事务,输入的命令进入到命令队列中,但不会执行,任何一个命令失败,都会导致exec全部失败
# exec
按顺序执行队列中的命令,任何一个命令失败,都不会回滚,其他命令会继续执行
# discard
中断队列,放弃此次事务
锁机制
悲观锁: 什么时候都会加锁
乐观锁:不会上锁,使用版本控制version,对比version 数据库操作时添加version字段 redis使用watch自动监视version
#监视
watch key
被监视的key在事务中命令进行排队时,另外的客户端对key进行了修改,事务执行时就会失败
只在事务中起作用
#取消对所有key的监视
unwatch
如果在执行WATCH命令后,exec命令或discard命令先被执行的话,那么就不需要再执行unwatch了
### redis使用乐观锁,因为redis追求效率,悲观锁对于轻量级的redis来说承担不起
持久化
RDB redis database
redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程全部结束,再将临时文件替换上次持久化好的文件。整个过程中,主进程不进行任何IO操作,保证了极高的性能,如果要对大规模数据进行恢复,且对数据的完整性要求不是很高,那么rdb效率要比aof要高,RDB的缺点就是最后一次持久化的数据可能会丢失,默认使用rdb,一般不需要改变配置
dump.rdb
#redis是内存数据库,不持久化就会失去数据
save 900 1 #900秒内,至少有一次key修改,进行持久化操作
save 300 10 #300秒内,至少有10次key修改,进行持久化操作
save 60 10000 #60秒内,至少有10000次key修改,进行持久化操作
#触发rdb条件
save中的设置
flushall触发
关闭redis服务
#如何恢复rdb文件数据
只要将rdb文件放到redis启动的同级目录下,redis启动时会自动扫描dump.rdb文件,恢复数据
优点:
-适合大规模的数据恢复
-对数据的完整性要求不高,效率高
缺点:
-需要一定时间间隔进行持久化操作,一旦redis宕机,最后一次持久化数据非常容易丢失
-fork子进程占用一定的内存空间
AOF操作 append only file
以日志的形式来记录每一个写操作,将redis执行的所有修改操作指令记录下来(读操作不记录),只需追加文件,不许修改文件,redis启动时会读取该文件重构数据,换言之,redis重启的话就根据日志将所有指令重新执行一遍来恢复数据
appendonly.aof
appendonly no #默认不开启aof,默认使用rdb,一般rdb就够用了
appendfilename "appendonly.aof" #持久化文件的名字
#appendsync always #每一次修改都同步总是执行,消耗性能
appendsync everysec #每秒执行一次同步,可能会丢失数据
#appendsync no #不执行,操作系统自动同步
#修复文件
#如果redis启动服务时,aof文件有错位,即被修改,redis服务无法启动,可以使用redis-check-aof --fix修复
redis-check-aof --fix appendonly.aof
#重写规则
no-appendfsync-on-rewrite no #默认不开启,当文件达到条件时,是否重写aof文件
auto-aof-rewrite-percentage 100 #条件一
auto-aof-rewrite-min-size 64mb #条件二
优点:
-每一次修改都同步,文件完整性会更好 默认不开启 always
-每秒同步一次,可能会丢失一秒的数据 everysec
-从不同步,效率最高
缺点:
-相对于数据文件大小来说,aof远远大于rdb,修复速度也比rdb慢
-aof运行效率也要比rdb慢,所以默认rdb持久化
主从复制
主从复制,是指将一台redis服务器的数据复制到其他的redis服务器,前者称为主节点(master/leader)后者称为从节点(slave/follower),数据复制是单向的,只能从主节点复制到从节点。Master执行写操作,slave执行读操作,读写分离
一个主节点可以有多个从节点,一个从节点只能有一个主节点
作用
1.数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式
2.故障恢复:当主节点发生故障时,可以由节点提供服务,实现快速的服务恢复
3.负载均衡:在主从复制的基础上,配合读写分离可以由主节点提供写服务,由从节点提供读服务,分担服务器负担
4.高可用(集群)基石:主从复制是哨兵模式和集群能够实施的基础,因此主从复制是redis高可用的基石
配置
# 只配置从库,不用配置主库,因为redis本身就是主库
#查看当前库的replication信息
info replication
### 开四个服务器客户端,一个用来测试
复制三份redis配置文件
-设置三个端口号
-设置pidfile名,防止重复
-设置logfile名,防止重复
-设置rdb文件名,防止重复
修改后启动三个服务
默认情况下,每一台服务都是主节点
只配置从机到主机就可以
#设置从机命令 认定哪个主机的哪个端口的redis服务为老大(主节点)
slaveof host port
# 配置文件
#配置从机找主机
replicaof masterip masterport
#配置主机密码
masterauth master-password
主机写,从机只能读,主机中的数据都会被从机保存
主机断开,从机还是连接到主机,只是没办法进行写操作
主机宕机时,可以手动配置新主机, 哨兵模式会监视自动替换主机
如果使用命令行配置的主从复制,重启就会恢复原样,需要在配置文件配死
从机关闭重启后,会发布同步命令,向主机索要数据
-全量复制:从机接收到主机数据后,全部保存到内存中
-增量复制:master继续将新收集到的数据发送给slave,完成同步
哨兵模式
手动更换主机
使用链路 主-》从-》从 替换 主-》从从
#主机宕机后,手动配置第一个从机
#或者从配置文件中注释replicaof配死
slaveof no one
#但是老大回来后,需要重新配置,比较麻烦,使用哨兵模式,主-》从从 自动替换
哨兵是一个特殊的模式,哨兵是一个独立的进程,独立运行。原理是哨兵通过向redis服务器发送命令,等待响应,从而监视多个服务器实例
监控redis运行状态
发现redis运行状态改变,通过发布订阅通知其他服务器修改配置文件
因为哨兵也可能会宕机,所以有了多哨兵模式,哨兵之间也互相监控
1.创建sentinel,conf哨兵配置文件
2.配置文件
#核心配置,master名字可以随便起,1代表开启投票机制
sentinel monitor master 127.0.0.1 6379 1
3.启动
redis-sentinel myconfig/sentinel.conf
4.如果master宕机,会投票随机选择主机
5.如果主机宕机后重启,就会变为新主机的从机
优点:
-哨兵模式,基于主从复制,有主从复制的优点
-主从可以切换,故障可以转移,系统的可用性好
-哨兵模式是主从复制的升级,从手动到自动
缺点:
-redis不好在线扩容,一旦集群到达上限,扩容十分麻烦
-实现真正的哨兵模式的配置十分复杂,有很多限制
# Example sentinel.conf
# 哨兵sentinel实例运行的端口 默认是26379,如果有哨兵集群,我们还需要配置每个哨兵端口
port 26379
#哨兵sentinel的工作目录
dir /tmp
#哨兵 sentine1 监控的redis主节点的 ip port
# master-name ,可以自己命名的主节点名字 只能由字母A-Z、数字0-9、这三个字符" . - _ "组成。
# quorum配置多少个sentine1哨兵统- -认为master主节点失联那么这时客观上认为主节点失联了
# sentine1 monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 2
#当在Redis实例中开启了requirepass foobared 授权密码这样所有连接kedis实例的客户端都要提供密码
#设置哨兵sentinel连接主从的密码注意必须为主从设置- - 样的验证密码
# sentine1 auth-pass <master-name> <password>
sentine1 auth-pass mymaster MySUPER--secret-0123passwOrd
#指定多少毫秒之后主节点没有应答哨兵sentine1 此时哨兵主观上认为主节点下线默认30秒
# sentinel down-after-mi 11i seconds <master-name> <mi 11iseconds>
sentine1 down-after-mi 11iseconds mymaster 30000
#这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行同步,这个数字越小,完成fai lover所需的时间就越长,但是如果这个数字越大,就意味着越多的slave因为replication而 不可用。可以通过将这个值设为1来保证每次只有一个slave处于不能处理命令请求的状态。
# sentine1 paralle1-syncs <master-name> <numslaves>
sentine1 paralle1-syncs mymaster 1
#故障转移的超时时间failover-timeout 可以用在以下这些方面:
#1.同一个sentine1对同一 个master两次fai lover之间的间隔时间。
#2.当一个slave从一 个错误的master那里同步数据开始计算时间。直到s1ave被纠正为向正确的master那里同步数据时。
#3.当想要取消一个正在进行的failover所需要的时间。
#4.当进行failover时,配置所有s1aves指向新的master所需的最大时间。不过,即使过了这个超时,slaves 依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了
#默认三分钟
# sentine1 failover-timeout <master-name> <milliseconds>
sentine1 fai lover-ti meout mymaster 180000
# SCRIPTS EXECUTION
#配置当某一事件发生时所需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时发邮件通知相关人员。
#对于脚本的运行结果有以下规则:
#若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10
#若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。
#如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同。
#一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被-一个SIGKILL信号终止,之后重新执行。
#通知型脚本:当sentine1有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等等),将会去调用这个脚本,这时这个脚本应该通过邮件,SMS等 方式去通知系统管理员关于系统不正常运行的信息。调用该脚本时,将传给脚本两个参数,一 个是事件的类型,一个是事件的描述。如果sentine1. conf配置文件中配置了这个脚本路径,那么必须保证这个脚本存在于这个路径,并且是可执行的,否则sentine1无法正常启动成功。
#通知脚本
# she11编程
# sentine1 notification-script <master-name> <script-path>
sentine1 notificati on-script mymaster /var/redis/notify. sh
#客户端重新配置主节点参数脚本
#当一个master由于failover而发生改变时,这个脚本将会被调用,通知相关的客户端关于master地址已经发生改变的信息。
#以下参数将会在调用脚本时传给脚本:
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
#目前<state>总是“failover",
# <role>是“Teader"或者"observer"中的-一个。
#参数from-ip, from-port, to-ip,to-port是用来和旧的master和新的master(即旧的s lave)通信的
#这个脚本应该是通用的,能被多次调用,不是针对性的。
# sentine1 client-reconfig-script <master-name> <script-path>
sentine1 client-reconfig-script mymaster /var/redis/reconfig.sh #一般都是由运维来配置!
缓存击穿、缓存穿透、缓存雪崩
缓存穿透
概念
缓存穿透(查不到)
用户查询数据,redis中没有,于是向数据库查询也没有,查询失败,当用户多的时候,缓存都没有命中,请求都到达数据库,会给数据库造成很大压力,造成数据库崩溃
解决方法
1.布隆过滤器是一种数据结构,对所有可能查询的参数以hash形式进行保存,在控制层先进行校验,不符合则丢弃,从而避免了存储系统的压力
2.缓存空对象,当存储层不命中时,返回空值也短暂缓存起来,之后再获取从缓存中拿,避免了数据库压力
问题:
-占用缓存空间
-缓存层和持久层的数据同步不一致,对于保持一致性的业务有影响
缓存击穿(缓存过期,并发访问)
概念
热点数据在过期的瞬间,收到特别大的访问量,直接抵达数据库层,导致数据库压力过大崩溃
解决方案
1.设置缓存用不过期,效率低,缓存容量有限
2.加互斥锁
分布式锁:使用分布式锁,保证对于每一个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限,因此只需要等待即可,这种方式将压力给到了分布式锁,考验分布式锁
缓存雪崩
概念
缓存雪崩,是指某一个时间段,缓存集中失效,导致所有操作到达数据库
尤其是断电或者断网引起的非自愿雪崩
解决方案
1.集群
2.限流降级,加锁或者队列控制对数据库读取的数量
3.数据预热,提前将可能被访问的数据访问一遍放入缓存,设置不同的过期时间