Redis入门三(主从复制、Redis哨兵、Redis集群、缓存更新策略、缓存穿透、缓存击穿、缓存雪崩)

文章目录

  • 一、主从复制
    • 1.单例redis存在的问题
    • 2.主从复制是什么?
    • 3.主从复制的原理
    • 4.主从搭建
      • 1)准备工作
      • 2)方式一
      • 3)方式二
    • 5.python中操作
      • 1)原生操作
      • 2)Django的缓存操作
  • 二、Redis哨兵(Redis-Sentinel)
    • 1.主从复制存在的问题
    • 2.哨兵(Redis-Sentinel)
      • 1)什么是哨兵
      • 2)架构说明
      • 3)搭建哨兵的目的
      • 4)哨兵的主要工作任务
    • 3.哨兵的搭建
    • 4.配置文件解释
    • 5.Python操作哨兵
  • 三、Redis集群(Redis Cluser)
    • 1.Redis集群介绍背景
      • 1)主从与哨兵存在的问题
      • 2)解决
    • 2.数据分布(分布式数据库)
      • 1)存在问题
      • 2)分区方案
    • 3.集群搭建
    • 4.Python中操作redis集群
    • 5.集群扩容
    • 6.集群缩容
  • 四、缓存更新策略
  • 五、缓存穿透,缓存击穿,缓存雪崩

一、主从复制

1.单例redis存在的问题

	'机器故障;容量瓶颈;QPS瓶颈'
		QPS瓶颈:主从  一主一从,写操作都写到主库,读操作从从库读
		容量瓶颈:集群
		机器故障:一主两从,哨兵故障转义

2.主从复制是什么?

	'一主一从,一主多从'
	作用1 :做读写分离
	作用2 :做数据副本
	作用3 :提高并发量
	
	一个master(主库)可以有多个slave(从库)
	一个slave(从库)只能有一个master(主库)
	'数据流向是单向的,从master(主库)到slave(从库,只能读,不允许写数据)'

3.主从复制的原理

	'主从复制的原理'
	1. 副本库(从库)通过slaveof 127.0.0.1 6379命令,连接主库,并发送SYNC给主库 
	2. 主库收到SYNC,会立即触发BGSAVE,后台保存RDB,发送给副本库
	3. 副本库接收后会应用RDB快照
	4. 主库会陆续将中间产生的新的操作,保存并发送给副本库
	5. 到此,我们主复制集就正常工作了
	
	6. 再此以后,主库只要发生新的操作,都会以命令传播的形式自动发送给副本库.
	7. 所有复制相关信息,从info信息中都可以查到.即使重启任何节点,他的主从关系依然都在.
	8. 如果发生主从关系断开时,从库数据没有任何损坏,在下次重连之后,从库发送PSYNC给主库
	9. 主库只会将从库缺失部分的数据同步给从库应用,达到快速恢复主从的目的

	'那么主从复制要不要开启持久化'
	 	无论创不创建持久化,都可以开启主从,但是如果不开持久化,主库重启操作,会造成所有主从数据丢失!

4.主从搭建

1)准备工作

	'启动两个redis-server的进程,来模拟两台机器的两个redis进程' 
	' 也可以多个从库,复制从库配置即可,修改端口和保存文件的文件夹即可'
	
    -准备两个配置文件
    	'配置文件1'
	    daemonize yes
	    bind 0.0.0.0
	    pidfile "/var/run/redis.pid"
	    requirepass "1234"  # 主库密码,redis最好设置密码 ,设置redis登录密码  这个看自己需求可以不要
	    port 6379
	    dir "/root/redis-7.2.4/data"
	    logfile "6379.log"
	    appendonly yes
	    appendfilename "appendonly-6379.aof"
	    appendfsync everysec
	    no-appendfsync-on-rewrite yes
	    aof-use-rdb-preamble yes
	    
    	-------------------------------
    	'配置文件2'
	    daemonize yes
	    bind 0.0.0.0
	    port 6380
	    dir "/root/redis-7.2.4/data1"
	    masterauth 1234  # 这里是主库的访问密码,主从认证密码,否则主从不能同步,这个看自己需求可以不要,如果不要就不能设置主库密码
	    logfile "6380.log"
	    appendonly yes
	    appendfilename "appendonly-6380.aof"
	    appendfsync everysec
	    no-appendfsync-on-rewrite yes
	    aof-use-rdb-preamble yes
    	
		'注意:如果两个配置都没有密码的情况下,可以直接操作,设置那个为从库,然后从库执行命令即可'
		'如果有密码的情况,必须提前设置从库,然后在从库中设置主库的访问密码才可以,我这里设置了密码,所以需要先设置'
	    -启动两个进程(当前文件下)
	    	reids-server ./redis.conf
			reids-server ./redis_6380.conf

