缓存架构体系

#### 缓存架构体系
##### 多级缓存架构
	html(Cache) ->> VIP ->> LVS ->> nginx(Cache) ->> Lua(访问缓存,如果没有则访问数据库)

#### redis 集群
	工作原理,主从复制
	1、Slave服务启动,主动连接Master,并发送SYNC命令,请求初始化同步; 
	2、Master收到SYNC后,执行BGSAVE命令生成RDB文件,并缓存该时间段内的写命令; 
	3、Master完成RDB文件后,将其发送给所有Slave服务器; 
	4、Slave服务器接收到RDB文件后,删除内存中旧的缓存数据,并装载RDB文件; 
	5、Master在发送完RDB后,即刻向所有Slave服务器发送缓存中的写命令;
	
##### 集群配置文件
	#端口 
	port ${PORT} 
	#非保护模式 
	protected-mode no 
	#启用集群模式 
	cluster-enabled yes 
	cluster-config-file nodes.conf 
	#超时时间 
	cluster-node-timeout 5000 
	#集群各节点IP地址 
	cluster-announce-ip 192.168.211.141 
	#集群节点映射端口 
	cluster-announce-port ${PORT} 
	#集群总线端口 
	cluster-announce-bus-port 1${PORT} 
	#开启aof持久化策略 
	appendonly yes 
	#后台运行 
	#daemonize yes 
	#进程号存储 
	pidfile /var/run/redis_${PORT}.pid 
	#集群加密 
	#masterauth itheima 
	#requirepass itheima
	
##### 创建集群
	#进入到任意一个安装好的redis节点的bin目录,里面有个脚本对象redis-cli,然后执行集群创建
	--cluster-replicas 表示有一个主有几个slave。
	
	./redis-cli --cluster create 172.18.0.2:7001 172.18.0.3:7002 172.18.0.4:7003 172.18.0.5:7004 172.18.0.6:7005 172.18.0.7:7006 --cluster-replicas 1

##### 增加节点

	增加主节点 192.168.211.141:7007 到  192.168.211.141:7001 集群
	./redis-cli --cluster add-node 192.168.211.141:7007 192.168.211.141:7001
	
	分配哈希槽 从 39c58827f 分配到 aed4f6a02235822a7 100 哈希槽
	./redis-cli --cluster reshard 192.168.211.141:7001 --cluster-from 39c58827f --cluster-to aed4f6a02235822a7 -- cluster-slots 100
	
	增加从节点 增加从节点 192.168.211.141:7008 到 192.168.211.141:7007 集群里的 6a02235822a7 master下
	./redis-cli --cluster add-node 192.168.211.141:7008 192.168.211.141:7007 --cluster-slave -- cluster-master-id 6a02235822a7

##### 移除节点
	移除主节点
	将哈希槽转到到其他master节点
	./redis-cli --cluster reshard 192.168.211.141:7007 --cluster-from 443096af2ff8c1e89f1160faed4f6a02235822a7 --cluster-to 80a69bb8af3737bce2913b2952b4456430a89eb3 --cluster-slots 33 --cluster-yes
	转移完哈希槽后,删除主节点
	./redis-cli --cluster del-node 192.168.211.141:7007 443096af2ff8c1e89f1160faed4f6a02235822a7
	
	移除 fa0441e5a821dce20ae 下的 192.168.211.141:7008 从节点
	./redis-cli --cluster del-node 192.168.211.141:7008 fa0441e5a821dce20ae

	
#### redis sentinel 哨兵
##### 监控
###### 10秒监控
	每隔10秒,每个Sentinel节点会向主节点和从节点发送info命令获取最新的主从结构,该命令有3个作用:
		1、通过向主节点执行info命令,获取从节点的信息,这也是为什么 Sentinel节点不需要显式配置监控从节点
		2、当有新的从节点加入时都可以立刻感知出来 
		3、节点不可达或者故障转移后,可以通过info命令实时更新节点结构信息
