高并发场景下,如何设计订单库存架构,一共9个关键性问题

库存系统可以分为实物库存和虚拟库存两种类型。实物库存的管理涉及到采购、存储、销售和库存轮换等复杂的活动,需要进行供应链管理和仓库管理等工作。相比之下,虚拟库存的管理相对简单,主要适用于线上资源的数量管理,包括各类虚拟商品权益,例如线上课程、付费优惠券包和活动库存等。五阳哥长期从事虚拟电商领域,在今天的分享中将主要介绍虚拟库存的管理。

假设产品需求中要求设置商品库存,限制售卖数量。我们应该如何设计技术方案?有哪些设计重点?

一共9个关键问题,全文目录如下

964451317e4ad3fa0f05626e931a6c91.jpeg

2f5e3f3880c29b5efd3f8bdf815134a6.jpeg

1. 记录库存余额还是记录售卖数量?

方案1:记录库存余额的方案是,每次购买时库存余额都减去购买数量。一旦库存余额小于等于 0,则无法再减少库存数量,商品则不可再售卖,直至库存得到补充。示例SQL如下

update inventory set cnt = cnt - #{buyCnt} WHERE productId = #{productId} AND cnt - #{buyCnt} >= 0

方案2:记录售卖数量的方案是,每次购买时,已售卖数量 + 当前购买数量。加和以后,一旦已购买数量大于库存总数时,则库存不足,商品则不可再对外售卖,直至库存得到补充。

update inventory set cnt = cnt + #{buyCnt} WHERE productId = #{productId} AND cnt + #{buyCnt} <= totalCnt

这两个方案都可以实现库存功能。但是在库存不足后,需要补充库存的场景,两个方案存在差异,存在优劣。

例如当前总库存为100,已售卖了51个,剩余库存为49个。按照方案1(库存余额)的要求,当库存从100增加到200时,除了库存总数需要增加,剩余库存数量也需要增加100个,变为149个。

然而,减少库存总数这一场景,方案1的实现方案更加复杂。当库存从100减少到50时,由于库存余额为49个,库存余额减掉50后,则为-1。因为库存余额为负数属于异常场景,所以需要将剩余库存设置为0。然而,这会引起数据的一致性问题。

因为库存余额不准确,所以 已售卖数量 = 库存总数 - 库存余额,这个等式也不再正确 ,如果商品需要展示 已售数量,使用这个公式就无法保证已售数量的准确性。

在方案1中,每次调整库存总数都需要调整库存余额,增加了操作复杂度。因为C端交易流程需要操作库存余额,B端调整库存总数也会涉及调整库存余额,BC端的库存操作需要互斥,否则会出现数据不一致的问题。

相比之下,方案2(记录售卖数量)则没有方案1的困境。增加或减少库存总数只需要调整相应的库存总数即可。当前售卖数量只有C端交易流程会修改,库存总数只有B端库存管理场景会修改。查询商品的已售卖数量只需要查库存的已售数量即可,而商品的库存余额可以通过库存总数减去已售数量得到。商品库存余额 = 库存总数 - 已售数量 ,BC端的操作不会影响这个等式的正确性。

综上所述,方案1使用库存余额更加复杂,并且没有明显的收益。而方案2记录售卖数量的方案更加简单,调整库存更加简洁优雅,而且不会出现数据一致性问题。通过记录售卖数量,很容易就可以知道当前商品的已售卖数量。

2. 是否需要预占库存?

在我所看到的大部分库存系统设计中,都提到了预占库存。仿佛必须要有预占库存,这里五哥甩一句话:虚拟商品库存无需预占库存。

预占库存是实物商品库存领域的设计,用户下单完成库存预占,仓储系统发货后释放预占库存,预占库存可以监控已下单未发货库存量。由于实物商品下单完成到发货完成有一段较长的时间窗口,并且为了更好的监控未发货库存数量,设计出预占库存这样一个概念。虚拟商品领域库存不存在发货这个动作,库存直接扣减就完事,整预占库存完全是增加系统理解难度,完全脱ku zi放X 的设计。

假如有预占库存

如果引入预占库存,库存充足的计算公式更加复杂,库存交互场景也更加复杂。

库存是否充足的公式则变为:总库存 > 已售卖数量+预占数量+当前购买数量。这个方案跟更加复杂。

下单阶段需要增加预占库存,支付阶段需要扣减预付库存,订单取消还需要回补库存,订单超时未支付也需要扣减预占库存。需要4个场景交互。

且每一个环节工作内容不同:分别包括增加预占库存、扣减预占库存、扣减预占库存+扣减实际库存、回补库存。这4步,每一步的内容都不同,非常复杂。