2)方式一

	-6379设置为主,6380设置为从
    -链接到从库,执行:slaveof 127.0.0.1 6379  
    # 异步,因为我是一台机器做的模拟,所以链接本地地址,如果不同机器就写设置主库的机器的ip地址和端口
    -info 可以查看主从关系
    -主从既能查,又能写
    -从库只能查
		
	-flushall  # 清空库数据

	-断开主从关系(也是在从库执行命令):slaveof no one # 取消复制,不会把之前的数据清除
		'一旦断开关系,那么从断开那刻开始,从库将接收不到主库数据,但是断开之前的数据任然保留着'

3)方式二

	通过配置文件
	min-slaves-to-write 1
    min-slaves-max-lag 3
    #在从服务器的数量少于1个,或者三个从服务器的延迟(lag)值都大于或等于3秒时,主服务器将拒绝执行写命令

	 -核心配置通过配置文件
    slaveof 127.0.0.1 6379
    slave-read-only yes

	'这种方式一配置好,从库就已经有主库的数据了'

5.python中操作

1)原生操作

	'原生操作'
	-主:10.0.0.111::6379
    -从:10.0.0.111::6380
    -从:10.0.0.111::6381
    
    '主库'
    conn=10.0.0.111::6379
    以后只 set mset rpush 操作
    '从库'
    conn1=10.0.0.111::6380
    conn2=10.0.0.111::6381
    只要是查询,随机从conn1和conn2中出
    
   10.0.0.111

2)Django的缓存操作

	第一步:redis的配置中配置多个redis
	CACHES = {
	    "default": {
	        "BACKEND": "django_redis.cache.RedisCache",
	        "LOCATION": "redis://xxx.xxx.xxx.xxx:6379/1",
	        "OPTIONS": {
	            "CLIENT_CLASS": "django_redis.client.DefaultClient",
	        }
	    },
	    "redis1": {
	        "BACKEND": "django_redis.cache.RedisCache",
	        "LOCATION": "redis://xxx.xxx.xxx.xxx:6379/0",
	        "OPTIONS": {
	            "CLIENT_CLASS": "django_redis.client.DefaultClient",
	        }
	    }
	}

	第二步:使用
	from django.core.cache import caches
	caches['default'].set("name",'jack')  # 写
	res=caches['redis1'].get('name')  # 读

二、Redis哨兵(Redis-Sentinel)

1.主从复制存在的问题

	主从复制存在的问题:
		'当主从复制中,有一主多从的情况下,如果主库发生故障,那么整个就会崩掉,因为需要解决这个问题,所以就需要用到哨兵'
		1 主从复制,主节点发生故障,需要做故障转移,可以手动转移:让其中一个slave变成master
			-使用哨兵来解决该问题
		2 主从复制,只能主写数据,所以写能力和存储能力有限
			-使用集群来解决该问题

2.哨兵(Redis-Sentinel)

1)什么是哨兵

在主从模式下(主从模式就是把下图的所有哨兵去掉),master节点负责写请求,然后异步同步给slave节点,从节点负责处理读请求。如果master宕机了,需要手动将从节点晋升为主节点,并且还要切换客户端的连接数据源。这就无法达到高可用,而通过哨兵模式就可以解决这一问题。

哨兵模式是Redis的高可用方式,哨兵节点是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。 哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过sentinel代理访问redis的主节点,当redis的主节点挂掉时,哨兵会第一时间感知到,并且在slave节点中重新选出来一个新的master,然后将新的master信息通知给client端,从而实现高可用。这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息。

在这里插入图片描述

