Java面试技术栈(四):消息中间件 Redis & MQ

  • Redis的支持的数据类型

String:最大512MB    Hash:哈希    List:列表     Set:集合  zset:有序集合    

Redis持久化方式,

RDB(Redis Database)定时持久化备份RDB文件,数据量大的情况下启动比较快,性能比AOF高。备份还原方便,缺点就是会丢数据,因为是定时备份的(性能要求高时可选用)

AOF(Append-only file)有三种配置,实时always+每秒everysec+不同步no   虽然效率低,但是保证了数据的完整性(数据完整性要求高时可选用,牺牲性能保证数据完整性)

Redis的高可用方案:  Master + Slave + Sentinel 1 + Sentinel 2 

缓存雪崩:当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。

如何避免:

  1. 做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期
  2. 不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。
  3. 在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。

缓存穿透:用户攻击者想要查询一个数据,发现redis内存数据库没有,也就是缓存没有命中,于是向持久层数据库查询。发现也没有,于是本次查询失败。当用户很多的时候,缓存都没有命中,于是都去请求了持久层数据库。这会给持久层数据库造成很大的压力,这时候就相当于出现了缓存穿透。

解决方案:

1.可以使用redis的set做一个key集合,将不存在的key请求拦截

2.缓存空对象。 就是即使数据库中也没有的数据,用null值存起来,然后设置一个有效期或定期清理

3.布隆过滤器

 

  • MQ消息队列

优点:在这个场景中,A 系统跟其它各种乱七八糟的系统严重耦合,A 系统产生一条比较关键的数据,很多系统都需要 A 系统将这个数据发送过来。A 系统要时时刻刻考虑 BCDE 四个系统如果挂了该咋办?要不要重发,要不要把消息存起来?

概括讲就是:解耦、异步、削峰

缺点:系统可用性会降低 & 系统复杂性增加

 

  • MQ组成(结构):
  1. Broker:消息服务器,作为server提供核心服务
  2. Producer:消息生成者,业务的发起方,负责生产消息传输给Broker
  3. Concumer消息消费者,业务的处理方,负责从Broker获取消息,并进行业务处理
  4. Topic:发布-订阅模式下的消息汇集地,实现消息广播(发送给不同的订阅者)
  5. Queue:队列,PTP模式下,特定生产者向特定queue发送消息,消费者订阅特定的queue完成消息的接收
  6. Message:消息体
  • 模式:

  1. 点对点,使用queue

  2. 发布-订阅 使用topic

 

如何解决重复读问题?

kafka有个offset的概念,添加全局唯一的id。messageId。消费的时候判断messageId是否消费过,没有则进行消费,结束后保存messageId至已消费队列。如果有,则放弃消费消息

保证消息队列消费的幂等性

比如数据写库,可以先根据主键查一下,如果这数据都有了,就update

比如写redis,那没问题,因为每次都是set,天然幂等性

如果不是上面两个场景,那做的稍微复杂一点,需要让生产者发送每条数据的时候,里面加一个全局唯一的id,类似订单id之类的东西,然后消费到了后,先根据这个id去比如redis里查一下,之前消费过吗?如果没有消费过,就处理,然后这个id写redis。如果消费过了,那就别处理了,保证别重复处理相同的消息即可。

还有比如基于数据库的唯一键来保证重复数据不会重复插入多条,重复数据拿到了以后我们插入的时候,因为有唯一键约束了,所以重复数据只会插入报错,不会导致数据库中出现脏数据

 

如何保证消息不丢失?

rabbitmq提供事务功能:可以保证消息传输可靠性(原子性)发现消息丢失,则会回滚

开启confirm模式 在生产者那里设置开启confirm模式后,每次写消息都会分配一个唯一的id,然后如果写入了rabbitmq中,rabbitmq会回传一个ack消息,告诉你说这个消息ok了。如果rabbitmq没能处理这个消息,会回调你一个nack接口,告诉你这个消息接收失败,你可以重试。而且你可以结合这个机制自己在内存里维护每个消息id的状态,如果超过一定时间还没接收到这个消息的回调,那么你可以重发

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值