每一个写操作都需要保证幂等性,这4个接口,就需要设计4种幂等方案。例如如何保证“ 扣减预占库存” 的幂等,如何保证 “扣减预占库存+扣减实际库存的幂等”

预占库存的数据准确性、预占库存和总库存的一致性也很难保证。

引入预占库存概念,大大增加了系统的复杂度。 a39c0f41e350036779f884086728a3bf.jpeg

假如没有预占库存

如果没有预占库存,库存充足计算公式更简单,库存交互也更加简单

下单阶段扣减库存,订单取消回补库存,订单超时未支付回补库存。只需要3个场景交互,相比预占库存方案,支付完成后,减少了 “扣减实际库存+扣减预占库存” 这一步。

更重要的是没有了预占库存这个概念,库存操作只有扣减库存和回补库存这两个动作,系统设计会更加简洁。保证这两个写接口的幂等,只需要库存扣减流水和库存回补流水就能做到。

e407d0721abb174b15e260018fda8cd5.jpeg

由此可见,虚拟商品库存设计时增加预占库存,属于画蛇添足的设计,得不偿失。

3. 下单扣减库存还是支付扣减库存?

下单扣库存

下单前扣减库存,当订单取消和退款时回补库存。这个方案可以保证用户下单成功就一定能购买成功,下单阶段就占用库存的坏处是,如果大量用户虚假下单,但是不支付订单,就会有大量库存被占用,影响正常用户下单。

支付前扣库存

为了避免下单扣库存带来的问题,可以引入了一种新的方案:支付前扣减库存,当订单退款时,回补库存。这样,用户下单时不再占用库存,避免了大量库存被占用但未支付的情况。

然而,这种方案也存在一些问题。如果用户下单成功后在支付时库存不足,系统会向其提示 "库存已售罄",这对用户体验造成了极大的影响。

我曾经在京东抢茅台的过程中遇到过这个问题,我认为只要下单成功,就应该能购买到商品,但在支付时被告知库存不足,我感觉自己被耍了,我非常气愤,从此以后我就再也不参与这个平台的秒杀抢购了。(后来也不用京东了,基本只用拼多多了)。

最好使用下单扣减库存

以上两个方案各有优劣,因为方案2(支付扣库存)的用户体验太差。所以尽量避免使用方案2(支付扣库存),优先使用方案1(下单扣库存)。

对于方案1(下单扣库存)的弊端,也有解决办法。

通常情况下,业界会限制订单支付时长,要求用户在15-30分钟内完成支付,以避免订单长时间处于待支付状态。如果订单未在规定时间内支付,订单会被取消,库存也会被还原,因此不会一直占用库存的情况发生。

大量正常用户下单后不支付而导致订单取消率过高,说明系统存在问题阻碍用户支付。这种情况下,大量占用库存属于异常场景,可以忽略不计。

只有黑产用户才会故意使用大量账号占用库存,以影响售卖。然而仔细思考一下,占用库存、影响售卖对黑产并没有好处。所以实际发生的概率非常低。只需要让订单提单接口接入风控,风控接口识别并封杀黑产用户,让风控团队和黑产斗智斗勇就能解决方案1(下单扣库存)的弊端。

在系统设计时,我们必须进行正确的权衡。方案1的缺陷是:容易受到黑产用户的攻击,但黑产动力有限,概率较低。方案2的缺陷是:用户体验极差,可能导致用户流失。

两害相权取其轻,我认为用户体验更为重要,应该选择方案1(下单扣库存)。这也是和大多数公司的选择相同。

4. 秒杀等高并发场景的库存系统难点

在高并发和低并发场景下,我们需要考虑不同的实现方法。

对于高并发场景,要求一秒钟能够支持一万次库存扣减操作。这种情况下,我们可以选择Redis作为库存系统的存储模型。Redis具有高性能和高并发的特点,能够满足这种高并发的秒杀场景。

相比MySQL 版库存方案,基于Redis版本的库存系统要更加的笨重和复杂,数据可靠性更低、库存功能的丰富度更低,可维护性也要更差。如果在低并发业务场景使用 Redis实现库存能力,想要实现同样的功能除牺牲数据可靠性,也牺牲了数据一致性,不光如此,Redis版库存也难以实现多商品库存扣减、分时库存扣减等场景。

接下来我们优先探讨使用MySQL实现秒杀库存的瓶颈点

秒杀场景问题

在秒杀场景中,当大量用户同时抢购同一件商品时,需要同时更新商品库存。在使用InnoDB数据库时,通过行锁和死锁检测机制来确保数据并发的一致性。然而,由于大量的竞争和并发操作,行锁和死锁检测机制会导致数据库的CPU资源被短时间内占满,使得整个数据库几乎无法响应其他请求。