2)架构说明

	'可以做故障判断,故障转移,通知客户端(sentinal其实是一个进程),客户端直接连接sentinel的地址'
	
	1 多个sentinel发现并确认master有问题(内部已经帮你实现了)
	2 选举出一个sentinel作为领导(Raft算法(共识算法/选举算法)3 选取一个slave作为新的master
	4 通知其余slave成为新的master的slave
	5 通知客户端主从变化
	6 等待老的master复活成为新master的slave

	'哨兵只需要配置文件配置好,上面的操作,可以自动实现'

请添加图片描述

3)搭建哨兵的目的

	一旦一主多从的架构,主库发生故障,能够自动转移
    一主多从架构的:高可用
    	-redis服务对外高度可用
        -django服务项目是否是高可用的?
        	-nginx的转发(负载解决)

4)哨兵的主要工作任务

1)监控:哨兵会不断地检查你的Master和Slave是否运作正常。

(2)通知提醒:当被监控的某个Redis节点出现问题时,哨兵可以通过 API 向管理员或者其他应用程序发送通知。

(3)自动故障迁移:
	当一个Master不能正常工作时,哨兵会进行自动故障迁移操作,将失效Master的其中一个Slave升级为新的Master,
	并让失效Master的其他Slave改为复制新的Master;当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,
	使得集群可以使用新Master代替失效Master。

3.哨兵的搭建

	哨兵配置步骤:
		'这里我就在一台机器上演示,做一主两从的(也可以搞更多都行)'
		(启动三个哨兵,也就会开启三个进程)
		-一台机器,启动三个sentinel


	1.先搭建一主两从的配置(跟上面搭建主从复制差不多的配置)
	# 记得得在当前路径下创建 data data1 data2 个文件夹,因为下面的配置文件中dir都需要一个文件夹
	'第一个是主库配置文件'
		daemonize yes
		pidfile /var/run/redis.pid
		port 6379
		dir "/root/redis/data"
		logfile “6379.log”
		requirepass 1234   # 我配置的redis设置密码,再生产环境都是需要的
		

	'第二个是从库配置文件'
		daemonize yes
		pidfile /var/run/redis2.pid
		port 6380
		dir "/root/redis/data1"
		logfile “6380.log”
		masterauth 1234  # 连接master密码,这里是主库的访问密码  '如果主库没有配置,就无需操作这个'
		slaveof 127.0.0.1 6379
		slave-read-only yes
		

	'第三个是从库配置文件'
		daemonize yes
		pidfile /var/run/redis3.pid
		port 6381
		dir "/root/redis/data2"
		logfile “6381.log”
		masterauth 1234  # 连接master密码,这里是主库的访问密码
		slaveof 127.0.0.1 6379
		slave-read-only yes

	2.启动三个redis服务(后台启动)
		redis-server ./redis.conf
		redis-server ./redis_6380.conf
		redis-server ./redis_6381.conf

	3.三个Sentinel配置
	# sentinel.conf这个文件
	# 把哨兵也当成一个redis服务器
	创建三个配置文件分别叫sentinel_26379.conf sentinel_26380.conf  sentinel_26381.conf
	#内容如下(需要修改端口,文件地址日志文件名字)
	'sentinel_26379.conf  sentinel_26380.conf  sentinel_26381.conf'
	-三个配置文件,改一下端口和dir即可
		port 26379
		daemonize yes
		dir ./data
		protected-mode no
		bind 0.0.0.0
		logfile "redis_sentinel3.log"
		sentinel auth-pass mymaster 1234 'redispass密码'  # 连接master密码,如果主库有密码,就需要配置
		sentinel monitor mymaster 127.0.0.1 6379 2
		sentinel down-after-milliseconds mymaster 30000
		sentinel parallel-syncs mymaster 1
		sentinel failover-timeout mymaster 180000

	4.启动哨兵
		./src/redis-sentinel ./sentinel_26379.conf 
		./src/redis-sentinel ./sentinel_26380.conf 
		./src/redis-sentinel ./sentinel_26381.conf
	
	5.查看哨兵是否正常启动
		ps aux |grep redis # 可以看到有三个redis-server和三个哨兵
	
	6.哨兵,客户端也可以链接
		redis-cli -p 26379
	    	-info  # 查看
	    		master0:name=mymaster,status=sdown,address=127.0.0.1:6379,slaves=2,sentinels=3
				集群名字叫:mymaster,状态ok,主库是:127.0.0.1:6379,有两个从库,哨兵有三个
					    	

	7.停止主库,启动哨兵,会故障转移,会从中选举一个从库,将之变成主库,而其他从库,复制现在的主库
		-kill -9  主库服务的进程号# 杀进程
		-pkill -9 redis  # 批量杀,会把跟redis相关的都停止掉
		-停止一个从库,是不会做转移
		-即便原来的主库启动,它也是从库了

