Java知识体系
#MQ
1. 为什么要使用MQ
一般MQ的使用场景有:解耦,异步,削峰
解耦
使用MQ前:
使用MQ后:
MQ在这个系统中的作用就是解除了A系统与BCD系统的耦合关系。
异步
异步前:
异步后:
原本需要30s的处理通过加入MQ变为异步处理后只需要一个请求的时间就解决问题,大大提升效率
削峰
使用前
由图可见,当大量用户同时来请求系统时,所有的压力都集中在数据库,但是数据库的性能是有限的,这样就可能导致数据库挂掉,即使勉强不挂掉,也会严重影响系统响应速度。
使用mq后
2. MQ保证高可用
rabbitmq
采用镜像集群模式,创建的queue,无论元数据还是queue里的消息都会存在于多个实例上,然后每次你写消息到queue的时候,都会自动把消息到多个实例的queue里进行消息同步。
优点是解决了高可用问题,缺点也很明显,消息同步所有机器,性能开销和网络开销大。
kafka
kafka基础架构是:多个broker组成,每个broker是一个节点;你创建一个topic,这个topic可以划分为多个partition,每个partition可以存在于不同的broker上,每个partition就放一部分数据。
kafka 0.8以后,提供了HA机制,就是replica副本机制。每个partition的数据都会同步到吉他机器上,形成自己的多个replica副本。然后所有replica会选举一个leader出来,那么生产和消费都跟这个leader打交道,然后其他replica就是follower。写的时候,leader会负责把数据同步到所有follower上去,读的时候就直接读leader上数据即可。只能读写leader?很简单,要是你可以随意读写每个follower,那么就要care数据一致性的问题,系统复杂度太高,很容易出问题。kafka会均匀的将一个partition的所有replica分布在不同的机器上,这样才可以提高容错性。
3. MQ保证消息不被重复消费
MQ是不能自己做到不被重复消费的,需要自己实现。
解决思路如下:
1.消除MQ重复消费的影响其实就是想保证消费的幂等,如果是插入或者update可以使用主键先查在操作。
2.如果是操作Redis就更便捷了,Set天然幂等。
3. 如不是上述场景需要因地制宜的处理,加入全局唯一id等方式处理即可。
4. MQ数据丢失问题
- 生产者:可开启rabbitmq事务功能,只要消息发送失败就事务回滚。
- rabbitmq :开启rabbitmq的数据持久化,就是把消息写入磁盘,如发生rabbitmq挂掉情况时保证消息不会丢(小概率会遇到消息数据还未持久化就挂掉的情况)。
- 消费者: 可使用rabbitmq提供的ack机制,默认关闭rabbitmq自动ack,只需要消费完手动调用ack即告诉rabbitmq你已完成消费。
5. MQ顺序执行问题
原理简单,只需要不同的执行操作对应不同的queue即可,多建几个queue,一个queue但是对应一个consumer。
6. MQ消息积压
- 快速处理积压消息, 1)先修复consumer的问题,确保其恢复消费速度,然后将现有cnosumer都停掉
2)新建一个topic,partition是原来的10倍,临时建立好原先10倍或者20倍的queue数量
3)然后写一个临时的分发数据的consumer程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的10倍数量的queue
4)接着临时征用10倍的机器来部署consumer,每一批consumer消费一个临时queue的数据
5)这种做法相当于是临时将queue资源和consumer资源扩大10倍,以正常的10倍速度来消费数据
6)等快速消费完积压数据之后,得恢复原先部署架构,重新用原先的consumer机器来消费消息 - 消息失效
没其他办法,只能等晚上用户使用较少时把丢失的数据找回来。
7. es如何实现分布式
核心思想就是在多台机器上启动多个es进程实例,组成了一个es集群。
es的基本单位是索引,类比于MySQL中的表,每个索引拆分成多个shard,每个shard存储部分数据。
每个shard都有多个备份,可以保证机器宕机时保证高可用。
es集群多个节点会自动选举master节点,如主节点宕机,剩下节点再次选举主节点。
8.es优化性能
- os cache 操作系统缓存,
- 缓存预热
热点数据定时访问一下,把数据放到filessystem cache里面 - 冷热分离
冷门数据与热点数据放到不同的索引,确保热点数据进行缓存预热时不被冷数据刷掉。 - es不使用复杂查询,应构建好数据模型后放置es中
9.es生产集群部署
(1)es生产集群我们部署了5台机器,每台机器是6核64G的,集群总内存是320G
(2)我们es集群的日增量数据大概是2000万条,每天日增量数据大概是500MB,每月增量数据大概是6亿,15G。目前系统已经运行了几个月,现在es集群里数据总量大概是100G左右。
(3)目前线上有5个索引(这个结合你们自己业务来,看看自己有哪些数据可以放es的),每个索引的数据量大概是20G,所以这个数据量之内,我们每个索引分配的是8个shard,比默认的5个shard多了3个shard。
10. 缓存如何实现高性能、高并发
高性能
原理就是第一次查询数据后,把数据放置在缓存里,当下一次查询过来时,就直接从缓存中查找并返回即可
高并发
实现原理是因为数据库不支持高并发,缓存是可以支持的。
11.Redis单线程为什么支持高并发
Redis线程模型:
客户端发起请求,Redis进程中建立一个与客户端请求对应的sercer_socket,通过server_socket调用IO多路复用程序将请求放到队列中排队。
高并发原因:非阻塞线程,IO复用,纯内存结构