如何简单优化秒杀问题

秒杀的性能瓶颈并非完全因为,"大量请求集中更新一条库存很慢",而是因为MySQL 开启死锁检测。当大量扣减库存请求到MySQL,MySQL会根据深度优先遍历整个图是否有环,有环说明死锁,这个环是事务和锁构建的环。由于请求量巨大,这个图是巨大的,这将导致遍历过程CPU负载极高。那么如果MySQL 关闭死锁检测,这个问题是否会不复存在呢?

MySQL 在其官方文档中,提到了高并发场景,建议可关闭死锁检测

在高并发系统上,当大量线程等待同一锁时,死锁检测可能会导致速度减慢。有时,禁用死锁检测,在发生死锁时依赖事务回滚的设置可能会更有效。可以使用该变量禁用死锁检测 innodb_deadlock_detect 。

默认情况下,innodb_deadlock_detect 死锁检测是开启的。需要注意禁用死锁检测后,当真出现死锁时,只能依赖事务超时机制结束死锁。超时时间通过 innodb_lock_wait_timeout 参数配置,默认50秒,比较长,建议调整到10s以下。

下图是 并发场景修改同一条库存记录时,开启和关闭死锁检测的性能对比。

05023759d5b8b1ed962048cc65dd1dd8.jpeg

从图中可得知,当512个客户端线程执行扣减SQL时,响应时间超过了1秒以上,系统接近于不可用。而同样并发度,关闭死锁检测,响应时间在129毫秒,系统还可用。由此可见,关闭死锁检测确实能提高秒杀场景的库存扣减性能。但是这并不是最优的思路,因为关闭死锁检测,也无法解决行锁争抢问题带来的性能下降。

AliSQL 秒杀场景MySQL

除关闭死锁检测外,AliSQL 也提供了排队的思路解决 MySQL 热点记录更新问题。

AliSQL是基于MySQL官方版本的一个分支,由阿里云数据库团队维护。宣称“在通用基准测试场景下,AliSQL版本比MySQL官方版本有着 70% 的性能提升。在秒杀场景下,性能提升 100倍”。

AliSQL解决热点记录更新问题的方法是通过排队,以解决死锁检测和行锁争抢的问题。需要你在SQL中明确指定更新记录的ID,以让AliSQL知道在哪个记录上排队,同时AliSQL在这个场景禁用了死锁检测。并且由于采用了排队执行的方式,也避免了行锁的争抢问题。

我没有找到秒杀场景,AliSQL和MySQL的性能对比报告。但我了解到,美团MTSQL的性能报告。MTSQL也使用排队思路解决热点记录更新问题。MTSQL的性能评测结果显示,基于MySQL,单条记录每秒2500次库存扣减时,系统接近不可用,而使用MTSQL,单条记录每秒超过10000次库存扣减,响应时间仍然很快。

因此,使用MySQL端的排队解决方案能够显著提升高并发场景下库存扣减的性能,相较于原生MySQL至少提升了5倍以上的性能。

使用AliSQL、MTSQL的好处

相比基于Redis,使用MySQL 服务端排队技术,对于业务方更加简单。Redis需要复杂的机制保证Redis和数据库的数据一致。Redis难以保证 库存扣减和库存流水的一致性,难以保证多个商品库存扣减的一致性。

使用AliSQL,可以继续使用数据库的事务机制,没有数据一致性的困扰,技术方案更加简洁和可靠。

有强大的底层存储系统,可以极大降低业务系统设计的复杂度!提高系统的健壮性!

底层越强大,上层越轻松!

5. 多商品库存扣减如何保证一致性?

如果一笔订单购买多个商品,如何保证多商品扣减一致性呢?在低并发场景,完全可使用MySQL事务保证库存操作的一致性。

update inventory set cnt = cnt + #{buyCnt} WHERE productId = #{productId1} AND cnt + #{buyCnt} <= totalCnt

update inventory set cnt = cnt + #{buyCnt} WHERE productId = #{productId2} AND cnt + #{buyCnt} <= totalCnt

例如同时操作productId1,productId2 两个商品的库存,可以使用以上两个SQL,在同一个事务中执行。 任何一个SQL更新失败,则抛出异常,回滚事务。

高并发场景如何实现一致性呢?分别聊聊使用Redis、AliMq如何保证一致性?

如果Redis 使用Redis Cluster?

Redis中同时修改多个库存,可以使用Lua脚本,一次性检查多个库存是否充足,然后扣减库存。因为Redis是单线程模型,所以Lua脚本执行中,不会被打断,不会存在并发问题,所以每个Lua脚本可近似看成 同时成功、同时失败。