4.配置文件解释

配置文件解释
sentinel monitor mymaster 10.0.0.111 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

解释:
1.sentinel monitor mymaster: 
-监控一个名为 mymaster 的主服务器,后面跟着主服务器的IP和端口,以及最少需要有多少个哨兵同意才进行故障转移。
-告诉sentinel去监听地址为ip:port的一个master,这里的master-name可以自定义,quorum是一个数字,指明当有多少个sentinel认为一个master失效时,master才算真正失效

2.sentinel down-after-milliseconds: 
-如果一个服务器在指定的毫秒数内没有响应,则认为它是主观下线。
-这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒,默认为303.sentinel parallel-syncs: 
-在故障转移期间,可以有几个从服务器同时进行同步。
-这个配置项指定了在发生主备切换时最多可以有多少个slave同时对新的master进行 同步,这个数字越小,完成主备切换所需的时间就越长,但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。

4.sentinel failover-timeout: 故障转移超时时间

5.Python操作哨兵

'''python操作哨兵'''
import redis
from redis.sentinel import Sentinel


'''连接哨兵服务器(主机名也可以用域名)'''
# 192.168.200.100
sentinel = Sentinel([('192.168.200.100', 26379),
                     ('192.168.200.100', 26380),
                     ('192.168.200.100', 26381)],
                    socket_timeout=5)

print(sentinel)

# 获取主服务器地址
master = sentinel.discover_master('mymaster')
print(master)

# 获取从服务器地址
slave = sentinel.discover_slaves('mymaster')
print(slave)


##### 读写分离
# 获取主服务器进行写入
master = sentinel.master_for('mymaster', socket_timeout=0.5)
w_ret = master.set('foo', 'bar')

slave = sentinel.slave_for('mymaster', socket_timeout=0.5)
r_ret = slave.get('foo')
print(r_ret)

三、Redis集群(Redis Cluser)

1.Redis集群介绍背景

1)主从与哨兵存在的问题

	#1 主从---》提高并发量
	#2 哨兵----》高可用
	1 并发量:单机redis qps为10w/s,但是我们可能需要百万级别的并发量
	2 数据量:机器内存16g--256g,如果存500g数据呢?

2)解决

	解决:加机器,分布式
	redis cluster 在2015年的 3.0 版本加入了,满足分布式的需求

2.数据分布(分布式数据库)

1)存在问题

假设全量的数据非常大,500g,单机已经无法满足,我们需要进行分区,分到若干个子集中

2)分区方案

