【高并发】——设计系统(1)

背景

其实如何设计一个高并发系统是一个非常复杂的过程,但是我们可以将他们简单的拆分成几个单独的技术模块:

  • 系统拆分:一般用dubbo或者其他的
  • 缓存:很好的支持高并发,一般是redis
  • MQ:消息队列,能够异步处理,很好的支持高并发
  • 分库分表:提高数据库的高并发、sql执行效率
  • 读写分离:一般读多写少的会比较好
  • ElasticSearch:分布式搜索引擎,一些全文搜索可以考虑

一、MQ的高可用性

RabbitMQ的三种模式

  • 单机模式:无高可用性
  • 普通集群模式:无高可用性,单个数据没有备份,一旦机器宕机,就无法使用,这个方案主要是提高吞吐量的
  • 镜像集群模式:高可用性,单个数据会有多个副本,但是对资源的依赖是很大的

Kafka的高可用性

其实RabbitMQ并不是一个分布式消息队列,一个 queue 的数据都是放在一个节点里的,镜像集群下,也是每个节点都放这个 queue 的完整数据,但是Kafka就是天然的分布式消息队列,每一个topic的数据,就是分散在多台机器上的,每个机器放一部分数据,在Kafka 0.8之后支持高可用性,支持replica副本机制,选举leader,然后只是从leader中去读写(保证数据一致性),如果这台宕机了,才会重新选举leader。

二、Redis的高并发和高可用

  • redis的主从架构:一主多从,单主用来写入数据,单机几万QPS,多从用来查询数据,多个实例可以提供10W几倍的QPS
  • redis基于哨兵模式实现高可用性,任何一个实例宕机,就进行主备切换

三、MQ的重复消费

Kafka是有一个offset的概念,就是每当你消费一个MQ的时候都会将这个已经消费的offset提交一下,这样你在下次消费的时候就从当前这个offset的后面的开始消费,但是有可能你消费完一条MQ,但是还没有来得及提交offset的时候系统关闭了,这样下次消费的时候就会有重复的MQ消息过来,所以我们需要从业务的层面来保证数据的幂等性,防止重复消费MQ消息。

  • 根据主键查询,有就Update,没有就insert
  • 写redis,天然幂等
  • 每条数据全局ID,先根据ID查询redis里面有没有,没有就消费,并更新redis,有就丢弃
  • 基于数据库的唯一主键来保证幂等性

四、MQ的顺序性

如果本来是增加、删除,结果你消费的顺序是删除、增加,这样数据就会出现问题

  • RabbitMQ:如上执行的时候顺序不对,办法是每个queue对应一个consumer
  • kafka:多线程消费的时候出现顺序不一致,如果换成单线程效率不高,每个线程消费同一个key数据的queue。

 五、MQ消息丢失

MQ消息丢失是很常见的现象,可能是生产者丢失了数据,也有可能是消费者在消费的过程中丢失了数据

RabbitMQ:

  • 生产者:添加事务,只有等待RabbitMQ返回成功才提交事务,但是效率低下,开启confirm模式,每次写的消息分配一个唯一的id,如果写入到RabbitMQ中就会回传一个ack消息,失败就回传nack消息,可以重试。如果是
  • RabbitMQ:RabbitMQ自己弄丢消息,可以持久化,可以与confirm机制配合使用。
  • 消费者:消费端主要是程序去保证吧

Kafka:

  • 生产者:一般不会丢失数据的
  • Kafka:Kafka的某个broker宕机,重新选举partition的leader,如果此时刚好follower有一些数据没有同步,如果这个follower成leader之后就会有一些数据的丢失。1.给 topic 设置 replication.factor 参数:这个值必须大于 1,要求每个 partition 必须有至少 2 个副本。2.在 Kafka 服务端设置 min.insync.replicas 参数:这个值必须大于 1,这个是要求一个 leader 至少感知到有至少一个 follower 还跟自己保持联系,没掉队。3.在 producer 端设置 acks=all:这个是要求每条数据,必须是写入所有 replica 之后,才能认为是写成功了。4.在 producer 端设置 retries=MAX(很大很大很大的一个值,无限次重试的意思):这个是要求一旦写入失败,就无限重试,卡在这里了。
  • 消费者:消费者主动提交了offset,但是当数据还没有处理完的时候机器宕机了,导致数据没有消费成功,但是Kafka认为他已经消费了,所以手动提交offset就行,

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
秒杀系统是一种高并发场景下的典型应用,其设计需要考虑到多方面的因素,包括系统架构、数据库设计、缓存策略、负载均衡等方面。下面是一个简单的秒杀系统设计方案: 1. 系统架构 秒杀系统可以采用分布式架构,将整个系统分成多个模块,包括前端负载均衡、应用服务器、数据库等。前端负载均衡可以使用Nginx或者F5等软硬件负载均衡设备,将请求分发到多个应用服务器上。应用服务器可以采用Tomcat、Jetty等Web容器,处理用户的请求,生成订单,进行库存扣减等操作。数据库可以采用MySQL、Oracle等关系型数据库,也可以采用Redis、MongoDB等NoSQL数据库。 2. 数据库设计 在秒杀系统中,订单和库存是两个非常重要的数据模块。订单表包括订单ID、用户ID、商品ID、购买数量、订单状态等字段。库存表包括商品ID、库存数量、已售数量、锁定数量等字段。在进行秒杀的时候,需要先对库存进行检查,如果库存不足,则无法生成订单。 3. 缓存策略 为了提高系统的并发能力,可以采用缓存策略来减轻数据库的负载。可以将商品的信息和库存数量等放入缓存中,当用户请求到达时,先从缓存中查询数据,如果缓存中没有,则从数据库中查询,并将查询结果放入缓存中。同时,库存扣减操作也需要对缓存进行更新。可以使用Redis等内存数据库作为缓存。 4. 负载均衡 为了平衡系统的负载,可以采用多台服务器进行分布式处理。可以使用Nginx等负载均衡设备将请求分发到多台服务器上,每台服务器处理一部分请求。同时,可以使用分布式锁等机制来保证订单生成的唯一性。 以上是一个简单的秒杀系统设计方案,实际上,秒杀系统设计需要考虑到多种因素,包括安全性、可靠性、性能等方面,需要根据实际情况进行具体的设计和实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值