项目介绍
该项目是学校项目课设,主要应用在促销,抽奖秒杀领域的一个基础模块,2H4G服务器基础配置为kafka,redis,mysql,后端,压测最高100TPS,QPS大约800左右。
分布式事务如何解决
1.其实是这样的,使用对于跨库的事务处理,一种是分布式事务,另外一种就是基于MO+任务调度补偿的方式,完成最终一致性。
2.那么鉴于抽奖系统的实时性要求,从用户流程体验上,希望更加流畅,支撑更大的并发量,而不是对整个流程添加过多的事务,降低性能。因为事务来说,是一种集中化的竟态,所以这部分设计上采用最终一致性的方式进行处理,而不是直接添加大块的事务。同时对于单kev的秒杀,还采用了滑块分段锁的方式进行处理,所以整人流程来看,都是希望是去中心化的,提高吞吐量的。
mq如何保证等幂性
对于寡等性处理流程;
- 使用Redis缓存对于重复的MO进行消费记录,,一般记录个12小时,短一点也可以。
- 消费前如果缓存没有记录,可以查询数据库,消费过进行缓存记录。
- 最终重要的,一股对于金、订单、支付等场景,必须使用数据库防重字段做强一致性拦截处理,避免重复消费造成资损和客诉
- 一般来说都是更新和插入,使用数据库主键或者version字段进行去重
系统优化
这个一个商品活动秒杀的实现方案,最开始的设计是基于一个活动号ID进行锁定,秒杀时锁定这个ID,用户购买完后就进行释放,但在大量用户抢购时,出现了秒杀分布式锁后的业务逻辑处理中发生异常,释放锁失败,导致所有的用户都不能再拿到锁,也就造成了有商品但不能下单的问题事故处理:优化独占竟态为分段静态,将活动ID+库存编号作为动态锁标识。当前秒杀的用户如果发生锁失败那么后面的用户可以继续秒杀不受影响。而失败的锁会有worker进行补偿恢复,那么最终会避免超卖以及不能售卖学习总结:核心的技术实现需要经过大量的数据验证以及压测,否则各个场景下很难评估是否会有风险。当然这也不是唯一的实现方案,可以根据不同的场景有不同的实现处理.
表设计
- 先介绍业务;抽奖系统作为营销活动平台中的一个环节,承接着活动玩法、积分消耗、奖品发放等系统的纽带,帮助整个业务完成用户的活跃。
- 后阐述领域;作为一个战略设计的一环,战术实现上要尽可能做到职责隔离,对应系统的具体实现上要拆分出;活动、算法、规则、策略、用户、订单等领域。
- 引入表设计;根据领域驱动中对各个模块的定义,设计数据库表,也就对应了活动表、抽奖策略配置表、准入规则引擎表、用户抽奖单记录表、以及配合这些表数据结构运行的其他表,如:记录用户的参与次数等。
如何评估QPS
首先需要根据业务提供的推广规模、渠道、人数,来评估。- 这里前面按照28法则评估过。 - 假如系统有1000万用户,那么每天来点击页面的占比20%,也就是200万用户访问。 - 假设平均每个用户点击50次,那么总用有1亿的PV - 一天24个小时,平均活跃时间段算在5个小时内【24*20%】,那么5个小时预计有8000万点击,也就是平均每秒4500个请求。 - 4500是一个均值,按照电商类峰值的话,一般是3~4倍均值量,也就是5个小时每秒18000个请求【QPS=1.8万】
为什么要选redis,redis 主从集群下潜在的锁失效问题怎么考虑怎么解决。
Redis作为一种高性能的内存数据库,其提供的分布式锁机制可以满足高并发场景下的锁控制需求。相比于传统的基于数据库的锁机制,Redis分布式锁具有更高的性能和更好的可扩展性。
同时,Redis还提供了多种锁实现方式,如SETNX、SET、NX、PX等,可以根据具体的业务场景选择最适合的方式。
在Redis主从集群下,由于主从节点之间的数据同步存在一定的延迟,可能会导致锁的失效问题。为了解决这个问题,可以采用以下几种方式:
- 使用RedLock算法:RedLock是一种多实例分布式锁算法,可以在Redis集群中实现更安全的锁机制,避免单点故障和网络分区问题。
- 设置适当的超时时间:在设置锁的过期时间时,可以适当增加一些缓冲时间,避免因主从同步延迟导致锁失效。
- 使用Redis Sentinel进行故障转移:通过配置Redis Sentinel进行主从切换,确保锁服务的高可用性。
zookeeper 作为分布式锁优缺点
Zookeeper作为一种高可用的分布式协调服务,其提供的分布式锁机制可以满足高并发场景下的锁控制需求。相比于Redis分布式锁,Zookeeper分布式锁具有以下优缺点:
- 优点:
- 可以避免锁的失效问题:Zookeeper采用基于ZAB协议的分布式一致性算法,可以保证分布式锁的强一致性,避免因主从同步延迟导致锁失效问题。
- 支持更复杂的锁机制:Zookeeper提供了两种锁实现方式:共享锁和排他锁,可以根据具体的业务场景选择最适合的方式。
- 可以与其他Zookeeper服务集成:Zookeeper还提供了诸如分布式队列、命名服务等功能,可以与分布式锁一起使用,构建更完整的分布式应用系统。
- 缺点:
- 性能相对较低:Zookeeper采用基于ZAB协议的分布式一致性算法,需要进行多次网络通信和数据同步,相比于Redis分布式锁,性能相对较低。
- 部署和维护成本较高:Zookeeper需要部署专门的服务器集群,需要进行一定的配置和维护工作,相比于Redis分布式锁,部署和维护成本较高。
还有没有其他方案-回答mysql,问 mysql 做分布式锁的优缺点
MySQL作为一种传统的关系型数据库,其提供的分布式锁机制可以满足一定程度上的锁控制需求。相比于Redis和Zookeeper分布式锁,MySQL分布式锁具有以下优缺点:
- 优点:
- 易于部署和维护:MySQL已经广泛应用于各种应用场景中,部署和维护相对较为简单。
- 支持更复杂的锁机制:MySQL提供了多种锁实现方式,如行锁、表锁、读锁、写锁等,可以根据具体的业务场景选择最适合的方式。
- 缺点:
- 性能较低:MySQL采用基于磁盘的存储方式,相比于Redis和Zookeeper,性能较低。
- 可扩展性较差:由于MySQL采用基于磁盘的存储方式,其可扩展性较差,难以应对高并发场景下的锁控制需求。
- 存在单点故障问题:MySQL采用主从复制的方式进行数据同步,存在单点故障问题,可能导致锁失效问题。
如果redis宕机导致incr失败怎么办
可以把 Redis 滑块锁的 key 的有效期设置为活动结束时间,这样即使宕机重启,key 也没有被释放。
为什么不能使用自增主键
如果使用自增主键,会导致无法复杂均衡。导致尾部热点问题。
- 导致分片不均匀
- 导致自增锁和插入锁
- 导致合并数据发生冲突
- 导致不同节点数据冲突
UUID为什么不能作为主键
- UUID是随机无序产生的,插入新数据时会导致索引的分裂和磁盘碎片,影响查询性能
- UUID不太容易理解
雪花算法
雪花算法原理就是生成一个的64位比特位的 long 类型的唯一 id。
- 最高1位固定值0,因为生成的 id 是正整数,如果是1就是负数了。
- 接下来41位存储毫秒级时间戳,2^41/(1000*60*60*24*365)=69,大概可以使用69年。
- 再接下10位存储机器码,包括5位 datacenterId 和5位 workerId。最多可以部署2^10=1024台机器。
- 最后12位存储序列号。同一毫秒时间戳时,通过这个递增的序列号来区分。即对于同一台机器而言,同一毫秒时间戳下,可以生成2^12=4096个不重复 id。
雪花算法有以下几个优点:
- 高并发分布式环境下生成不重复 id,每秒可生成百万个不重复 id。
- 基于时间戳,以及同一时间戳下序列号自增,基本保证 id 有序递增。
- 不依赖第三方库或者中间件。
- 算法简单,在内存中进行,效率高。
雪花算法有如下缺点:
- 依赖服务器时间,服务器时钟回拨时可能会生成重复 id。算法中可通过记录最后一个生成 id 时的时间戳来解决,每次生成 id 之前比较当前服务器时钟是否被回拨,避免生成重复 id。
- 时间跨度只有69年,可以优化一下算法生成,生成时间戳减去系统上线的时间。