但是当Redis使用 集群模式时,无法使用修改多个Key的Lua脚本。

因为Redis-Cluster结构无法保证Lua脚本中多个Key的操作路由到一个节点,自然无法保证多Key操作的一致性。

所以使用Lua脚本实现多商品库存修改,必须确保Redis不得使用Cluster集群模式。

如果使用 AliSQL

使用AliSQL 和正常使用MySQL几乎一样,所以推荐高并发场景使用AliSQl实现库存方案,不推荐使用Redis。

6. 如何保证库存扣减的幂等

以上库存操作的SQL,如果重复执行会导致库存重复扣减。可以考虑在库存操作事务中,新增库存扣减流水,使用订单ID作为流水幂等键,当流水新增冲突时,则说明库存重复扣减,回滚事务即可。

SQL代码示例如下

4940bd72742126db3b66e681fac82498.jpeg

先扣减库存,还是先新增流水

可以考虑先增加库存流水,后修改库存。

在使用AliSQL 优化秒杀场景的库存修改时,可以设置 库存修改SQL在MySQL服务端执行完成后,立即提交事务,无需等待客户端提交事务,减少网络交互,提高性能。

ClientAliSQL开启事务 (Spring托管事务,Spring帮忙开启事务)发起新增库存流水 SQL发起库存扣减 SQL提交事务ClientAliSQL

AliSQL 支持在第三步,扣减库存时,自动提交事务,省却了一次网络开销。

同时,先扣减库存再增加流水,会导致行锁持有的时间更长,降低了库存扣减并发度。新增库存流水在前,新增流水时,还未锁定 库存行锁,其他事务可扣减库存,这样并发度更高。