分布方式特点产品
哈希分布数据分散度高,建值分布于业务无关,无法顺序访问,支持批量操作一致性哈希memcache,redis cluster,其他缓存产品
顺序分布数据分散度易倾斜,建值业务相关,可顺序访问,支持批量操作BigTable,HBase
	1.顺序分区
		原理:100个数据分到3个节点上 1--33第一个节点;34--66第二个节点;67--100第三个节点(很多关系型数据库使用此种方式)
		'数据分散度易倾斜,建值业务相关,可顺序访问,支持批量操作'
		
	2.哈希分区
		原理:hash分区: 节点取余 ,假设3台机器, hash(key)%3,落到不同节点上
		'数据分散度高,建值分布于业务无关,无法顺序访问,支持批量操作	一致性哈希memcache,redis cluster,其他缓存产品'
	
		节点取余分区:
		缺点:节点扩容,添加一个节点,存在问题,很多数据需要偏移,总偏移量要大于80%,推荐翻倍扩容,由3变成6,数据量迁移为50%,比80%降低
	
		一致性哈希分区
		客户端分片:哈希+顺时针(优化取余)
		节点伸缩:只影响临近节点,但是还有数据迁移的情况
		伸缩:保证最小迁移数据和无法保证负载均衡(这样总共5个节点,数据就不均匀了),翻倍扩容可以实现负载均衡
		
		
		虚拟槽分区(redis集群)
		    预设虚拟槽:每个槽映射一个数据子集(16384个槽),一般比节点数大(redis集群不会超过16384台机器)
		    良好的哈希函数:如CRC16
		    服务端管理节点、槽、数据:如redis cluster(槽的范围0163835个节点,把16384个槽平均分配到每个节点,客户端会把数据发送给任意一个节点,通过CRC16对key进行哈希对16383进行取余,
	    算出当前key属于哪部分槽,属于哪个节点,每个节点都会记录是不是负责这部分槽,如果是负责的,进行保存,如果槽不在自己范围内,
	    redis cluster是共享消息的模式,它知道哪个节点负责哪些槽,返回结果,让客户端找对应的节点去存
	    服务端管理节点,槽,关系

3.集群搭建

	'这里就演示,启动6个redis节点,一主一从架构  3个节点 存数据,每个有一个从库,做高可用'
	
	搭建步骤:
		1.第一步:写6个redis配置文件  (redis-7000  ------7005)
			i redis-7000.conf
			port 7000
			daemonize yes
			dir "/root/redis-7.2.4/data/"
			logfile "7000.log"
			dbfilename "dump-7000.rdb"
			
			cluster-enabled yes
			cluster-config-file nodes-7000.conf
			cluster-require-full-coverage yes 

		2.第二步:快速生成剩余5个配置文件
			sed 's/7000/7001/g' redis-7000.conf > redis-7001.conf
			sed 's/7000/7002/g' redis-7000.conf > redis-7002.conf
			sed 's/7000/7003/g' redis-7000.conf > redis-7003.conf
			sed 's/7000/7004/g' redis-7000.conf > redis-7004.conf
			sed 's/7000/7005/g' redis-7000.conf > redis-7005.conf
		
		3.第三步;启动6个节点
			redis-server ./redis-7000.conf
			redis-server ./redis-7001.conf
			redis-server ./redis-7002.conf
			redis-server ./redis-7003.conf
			redis-server ./redis-7004.conf
			redis-server ./redis-7005.conf
		
		4.第四步:搭建集群
			redis-cli --cluster create --cluster-replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
			# yes  同意
		
		5.第五步:测试
			往 7000 上写 set name jack 这个数据,写不进去
		    原因是:name被hash后,得到的槽不归 7000[0--5460]
		    返回给我们错误,让我们去7001(具体看分配的槽决定去那个看)上写,顺利写进去
		
		6.第六步:查看机器信息
			cluster nodes
    		cluster info
		
		7.使用集群模式连接,自动切换到不同节点,这样就不需要在对应的槽所对应的主库写了,会自动找
			redis-cli -p 7000 -c
		
		8.这样之后,停掉一个主库,原来的从库会升级为主库

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.Python中操作redis集群

pip3 install redis-py-cluster  安装模块

from rediscluster import RedisCluster
startup_nodes = [{"host":"127.0.0.1", "port": "7005"},{"host":"127.0.0.1", "port": "7001"},{"host":"127.0.0.1", "port": "7002"}]
rc = RedisCluster(startup_nodes=startup_nodes)
rc.set("foo", "bar")
print(rc.get("foo"))

5.集群扩容

	'基于上面的6台机器(3个节点),扩成8台机器(4个节点)'
	1 准备两台机器
	sed 's/7000/7006/g' redis-7000.conf > redis-7006.conf
	sed 's/7000/7007/g' redis-7000.conf > redis-7007.conf
	
	2 启动两台机器
	redis-server ./redis-7006.conf
	redis-server ./redis-7007.conf
	
	3 两台机器加入到集群中去
	redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000(后面的127.0.0.1:70007005都可以,相当于向集群中任何一个人去说明加入即可)
	redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7000(同上解释一样)
	        
	47007复制7006
	redis-cli -p 7007 cluster replicate 88610dbe6c3938b43e529043cb98ad9e8949b0ef
	'这样弄完,没有槽,就无用'
	        
	5 迁移槽
	redis-cli --cluster reshard 127.0.0.1:7000  # 重新分配槽
	    -迁移4096个槽   16384/4   # 因为是8个机器,四个节点,所以用16384/4  平均分配槽,也可以不均匀,我这里使用均匀
	    -7006的机器接收槽  7006id号:88610dbe6c3938b43e529043cb98ad9e8949b0ef
	    -all  从每个主库槽中迁移一个到7006all就是让自动弄,否则就是自己来分配

在这里插入图片描述
在这里插入图片描述

6.集群缩容

	'基于上面的8台机器(4个节点),缩容成6台机器(3个节点)'
	第一步:下线迁槽(把70061366个槽迁移到7000上)
	from 70060-1365的槽,在返回给之前的7000
	redis-cli --cluster reshard --cluster-from 88610dbe6c3938b43e529043cb98ad9e8949b0ef --cluster-to f48f088daf59ad15950e5d665be89e6389e3430d --cluster-slots 1365 127.0.0.1:7000
	yes
	
	from 70065461-6826的槽,在返回给之前的7001
	redis-cli --cluster reshard --cluster-from 88610dbe6c3938b43e529043cb98ad9e8949b0ef --cluster-to f650a325f3f7bf63265fcf9bc2dac69e3d7042be --cluster-slots 1366 127.0.0.1:7001
	yes
	
	from 700610923-12287的槽,在返回给之前的7002
	redis-cli --cluster reshard --cluster-from 88610dbe6c3938b43e529043cb98ad9e8949b0ef --cluster-to 7fd6951117dadf8f738d5d2637ed3c921bc7aa6d --cluster-slots 1365 127.0.0.1:7002
	yes
	
	
	第二步:下线节点 忘记节点,关闭节点
	redis-cli --cluster del-node 127.0.0.1:7000 408242644423ff0d9d29434f7c7c5450b0ec996f # 先下从,再下主,因为先下主会触发故障转移
	redis-cli --cluster del-node 127.0.0.1:7000 7947d7df93b5a66832068f6baed8af7d823b02c3
	
	第三步:关掉其中一个主,另一个从立马变成主顶上, 重启停止的主,发现变成了从

四、缓存更新策略

	'如果内存中redis数据满了,再继续往里存数据,redis会触发缓存更新的策略'
	有如下几种:
	LRU/LFU/FIFO算法剔除:例如maxmemory-policy(到了最大内存,对应的应对策略)
	
	1.LRU -Least Recently Used,没有被使用时间最长的
	2.LFU -Least Frequenty User,一定时间段内使用次数最少的
	3.FIFO -First In First Out,最早放进去的key
	
	4.LIRS (Low Inter-reference Recency Set)是一个页替换算法,相比于LRU(Least Recently Used)和很多其他的替换算法,
	LIRS具有较高的性能。这是通过使用两次访问同一页之间的距离(本距离指中间被访问了多少非重复块)作为一种尺度去动态地将访问页排序,
	从而去做一个替换的选择
	'配置文件中设置:'
	
	1.LRU配置
	>maxmemory-policy:volatile-lru
	>1)noeviction: 如果内存使用达到了maxmemory,client还要继续写入数据,那么就直接报错给客户端
	>2)allkeys-lru: 就是我们常说的LRU算法,移除掉最近最少使用的那些keys对应的数据,ps最长用的策略
	>3)volatile-lru: 也是采取LRU算法,但是仅仅针对那些设置了指定存活时间(TTL)的key才会清理掉
	>4)allkeys-random: 随机选择一些key来删除掉
	>5)volatile-random: 随机选择一些设置了TTL的key来删除掉
	>6)volatile-ttl: 移除掉部分keys,选择那些TTL时间比较短的keys
	
	2.LFU配置 
	Redis4.0之后为maxmemory_policy淘汰策略添加了两个LFU模式:
	>volatile-lfu:对有过期时间的key采用LFU淘汰算法
	>allkeys-lfu:对全部key采用LFU淘汰算法
	>还有2个配置可以调整LFU算法:
	>lfu-log-factor 10
	>lfu-decay-time 1
	>lfu-log-factor可以调整计数器counter的增长速度,lfu-log-factor越大,counter增长的越慢。
	>lfu-decay-time是一个以分钟为单位的数值,可以调整counter的减少速度