###### 2秒监控
	每隔2秒,每个Sentinel节点会向Redis数据节点的 __sentinel__:hello 频道上发送该Sentinel节点对于
	主节点的判断以及当前Sentinel节点的信息 ,同时每个Sentinel节点也会订阅该频道,来了解其他 Sentinel
	节点以及它们对主节点的判断。该定时任务主要有2个作用:
		1、发现新的Sentinel节点:通过订阅主节点的__sentinel__:hello了解其他的Sentinel节点信息,如果是
		新加入的 Sentinel节点,将该Sentinel节点信息保存起来,并与该Sentinel节点创建连接。 
		2、Sentinel节点之间交换主节点的状态,作为后面客观下线以及领导者选举的依据。
###### 1秒监控
	每隔1秒,每个Sentinel节点会向主节点、从节点、其余Sentinel节点发送一条ping命令做一次心跳检测,来确认
	这些节点当前是否可达,从而实现检查每个节点的健康状态。

#### nginx 缓存
##### OpenResty
	OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及
	大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、 Web 服务和动态网关。
	OpenResty 通过lua脚本扩展 nginx 功能,可提供负载均衡、请求路由、安全认证、服务鉴权、流量控制与日志监
	控等服务。
	OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地
	变成一个强大的通用 Web 应用平台。这样, Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持
	的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。
	
##### 浏览器缓存
	客户端侧缓存一般指的是浏览器缓存、app缓存等等,目的就是加速各种静态资源的访问,降低服务器压力。 我们
	通过配置Nginx设置网页缓存信息,从而降低用户对服务器频繁访问造成的巨大压力。我们先配置一个案例,再基于
	案例去讲解Nginx缓存。
	
	nginx 缓存配置
	server {
		listen 80;
		server_name localhost;
		location / {
			#静态文件路径
			root /usr/local/server/html;
			#缓存10秒
			expires 10s;
		}
	}
	
	过期时间配置说明
	expires 30s; #30秒
	expires 30m; #30分钟
	expires 2h; #2个小时
	expires 30d; #30天

##### 代理缓存
	nginx 配置
	
	proxy_cache_path /usr/local/openresty/nginx/cache levels=1:2 keys_zone=openresty_cache:10m max_size=10g inactive=60m use_temp_path=off;
	
	server {
		listen 80;
		server_name localhost;
		location /user {
			proxy_pass http://192.168.18.236:8089;
			#启用缓存openresty_cache
			proxy_cache openresty_cache;
			##针对指定请求缓存
			##proxy_cache_methods GET;
			##设置指定请求会缓存
			proxy_cache_valid 200 304 10s;
			##最少请求1次才会缓存
			proxy_cache_min_uses 3;
			##如果并发请求,只有第1个请求会去服务器获取数据
			##proxy_cache_lock on;
			##唯一的key
			proxy_cache_key $host$uri$is_args$args;
			proxy_pass http://192.168.18.236:8089;
		}
	}
	proxy_cache_path /usr/local/openresty/nginx/cache levels=1:2
	keys_zone=openresty_cache:10m max_size=10g inactive=60m use_temp_path=off;
	
	【作用】指定缓存存储的路径,缓存存储在/usr/local/openresty/nginx/cache目录
	【levels=1:2】设置一个两级目录层次结构存储缓存,在单个目录中包含大量文件会降低文件访问速度,因此我们建议对大
	多数部署使用两级目录层次结构。如果 levels 未包含该参数,Nginx 会将所有文件放在同一目录中。
	【keys_zone=openresty_cache:10m】设置共享内存区域,用于存储缓存键和元数据,例如使用计时器。拥有内存中的密
	钥副本,Nginx 可以快速确定请求是否是一个 HIT 或 MISS 不必转到磁盘,从而大大加快了检查速度。1 MB 区域可以存
	储大约 8,000 个密钥的数据,因此示例中配置的 10 MB 区域可以存储大约 80,000 个密钥的数据。
	【max_size=10g】设置缓存大小的上限。它是可选的; 不指定值允许缓存增长以使用所有可用磁盘空间。当缓存大小达到限
	制时,一个称为缓存管理器的进程将删除最近最少使用的缓存,将大小恢复到限制之下的文件。
	【inactive=60m】指定项目在未被访问的情况下可以保留在缓存中的时间长度。在此示例中,缓存管理器进程会自动从缓存
	中删除 60 分钟未请求的文件,无论其是否已过期。默认值为 10 分钟(10m)。非活动内容与过期内容不同。Nginx 不会
	自动删除缓存 header 定义为已过期内容(例如 Cache-Control:max-age=120)。过期(陈旧)内容仅在指定时间内未
	被访问时被删除。访问过期内容时,Nginx 会从原始服务器刷新它并重置 inactive 计时器。
	【use_temp_path=off】表示NGINX会将临时文件保存在缓存数据的同一目录中。这是为了避免在更新缓存时,磁盘之间互
	相复制响应数据,我们一般关闭该功能。

