NOsql
泛指非关系型数据库,为了克服超大规模的高并发的问题,NoSQL在当今大数据环境下发展的十分迅速,Redis是发展最快的。
方便扩展(数据之间没有关系)
大数据量高性能(Redis一秒写8万次,读取11万次,NoSQL的缓存记录级,是一种细粒度的缓存,性能会比较高)
数据类型是多样的(不需要事先设计数据库)
发展历程
单机MySQL->缓存+Mysql+垂直拆分(读写分离)->分库分表+水平拆分+服务器集群
四大分类
K-V键值对 -Redis
文档型数据库
MongoDB是一个基于分布式文件存储的数据库,C++编写,主要用来处理大量的文档!
MongoDB是一个介于关系型数据库和非关系型数据库中间的产品
MongoDB是非关系型数据库中功能最丰富的
列存储数据库 -HBase -分布式文件系统
图关系数据库 -Neo4J -InfoGird
Redis入门
简介:一个开源的使用ANSI C语言编写,支持网络,可基于内存衣可持久化的日志型,K-V数据库,并提供多种语言的API。免费和开源!
windows安装
下载安装包
通过CMD启动,cd到redis的安装目录下
运行命令 redis-server redis.windows.conf
Linux安装
下载安装包,放到/opt目录下 ,解压
进入解压后的文件,找到redis.conf
yum install gcc-c++
make //下载环境
make install
redis的默认安装路径 /usr/local/bin
复制配置文件到指定目录
redis默认不是后台启动的,修改配置文件,使redis后台启动
启动redis服务
查看redis进程是否开启
Redis性能测试
redis -benchmark
Redis基础
redis有16个数据库,默认使用第0个。
Redis是单线程的,基于内存操作,CPU不是Redis的性能瓶颈,Redis的瓶颈是根据机器的内存和网络带宽,既然可以使用单线程来实现,就使用单线程来实现
Redis是C语言写的,每秒100000+的QPS,完全不比同样是使用key-value的Memecache(一套分布式的快取系统)差.
Redis为什么单线程还这么快?
误区1:高性能的服务器一定是多线程的?
误区2:多线程(CPU上下文会切换)一定比单线程效率高!
核心:redis将所有的数据全部放在内存中,所以使用单线程去操作效率最高,多线程(CPU上下文会切换:耗时的操作),对于内存系统来说,如果没有上下文切换效率就是最高的!多次读写都是在一个CPU上的,这就是最佳方案。
五大数据类型
Redis-Key
setkey value#set key
keys *#查看所有key
exists key#判断当前key是否存在
move key database#移除当前key
expire key seconds#设置key的过期时间,单位秒
tll key#查看当前key的剩余时间
type key#查看当前key的类型
append key “”#追加/如key不存在就相当于set
strlen key#获取字符创的长度
################################################
#步长 i+=
#i++
setviews0#初始浏览量为0
incr views#自增1
decr views#自减1
incrby views10#可以设置步长,指定增量
###################################################
#字符串范围 range
GETRANGE key03#截取字符串[0,3]
GETRANGE key0-1#获取全部的字符串
#替换
SETRANGE key1xx#替换指定位置开始的字符串
#######################################################
#setex (set with expire) #设置过期时间
#setnx (set if not exist) #不存在 再设置 (在分布式锁种会常常使用!)
############################################################
mset#同时设置多个值
mget#同时获取多个值
#对象
setuser:1 {name:wir,age:3}#设置一个user:1对象值为json字符来保存一个对象
#######################################################################
getset#先get再set
#如果不存在值,怎创建返回nil;如果存在值,获取原来的值并设置新值
String
String类似的使用场景:value除了是字符串还可以是数字
计数器
统计多单位的数量
List(命令l开头)
基本的数据类型,列表;可以用list实现栈,队列,阻塞队列。
LPUSH list one#将一个值(多个),插入到列表的头部(左)
RPUSH list right#将一个值(多个),插入到列表的头部(右)
LRANGE list0-1#查询list
#####################################################
LPOP
RPOP
LPOP list#移除list的第一个元素
RPOP list#移除list的最后一个元素
#########################################################
Llen list#返回list的长度
###############################
lrem list1one#移除 list集合中指定个数的value
ltrim list12#通过下标截取指定的长度
##################################################
rpoplpush#移除列表的最后一个元素,将它移动到新的列表中!
rpoplpush list1 list2
###################################################
小结
list实际上类似链表,left,right,before Node after 都可以插入值
如果key不存在,创建新的链表
如果key存在,新增内容
如果移除了所有值,链表空,表示不存在
在两边插入或者改动值效率最高!中间元素,相对来说效率会低一点~
消息排队!消息队列(Lpush Rpop),栈(Lpush Lpop)
Set(集合)
##########################################################
sadd myset"hello"#set集合红添加元素
SMEMBERS myser#查看指定set的所有值
SISMEMBER myset hello#判断某一个值在集合中是否存在
########################################
srem myset hello#移除set集合中的指定元素
########################################
SRANDMEMBER myset /2#随机拿出一个元素 /指定个数的元素
#################################
spop myset#随机删除key中的元素
#########################
smove key1 key2"xxx"#将xxx移动到key2 中
##############################
SDIFF k1 k2#查看k1 k2两个集合中不同的元素
SINTER k1 k2#查看k1 k2两个集合中相同的元素
SUNION k1 k2#查看k1 k2两个集合中所有元素
Hash(哈希)
key -<key,value>(map)!这个value是一个map集合 ;可以做变更数据,例如用户信息
##############################################
hset key field1 value#set一个具体的 key-value
hmset key field1 value11 field2 value22#同时set多个具体的k-v
hmget key field1 field2#获取多个字段
hgetall key#获取全部数据
######################################################
hdel key field1#删除hash指定的key
#####################################################
hlen key#获取hash表的字段数量
#####################################
HEXISTS key field1#判断hash中指定字段是否存在
############################################
hkeys key#获取所有的key
hvalues key#获取所有的value
Zset(有序集合)
三种特殊数据类型
Geospatial-地理空间
#geoadd
#规则:两极无法直接添加,一般通过程序一次性导入
#参数 key 值(纬度,经度,名称)
geoadd china:city116.40.39.90 beijing#添加坐标
#geopos
geopos china:city beijing#获取指定的城市的经度和纬度
#geodist
geodist china:china beijin shanghai km# 两地距离 单位:m,km,mi(英里),ft(英尺)
#georadius
georadius china:city110301000km withdist withcoord count1#以经纬度为中心1000km为半径查找 显示到中间距离的位置 显示他人的定位信息 筛选出指定的结果
#georadiusbymember
georadiusbymember china:city beijing1000km#找出位于指定元素周围的其他元素
Hyperloglog
占用的内存是固定的,2^64不同的元素基数,只要12KB内存。0.18%错误率!
PFadd key
PFCOUNT key#统计
Bitmaps-位存储
bitmaps位图,数据结构!都是操作二进制位来进行记录,就只有0和1两个状态!
事务
Redis事务本质:一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行!
一次性,顺序性,排他性!执行一些列的命令!
Redis事务没有隔离级别的概念!(不会出现脏读,幻读,不可重复读)
所有的命令在事务中,并没有直接被执行!只有发起执行命令的时候才会执行!Exec
Redis单条命令是保证原子性的,但是事务不保证原子性
redis事务
开启事务(multi)
命令入队()
执行事务(exec)
正常执行事务
放弃事务-discard#取消事务
编译型异常(代码有问题!命令有错),事务中所有的命令都不会被执行
运行时异常,如果事务队列中存在语法错误,那么执行命令的时候,其他命令是可以正常执行的,错误命令会抛出异常
监控! Watch
悲观锁:
悲观,无论做什么都加锁!效率低下
乐观锁:
乐观,认为不会出问题,所以不加锁!更新数据时去判断在此期间是否有人修改数据。
获取version
更新时比较version
Redis监控测试
正常执行成功!
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money #监视money对象
OK
127.0.0.1:6379> multi #事务正常结束,数据期间没有发生变动,这个时候就正常执行成功
OK
127.0.0.1:6379(TX)> DECRBY money 20
QUEUED
127.0.0.1:6379(TX)> INCRBY out 20
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 80
2) (integer) 20
如果事务执行失败!就先unwatch(解除监视)然后再watch(再次监视),最后对比监视的值是否发生变化,如果没有变化,那么可以成功,如果有变化就执行失败!继续重复。
Jedis
Jedis是Redis官方推荐的Java连接开发工具!使用Java操作Redis中间件
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.5.1</version>
</dependency>
具体方法同redis命令
Spring Boot整合
SpringBoot2.x之后,原来使用的jedis被替换为lettuce
jedis:才用的直连,多个线程操作的话,是不安全的,如果想要避免不安全,需要使用jedis pool 连接池!
lettuce :采用netty,实例可以在多个线程中进行共享,可以减少线程数量
源码分析:
@Bean
@ConditionalOnMissingBean(name="redisTemplate")//如果没有配置Bean会生效,所以可以自己定义一个redisTemplate来替换
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
publicRedisTemplate<Object,Object>redisTemplate(RedisConnectionFactoryredisConnectionFactory) {
//默认的RedisTemplate没有过多的设置,redis对象都是需要序列化的
//泛型都是object,类型,使用后需要强制类型转换
RedisTemplate<Object,Object>template=newRedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
returntemplate;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)//String是redis中最常使用的类型,所以单独提出来一个bean
publicStringRedisTemplatestringRedisTemplate(RedisConnectionFactoryredisConnectionFactory) {
StringRedisTemplatetemplate=newStringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
returntemplate;
}
Redis持久化
Redis是基于内存的数据库,如果不将内存中的数据保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失,所以Redis提供了持久化功能!
RDB(默认RDB,一般情况下不需要修改配置)
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是快照。它恢复时是将快照文件直接读到内存里。
redis会单独创建一个子进程来进行持久化,先将数据写入一个临时文件中,待持久化过程结束,在用临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的。这就确保了极高的性能。
如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加搞笑。
RDB的缺点是最后一个持久化后的数据可能丢失。
rdb保存的文件是dump.rdb,在配置文件中的快照进行配置
触发机制
save的规则满足的情况下,会自动触发rdb规则
执行flushall命令,也会触发rdb规则!
退出redis,也会产生rdb文件
备份会自动生成一个dump.rdb
如何恢复rdb文件!
只需要将rdb文件放在我们的redis启动目录就可以,redis启动时会自动检查dump.rdb并恢复其中的数据
优点
适合大规模的数据恢复!
对数据的完整性要求不高!
缺点
需要一定的时间间隔进行操作!如果redis宕机了,这个最后一次修改的数据就没有了
fork进程的时候,会占用一定的内存空间
AOF(Append Only File)
将所有命令都记录下来,恢复的时候会把这个文件全部执行一遍
以日志的形式来记录每个写操纵,将Redis执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,Redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
Aof保存的文件是appendonly.aof文件
redis默认不开启aof,需要手动修改配置文件!将appendonly改为yes才能开启aof
如果aof文件有问题,无法重新启动redis服务,需要用redis-check-aof --fix appendonly-aof
如果aof文件大于64m!fork一个新的进程来将文件进行重写
优点和缺点
优点:
每一次修改都同步,文件的完整性更好
默认每秒同步一次,可能会丢失一秒的数据
若从不同步,效率最高!
缺点:
相对于数据文件来说,aof远远大于rdb,修复的速度也比rdb慢!
Aof运行的效率也要比rdb慢,所以redis默认的持久化方式是rdb!
扩展:
RDB持久化方式能够在指定的时间间隔内对数据进行快照存储
AOF持久化方式记录每次对服务器的写操作,当服务器重启的时候回重新执行这些命令来恢复原始数据,AOF命令以Redis协议追加保存每次写的操作到文件末尾,Redis还能对aof文件进行后台重写,防止aof文件体积不至于过大。
只做缓存,不需要使用任何持久化
同时开启两种持久化方式
在这种情况下当redis重启的时候会优先载入aof文件来恢复原始数据,因为在通常情况下aof文件保存的数据集要比RDB文件保存的数据集完整
RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件,不建议只使用AOF,因为RDB更适合用于数据备份(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的Bug,留着作为一个万一的手段。
性能建议
因为RDB文件只用作备份用途,建议只在Slave(从盘)上持久化RDB文件,而且只要15分钟备份一次即可,只保留 save 900 1(15分钟至少修改一条就开启备份)这个规则。
如果Enable AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了,代价一是带来了持续的IO,二是AOF rewirte的最后将重写过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF重写的频率,AOF重写的基础大小默认值64M太小了,可以设置到5G以上,默认超过原大小100%重写可以改到适当的数值。
如果不开启AOF,仅靠Master-Slave(主从复制) Repllcation实现高可用性也可以,能减少很多IO操作,也减少了重写时带来的系统波动,代价是Master/Slave同时宕机(断电),会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个,微博就是这种架构。
Redis发布订阅
Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。微信,微博,关注系统!
Redis客户端可以订阅任意数量的频道。
订阅/发布消息图:
测试
订阅端:
127.0.0.1:6379> SUBSCRIBE wirdeos#订阅一个频道
Reading messages... (press Ctrl-C to quit)
1)"subscribe"
2)"wirdeos"
3) (integer)1
#等待读取推送的信息
1)"message"#消息
2)"wirdeos"#频道
3)"1231341"#内容
发送端:
127.0.0.1:6379> PUBLISH wirdeos 1231341 #发送者发送消息到频道!
(integer) 1
原理
Redis是使用C实现的,通过分析Redis源码里的pubsub.c文件,了解发布和订阅机制的底层实现,籍此加深对Redis的理解。
Redis通过PUBLISH,SUBSCRIBE和PSUBSCRIBE等命令实现发布和订阅功能。
通过SUBSCRIBE命令订阅某频道后,redis-server里维护了一个字典,字典的键就是一个个channel,而字典的值则是一个链表,链表中保存了所有订阅这个channel客户端。SUBSCRIBE命令的关键,就是将客户端添加到给定channel的订阅链表中。
通过PUBLISH命令向订阅者发送消息,redis-server会使用给定的频道作为键,在它所维护的channel字典中查找记录了订阅这个频道的所有客户端链表,遍历这个链表,将消息发布给所有订阅者
Pub/Sub从字面理解就是发布(Publish)与订阅(Subscribe),在Redis中可以设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,所有订阅他的客户端都会收到相应的消息。这一功能最明显的用法就是用作实时消息系统,比如普通的即使聊天,群聊等。
使用场景:
实时消息系统!
实时聊天!
订阅关注系统!
Redis主从复制
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者成为主节点(Master/leader),后者称为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。Master以写为主,Slave以读为主。
默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有),但一个从节点只可以有一个主节点。
主从复制的作用主要包括:
数据冗余(重复数据):主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余
负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写数据时应用连接主节点,读Redis数据应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
高可用(集群)基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制时Redis高可用的基础。
最少,一主二从
一般来说,要将redis运用于工程项目中,只用一台redis是不够的,原因如下:
从结构上,单个Redis服务器会发色单点故障,并且一台服务器需要处理所有的请求负载,压力较大;
从容量上,单个Redis服务器内部容量有限,无法将所有内存用作Redis存储内存。一般来说,单台Redis的最大使用内存不应该超过20G
环境配置
只配置从库,不用配置主库!
[root@localhost bin]# redis-server wconfig/redis.conf
[root@localhost bin]# redis-cli -p 6379
127.0.0.1:6379> info replication#查看当前库的信息
# Replication
role:master
connected_slaves:0#从机个数
master_failover_state:no-failover
master_replid:578832bddda2f86b82bf1cf619620397a44c0d98
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
赋值配置文件,修改对应的信息
端口
pid名字
log文件名字
dump.rdb名字
一主二从
默认情况下,每台Redis服务器都是主节点;一般情况下只需要配置从机就好了!
SLAVEOF 主机ip 端口号#在从机中配置
真实的主从配置应该在配置文件中配置,这样才是永久的,使用命令配置是暂时的.
细节
主机可以写,从机只能读!主机中的所有信息和数据,都会自动的被从机保存
测试:主机断开连接,从机依旧连接到主机,但是没有写操作;主机如果重连,从机依旧可以获取主机写入的信息
如果是使用命令行配置主从,如果重启从机,从机就会变回主机。如果重新设置成从机,那么还可以获取主机数据
复制原理
从机启动成功连接到主机后会发送一个同步命令
主机接到命令,启动后台的存盘进程,同时收集所有接受到的用于修改数据集命令,在后台进程执行完毕之后主机将整个数据文件传到从机,并完成一次完全同步。
全量赋值:从机服务在接收到数据库文件数据后,将其存盘并加载到内存中
增量赋值:主机继续将新的所有收集到的修改命令一次传给从机完成同步
但是只要重新连接主机,一次完全同步(全量复制)将被自动执行!数据一定可以在从机中看到
这个时候也可以完成主从复制
如果主节点断开,这个时候只能手动完成(没有哨兵模式)
SLAVEOF on one;若主机断开,将从节点设置成主节点!其他的结点就可以手动操作到主节点
哨兵模式(redis2.8开始提供)
概述
能够后台监控主机是否故障,如果故障了根据投票数自动将从库转为主库
哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行多个Redis实例。
这里的哨兵有两个作用
通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器
当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机
然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,因此可以采用多哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。
假设主服务器宕机,哨兵1先检测到这个结果,系统不会马上进行重新选举的过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象称为主观下线。当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行故障转移操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程成为客观下线。
哨兵配置
[root@localhost wconfig]# vim sentinel.conf #在配置文件目录下新建哨兵配置文件
#sentinel monitor 被监控的名称 host port 1 #开启投票
sentinel monitor myredis127.0.0.163791
启动哨兵
[root@localhost bin]# redis-sentinel wconfig/sentinel.conf
[root@localhost bin]# redis-sentinel wconfig/sentinel.conf
3450:X23Mar202114:01:35.952# oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
3450:X23Mar202114:01:35.952# Redis version=6.2.1, bits=64, commit=00000000, modified=0, pid=3450, just started
3450:X23Mar202114:01:35.952# Configuration loaded
3450:X23Mar202114:01:35.953 * Increased maximum number of open files to10032(it was originallysetto1024).
3450:X23Mar202114:01:35.953 * monotonic clock: POSIX clock_gettime
_._
_.-``__''-._
_.-```. `_.''-._ Redis6.2.1 (00000000/0)64bit
.-``.-```. ```\/ _.,_''-._
(' , .-` | `, ) Running in sentinel mode
|`-._`-...-` __...-.``-._|'`_.-'| Port: 26379
|`-._ `._ / _.-' | PID: 3450
`-._ `-._`-./ _.-' _.-'
|`-._`-._`-.__.-' _.-'_.-'|
|`-._`-._ _.-'_.-'| http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._`-.__.-' _.-'_.-'|
|`-._`-._ _.-'_.-'|
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
3450:X23Mar202114:01:35.954# WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
3450:X23Mar202114:01:35.955# Sentinel ID is 80bbca2a11769d234d3cfb2b826429af2ae27f80
3450:X23Mar202114:01:35.955# +monitor master myredis 127.0.0.1 6379 quorum 1
3450:X23Mar202114:01:35.956 *+slave slave127.0.0.1:6380127.0.0.16380@ myredis127.0.0.16379
3450:X23Mar202114:01:35.965 *+slave slave127.0.0.1:6381127.0.0.16381@ myredis127.0.0.16379
如果主机宕机,哨兵会自动选出新的主机并做好迁移处理,而原主机重连之后,只能归并到新的主机下变为从机
哨兵模式
优点:
哨兵集群基于主从复制模式,所有的主从配置优点全都有
主从可以切换,故障可以转义,系统可用性会更好
哨兵模式类似于主从模式的升级,从手动到自动,健壮性更好
缺点:
Redis不好在线扩容,集群容量一旦到达上线,在线扩容十分麻烦!
实现哨兵模式的配置很麻烦,选择比较多
哨兵模式的全部配置
# Example sentinel.conf
# 哨兵sentinel实例运行的端口 默认是26379,如果有哨兵集群,还需要配置每个哨兵端口
port26379
#哨兵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 mymaster127.0.0.163792
#当在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 mymaster30000
#这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行同步,
这个数字越小,完成fai lover所需的时间就越长,
但是如果这个数字越大,就意味着越多的slave因为replication而 不可用。
可以通过将这个值设为1来保证每次只有一个slave处于不能处理命令请求的状态。
# sentine1 paralle1-syncs <master-name> <numslaves>
sentine1 paralle1-syncs mymaster1
#故障转移的超时时间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 mymaster180000
# 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缓存穿透和雪崩
缓存穿透(查不到)
概念
缓存穿透,就是查一个数据缓存中没有,然后向数据库中查询。发现数据库也没有,因此查询失败。而当数据访问量特别大的时候,会对数据库造成很大压力,出现了缓存穿透。
解决方案
布隆过滤器
布隆过滤器是一种数据结构,对所以可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力。
优缺点
优点:由于存放的不是完整数据,所以占用内存少,而且新增,查询速度快
缺点:锁着数据的增加,误判率会随之增加;无法做到删除数据;也就是说布隆过滤器说不存在就一定不存在,说存在那么是可能存在。
缓存空对象
当存储曾不命中后,即使返回空对象也将其缓存起来,同时或设置一个过期时间,之后再访问这个数据将会从缓存中获取,不会再访问数据库。
缓存空对象存在问题
如果空值可以被缓存,这就意味着需要更多的空间存储更多的键,因为空值的键可能会占用很大空间
即使对空值设置过期时间,还是会存在缓存和数据库的数据会有一段时间窗口不一致,对数据的一致性会有影响
缓存击穿(库有缓存无,量大)
概述
缓存击穿指一个key非常热点,在高并发的环境下,缓存中查不到,但是数据库中可以查到,导致所有访问都进入到数据库中,数据库瞬间压力过大。
解决方案
设置value永不过期
加互斥锁(类似synchronized)
分布式锁:使用分布式锁,保证对于每个key同一时间只有一个线程去查询后端服务,其他线程只能等待。将高并发的压力转移到分布式锁,因此对于分布式锁的考验很大
缓存雪崩
概述
缓存雪崩,指同一时间缓存大量失效,到时大量访问全部进入数据库,可能会造成数据库崩溃进而导致网站崩溃
解决方案
Redis高可用-搭建集群
限流降级
数据预热
正式部署之前,先把可能的数据预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中。在即将发生高并发访问钱手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