(MySQL 新增记录默认是并发的 # 真丢人,工作六七年了,没搞明白MySQL插入是并发还是串行?)

回补库存也需要流水吗?

回补库存也需要流水。避免回补库存操作,重复执行,出现库存不准确现象。

库存流水表的唯一键 应该包括 orderId + productId + opType。加上库存操作方向,库存扣减和回补各自对应一条流水记录。

多个商品扣减库存,需要多条流水吗?

如果多个商品的库存扣减是在同一个事务中进行的,可以考虑只记录一条库存流水。

那么,对于库存回补操作,是否也应该对应一条流水呢?库存回补操作需要对应多条流水。这是因为订单可能会进行部分退款,也就是说,部分商品会退款,而部分商品不会退款。在这种情况下,就会出现部分商品的库存回滚,而另一部分商品则不会回滚。因此,一个订单的库存回补操作可能会执行多次,相应地,库存流水也应该有多条。

刚才提到的库存流水表的唯一键orderId + productId + opType。当进行库存扣减时,由于多个商品共享同一条库存流水,可以指定 productId=0 即可。

7. 日库存、周库存等分时库存如何实现?

以日库存为例,每日库存均生成一条库存记录,扣减库存时,需指定订单的提单时间,扣减库存模块,需根据提单时间,生成对应的 日库存 key。 扣减对应的库存。

存储模型如下

a429b343d70d451d7005f48a28ce19c0.jpeg

1036fb7d2a2def2c804a3d137700d196.jpeg

当扣减库存时,从商品的库存配置中获取到,该商品有哪类库存。如果包含日库存、周库存,构建库存扣减上下文,计算要扣减库存的Key。

在未来可以使用inventoryType进行扩展其他库存。例如月库存、年库存等也可以这样扩展。

值得一提的是,如果库存不限制时间,而是总库存,可设定 inventoryType = 1,inventoryKey = "Total" 表示总库存。

8. 除商品库存外,还有其他库存吗?

在电商环境中,并非只有商品具备库存,很多资源实体都有库存。

例如用户领券时,当库存不足时,则无法领券,需要设置发券的库存。

例如售卖商品时,不同的渠道共用一个库存,此时库存的维度并非商品,而是渠道。

例如某个营销活动需要控制预算,需要配置活动库存,此时的库存维度并非商品,而是活动。

所以在原有的库存模型上,需要增加维度。

e681608b49a223567a22ca3ef2c7ea17.jpeg

  1. targetType 表示 库存资源实体的类型

  2. targetId 表示 库存资源实体的 ID。

在查询和扣减库存时,我们需要额外指定所需库存资源的类型。如果客户端是商品库存场景,就需要指定资源类型为商品;如果客户端是活动库存场景,就需要指定资源类型为活动。通过新增资源类型,我们可以实现多种业务场景共用一个库存系统。

9. 如何设计库存接口的语义

通过问题2的讨论,可以得出一个结论:不需要设置预占库存。没有预占库存后,库存接口只有两个,扣减库存和回滚库存。这两个接口如何设计接口语义呢?换句话说,上游调用这两个接口何时为成功,何时为失败呢?

库存接口的各种场景

3cc4de9ef9aa2092160cf99421ab3662.jpeg

接下来,讨论这两个接口的返回值场景

库存扣减返回值处理

库存扣减的返回场景和对应处理如下

eebac391603e7946aecbe2ddc8767cfd.jpeg

扣减成功和库存不足失败的场景,上游分别认定为成功和失败处理即可,无需赘言。

值得说明的是,如果上游调用扣减库存超时,应如何处理?重新扣减库存还是直接认定失败。我认为两者都可以,但是要区分场景。

对时间不敏感的场景

当调用扣减库存超时,如果是时间不敏感的场景,例如异步发券等,可以考虑通过重试接口,获取准确的结果。一般情况下,库存都是充足的,接口超时的时候,大多数重试扣减都是可以扣减成功的。

对时间敏感的场景

当调用扣减库存超时,如果库存接口上游对时间比较敏感,调用库存扣减超时,则认定为失败。

例如提单扣减库存接口对耗时极为敏感。因为提单接口调用链路非常复杂,往往需要很多次下游接口调用和数据库调用,所以提单接口的耗时较长。同时提单时间太长,对用户影响非常大。当提单阶段扣减库存超时了,就应该认定为库存扣减失败,终止提单即可。因为库存接口超时,说明提单接口耗时已经很长了,再次重试,则会雪上加霜,不如选择抛出异常,由用户发起重试提单。

调用库存扣减超时,认定为失败,还需要调用库存回滚接口,尝试回滚库存。因为接口超时时,无法确定库存是否扣减成功。 上游应该发消息,尝试异步回滚库存。

库存回滚接口返回值

除了扣减库存超时,需要异步回滚库存。其他场景,包括订单退款,也需要扣减库存。

库存接口的语义如下

dcf57804215aca420a0b10df2f7d0d54.jpeg

回滚库存接口应该保证,如果扣减成功,则立即回滚库存;如果扣减失败或未扣减,则回滚失败。

异步回滚库存时,如果调用接口超时,上游应该重试回滚;如果返回库存已回滚,则认定为回滚成功。

总之,异步回滚库存,应该通过重试,保证回滚接口返回 成功或重复回滚 两个返回值中的一个。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 是一款广受欢迎的开源关系型数据库管理系统(RDBMS),由瑞典MySQL AB公司开发,现隶属于美国甲骨文公司(Oracle)。自1998年首次发布以来,MySQL以其卓越的性能、可靠性和可扩展性,成为全球范围内Web应用程序、企业级解决方案以及其他各种数据处理场景的首选数据库平台之一。 以下是对MySQL数据库的详细介绍: 核心特性与优势 开源与跨平台 MySQL遵循GPL开源协议,这意味着任何人都可以免费下载、使用和修改其源代码。这种开放性促进了广泛的社区支持和第三方插件、工具的发展。此外,MySQL支持多种操作系统,包括Windows、Linux、macOS、Solaris等,确保了其在不同环境下的兼容性和部署灵活性。 关系型模型与SQL支持 MySQL基于关系型数据库模型,数据以表格形式组织,并通过预定义的键(如主键、外键)在表之间建立关联。它完全支持结构化查询语言(SQL),允许用户进行数据查询、插入、更新、删除、创建和管理数据库结构等操作。SQL标准的广泛支持使得MySQL易于学习,且与其他关系型数据库系统有良好的互操作性。 存储引擎 MySQL支持多种存储引擎,如InnoDB、MyISAM、MEMORY等,每种引擎都有特定的优势和适用场景。例如,InnoDB提供事务安全、行级锁定和外键约束,适合处理高并发事务性的应用;MyISAM则更侧重于读取密集型操作,提供全文索引支持,适用于读多写少的场景。这种多引擎架构使得MySQL能够适应不同业务需求,提供高度定制化的存储解决方案。 性能与可扩展性 MySQL通过高效的缓存机制、查询优化器以及对硬件资源的有效利用,保证了在高负载情况下的稳定性和快速响应。它支持水平扩展(如通过分片、复制等技术)和垂直扩展(如增加硬件资源),以应对大规模数据存储和高并发访问的需求。 安全性与管理工具 MySQL提供了一系列安全措施,如用户账户管理、访问权限控制、SSL/TLS加密连接、审计日志等功能,确保数据的安全性和合规性。同时,MySQL附带了一系列管理工具,如MySQL Server、MySQL Workbench、MySQL Shell等,便于用户进行数据库配置、监控、备份、恢复、迁移等工作。 社区与生态系统 MySQL拥有庞大的开发者社区和丰富的第三方插件、库、中间件支持,提供了丰富的文档、教程、论坛以及专业服务,极大地简化了开发、运维和故障排查过程。 关键组件与日志 系统数据库 MySQL内部包含几个特殊的系统数据库,如: information_schema:提供关于所有数据库、表、列、索引等元数据信息,是查询数据库结构的标准接口。 mysql:存储MySQL自身的系统信息,如用户权限、服务器配置、事件调度等。 performance_schema:自MySQL 5.5版本引入,用于收集服务器性能数据,帮助诊断和优化系统性能。 test(非必要):默认提供的测试数据库,通常用于学习和实验,生产环境中可考虑删除。 sys(自MySQL 5.7版本):提供更易用的视图来访问performance_schema中的信息,简化性能分析工作。 日志文件 MySQL通过日志记录来保证数据一致性、支持故障恢复和审计需求,主要包括: 错误日志(Error Log):记录MySQL服务器运行期间的严重错误、警告和其他重要事件。 二进制日志(Binary Log,binlog):记录对数据库进行数据更改(如INSERT、UPDATE、DELETE)的操作序列,用于数据复制和恢复。 查询日志(query log):可选地记录所有发送到MySQL服务器的SQL查询,用于调试和审计。 慢查询日志(slow query log):记录执行时间超过指定阈值的查询,帮助识别和优化性能瓶颈。 应用场景 MySQL广泛应用于各种规模和类型的项目,包括但不限于: Web应用程序:作为众多网站和Web服务(如电子商务、社交媒体、内容管理系统等)的后台数据库。 数据分析与报表:与数据仓库技术结合,支持OLAP(在线分析处理)和数据可视化。 移动应用与物联网(IoT):作为数据存储层,支撑大量设备的数据采集、存储和查询需求。 嵌入式系统:在资源有限的环境中,作为轻量级数据库解决方案。 总之,MySQL凭借其开源、跨平台、高性能、灵活扩展、丰富功能集和庞大社区支持等特点,成为现代数据管理领域中不可或缺的一部分,适用于各种行业和业务场景数据库需求。
上百节课详细讲解,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。 课程介绍: 01_先来看一个互联网java工程师的招聘JD 02_互联网Java工程师面试突击训练课程第一季的内容说明 03_关于互联网Java工程师面试突击训练课程的几点说明 04_体验一下面试官对于消息队列的7个连环炮 05_知其然而知其所以然:如何进行消息队列的技术选型? 06_引入消息队列之后该如何保证其高可用性? 07_我的天!我为什么在消息队列里消费到了重复的数据? 08_啥?我发到消息队列里面的数据怎么不见了? 09_我该怎么保证从消息队列里拿到的数据按顺序执行? 10_完了!生产事故!几百万消息在消息队列里积压了几个小时! 11_如果让你来开发一个消息队列中间件,你会怎么设计架构? 12_总结一下消息队列相关问题的面试技巧 13_体验一下面试官对于分布式搜索引擎的4个连环炮 14_分布式搜索引擎的架构是怎么设计的?为啥是分布式的? 15_分布式搜索引擎写入和查询的工作流程是什么样的? 16_分布式搜索引擎在几十亿数据量级的场景下如何优化查询性能? 17_你们公司生产环境的分布式搜索引擎是怎么部署的呢? 18_总结一下分布式搜索引擎相关问题的面试技巧 19_先平易近人的随口问你一句分布式缓存的第一个问题 20_来聊聊redis的线程模型吧?为啥单线程还能有很高的效率? 21_redis都有哪些数据类型?分别在哪些场景下使用比较合适呢? 22_redis的过期策略能介绍一下?要不你再手写一个LRU? 23_怎么保证redis是高并发以及高可用的? 24_怎么保证redis挂掉之后再重启数据可以进行恢复? 25_你能聊聊redis cluster集群模式的原理吗? 26_你能说说我们一般如何应对缓存雪崩以及穿透问题吗? 27_如何保证缓存与数据库双写时的数据一致性? 28_你能说说redis的并发竞争问题该如何解决吗? 29_你们公司生产环境的redis集群的部署架构是什么样的? 30_分布式缓存相关面试题的回答技巧总结 31_体验一下面试官可能会对分布式系统发起的一串连环炮 32_为什么要把系统拆分成分布式的?为啥要用dubbo? 33_dubbo的工作原理是啥?注册中心挂了可以继续通信吗? 34_dubbo都支持哪些通信协议以及序列化协议? 35_dubbo支持哪些负载均衡、高可用以及动态代理的策略? 36_SPI是啥思想?dubbo的SPI机制是怎么玩儿的? 37_基于dubbo如何做服务治理、服务降级以及重试? 38_分布式系统中接口的幂等性该如何保证?比如不能重复扣款? 39_分布式系统中的接口调用如何保证顺序性? 40_如何设计一个类似dubbo的rpc框架?架构上该如何考虑? 41_说说zookeeper一般都有哪些使用场景? 42_分布式锁是啥?对比下redis和zk两种分布式锁的优劣? 43_说说你们的分布式session方案是啥?怎么做的? 44_了解分布式事务方案吗?你们都咋做的?有啥坑? 45_说说一般如何设计一个高并发系统架构? 46_体验一下面试官对于分库分表这个事儿的一个连环炮 47_来来来!咱们聊一下你们公司是怎么玩儿分库分表的? 48_你们当时是如何把系统不停机迁移到分库分表的? 49_好啊!那如何设计可以动态扩容缩容的分库分表方案? 50_一个关键的问题!分库分表之后全局id咋生成? 51_说说MySQL读写分离的原理?主从同步延时咋解决? 52_如何设计高可用系统架构?限流?熔断?降级?什么鬼!
《大型分布式网站架构设计与实践》主要介绍了大型分布式网站架构所涉及的一些技术细节,包括SOA架构的实现、互联网安全架构、构建分布式网站所依赖的基础设施、系统稳定性保障和海量数据分析等内容;深入地讲述了大型分布式网站架构设计的核心原理,并通过一些架构设计的典型案例,帮助读者了解大型分布式网站设计的一些常见场景及遇到的问题。 作者结合自己在阿里巴巴及淘宝网的实际工作经历展开论述。《大型分布式网站架构设计与实践》既可供初学者学习,帮助读者了解大型分布式网站的架构,以及解决问题的思路和方法,也可供业界同行参考,给日常工作带来启发。 作者简介 陈康贤,淘宝花名龙隆,淘宝技术部研发工程师,2011年加入淘宝网,参与了阿里云手机商城、口碑网迁移、店铺建站、offer、支付宝卡宝、生活商城、淘宝同学等项目,在分布式系统架构设计高并发系统设计系统稳定性保障等领域积累了较为丰富的实践经验。曾在程序员上发表过《漫谈基于http协议的SOA架构》《浅析HTTP平台的安全稳定性架构》两篇文章,对基于HTTP协议的SOA架构有深入研究,在排查解决线上问题和故障方面有丰富的实践经验,擅于利用数据分析解决实际问题,对新技术有浓厚的兴趣。 目录 第1章 面向服务的体系架构(SOA) 1 1.1 基于TCP协议的RPC 3 1.1.1 RPC名词解释 3 1.1.2 对象的序列化 4 1.1.3 基于TCP协议实现RPC 6 1.2 基于HTTP协议的RPC 9 1.2.1 HTTP协议栈 9 1.2.2 HTTP请求与响应 15 1.2.3 通过HttpClient发送HTTP请求 16 1.2.4 使用HTTP协议的优势 17 1.2.5 JSON和XML 18 1.2.6 RESTful和RPC 20 1.2.7 基于HTTP协议的RPC的实现 22 1.3 服务的路由和负载均衡 30 1.3.1 服务化的演变 30 显示全部信息 前言 在大型网站架构的演变过程中,集中式的架构设计出于对系统的可扩展性、可维护性以及成本等多方面因素的考虑,逐渐被放弃,转而采用分布式的架构设计。分布式架构的核心思想是采用大量廉价的PC Server,构建一个低成本、高可用、高可扩展、高吞吐的集群系统,以支撑海量的用户访问和数据存储,理论上具备无限的扩展能力。分布式系统设计,是一门复杂的学问,它涉及到通信协议、远程调用,服务治理,系统安全、存储、搜索、监控、稳定性保障、性能优化、数据分析、数据挖掘等各个领域,对任何一个领域的深入挖掘,都能够编写一本篇幅不亚于本书的专门书籍。本书结合作者在阿里巴巴及淘宝网的实际工作经历,重点介绍大型分布式系统架构设计,同时,为避免过度专注于理论而使得内容显得空洞,作者穿插介绍了很多实践的案例,尽量让每一个关键的技术点都落到实处,相信能够帮助读者更好地理解本书的内容。 内容大纲 全书共5章,章与章之间几乎是相互独立的,没有必然的前后依赖关系,因此,读者可以从任何一个感兴趣的专题开始阅读,但是,每一章的各个小节之间的内容是相互关联的,因此,最好按照原文的先后顺序阅读。 第1章主要介绍企业内部SOA(Service Oriented Architecture,即面向服务的体系结构)架构的实现,包括HTTP协议的工作原理,基于TCP协议和基于HTTP协议的RPC实现,如
,主要是学习springMVC模式开发。框架的搭建,数据库mysql的整合,缓存redis的使用规则和编程的习惯 MySQL 是一款广受欢迎的开源关系型数据库管理系统(RDBMS),由瑞典MySQL AB公司开发,现隶属于美国甲骨文公司(Oracle)。自1998年首次发布以来,MySQL以其卓越的性能、可靠性和可扩展性,成为全球范围内Web应用程序、企业级解决方案以及其他各种数据处理场景的首选数据库平台之一。 以下是对MySQL数据库的详细介绍: 核心特性与优势 开源与跨平台 MySQL遵循GPL开源协议,这意味着任何人都可以免费下载、使用和修改其源代码。这种开放性促进了广泛的社区支持和第三方插件、工具的发展。此外,MySQL支持多种操作系统,包括Windows、Linux、macOS、Solaris等,确保了其在不同环境下的兼容性和部署灵活性。 关系型模型与SQL支持 MySQL基于关系型数据库模型,数据以表格形式组织,并通过预定义的键(如主键、外键)在表之间建立关联。它完全支持结构化查询语言(SQL),允许用户进行数据查询、插入、更新、删除、创建和管理数据库结构等操作。SQL标准的广泛支持使得MySQL易于学习,且与其他关系型数据库系统有良好的互操作性。 存储引擎 MySQL支持多种存储引擎,如InnoDB、MyISAM、MEMORY等,每种引擎都有特定的优势和适用场景。例如,InnoDB提供事务安全、行级锁定和外键约束,适合处理高并发事务性的应用;MyISAM则更侧重于读取密集型操作,提供全文索引支持,适用于读多写少的场景。这种多引擎架构使得MySQL能够适应不同业务需求,提供高度定制化的存储解决方案。 性能与可扩展性 MySQL通过高效的缓存机制、查询优化器以及对硬件资源的有效利用,保证了在高负载情况下的稳定性和快速响应。它支持水平扩展(如通过分片、复制等技术)和垂直扩展(如增加硬件资源),以应对大规模数据存储和高并发访问的需求。 安全性与管理工具 MySQL提供了一系列安全措施,如用户账户管理、访问权限控制、SSL/TLS加密连接、审计日志等功能,确保数据的安全性和合规性。同时,MySQL附带了一系列管理工具,如MySQL Server、MySQL Workbench、MySQL Shell等,便于用户进行数据库配置、监控、备份、恢复、迁移等工作。 社区与生态系统 MySQL拥有庞大的开发者社区和丰富的第三方插件、库、中间件支持,提供了丰富的文档、教程、论坛以及专业服务,极大地简化了开发、运维和故障排查过程。 关键组件与日志 系统数据库 MySQL内部包含几个特殊的系统数据库,如: information_schema:提供关于所有数据库、表、列、索引等元数据信息,是查询数据库结构的标准接口。 mysql:存储MySQL自身的系统信息,如用户权限、服务器配置、事件调度等。 performance_schema:自MySQL 5.5版本引入,用于收集服务器性能数据,帮助诊断和优化系统性能。 test(非必要):默认提供的测试数据库,通常用于学习和实验,生产环境中可考虑删除。 sys(自MySQL 5.7版本):提供更易用的视图来访问performance_schema中的信息,简化性能分析工作。 日志文件 MySQL通过日志记录来保证数据一致性、支持故障恢复和审计需求,主要包括: 错误日志(Error Log):记录MySQL服务器运行期间的严重错误、警告和其他重要事件。 二进制日志(Binary Log,binlog):记录对数据库进行数据更改(如INSERT、UPDATE、DELETE)的操作序列,用于数据复制和恢复。 查询日志(query log):可选地记录所有发送到MySQL服务器的SQL查询,用于调试和审计。 慢查询日志(slow query log):记录执行时间超过指定阈值的查询,帮助识别和优化性能瓶颈。 应用场景 MySQL广泛应用于各种规模和类型的项目,包括但不限于: Web应用程序:作为众多网站和Web服务(如电子商务、社交媒体、内容管理系统等)的后台数据库。 数据分析与报表:与数据仓库技术结合,支持OLAP(在线分析处理)和数据可视化。 移动应用与物联网(IoT):作为数据存储层,支撑大量设备的数据采集、存储和查询需求。 嵌入式系统:在资源有限的环境中,作为轻量级数据库解决方案。 总之,MySQL凭借其开源、跨平台、高性能、灵活扩展、丰富功能集和庞大社区支持等特点,成为现代数据管理领域中不可或缺的一部分,适用于各种行业和业务场景数据库需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值