Java知识体系

#MQ

1. 为什么要使用MQ

一般MQ的使用场景有:解耦,异步,削峰

解耦

使用MQ前:Java知识体系
使用MQ后:
Java知识体系
MQ在这个系统中的作用就是解除了A系统与BCD系统的耦合关系。

异步

异步前:

Java知识体系

异步后:
Java知识体系
原本需要30s的处理通过加入MQ变为异步处理后只需要一个请求的时间就解决问题,大大提升效率

削峰

使用前
Java知识体系
由图可见,当大量用户同时来请求系统时,所有的压力都集中在数据库,但是数据库的性能是有限的,这样就可能导致数据库挂掉,即使勉强不挂掉,也会严重影响系统响应速度。

使用mq后
Java知识体系

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数据丢失问题

  1. 生产者:可开启rabbitmq事务功能,只要消息发送失败就事务回滚。
  2. rabbitmq :开启rabbitmq的数据持久化,就是把消息写入磁盘,如发生rabbitmq挂掉情况时保证消息不会丢(小概率会遇到消息数据还未持久化就挂掉的情况)。
  3. 消费者: 可使用rabbitmq提供的ack机制,默认关闭rabbitmq自动ack,只需要消费完手动调用ack即告诉rabbitmq你已完成消费。

5. MQ顺序执行问题

原理简单,只需要不同的执行操作对应不同的queue即可,多建几个queue,一个queue但是对应一个consumer。

6. MQ消息积压

  1. 快速处理积压消息, 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机器来消费消息
  2. 消息失效
    没其他办法,只能等晚上用户使用较少时把丢失的数据找回来。

7. es如何实现分布式

核心思想就是在多台机器上启动多个es进程实例,组成了一个es集群。
es的基本单位是索引,类比于MySQL中的表,每个索引拆分成多个shard,每个shard存储部分数据。
每个shard都有多个备份,可以保证机器宕机时保证高可用。
es集群多个节点会自动选举master节点,如主节点宕机,剩下节点再次选举主节点。

8.es优化性能

  1. os cache 操作系统缓存,
    Java知识体系
  2. 缓存预热
    热点数据定时访问一下,把数据放到filessystem cache里面
  3. 冷热分离
    冷门数据与热点数据放到不同的索引,确保热点数据进行缓存预热时不被冷数据刷掉。
  4. 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. 缓存如何实现高性能、高并发

Java知识体系

高性能

原理就是第一次查询数据后,把数据放置在缓存里,当下一次查询过来时,就直接从缓存中查找并返回即可

Java知识体系

高并发

实现原理是因为数据库不支持高并发,缓存是可以支持的。

11.Redis单线程为什么支持高并发

Redis线程模型:
Java知识体系
客户端发起请求,Redis进程中建立一个与客户端请求对应的sercer_socket,通过server_socket调用IO多路复用程序将请求放到队列中排队。
高并发原因:非阻塞线程,IO复用,纯内存结构

12. Redis数据类型