This commit is contained in:
louzefeng
2024-07-11 05:50:32 +00:00
parent bf99793fd0
commit d3828a7aee
6071 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
<audio id="audio" title="开篇词 | 从今天起,换种方式学存储" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/bc/8b/bc25f54e2bbf0a70d45e0e67935f168b.mp3"></audio>
你好,我是李玥,《[消息队列高手课](https://time.geekbang.org/column/intro/212?utm_term=zeusI4EZD&utm_source=geektime&utm_medium=cunchu)》专栏的作者,目前在京东任职架构师。这是我在极客时间上的第二门课程,很高兴在这里遇见你。
在十多年的开发者职业生涯中我的从业经历应该算是比较丰富的。在传统IT行业做过非常多的企业级ToB的系统转战互联网后我又曾经带领创业团队体会过从0到1创业的艰辛见证过互联网高速增长的高光时刻也经历过京东数年大促的洗礼。
在工作过程中我接触过很多系统。不同的系统它的业务不一样有做社交的有做电商的还有做内容的。系统的规模也不一样有很小规模的系统也有像BAT这样的巨无霸系统。在构建这些系统时都会面临五花八门的问题。但总结下来我发现一个“神奇”的规律
>
**凡是那些特别难解决的、让你付出巨大代价的,或者是损失惨重的技术问题,几乎都可以归为存储系统的问题。**
这个规律其实并不神奇,它是有原因的。
你可以想一下我们开发的各种业务系统几乎都是MIS系统中文叫“管理信息系统”有的大学还有这个专业。管理信息系统这个词的含义就是字面的意思管理信息的系统。这里面的信息是什么其实就是数据。不管你的系统业务是什么样的最终都要落到对信息的管理或者通俗点儿说你系统的业务功能最终的结果就是数据。
只要这个数据是正确的,剩下的都是小问题。数据错了、丢了,甚至数据处理不及时,这些都是损失惨重的大问题。
所以用于承载数据的存储系统就显得非常重要,如果说,你能构建一个安全可靠、快速稳定的存储系统,基于这个基础之上构建的业务系统,显然就让人放心多了。
所以说,**存储是系统中最核心、最重要、最关键的组成部分,没有之一。**
## 你要关注存储的哪些特点?
我们常用的存储系统有很多有单机的也有分布式的有数据库、文件系统还有一些介于二者之间的种类非常多。无论是什么样的存储比如MySQL、Redis、ElasticSearch等等它们都有几个共同的特点。
**第一个特点是难用****。**怎么难用呢?对于应用程序来说,存储无非就是帮我们安全可靠地保存数据,在我需要的时候能快速读出来也就可以了。很遗憾,几乎没有存储系统能满足这么简单的要求。
有一个非常形象的比喻:我开着车去商场购物,到了停车场发现这个停车场不能存车,只能存零件。我必须自己把车拆了,然后把这些零件分门别类打上标签,存放到停车场货架上,走的时候自己再把零件取出来把车组装起来。
听起来很可笑是吧,你想想咱们用的这些存储系统,不就是这样吗?我们应用程序里管理的数据都是对象是吧?你告诉我哪个存储系统能存对象?没有吧?
拿MySQL举例我要存取对象必须把对象转换成MySQL表中的行还得写SQL语句才能存取。是不是很难用难用你还不得不用并且还得把它给用好了这里面有很多的方法、技巧和实践经验需要学习掌握。
**第二个特点是慢。**最近几年的技术圈分布式存储这块儿非常繁荣你可以看到过一段时间就有一个新的数据库诞生了不管它们功能怎么样无一例外都说自己的有多快性能多好顺便把像MySQL这样的老家伙拉出来做个性能对比测试吊打一遍。
“一个人炫耀什么,说明内心缺少什么”,这个道理放到技术圈同样适用,不断有新的存储刷新性能记录,恰恰说明了存储系统性能不能让人满意。
一个经过良好优化过的业务系统,它的性能瓶颈一定是存储。从性能角度上来说,存储系统就是整个系统中最短的那块儿板子,存储系统有多慢,你的整个系统就多慢。如何优化存储性能,从而让整个系统运转如飞,这里面同样有很多的方法、技巧和经验需要掌握。
**第三个特点是杂。**存储这块儿不像其他的成熟的技术领域基本上都是一两种方案包打天下比如Java开发基本上就被Spring统治了再比如Web容器静态用Nginx动态Tomcat。但存储这块儿却不是这样的就拿真正广泛应用在生产系统中的存储来说你看有多少种
MySQL、Redis、ElasticSearch、HBase、Hive、MongoDB、RocksDB、CockroachDB等等这些存储还真就是谁都替代不了谁每一种都有它擅长的地方有它适用的场景当然也有很突出的短板。如何根据业务系统的特点选择合适的存储来构建我们的系统这也是需要学习和掌握的。
## 学习存储的最佳姿势是什么样的?
既然存储有“难用、慢、杂”这几大特点,学习起来就更需要注意方法。如何来学最高效呢?我认为是实战,从问题入手。
存储涉及到很多理论知识和概念,比如各种数据结构、哈希、树以及它们的时间复杂度等等,这些内容往往都是偏数学范畴的一些知识,学起来不容易理解和记忆。并且,理论和实践之间往往存在着非常大的鸿沟,往往是“懂了一堆道理,却还是写不好代码”。
所以,我在极客时间上开了第二个专栏讲存储,我们只讲实践中大家都会遇到的问题,讲这些问题的解决方法,同时在这里面贯穿一些知识和原理。通过这样的学习方式,既可以快速地帮你解决实际问题,同时还能提升你的技术能力。
在接下来的课程中,我会带你一起,**从0到1从小到大以电商作为场景讲解不同规模的存储系统应该如何构建**。
每一节课我们一起解决一两个实战的问题比如为什么明明数据量和访问量不大MySQL还是很慢数据库宕机了怎么办
为什么选择电商系统来讲呢?因为我熟啊!开个玩笑,当然不只是因为我做过几年电商系统。其实,很多培训学校、各种技术论坛都特别喜欢讲电商系统。因为电商这个系统,特别有代表性,特别适合作为案例来研究和学习。
**首先,电商系统覆盖面足够广泛****。**特别是是在互联网行业,你会发现几乎所有的互联网公司都在做两个事情:电商和社交。
**其次,****用电商系统作为案例,直接就能学以致用**。即使你面对的业务和电商关系不大,因为电商的系统足够复杂,你在其他业务中可能遇到的技术问题,大多数在电商系统中基本都会遇到,一样有借鉴的意义。另外,电商这个业务领域对所有人来说都很熟悉,拿它作为案例基本上不需要再讲解业务知识,我们可以快速地专注于技术问题本身。
即使是同样一个电商系统,不同的规模,它需要解决的问题也不一样。不少做技术的同学崇尚于海量数据和高并发,认为只有大厂那些高并发、海量数据的核心或者是底层存储系统,才是真正“有技术含量”的系统,能胜任这样系统的开发者,才是真正的技术大牛。这其实是一个技术认知误区。为什么这么说?
因为,并不是规模小的系统就简单,只有大规模的系统才有难度。
创业团队需要快速低成本把系统完整地实现出来,好快速验证它的商业模式;处于高速增长期的团队,它面临的问题是业务高速增长和不断变化,相应的,也要对系统不停地进行升级改造来适应变化,并且要在变化的过程中确保稳定;业务规模足够大的一些大厂,它需要解决的是如何应对高并发、海量数据这些问题。
所以说,不同规模的系统,在技术上没有高低贵贱之分,它们的建设目标不一样,面临的挑战不一样,需要解决的问题也不一样,对于存储系统的选择、架构设计也是不一样的。
所以,我们的课程设计就是按照系统的发展过程,分成了创业篇、高速增长篇和海量数据篇这三个部分。
- 在创业篇我们重点解决从0到1的问题比如如何低成本高质量地快速构建一个小规模的订单存储系统。
- 在高速增长篇,我们关注在高速变化的过程中,你的系统一定会遇到的一些共通问题,以及该如何应对这些问题。比如说,如何从单机的存储系统逐步演进为分布式存储系统;如何在线平滑的扩容我们的存储系统。
- 在海量数据篇,我们重点解决高并发、海量数据情况下的存储系统该如何设计的问题。比如,海量的埋点数据该怎么存储;如何在各种数据库之间实时迁移和同步海量数据,等等。
通过学习这门课程,你将收获的不仅是案例中那些解决具体问题的方法,在电商系统架构、对存储系统的认知以及存储系统的设计能力这几个方面,都会有所提升。
更重要的是,通过案例来学习常用的数据库和存储系统的使用和实现,可以总结出存储系统最通用、本质的技术原理。掌握了存储系统的本质之后,不仅会让你在面试时更加从容,而且会让你对存储的理解上升一个层次,从“知道怎么用”,升级为“知道为什么这么用”,最终做到活学活用。
在极客时间的一段新旅程即将开始,在开始正式学习之前,我还想再说一些我的想法。技术的发展让使用技术变得越来越简单,但是作为有理想有情怀开发者,不能让技术把我们的变得越来越“简单”。我很开心又能同各位同学一起持续地丰富自己,也希望你能不负时光,认真对待这段学习之旅。
在学习过程中你都可以在留言区提问我看到会第一时间给你回复。另外像《消息队列高手课》专栏一样我也希望你可以在学习之初立一个Flag。有了目标指引持之以恒地探索成功必不会偏航。
好,开始学习吧!

View File

@@ -0,0 +1,142 @@
<audio id="audio" title="课前加餐 | 电商系统是如何设计的?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/70/1d/7077b3844c3a4b9518a26dd49428fa1d.mp3"></audio>
你好,我是李玥。
在这个系列课程中,我们会讲电商这个行业在多年系统建设和运维过程中,总结出来的使用分布式存储系统的一些最佳实践。也会以电商系统作为例子来讲解存储相关的技术知识和问题。这都需要你对电商的业务逻辑、系统架构、核心业务流程有一个基本的认知。
虽然说电商这个业务和你的生活息息相关你可能对电商多少有一些了解但是即使是一个最小化的电商系统它仍然非常复杂。所以我们先花一节课的时间一起以一个创业公司的CTO的视角设计一个最小化的电商系统在这个过程中帮你理清楚电商系统的架构。
这样,我们在学习后续课程的时候,就不再解释电商的业务和系统了,直接来讲具体的技术问题。
我们的故事从一个电话开始。某一天,一个曾经认识但并不太熟悉的老板突然来了一个电话:
“我有一个改变世界的想法,就差一个程序员了!你来吧!”
新公司很快就成立了你成了新公司的CTO。关于要如何改变世界目前唯一能确定的是老板要做一个电商系统。具体做成什么样还不清楚。你需要和老板讨论需求。
“咱们要做的业务模式是C2C、B2C还是B2B呢
老板“什么B什么C我不懂你们那些技术的东西。”
“这么说吧你要山寨啊不对做一个某宝网还是某东网还是某848网呢
老板:“不都是一样的么?有什么区别?你赶紧做一个出来我看看不就知道了?!”
有没有感觉似曾相识?作为研发谁没碰到过几个啥也不懂的需求方不是?那这种情况下,你怎么办呢?
**在需求还不太明确的情况下,比较可行的方式就是,先把那些不太会变化的核心系统搭建出来,尽量简单地实现出一个最小化的系统,然后再逐步迭代完善。**
## 电商系统的核心流程是什么样的?
接下来我带你一起来设计这个电商的核心系统。
遵照软件工程的一般规律,我们先从需求阶段开始。如何来做需求分析?理想情况下,应该由系统分析师或者是产品经理来承担这个任务。但现实很骨感,绝大多数情况下,你得到的所谓的“需求”,就是一两句话。需求分析的工作实际上就落在了开发者身上。
很多项目交付以后,还要改来改去,用户不满意,开发者很痛苦,其实就是缺失了需求分析这个步骤。所以,为了自己,每一个开发者都应该掌握一点需求分析的方法。
开发者怎么来做需求分析?这里面我们不讲那些做需求分析的方法和理论,只告诉你最重要、最关键的一个点。
不要一上来就设计功能,而是先要回答下面这两个问题:
1. 这个系统(或者是功能)是给哪些人用的?
1. 这些人使用这个系统来解决什么问题?
这两个问题的答案,我把它们称为业务需求。在我们将要设计的这个电商系统中,它的业务需求是什么?电商的业务,每个人都熟悉,很容易回答这两个问题。
第一个问题,电商系统给哪些人用?
首先得有买东西的人,我们叫“用户”,还得有卖东西的人?我们叫“运营人员”。还有什么人会用这个系统?老板啊!你记住,你在设计任何一个系统的时候,千万不要把老板或者是领导给忘了,他们是给你钱的人,他们的意见非常重要!
然后我们一起回答第二个问题:用户、运营和老板,分别用电商系统来干什么?
这个问题也很容易回答,用户用系统来买东西,运营用系统来卖东西,老板需要在系统中看到他赚了多少钱。这两个问题的答案,或者说是业务需求,稍加细化后,可以用下面这个图来清晰的表述:
<img src="https://static001.geekbang.org/resource/image/c7/bc/c75357b43ec89aebd88fbc2a3efcd1bc.jpg" alt="">
这个图在UML统一建模语言中称为用例图Use Case是需求分析的时候你需要画的第一张图。它回答的就是业务需求中的那两个关键的问题这个系统给谁用他们用这个系统解决什么问题
一般来说,业务需求和我们要设计的系统关系不大。为什么这么说呢?你可以看一下上面这个图里面的用例,放在传统的商业企业里面,比如一个小杂货铺、一个线下实体商场商店或者一个做电视购物的公司,是不是也是适用的?所以做业务需求的主要目的,是理清楚业务场景是什么样的。
然后我们来分析电商系统的流程。显然,一个电商系统最主要的业务流程,一定是购物这个流程。你应该很容易就能把这个流程分析出来,它的流程图是这样的:
<img src="https://static001.geekbang.org/resource/image/bd/cf/bd778c67b3971e16d3cdbd9fae800dcf.jpg" alt="">
所有的电商几乎都是这样一个流程,我和你一起来看一下这个流程。
流程从用户选购商品开始用户先从你的App中浏览商品找到心仪的商品之后把商品添加到购物车里面都选好了之后打开购物车下一个订单下单结算之后就可以支付了支付成功后运营人员接下来会给每个已经支付的订单发货邮寄商品给用户之后用户确认收货到这里一个完整的购物流程就结束了。
## 如何根据流程来划分功能模块?
接下来我们把这个业务流程再细化看一下电商系统如何来实现这个流程我把细化之后的流程绘制成了下面这个时序图Sequence Diagram
<img src="https://static001.geekbang.org/resource/image/f5/ea/f5f3d89c31770591c5d59591a3390eea.jpg" alt="">
我们一起看下这个时序图中的每个步骤。
1. 用户开始浏览商品,需要有一个**商品模块**来支撑,给用户展示商品的介绍、价格等等这些信息。
1. 用户把选好的商品加入购物车,这个步骤,也需要一个**购物车模块**来维护用户购物车中的商品。
1. 用户下单肯定需要一个**订单模块**来创建这个新订单。订单创建好了之后,需要把订单中的商品从购物车中删除掉。
1. 订单创建完成后,需要引导用户付款,也就是发起支付流程,这里需要有一个**支付模块**来实现支付功能,用户成功完成支付之后,需要把订单的状态变更为“已支付”。
1. 之后运营人员就可以发货了,在系统中,发货这个步骤,需要扣减对应商品的库存数量,这个功能需要**库存模块**来实现,发货完成后,还需要把订单状态变更为“已发货”。
1. 最后,用户收货之后,在系统中确认收货,系统把订单状态变更为“已收货”,流程结束。
这个流程涉及到的功能模块有:**商品、购物车、订单、支付和库存,**这几个模块就是一个电商系统中的核心功能模块。
当然,仅仅有这几个模块还是不够的,因为我们只分析了“购物”这个最主要的流程,并没有完全涵盖业务需求中的全部用例,比如:运营人员进货、老板查看报表这些用例还没有覆盖到。
相比购物这个流程,剩下的几个用例和流程都没那么复杂,用同样的方法就可以把其他功能模块分析出来。在这里我们就省略分析过程,直接给出我们电商系统的功能模块划分:
<img src="https://static001.geekbang.org/resource/image/0b/54/0b37cfadd0e181cd9648efc9e9924354.jpg" alt="">
上面这个图我使用的是UML中的包图(Package Diagram)来表示。整个系统按照功能,划分为十个模块,除了购物流程中涉及到的:商品、订单、购物车、支付、库存五个模块以外,还补充了促销、用户、账户、搜索推荐和报表这几个模块,这些都是构建一个电商系统必不可少的功能。我们一个一个来说每个模块需要实现的功能。
- 商品:维护和展示商品信息和价格。
- 订单:维护订单信息和订单状态,计算订单金额。
- 购物车:维护用户购物车中的商品。
- 支付:负责与系统内外部的支付渠道对接,实现支付功能。
- 库存:维护商品的库存数量和库存信息。
- 促销:制定促销规则,计算促销优惠。
- 用户:维护系统的用户信息,注意用户模块它是一个业务模块,一般不负责用户登录和认证,这是两个完全不同的功能。
- 账户:负责维护用户的账户余额。
- 搜索推荐:负责商城中,搜索商品和各种列表页和促销页的组织和展示,简单的说就是决定让用户优先看到哪些商品。
- 报表:实现统计和分析功能,生成报表,给老板来做经营分析和决策使用。
这里面需要特别说一下促销模块,它是电商系统中,最复杂的一个模块。各种优惠券、满减、返现等等这些促销规则,每个都非常复杂,再加上这些规则叠加计算,常常是复杂到连制定促销规则的人都搞不清楚。
所以每个电商公司无一例外都爆出过,因为促销规则制定失误,而产生非常便宜的“羊毛单”,让精明的消费者薅了“羊毛”。不过五花八门的促销是提升销售最有效的手段,肯定不能因噎废食。
作为系统设计者,我们需要把促销的变化和复杂性封禁在促销模块内部,不能让一个促销模块把整个电商系统都搞得非常复杂,否则就很难去设计和实现。
可行的做法是,把促销模块与其他模块的接口设计的相对简单和固定,这样系统的其他模块就不会因为新的促销玩儿法而改变。
在创建订单时,订单模块把商品和价格信息传给促销模块,促销模块返回一个可以使用的促销列表,用户选择好促销和优惠,订单模块把商品、价格、促销优惠这些信息,再次传给促销模块,促销模块则返回促销价格。
最终生成的订单中,只记录订单使用了哪几种促销,以及最终的促销价就可以了。这样,不管促销这个模块的玩儿法怎么变化,订单和其他模块的业务逻辑不需要随之改变。
至此,我们就完成了一个电商系统的概要设计,你应该对电商系统也有了一个初步的了解。
## 小结
我们每节课的正文结束之后,都会安排一个小结,对课程的重点内容做一个总结。
今天我们再来回顾一下,一个电商系统的设计中,最核心的几个关键点。
首先,系统的角色是:用户、运营人员和老板。这三个角色对电商系统的需求是:用户使用系统来购物,运营人员负责销售商品,老板关注系统中经营数据。电商系统最核心的流程就是用户购物的流程,流程从用户浏览选购商品开始,加购、下单、支付、运营人员发货、用户确认收货,至此流程结束。
细化这个流程之后,我们可以分析出,支撑这个流程几个核心的功能模块:商品、订单、购物车、支付和库存。此外,还需要促销、用户、账户、搜索推荐和报表这些必备的功能模块支撑,才能构成一个完整的电商系统。
我还和你分享了作为一个开发者,你在做需求分析的时候,需要把握的一个要点:不要一上来就设计功能,而是要先理清业务需求,也就是这节课反复强调的两个问题:这个系统是给哪些人用的?他们分别用这个系统来解决什么问题?这样可以确保你做出来的系统,大体上不会偏离用户的预期。
最后,在讲解系统功能模块划分的时候,我们说了一个有效减少系统复杂度的设计经验。那就是,如果系统业务是复杂而多变的,尽量识别出这部分复杂业务的边界,将复杂封禁在一个模块的内部,避免这种复杂度扩散到整个系统中去。
这节课是我们专栏的课前加餐,目的是为了让你了解电商的组成模块。在后续的课程中,我将和你一起经历这个电商系统在从小到大的发展过程中遇到的存储技术问题,并一起解决它。
## 思考题
做完了概要设计就可以来做技术选型了。作为公司的CTO课后请你思考一下这个电商系统的技术选型应该是什么样的
- 使用什么编程语言和技术栈?
- 需要哪些第三方的框架和云服务?
- 我们最关心的存储系统该怎么选型?
欢迎你在留言区与我讨论,如果你觉得今天的内容对你有帮助,也欢迎把它分享给你的朋友。