五、缓存穿透,缓存击穿,缓存雪崩

'缓存穿透'
描述:
	缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。
	这时的用户很可能是攻击者,攻击会导致数据库压力过大。
解决方案:
	1 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
	2 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,
	如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
	3 通过布隆过滤器实现:把所有用户id放到布隆过滤器中---》请求过来---》去布隆过滤器中检查 id在不在,
	如果在---》数据肯定有---》继续往后走  ---》如果布隆过滤器中没有---》不是我们的数据---》直接拒绝


'缓存击穿'
描述:
	缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,
	又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力
解决方案:
	设置热点数据永远不过期。

 
'缓存雪崩'
描述:
	缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,
	缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
解决方案:
	1 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
	2 如果缓存数据库是分布式部署,将热点数据均匀分布在不同得缓存数据库中。
	3 设置热点(访问最多)数据永远不过期。


你知道redis的跳跃表吗?
	-听说过,它是redis 存储有序集合底层的数据结构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/491896.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis和MySQL如何保持数据一致性?

在高并发的场景下&#xff0c;大量的请求直接访问MySQL很容易造成性能问题。所以&#xff0c;我们都会用Redis来做数据的缓存&#xff0c;削减对数据库的请求。但是&#xff0c;MySQL和Redis是两种不同的数据库&#xff0c;如何保证不同数据库之间数据的一致性就非常关键了。 …

