赞
踩
稳定性强,占用内存小,并发量高(5W),负载均衡,动静分离,反向代理。
- 正向代理是设立在客户端的,客户端向代理发送请求,代理向目标服务器转交请求并将返回结果返回给客户端。(翻墙软件,VPN等等)
- 反向代理是配置在服务端的,作用是让客户端不知道访问的是哪一台服务器,隐藏服务器真正的ip地址。
- 轮询:平均的分配给每一台服务器。
- 权重:根据服务器分配的权重值分配。
- ip_hash:根据客户端请求的ip,分配到不同的服务器上。
Nginx通过动静分离,来提升Nginx的并发能力,给用户更快地响应。
AMQP是一种协议,RabbitMQ 中的交换器、交换器类型、队列、绑定、路由键等都是遵循的 AMQP 协议中相 应的概念。
- 交换器 (Exchange):消息代理服务器中用于把消息路由到队列的组件。
- 队列 (Queue):用来存储消息的数据结构,位于硬盘或内存中。
- 绑定 (Binding):一套规则,告知交换器消息应该将消息投递给哪个队列。
解耦,异步,削峰
- 解耦(降低模块与模块之间的耦合):当A系统的接口被多个系统调用,A系统需要考虑调用接口的系统有没有挂了,需不需要重发等问题,但是如果有了MQ消息队列,A系统只需要把消息发送给MQ,如果有系统要调用直接消费MQ消息即可,如果没有就取消消费,这样A系统就不需要考虑到底要给谁发消息,也不需要考虑发送是否成功,发送超时等问题。
- 异步(提高效率):异步发送消息,从而提高效率。
- 削峰(降低并发请求量):用MQ来降低并发请求到数据库的数据,给数据库一定的时间去处理。
改变MQ的削峰模式,将推模式改为拉模式,定时或者批量拉取可以削平流量,实现自我保护的作用。
但是如果发送流量过大,MQ拉取的速度过慢,就会导致消息的堆积,所以还需要优化消费者,可以采用批量处理的方法提高吞吐量。
- 重复消费场景:消费者正常消费后正准备发送应答ACK,但此时出现了网络闪断,channel断开连接,消息被再次放入队列中,导致重复消费。
- 幂等性(例如删除操作,执行一次和执行多次的操作是一样的,所以不需要考虑重复消费的问题)
- 使用redis,在消息被消费前,将其采用key为id_0的形式保存在redis中,0代表正在消费,1代表已消费。
RabitMQServer、Vhost、Channel、Exchange、Routing、Queue、Provider、Consumer、Binding
- Hello-Word(一个生产者,一个默认的交换机,一个队列,一个消费者)
- Work(一个生产者,一个默认的交换机,一个队列,两个消费者)
- 交换机采用轮询发送消息,给第一个发一条,另一个发下一条
- publish(一个生产者,一个交换机,两个队列,两个消费者)
- Routing(一个生产者,一个交换机,两个队列,两个消费者)
- Topic(一个生产者,一个交换机,两个队列,两个消费者)
根据交换机的路由键进行分发到MQ中。
开启Confirm确认机制,当消息由提供者送到交换机时,调用回调函数确认已送达到交换机。
开启Return返回机制,确认消息被送达到对应的队列中。
手动ACK
在生产者发送消息的时候,使用confirm确认机制确保消息到达exchange,采用return返回机制来确保消息抵达queue,最后使用redis避免重复消费消息。
死信队列的作用就是避免消息的丢失。一般来说,consumer从队列中取出消息进行消费,但由于某些原因导致队列中的某些消息无法被消费,这种消息如果没有后续的处理,如果配置了死信队列就会丢进死信队列中,如果没有配置死信队列则被丢弃。
- 消息被拒绝,也就是Reject/Nack,并且requeue=false;
- ttl时间过期;
- 队列中满了,无法继续添加数据到MQ中。
@Bean
public Queue businessQueue(){
Map<String, Object> args = new HashMap<>();
//这里声明当前队列绑定的死信交换机
args.put("x-dead-letter-exchange", "deadLetterExchange");
//这里声明当前队列的死信路由key
args.put("x-dead-letter-routing-key", "dle.err");
return new Queue("businessQueue",true,false,false,args);
}
延时队列存储的就是延时消息,延时消息就是当消息发送后,不让消费者第一时间立即消费,而是等待一段时间后,消费者才拿到消息消费。
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-message-ttl", 6000);// 但是毫秒
channel.queueDeclare(queueName, durable, exclusive, autoDelete, args);
自动ACK:MQ只需要确认消息发送成功,不需要等待应答直接丢弃消息。(如果出现断电或者网络异常就会出现消息丢失的问题)
手动ACK:如果消费者端出现了异常,那么大量消息就会堆积在Unacked消息中,导致消息阻塞。
NACK:通知MQ把消息放回队列头部。(如果消费者有问题,就算放回头部,消费者再次消费,还是出错又被放回队列,陷入死循环中)
basicReject/basicNack
MQ的消费模式分为两种,一种是MQ把消息推给消费者,另外一种是消费者从MQ队列中拉去消息。
推模式采用BasicConsume,拉模式采用BasicGet
出现的原因:网络异常,消费者出现异常,没有ACK。
采用多线程发送到更多的MQ中,提高吞吐量
- 在发送消息的时候就要确定消息的有序性。
- 在消费者消费消息的时候判断一下他的上一个是否被消费了。
- 如果上一个消费了,可以被消费,消费完后需要将消费记录放到Redis中存储,如果上一个消息还未被消费,直接返回Nack。
设置MQ队列的最大长度。
Elasticsearch是一个基于Lucene的搜索引擎框架。
比如说“苹果”,将其分成“苹”和“果”和“苹果”进行匹配,出现次数最多的匹配度最高。
在搜索引擎中,每一个文档都有一个对应的文档Id,文档内容表现为一系列关键词的集合。那么,倒排索引就是关键词对文档Id的映射,每个关键词都对应着一系列的文件。其中记录了关键词Id,在文档中出现的次数以及在文档中的位置。
- Mysql的库对应ES的索引。
- Mysql的表对应ES的类型。
- Mysql的一条数据对应ES的Document。
- Mysql的属性字段对应ES的Field。
- 关系型数据库以表格形式存储,数据表可以彼此关联协作存储。
- 非关系型数据库不适合存储在数据表的行和列中,而是大块组合在一起,一般强调的是数据最终一致性。
- Redis是一个高性能的key-value非关系型数据库。
- 支持数据持久化,可以将内存中的数据保存在磁盘中,重启的时候可以重新加载使用。
- 除了支持key-value类型的数据外,还支持set,list,zset,hash等数据结构的存储。
- 支持数据的备份,即master-slave模式的数据备份。
优势:
- 性能高,Redis读写的速度非常快。
- 丰富的数据类型,支持String,List,Hash,Set等数据类型。
- 事务。
- 持久化。
- 支持主从模式备份,读写分离。
缺点:
一旦Redis宕机后,没有任何容错机制。
高性能,高并发,减少和数据库的交互。
- 服务注册和发现
- 缓存服务器。
- 自增自减
RDB(Redis DataBase):
用快照的方式,保存内存结构(二进制文件)
- 优点:加载速度快。
- 缺点:数据安全性低。
AOF(Append-only-file):
把写的命令全部保存到文件。
- 优点:数据安全。
- 缺点:AOF文件大,且数据恢复速度慢。
- 惰性删除:每次获取键的时候,检查键是否过期,如果键过期就删除键,没过期就返回键。
- 定期删除:每隔一段时间就对redis数据库进行检查,删除里面的过期键,但删除多少过期键和检查多少个数据库由算法决定。
- 定时删除:太消耗资源不推荐。
- 1.当第一次从MySql获取数据的时候,将其存在redis中并设置过期时间,以后每次查询redis中的数据时判断是否还在redis中,如果存在就给他延长过期时间,以此来保证redis中的数据都是热点数据。
- 2.使用淘汰策略。
- LRU(Least Recently Used):最近最少使用。
- LFU(Least Frequently Used):最近最少频繁使用。
- TTL(Time To Live):生存时间最少。
- RANDOM:随机淘汰。
- 抽取样本进行淘汰。
1.全量复制:
用于节点初始化的情况下,将主节点的所有数据发送给从节点,当数据量特别大的时候,会对主节点和网络造成很大的一个开销。
2.增量复制
要么会发生报错,要么会调用淘汰策略清除一些key来保证redis的正常运行。
- 1.给每个key都设置生存时间。
- 2.争对业务场景给出对应的淘汰策略。
- 3.正确使用Redis数据结构。
- multi:开启事务。
- exec:执行事务块内的所有命令。
- discard:取消事务。
- watch:监听key在事务执行之前是否改变,若已修改则事务内的事务取消执行。
- unwatch:取消对key的监听。
- 1.multi:开启事务。
- 2.添加命令到事务块中。
- 3.exec/discard:执行事务块中的命令/取消执行事务块中的命令。
setnx
集群解决单点故障(有状态和无状态)
管调哪台服务器返回的结果是一样的(无)
需要服务器共享数据的(redis,eureka,zookeeper)
- 主从架构:一主多从,作用只是数据备份方案。
- 读写分离:主只提供写的操作,从只提供读的操作。2.提高Redis读的速度
- 哨兵机制:对Redis节点的监视和选举,哨兵数量至少为3个,只要有一半哨兵投票通过,那么选举出来的就为主节点。
- redis集群没有主从一说,去中心化,使用hash槽让key每次访问的都是同一个redis服务器。
先删除缓存,然后更新数据库,如果这时候有请求发送过来,他会访问到空的缓存,然后去数据库中拿数据,如果此时数据库未更新成功,那么此时缓存中的数据还是旧数据,导致数据库和缓存中数据不一致,那么就需要延迟一段时间后再删除一次缓存。(双删延迟)
首先,Redis集群中总共有16384个hahs槽,执行写命令的时候会将key按照一种算法得到一个结果,然后将这个结果对hash槽个数进行取余,然后将key放到这个位置的hash槽中。(Nigix负载均衡中ip_hash用到了hash槽,类似hashmap底层)
16384
1.出现的原因:
redis中没有,mysql中也没有(比如查询的id为1)
2.如何解决:
设置一个默认值(如果在数据库中也没有查询到数据,就在缓存中存放一个默认值)
对id进行过滤,过滤掉一些不合法的id(比如负数)
1.出现的原因:
- 数据库中有,但redis中没有(热点数据突然过期)
- 并发查询数据库
2.如何解决:
- 分布式锁
- 设值热点数据不过期
1.出现的原因:
大量数据在同一时间过期
2.如何解决:
设置数据的过期时间随机分布在30-60秒内,不让数据同时过期。
1.出现的原因:
高并发请求访问一个redis服务
2.如何解决:
搭建redis集群和主从架构
1.出现的原因:
发生在项目上线之前,热数据需要提前存放在redis中
2.如何解决:
数据量不大可以人工手动导入
定时热刷新
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。