redis、rocketmq 高级面试考点

redis

redis如何保证原子性?

1 incr是原子操作的, 直接用redis的incr实现read和write的打包原子操作,就不会出现读了一半,然后被别人篡改了。 像批量设置多个值的场景可以用mset,批量获取多个值的mget,与incr相对应的decr,这些都是原子的。
2 即使redis支持很多原子命令,但是还是无法满足所有场景,于是redis在2.6之后开始支持开发者编写lua脚本传到redis中,使用lua脚本的好处就是:

减少网络开销,通过lua脚本可以一次性的将多个请求合并成一个请求。
原子操作,redis将lua脚本作为一个整体,执行过程中,不会被其他命令打断,不会出现竞态问题。
复用,客户端发送的lua脚本会永远存在redis服务中。

redis部署的方式有哪些?

单机模式
主从模式
哨兵模式
集群模式

redis以上的部署方式有哪些优势、弊端?

单机模式:

  • 优点
    部署简单
  • 缺点
    可支持的并发量少

主从模式:

  • 优点:
    1 能够为后续的高可用机制打下基础
    2 在持久化的基础上能够将数据同步到其他机器,在极端情况下做到灾备的效果
    3 能够通过主写从读的形式实现读写分离提升Redis整体吞吐,并且读的性能可以通过对从节点进行线性扩容无限提升
  • 缺点:
    1 全量数据同步时如果数据量比较大,在之前会导致线上短暂性的卡顿。
    2 一旦主节点宕机,需要人工干预从节点晋升为主节点,同时需要修改应用方的主节点地址,还需要命令所有从节点去复制新的主节点,整个过程需要人工干预。
    3 写入的QPS性能受到主节点限制,虽然主从复制能够通过读写分离来提升整体性能,但是只有从节点能够做到线性扩容升吞吐,写入的性能还是受到主节点限制木桶效应,整个Redis节点群能够存储的数据容量受到所有节点中内存最小的那台限制,比如一主两从架构:master=32GB、slave1=32GB、slave2=16GB,那么整个Redis节点群能够存储的最大容量为16GB 。

哨兵模式:数据的分布都是去中心化,可支持的读并发有限

  • 优点:
    1 解决了之前主从切换需要人工干预问题,保证了一定意义上的高可用
  • 缺点:
    1 全量数据同步仍然会导致线上出现短暂卡顿
    2 写入QPS仍然受到主节点单机限制,对于写入并发较高的项目无法满足需求
    3 仍然存在主从复制时的木桶效应问题,存储容量受到节点群中最小内存机器限制

集群模式:

redis分布式锁的底层原理

setnx,如果

redis使用过程中遇到的一些问题

缓存雪崩:短时间redis的key失效,所有的请求直接到数据库。
解决办法:设置key随机消失的时间。

缓存击穿:热key失效
解决办法:1 设置永不过期;

缓存穿透:使用不存在的key查询
解决办法:1、设置ip白名单,防止黑客攻击;2、对空值进行缓存

rocketMQ

如何保证消息的可靠性(不丢失)

保证消息的不丢失,主要从三个方面:生产端、broker端、消费端处理。

  • 生产端
    在生产阶段,主要通过请求确认机制,来保证消息的可靠传递。
    1、同步发送的时候,要注意处理响应结果和异常。如果返回响应OK,表示消息成功发送到了Broker,如果响应失败,或者发生其它异常,都应该重试。
    2、异步发送的时候,应该在回调方法里检查,如果发送失败或者异常,都应该进行重试。
    3、如果发生超时的情况,也可以通过查询日志的API,来检查是否在Broker存储成功。
  • broker端
    存储阶段,可以通过配置可靠性优先的 Broker 参数来避免因为宕机丢消息,简单说就是可靠性优先的场景都应该使用同步。
    1、消息只要持久化到CommitLog(日志文件)中,即使Broker宕机,未消费的消息也能重新恢复再消费。
    2、Broker的刷盘机制:同步刷盘和异步刷盘,不管哪种刷盘都可以保证消息一定存储在pagecache中(内存中),但是同步刷盘更可靠,它是Producer发送消息后等数据持久化到磁盘之后再返回响应给Producer。
    3、Broker通过主从模式来保证高可用,Broker支持Master和Slave同步复制、Master和Slave异步复制模式,生产者的消息都是发送给Master,但是消费既可以从Master消费,也可以从Slave消费。同步复制模式可以保证即使Master宕机,消息肯定在Slave中有备份,保证了消息不会丢失。
  • 消费端
    Consumer保证消息成功消费的关键在于确认的时机,不要在收到消息后就立即发送消费确认,而是应该在执行完所有消费业务逻辑之后,再发送消费确认。因为消息队列维护了消费的位置,逻辑执行失败了,没有确认,再去队列拉取消息,就还是之前的一条。

消息积压如何处理

发生了消息积压,这时候就得想办法赶紧把积压的消息消费完,就得考虑提高消费能力,一般有两种办法:

  • 消费者扩容:如果当前Topic的Message Queue的数量大于消费者数量,就可以对消费者进行扩容,增加消费者,来提高消费能力,尽快把积压的消息消费玩。

  • 消息迁移Queue扩容:如果当前Topic的Message Queue的数量小于或者等于消费者数量,这种情况,再扩容消费者就没什么用,就得考虑扩容Message Queue。可以新建一个临时的Topic,临时的Topic多设置一些Message Queue,然后先用一些消费者把消费的数据丢到临时的Topic,因为不用业务处理,只是转发一下消息,还是很快的。接下来用扩容的消费者去消费新的Topic里的数据,消费完了之后,恢复原状。

如何保证不重复消费

对分布式消息队列来说,同时做到确保一定投递和不重复投递是很难的,就是所谓的“有且仅有一次” 。 RocketMQ择了确保一定投递,保证消息不丢失,但有可能造成消息重复。
处理消息重复问题,主要有业务端自己保证,主要的方式有两种:业务幂等和消息去重。

  • 业务幂等:第一种是保证消费逻辑的幂等性,也就是多次调用和一次调用的效果是一样的。这样一来,不管消息消费多少次,对业务都没有影响。

  • 消息去重:第二种是业务端,对重复的消息就不再消费了。这种方法,需要保证每条消息都有一个惟一的编号,通常是业务相关的,比如订单号,消费的记录需要落库,而且需要保证和消息确认这一步的原子性。
    具体做法是可以建立一个消费记录表,拿到这个消息做数据库的insert操作。给这个消息做一个唯一主键(primary key)或者唯一约束,那么就算出现重复消费的情况,就会导致主键冲突,那么就不再处理这条消息。

如何实现顺序消息

顺序消息是指消息的消费顺序和产生顺序相同,在有些业务逻辑下,必须保证顺序,比如订单的生成、付款、发货,这个消息必须按顺序处理才行。

顺序消息分为全局顺序消息和部分顺序消息,全局顺序消息指某个 Topic 下的所有消息都要保证顺序;

部分顺序消息只要保证每一组消息被顺序消费即可,比如订单消息,只要保证同一个订单 ID 个消息能按顺序消费即可。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值