##### 缓存清理
	nginx增加 ngx_cache_purge 模块。
	设置清理缓存地址:
	location ~ /purge(/.*) {
		# 清理缓存
		proxy_cache_purge openresty_cache $host$1$is_args$args;
	}
	
	$1 代表的是 (/.*) 的数据
	

#### LUA
	lua是一门性能著称的脚本语言,被广泛引用在很多方面。lua一般用于嵌入式应用。
	优势:
		1,可以非常轻松嵌入到其他程序中。
		2,提升应用性能,比如:游戏脚本,nginx,wireshark的脚本。
		3,兼容性强,可以直接使用c代码写的函数。比如corona 移动应用开发平台,跟phoneRap类似。
		4,在给软件提供嵌入式脚本编程能力上,lua是最佳选择。

#### nginx限流
##### 控制速率 
	采用漏桶算法。
	nginx配置(在server之上,创建缓存空间):
	
	contentRateLimit:10m	命名空间的名字,缓存空间大小
	limit_req			使用限流配置
	rate=2r/s			速率限流标志,每秒中处理两个请求。
	limit_req_zone $binary_remote_addr zone=contentRateLimit:10m rate=2r/s;
	server {
		location /* {
			limit_req zone=contentRateLimit;
		}
	}


	缓存请求,缓存请求数量4个
	burest=4,若同事有4个请求到达,nginx会处理第一个请求,剩余3个请求将放入队列,然后每隔500ms从队列中获取
	一个请求处理,若请求数大于4,将拒绝处理的多余请求,直接返回503.
	不过单独使用burst参数并不实用。假设burst=50,rate依然为10r/s,排队中的50个请求虽然没100ms会处理一个
	,但是第50个需要等待50*100ms时间,因此burst结合nodelay一起实用。不需要延迟,同时处理。
	
	location /* {
		limit_req zone=contentRateLimit burst=4 nodelay;
	}
		
##### 控制并发连接数
###### ip并发限流
	nginx 配置
	配置限流名,限流缓存大小
	没秒钟只循序有两个并发请求
	
	limit_conn_zone $binary_remote_addr zone=addr:1m;
	server {
		location /* {
			limit_conn addr 2;
		}
	}
	
###### 总数限流
	nginx配置
	
	# 根据ip进行限流
	limit_conn_zeon $binary_remote_addr zone=perip:10m;
	# 根据servername限流
	limit_conn_zone $server_name zone=perserver:10;
	server {
		location /* {
			# 用户限流
			limit_conn perip 3;		# 单个客户端ip与服务器连接数
			# server限流
			limit_conn perserver 100;	# 限制与服务器的总连接数
		}
	}

#### 缓存穿透解决方案
	在mysql读取数据后,如果无数据,将无数据状态放入redis中,防止缓存穿透。
##### 布隆过滤器:
	防止缓存穿透,有多种方案。布隆过滤器主要是解决大规模数据下不需要精确过滤的业务场景,如检查垃圾邮件地址。
	爬虫url地址去重,解决缓存穿透问题等。
		
#### 缓存击穿解决方案
##### 定时器
	定时刷新缓存信息
	
##### 多级缓存
	将缓存存放在nginx,redis做多级缓存。
	
##### 分布式锁
	在数据库查询的代码块,加分布式锁,只由一条请求去mysql查询,将数据存放至缓存。
	
##### 队列术
	使用nginx队列
	nginx配置
	
	server{
		location / {
			# 启用openresty缓存
			proxy_cache openresty_cache;
			# 针对指定请求缓存
			# proxy_cache_methosd GET;
			# 设置指定请求会缓存
			proxy_cache_valid 200 304 10s;
			# 最少请求一次才会缓存
			proxy_cache_min_uses 1;
			
			# * 如果并发请求,只有第一个请求会去服务器获取数据
			proxy_cache_lock on;
			
			# 缓存唯一的key
			proxy_cache_key $host$uri$is_args$args;
			proxy_pass http:abc.com
		}
	}
	
#### 缓存雪崩解决方案
	1) 缓存高可用
		即使个别节点,个别机器,甚至是机房宕机,依然可以提供服务,比如redis sentinel 和 redis cluster
		都实现了高可用。
	2)限流
		微服务网关或者nginx做好限流操作,防止大量请求直接进入后端,使后端负载过重最后宕机。
	3)数据预热
		预先更新缓存,再即将发生大并发访问钱手动出发加载缓存不同的key,设置不同的过期时间,让缓存失效的
		时间点尽量均衡,不要同时失效。
	4)队列术限流
		使用nginx队列或者mq队列,缓存用户的请求,让所有的相同的操作只有1次查询数据库,并将查询的数据加入到
		缓存。
	5)加锁
		
	6)多级缓存(推荐)
		nginx-cache -> redis-cache -> mybatis-cache -> mysql
		
#### 缓存一致性解决方案
	Canal主要用途是基于mysql数据库日志解析,监听数据库数据变化。
##### Canal工作原理
	1,canal模拟mysql slave的交互协议,伪装自己为mysql slave,想mysql master发送dump协议
	2,mysql master收到dump请求,凯斯推送binary log给 slave(canal)
	3,canal解析binary log对象(原始为byte流)

###### canal配置
	1) 开启mysql的bin-log
		在mysql的配置文件 mysqld.cnf 最下面增加如下配置:
		# 开启binlog
		log-bin=/var/lib/mysql/mysql-bin
		# 选择row模式
		binlog-format=ROW
		# 配置mysql replaction需要定义,不要和canal的slaveId重复
		server-id=123456
		
		创建canal用户
		create user canal@"%" IDENTIFIED by "canal";
		GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT,SUPER ON *.* TO 'canal'@'%';
		FLUSH PRIVILEGES;
				
	2) canal安装
		docker run -p 11111:11111 --name canal -d docker.io/canal/canal-server
		配置CanalServer
		修改 /home/admin/canal-server/conf/canal.properties,讲他的id改成和mysql数据库中的
		server-id不同的值。
		修改 /home/admin/canal-server/conf/example/instance.properties ,配置要监听的数据库
		服务地址和数据变化的数据库以及表
		
		# 监听的数据库
		canal.instance.master.address=192.168.18.204:3306
		# 用户名
		canal.instance.dbUsername=canal
		# 密码
		canal.instance.dbPassword=canal
		# 监听表规则
		canal.instance.filter.regex
			mysql关注表,perl正则表达式
			多个正则使用逗号分割,转义符需要使用双斜杠
			例:
				1,表示所有 .*
				2, canal schema下所有表: canal\\..*
				3, canal下以canal打头的表: canal\\.canal*
				4, canal sechema下的一张表:canal.test1
				5,多个组合使用: canal\\..*,canal\\.canal.*,canal.test1
			注意:此过滤条件只针对row模式的数据有效(ps. mixed/statement因为解析不到sql,所以无法
			准确提取到tableName进行过滤)

	3) canal springboot yaml配置
		canal:
			server: canal 服务地址
			destination: example
		java 代码
		
		@CanalTable(value="") // 监听哪张表变更
		public class async implements EntryHandlerM<监听表对应的java实体>{
			//指定表插入触发
			insert()
			//指定表修改触发
			update()
			//指定表删除触发
			delete()
		}











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值