Vue3 新项目默认工程文件理解

Vue3 新项目默认工程文件理解 文章目录 Vue3 新项目默认工程文件理解0、工程文件结构图1、main.ts2、index.html源文件编译后 3、App.vue4、.d.ts 文件作用 0、工程文件结构图 1、main.ts // 引入 createApp 函数 import { createApp } from vue // 引入 style.css 文件&#…

工业镜头常用参数之实效F(Fno.)和像圈

Fno. 工业镜头中常用到的参数F&#xff0c;有时候用F/#&#xff0c;Fno.来表示&#xff0c;指的是镜头通光能力的参数。它可用镜头焦距及入瞳直径来表示&#xff0c;也可通过镜头数值孔径&#xff08;NA&#xff09;和光学放大倍率&#xff08;β&#xff09;来计算。有效Fno.…

FPGA亚稳态学习总结

首先是组合逻辑电路考虑的是竞争冒险&#xff0c;冒险会产生毛刺。重点研究如何去毛刺 时序逻辑电路考虑的是时序不满足会产生的亚稳态问题&#xff1a;如何考量时序满不满足呢&#xff1f;根据不同的场景又有不同的说法。 时序分析的两组基本概念 建立时间与保持时间 1.在…

【Flask开发实战】安装mysql数据库与配置连接

1、安装mysql 通过yum方式安装MySQL服务器&#xff1a; sudo yum install mysql-server 在安装过程中&#xff0c;系统可能会要求确认安装。按下Y键并按回车键继续。 安装完成后&#xff0c;MySQL服务器应已自动启动。可以使用以下命令查看和启动MySQL服务&#xff1a; sudo…

Go语言介绍以及如何在Go语言中操作MySQL数据库

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

卷起来——高级数据分析师

要成为一名高级数据分析师&#xff0c;需要掌握一系列的技能&#xff0c;包括数据处理、统计分析、机器学习、数据可视化以及业务理解等&#xff0c;喜欢或者想往这方面发展的童鞋们&#xff0c;卷起来&#xff0c;点击以下链接中的链接&#xff0c;备注"分析"进群交…

Godot 学习笔记(5):国际化多语言翻译,包含常用10种语言机翻!

文章目录 前言国际化翻译Api选择小牛测试 语言选择代码逻辑实体对象翻译帮助类导出模板读取文件翻译测试多语言测试 综合翻译文件准备测试代码测试结果 完整代码实体类翻译帮助类网络帮助类 最终效果翻译前翻译中翻译后 总结 前言 为了面向更大的市场&#xff0c;国际化是肯定…

TransformControls 是 Three.js 中的一个类,用于在网页中进行 3D 场景中物体的交互式操作。

demo案例 TransformControls 是 Three.js 中的一个类&#xff0c;用于在网页中进行 3D 场景中物体的交互式操作。让我们来详细讲解它的输入参数、输出、属性和方法&#xff1a; 输入参数&#xff1a; TransformControls 构造函数通常接受两个参数&#xff1a; camera&#…

gcc任意版本安装流程(linux)

一.更换镜像源 仅仅针对有需要换镜像需求的用户 sudo gedit /etc/apt/sources.list 用于在基于Debian的Linux发行版&#xff08;如Ubuntu&#xff09;上用来编辑软件源列表的命令。 我们更换阿里源&#xff1a; deb http://mirrors.aliyun.com/ubuntu/ focal main restricted…

Linux课程____shell脚本应用

一、认识shell 常用解释器 Bash , ksh , csh 登陆后默认使用shell&#xff0c;一般为/bin/bash&#xff0c;不同的指令&#xff0c;运行的环境也不同 二、 编写简单脚本并使用 # vim /frist.sh //编写脚本文件&#xff0c;简单内容 #&#xff01;/bin/bash …

ethers.js:sign(签名)

Signers 在ethers中Signer是以太坊账户的抽象&#xff0c;可以用来签名消息和交易&#xff0c;如将签名的交易发送到以太坊网络以执行状态更改的操作。 npm install ethers5.4.0// 引入 import { ethers } from ethers签名 this.provider new ethers.providers.Web3Provider(…

SD卡备份和烧录ubuntu20.04镜像

设备及系统&#xff1a;nuc幻影峡谷工控机&#xff0c;ubuntu20.04 一、确定SD卡设备号的两种方法 方法1&#xff1a; 将有ubuntu镜像的SD卡插入读卡器&#xff0c;再将读卡器插入电脑主机&#xff0c;在 工具 中打开 磁盘&#xff0c;查看SD卡设备号&#xff0c;如下图所示…

centos 7 安装磐维(PanWeiDB)数据库(单机)

前置环境准备 文件系统环境要求 文件系统环境所要求的扇区必须为512bytes&#xff0c;查看方法如下&#xff1a; [rootdevops-core-highapp3-b-32 ~]#df -h /apps/ [rootdevops-core-highapp3-b-32 ~]#ll /dev/mapper/vg--docker-lvapp [rootdevops-core-highapp3-b-32 ~]#f…

AXI-Stream——草稿版

参考自哔站&#xff1a;FPGA IP之AXI4-Lite AXI4-Stream_哔哩哔哩_bilibili 信号 传输层级从小到大 包(----------transfer--transfer--------)------delay--------包(----------transfer--transfer--------) TKEEP和TSTRB共同决定了是哪种数据流

BEVFusion-ICRA-2023异常

异常&#xff1a; RuntimeError: /tmp/mmcv/mmcv/ops/csrc/pytorch/cuda/sparse_indice.cu 126 cuda execution failed with error 2 ERROR:torch.distributed.elastic.multiprocessing.api:failed (exitcode: 1) local_rank: 0 (pid: 2901726) of binary: 解决&#xff1a; …

Arco动态生成表头信息

文章目录 需求分析需求 a-table动态生成表头,需求如下,部分是动态生成的表头,部分是固定的表头信息,现需要在动态表头的表中拿到固定表中的字段信息,但表头是动态表中返给的 分析 用两个表进行接收不同的信息,一个存放固定的 视图<a-table ref="tableRef&quo…

vue3从精通到入门2:虚拟DOM的生成与真实DOM的转化

虚拟 DOM 实现是 Vue 框架的核心部分之一&#xff0c;它负责在真实 DOM 之上抽象出一个轻量级的、可复用的 JavaScript 对象树&#xff0c;用于高效地更新视图。 什么是虚拟DOM? 虚拟 DOM 是一个编程概念&#xff0c;它将真实的 DOM 树抽象为一个轻量级的 JavaScript 对象树…

Spring事务-两种开启事务管理的方式:基于注解的声明式事务管理、基于编程式的事务管理

Spring事务-两种开启事务管理的方式 1、前期准备2、基于注解的声明式事务管理3、基于编程式的事务管理4、声明式事务失效的情况 例子&#xff1a;假设有一个银行转账的业务&#xff0c;其中涉及到从一个账户转钱到另一个账户。在这个业务中&#xff0c;我们需要保证要么两个账户…

Spark—GraphX实战 OneID

OneID 前面我们学习了ID Mapping&#xff0c;包括ID Mapping 的背景介绍和业务场景&#xff0c;以及如何使用Spark 实现ID Mapping&#xff0c;这个过程中涉及到了很多东西&#xff0c;当然我们都通过文章的形式介绍给大家了&#xff0c;所以你再学习今天这一节之前&#xff0…