系统设计与构架群

1427 2019-10-13 22:20

加微信ID onetptp 好友,回复【系统设计】,我们会拉你入群

群讨论内容会被同步到 https://t.me/system_design_cn

我们还有一个英文社区在 Telegram 上:https://t.me/system_design_and_architecture

本群成立目的是想让对系统设计与架构感兴趣的同学们有一个可以切磋技术、互相答疑、分享机会的地方。

群里只谈技术,不谈风月、政治、投资、职场发展等。禁止未经允许发广告。希望同学们共同努力,提高群聊的信噪比。技术方面,鼓励提问,大胆回答,不怕犯错,也不要diss别人的提问或回答。技术没高下,只有早知道和晚知道。

为保持群内讨论环境和专业程度,群内要求实名制。请将群昵称改为“姓名-公司-职位”,比如“TianPan.co-IoTeX-SWE”;找工作的同学可以改成“姓名-学校-想找工作的方向”。

运营准则

  1. 问/答/分享。欢迎问问题、回答问题、分享知识。推广可以有,非原创可以有,但是必须要切题,质量要高。问问题之前先学习如何问问题。
  2. 主观高于客观。客观的知识你总能搜索到,所以我们更看重你个人的实际体验和感受。注重速成,一句话的精妙解释优于一本书的故弄玄虚。
  3. 7:3 的信噪比。希望我们的讨论既有用又有趣 —— 7:3 是个不错的比例。

讨论

Natee

想实现一个模式,对后端服务的 login 请求经过网关层的基础验证以后,转发给 ‘登陆服务器’,‘登陆服务器’在验证过request中的username&password之后将用户的部分信息,例如分组,权限以JWT存入token中,返回给客户,客户在后续请求中带上此token,随后在网关中解析token将payload里面的分组,权限信息解码放到header中,供后面服务模块调用。 但是我遇到一个问题,我使用的api网关KONG在解析token需要有iss,就是consumer,对应的consumer做成的jwt中有issuser,指明token是给谁用的,然而我在生成token时候是在登陆服务模块生成的,这样子的话,我在做token的时候就需要把iss写到payload中去,但是iss是在网关里配置consumer的jwt时候生成的key,这个key也可以指定,不指定的话随机生成。这样子就出现问题了,在登陆服务器验证时候一定要放入一个iss进jwt的payload,然而这个iss是在网关层生成的

这个要看你 jwt 具体的算法 algo ,你们 iss 到底是用不同的用户的不同的 key 签的,还是所有的 jwt 共享一个 iss。我的意思是,在对称加密algo 的情况下,不同用户有不同的 sub,但是 iss 是可以共享用一个 master key 签名的

这样只需要让登陆服务器和 api 网关共享一个 master key 就可以了

Jack

  1. 我想知道enterprise service bus,像Apache camel,是过时了吗? 是不是不符合Smart endpoints dumb channel?
  2. 还有event vs threads, 现在有个定论哪个好吗?还看到说akka, Haskell就是综合两者的优点,可以讨论一下

York

用java的akka写过一点点很简单的actor model的代码,在用debugger的时候还是看到下面起的还是 thread。个人觉得akka只是对thread进行封装,用actor model(event/message processing)的套路呈现给你一系列API用来处理concurrency。所以就event和thread而言,就看你的app对计算资源的控制需要多细的粒度。event更high level一些更接近业务逻辑。直接用thread的话,假设你实现的好overhead应该还是会比用akka要小吧

大小说家👻

同意,我们组用的scala akka stream,高度封装的akka actor, 仍然需要implicit的传入一个executionContext,(相当于Java的线程池)。返回future的时候,实际上是通过这个线程池新开了一个线程异步处理+call back。

写起来比多线程需要考虑的少一些,也安全一点,因为通过map, reduce 的stream处理方式避免了shared variable的使用

开发的时候能更关注于业务本身

Jack

谢谢分享,你的体验和这里说的一样: https://blog.acolyer.org/2014/12/12/scala-actors-unifying-thread-based-and-event-based-programming/ “Compared to a purely event-based approach, users are relieved from writing their own ad hoc thread pooling code. Since the internal thread pool can be global to the web application server, the thread pool controller can leverage more information for its decisions. Finally, accesses to an actor’s mailbox are race-free. Therefore, resources such as user profiles can be protected by modeling them as (thread-less) actors.” 真的是两种的好处都有。

我感觉 actor 应该等同于CSP (communicating sequential processes)里的 sequential process, 是用artibter做了serialization

这篇文章说events不好 https://blog.acolyer.org/2014/12/10/why-events-are-a-bad-idea/ , 还不如threads, 作者包括Eric brewer, 他们发现除了pub-sub以外用threads又快(用系统的threads, 没有event loop的bottleneck),又容易写,又容易发现错误(stack, not heap),是不是说核心的components就应该用threads,还是说现在语言,操作系统,硬件等都进步了,这篇文章也过时了?

这个网站推荐用event driven/messaging based/async microservices,而不是synchronous restful microservices https://solace.com/blog/experience-awesomeness-event-driven-microservices/ https://solace.com/blog/achieving-microservices-flexibility-patterns/ 我觉得有点牵强,大家能不能看看,有没有可取的地方

Jack

架构师之路说“服务读写分离架构,绝不推荐” https://blog.csdn.net/z50L2O08e2u4afToR9A/article/details/78841727

solace 说:“What you do sacrifce with CQRS(读写分离) is consistency, but you enhance both performance and availability and, as mentioned earlier, embracing eventual consistency alleviates this concern for most use cases.”

Martin fowler 都说用cqrs要小心,一般都效果不好: https://martinfowler.com/bliki/CQRS.html

Such

https://juejin.im/post/5da2f8fee51d457849547305 golang的interface实现的理解

Tian

补充一下背景知识,并发模型大比拼

  • threading/multiprocessing, lock-based concurrency
    • protecting critical section vs. performance
  • Communicating Sequential Processes (CSP)
    • Golang or Clojure’s core.async.
    • process/thread passes data through channels.
  • Actor Model (AM): Elixir, Erlang, Scala
    • asynchronous by nature, and have location transparency that spans runtimes and machines - if you have a reference (Akka) or PID (Erlang) of an actor, you can message it.
    • powerful fault tolerance by organizing actors into a supervision hierarchy, and you can handle failures at its exact level of hierarchy.
  • Software Transactional Memory (STM): Clojure, Haskell
    • like MVCC: commit / abort / retry
  • Single threaded - Callbacks, Promises, Observables and async/await: JS

event driven/messaging based/async microservices vs. sync restful microservices 这个我觉得还是以业务需求为主要的决定因素,比如用户注册时的 fraud detection 必须实时做决定这个请求要不要block,必须是 sync 的;银行的支付系统就是特别的慢,十几秒用户等不起,那么只能够做成 async 的;大企业构架很混乱,为了解耦加入一个 message queue,把很多 n^2 的关系复杂度变成 1

CQRS 出现的主要原因是写比读成本高而且互联网服务的读写比大概 200:1,而我们想要优化吞吐量。具体实现上是做在服务层还是数据层要看情况。我在 Uber 见到的奇葩的情况:数据层主从数据库读写分离,上游是一个 monolithic API 层,再往上是一个超大的 Cache 层,再往上是 realtime api 层。

Facebook TAO 在我看来本质上也是读写分离,而这个分离跨越了主从 cache,数据库,还有跨区域的数据中心

所以说读写分离在数据层还是服务层做不是一个值得讨论的问题,因为数据也是一种服务,服务于具体的需求

Jack

https://www.oreilly.com/library/view/microservices-for-java/9781492038290/ch04.html

“Real applications could have dozens or even hundreds of microservices. A simple process like buying a book from an online store like Amazon can cause a client (your web browser or your mobile app) to use several other microservices. A client that has direct access to the microservice would have to locate and invoke them and handle any failures they caused itself. So, usually a better approach is to hide those services behind a new service layer. This aggregator service layer is known as an API gateway.”

"Apache Camel is an open source integration framework that is well suited to implementing API gateways. "

Adrianliu & 周宇超 & 低调 & Kai: idempotent key 在服务端还是客户端产生

请教个问题:如果想让整个 system idempotent, 比如payment system 防止duplicate pay, 一般来说是在client 发送请求时生成一个UUID 发给server,还是让server 去产生一个UUID给client,然后client 再发送request?

这个是2 phase commit吧?

不是。我的问题是防止客户端retry 导致duplicated request

我知道是防止duplicate这种事要从全局去避免。但是我现在主要在纠结客户端的duplicate request 那种情况

payment系统一般比这复杂,我明白你意思了,你相当于用UUID作为token唯一识别一次transaction

嗯嗯嗯对的对的

我们组之前做过类似的,是在server生成UUID

这样的弊端是不是多了一个round trip ,客户端拿到UUID,然后再发送真正的请求

感觉都可行,是取舍的问题,客户端生成UUID有什么弊端?不安全吗?

没想明白暂时。。

https://medium.com/airbnb-engineering/avoiding-double-payments-in-a-distributed-payments-system-2981f6b070bb

这篇我看了,感觉他说就是用一个library啥的

这篇文章还是没说那个idempotency key 哪里产生的

payment还是看uber的吧,气床毕竟不算高并发

这个重要么?如果数据库已经有了这个key就插不进去,如果没有那么就意味着可以

重不重要我不知道,只是想知道哪种比较好

嗯嗯那个看了。有个疑问,如果第三方Payment provider 失败了,这个时候我们把这个record 放到retry queue去,这样还能保证同一个user的多个request的order吗

Uber那个缺了个对账环节,就是有可能银行那边数据和uber这边数据不一致

怎么讲?每天对一次账这样么

自己根据数据量来定对账频率

cron job?

这个需要银行那边对完帐再发给我们系统,然后我们来对吧。

所以得依赖第三方的频率

这里是跟PSP对账还是银行?

总结:idempotent key 在服务端产生的好处是比较安全,坏处是多了一个 round trip; 因为格式是固定的,还可能是随机的,比如 UUID,那么客户端产生也可以,但是要注意检查这个 idempotent key 与 order ID 的联系,确保客户端不能够用之前已经成功的 order 支付的 idempotent key 算做最新的 order 的支付

王博睿: grpc + kinesis

请假大家一下。我如果想搭一个grpc和aws kinesis的服务,整个构架应该怎么弄呢?

整个服务很简单,只需要用户通过grpc的服务来访问读取kinesis的数据就好了

双双:请问下大家如何模拟分布式系统三个服务器统计一本书的字频,需要实现选举。慕清、大小说家、Elias、低调、=.=

想到了当年的 master slave, map reduce

我觉得主要还是解决一致性问题,可以通过paxos协议实现,保证选举。或者最近我有看区块链技术,也可以通过区块链的共识算法实现选举,这个是我个人想法。

插科打诨:一本书哪需要三台服务器😝

我们这个是作业,老师就让模拟下,说可以用paxos

可以考虑一下bully算法,实现简单,节点数少的时候还不错

这个群藏龙卧虎啊,感谢大家,我都看看[Whimper]

请问下大家实现整个系统的流程嘛,刚开始接触分布式系统,完全小白[Whimper]

主要是老师说要先选出leader,把任务分成一堆chunk,cluster里的各个server要处理不同的chunk,最后再汇总到leader那里,再传给client。这个过程我感觉就是MapReduce的过程。除了选leader和paxos一样。所以我不太清楚要在那里使用zookeeper。希望大佬们可以帮忙解惑一下

zookeeper就是用来解决选举的,如果使用paxos了 就不用管了

没要求用什么方法,就说要实现这个功能,举了个例子说paxos

还可以用pseudo random

区块链流行 PBFT, 我们公司在实现的时候用的 libp2p + PBFT

System Security: Natee

请问下,这个是要什么回答?

engineering security education (e.g. owasp top 10) + code review + product security review + bug bounty

@Natee 碰巧遇到一个答案 https://mp.weixin.qq.com/s/DtGLFwcwNMCZseOKOAOC9Q

历史记录

系统设计与架构

Windson: @Super🍋Ariel 你可以看看你截图的文章里面的链接,其中 x1e.32xlarge 内存为 4t,不过按照表格来看,应该是 32个 x1e.xlarge 组成的集群。

Windson: 什么文章

metacpp: @Windson Pramp里面的面试官都什么背景啊

TianPan.co: 为什么大家会这么在意 mock?

A: 用缓存怎么保证高并发呢?

车少: 该怎么理解你这个问题。

A: 用缓存的作用是什么呢?

车少: 快速检索数据。

车少: 快速读取。

A: 可以用来高并发吗?

车少: 你这样子问感觉是在问,A是解决某问题的银弹吗?

A: 我是看了个材料说也可以保证高并发

A: 我没想明白他的说法

TianPan.co: @A https://tianpan.co/notes/122-key-value-cache

A: 谢谢

TianPan.co: @丹尼 @Windson 还有 skiplist, merkle tree, cuckoo hashing, snappy/lzss

TianPan.co: LevelDB, Redis sorted set, Lucene

ReBlueD: Leveldb rocksdb 好像都用到了skiplist

丹尼: Leetcode有一道实现跳表(skiplist)的题目

https://leetcode.com/problems/design-skiplist/

懒懒的低调: 会员有啥区别

丹尼: 真牛

ReBlueD: 没有采用树结构

丹尼: 嗯,morning paper我也跟了。只是经常看不懂,就放弃了

ReBlueD: 结合mvcc,并发就能提供起来了

丹尼:

Windson: [Smart]

metacpp: https://blog.acolyer.org/

Wei Liao 🏠Realtor®🏡: 用private mode 可以随便看

ReBlueD: 标题很虎,内容真不错

ReBlueD: sstable

ReBlueD: 反向索引不到可能存在传统R DBMS的

ReBlueD: [ThumbsUp]

Windson: [Smart][Smart]

Such: memtable

ReBlueD: 有没有更好的数据结构?

不靠谱: 学习是因为工作用到还是面试

Windson: [Scowl],我先看看资料,之前我只知道 redis 在用

八意: 问个问题 inverted index一般是只放在内存 还是disk也要存一份?是存在file里还是db?

ReBlueD: 持久化的是SS table

ReBlueD:

Windson: 谢谢,我只有一两个,让我用几天时间整理再分享出来[Smart]

赞机器人

metacpp: 推荐个公众号

metacpp: 质量很高

Christiano Cai: 这个公众号貌似微信官方推荐过

Christiano Cai: 在我feed流里看到过

丹尼: [ThumbsUp][ThumbsUp] 扫一下,文章目录。60多篇,蛮多关于networking和golang实现的分析。挺hardcore的

TianPan.co: https://docs.google.com/spreadsheets/d/11Rjv-SVXj4DN9l2qTZzM-oirMMK9wXTjbS8GFzBmR0s/edit#gid=2041570299 除了这些,新闻和口头知识我会看 Twitter 加王兴的饭否(为了王兴买了一个饭否号),中期知识订阅hbr/wired/economists,长期知识就是拆书,既有kindle,又有得到和blinkist,补充以公众号和知乎的搜索

谷哒兔: [ThumbsUp][ThumbsUp][ThumbsUp]

TianPan.co: 职业知识靠 pluralsight

丹尼:

丹尼: 讨论一下第四题。关于hashmap的逻辑结构,在想是什么样的。key是国家名,value是经纬度的range。这样理解合不合理?

Triose: map[N][M]=C可不可行?N经度、M纬度、C国家编号。就是得先看一下地图是啥方式给出来的[Facepalm]这样查询是O(1) 占内存好像也不大

丹尼: 所整个地球的经纬度全部存起来?这个量太大了,不ineffcient吧。

1点50分: 像不像数据库那种 B tree之类

Triose: 或者可以离散化然后用ST表之类的

丹尼: 嗯,每个国家的边界都是一个不规则多边形。

如果弄个0-1的2D matrix, 纵横坐标对应着经纬度。所以每个国家的01矩阵都是一个sparse matrix

TianPan.co: 内存不够的话,像是bitcask 那样 key 在内存里,value 在外存里面

柚: 现在ok了

Windson: 感觉 geohash 算法应该也适用

Windson: @丹尼 你可以详细说下你的实现方法吗?

Windson: 我的想法是:

初始化:

  1. 使用 geohash(或者 S2) 算法把全球分成不同的小块
  2. 建立哈希表 H,记录每个小块里面对应的国家列表

查找 A 地点:

  1. 找到 A 地点对应的小块
  2. 根据哈希表 H,找到可能的国家列表 C
  3. 轮询 C 的经纬度范围来判断具体是哪一个国家

慕清: 老板 你们聊得

慕清: 都好厉害

熊: 请问上面那个题是哪个公司的面经?

丹尼: @Windson 我没有清楚的想法。

不过,感觉应该是geohash

  1. geohash有一个前缀关系: 9vgx代表的区域会包括9vgxa代表的区域。

  2. 一个国家应该可以表示成一个geohash list。 e.g, country1: [9vgx, 9vbxe, 9vcedf, …]

  3. 然后,我们有一个点(latitude, longitude)。 可以把它转化成geohash,比如说9vcedfge

丹尼: 4. 一个简单办法是:把第二步的所有geohash建成一个trie tree。

丹尼: 5. 查询时,按第三步的geohash来做一个trie的lookup

丹尼: 这个workflow,大家觉得make sense吗

Windson: 你的第二步有什么用

Windson: 建立国家对应geohash的列表,之后哪里用到?

丹尼: 是为了准确表达一个国家的边界。

一个国家是复杂的多边形。所以geohash的list中有的块很大,有的块很小。

丹尼: step4需要step2来建一个trie

丹尼: trie的叶结点为country id

丹尼: 每一条从root到叶结点的path, 串起来为一个geohash

Windson: 但是一个geohash可能对应多个国家啊

丹尼: 是的,那样的话,这个geohash就要zoom in。

这也就是为什么我说“一个国家是复杂的多边形。所以geohash的list中有的块很大,有的块很小。”

Windson: 你参考下我的解法

丹尼: “1. 找到 A 地点对应的小块”

丹尼: “ 2. 根据哈希表 H,找到可能的国家列表 C”

丹尼: 如何保证A对于的小块,在Hashmap中key存在?

Windson: 建立hashmap的时候以小块为键,国家列表为值。如果不存在代表 A 对应的小块没有国家

丹尼: A地点,是一个经纬度坐标,你如何知道它对应的小块呢?

比如: vg55x4

是不是先判断, hashmap里有没有vg55x4。 如果没有,就再试vg55x。然后再试vg55x?

dreamy: 我想到一个简单方法,不知道行不行。 世界上也就200多个国家,实现用多边形把国家表示起来,然后便利一下是否在这个国家呢。准确率取决于多边形的边数

丹尼: 我的算法,还处于rectangle的水平。

求问:如何判断一个点是否处于某个不规则的多边形中?

周宇超: 好像leetcode有一道类似的算法题?

dreamy: 「丹尼:我的算法,还处于rectangle的水平。

求问:如何判断一个点是否处于某个不规则的多边形中?」


这个是数学问题,了解一下就不难

Windson: @丹尼 你可以看看geohash的具体实现

周宇超: https://leetcode.com/problems/erect-the-fence/

丹尼: @周宇超 多谢。我还以为是说 https://leetcode.com/problems/minimum-score-triangulation-of-polygon/description/

丹尼: @Windson k

丹尼: 嗯,是个凸包 问题。 还有三种解法。厉害。

Windson: 在一开始划分geohash的时候你已经确定好精度了,例如6位的长度。之后把 A 地点按照这个精度转换就可以了。

周宇超: 如果是算法,遇上也算倒霉。。

丹尼: @Windson , 所以你在计算国家边界时, geohash的精度都是固定长度的?

丹尼: “轮询 C 的经纬度范围来判断具体是哪一个国家”。 所以,在完成这一步时,光那个hashmap还是不够的。还需要辅助结构来回答这个问题?

Windson: 固定长度

丹尼: 嗯,如何回答最后一步: “轮询 C 的经纬度范围来判断具体是哪一个国家”

Windson: 另外一个哈希表对应了国家以及其经纬度范围,轮询并判断点 A 是否在范围内。如果在多个国家范围内的话,返回国家的经度总距离或维度总距离最短的国家。

丹尼: 嗯,再有一个辅助数据结构,是可以解决这个问题

Windson: 应该还有很多方法的

Windson: @dreamy 具体怎么用多边形来表示国家?

dreamy: 国家的边界中,采样一定数量的点,构成了凹多边形,这一步是预先构建的

dreamy: 然后对于任意一个点,采用上面leetcode中的算法就可以知道是否在多边形内

dreamy: 如果要更精细的位置,我觉得可以分层吧,先决定在那个洲(亚洲还是欧洲),然后那个国家,然后那个省份。。。。。。

Windson: 遍历所有国家的多边形?

dreamy: 恩,应该可以二分,但我没想到。但国家数量也不多,遍历问题也不大

Windson: 但是可能以后需要判断在哪个城市内

dreamy: 对啊,我上面说的就是这个,不断递归就行了

dreamy: 国家->省->市->乡镇 只要有边界就行

dreamy: 如果要知道这块是什么建筑,什么餐馆名字,就需要附近的xx算法了

A: 这个不是主要handle 边界问题吗?

熊: 大家平时在设计系统的时候估算QPS,还有用户量,DAU什么的有什么规律吗?

熊: 还是凭经验来的数字

luke: 想起了一句话,闭眼随手几个0是个缘

熊: 哈哈哈哈

熊: 我看grokking里基本就那么几个数字

熊: 500M,300M什么的

熊: 但我在想这种估算有什么依据么

luke: 面试的话,不是跟面试官商量这来嘛,如果平时,不就是试着来嘛,没有perfect solution。

luke: 很想知道有经验的大佬都怎么玩味这些个数字的

焦加麟: Grokking system design这个课程质量不太高

焦加麟: 比较拼凑

richard: 同意 但是又不知道哪里有更好的

丹尼: 目测,现在的system design已经分划成四大类了。

Grokking system design只能算是一个fundanmental的intro

丹尼: 1. Detail的OOD design. 定义一些和实现面向对象的函数和接口。例如parking lot, elevator design

丹尼: 2. General system design 重要是conversational discussion。全程会被面试官不断打扰。至于最终是否会有design的结果不重要。 例如, design twitter, design dropbox

丹尼: 3. Design technical component 比较hardcore的,偏domain的system design. 例如,实现一个message queue, distributed web crawler

丹尼: 4. Product design 主要是design产品的功能,use case和trade-off 感觉UX/PM面得多一点

欢迎讨论

richard: 有道理 grokking 最多算个入门

熊: 感觉这种面试new grad没啥经验也只能照猫画虎了

熊: 不像刷题

熊: slides吗

luke: 不是 就是视频[Facepalm]

熊: wow

熊: 我去找找

Liang: yunpanjingling

Liang: 云盘精灵上搜 有不少

Liang: 谁有九章 AWS的视频?

熊: 话说大家觉得grokking比较欠缺的是什么

熊: 深度吗

熊: new grad表示只看过grokking和一些零星的材料

熊: 感觉总是摸不到门路

Paradox-JSA: 我个人觉得grokking讲的各个题目还是较全面的了。具体的知识块也都连接到wikipedia上了。是个不错的入门

熊: 还有一个我觉得grokking里面有点模糊的地方是对于每个数据字段占用空间的估计

熊: 感觉似乎也应该有点规律但目前还没摸到。。

Paradox-JSA: back of envelope计算本来就蛮tricky的,估算的言之有理就行了我觉得。我也还在摸索。。。

熊: 因为我感觉算来算去最后都是为了证明单机能handle or 单机不能handle

熊: 一般持久存储的话单机肯定都是不能handle。。

熊: 我感觉grokking还有一个我没太get到的地方是他每个文章的结构都不太consistent。。。全部看完了也get不到一个总体的套路

熊: 比如有的说了sharding有的就没说

不靠谱: 每篇都是各种材料拼凑吧

车少: system design面试时应该先说什么再说什么。

luke: scenario,service,storage,Scalability

车少: Data model放在哪里说呢

熊: 感觉是scenario和service之间?

熊: 按照grokking的套路来讲。。

车少: 画图在什么时候画呢

车少: Api呢

熊: service?

熊: 应该有一步是high level design吧

车少: 嗯

熊: 我其实之前在想一个问题是面试的时候是不是应该先画一个特别简单的,然后慢慢擦掉往里面加东西

熊: 还是一开始就把空都留好了。。

TianPan.co: 四步搞定,看看这篇吧 https://tianpan.co/notes/2016-02-13-crack-the-system-design-interview

熊: [ThumbsUp]

熊: 所以群主是推荐把back of envelope calculation放在最后一步?

TianPan.co: 当然了,结构不清楚,流量怎么拆不清楚,没法列出估算的式子或函数

熊: 嗯

1点50分: 可是如果放最后算的话,怎么选架构呢?

TianPan.co: 本来前面讨论的时候的目的也不是只挑一个构架,而是把所有可以的和它的 tradeoff 都展示出来

1点50分: 我意思是 不知道大概数据 可能在用单体还是分布式都是个问题

TianPan.co: 同意,所以在设计的时候,单体和分布式能够讲都要提出来

TianPan.co: 我给你举个例子,Uber 因为是 microservice 的环境,所以会着重考察分布式;robinhood 和 tesla 是单裤,所以会着重数据库表级别的设计

TianPan.co: 但是你作为面试者,两种情况在一开始设计的时候都要提出来

TianPan.co: scale 上在 requirements 里做出 assumption 和最后估算是两件不同的事情

周宇超: 怪不得robinhood挂那么久

TianPan.co: 是的,我有朋友面,她的主要的 takeaway 就是这个,scale不同,assumption不同,不能用面uber的方式面robinhood

TianPan.co: 与之不同的是,back on envelop 估算的主要目的是为了做 capacity planning,跟预算和配置机器的量有关;跟构架的技术选型关系反而更小

TianPan.co: 因为 capacity planning 在这个阶段没有那么重要,所以 back on envelop 估算在四步里面的重要性最底,在大多数情况下是可以不用讲的

熊: 原来是这样

熊: grokking里基本都放在很前面了倒是

焦加麟: Grokking就是一个模板 套路

焦加麟: 建议大家看designing data intensive application

1点50分: 所以前面其实是根据产品做估计,需要说明用几台机器的时候 再具体算

1点50分: 这才符合我们平时工作的流程

Paradox-JSA: designing data intensive application是一本好书,但是太厚了

Super🍋Ariel: 请问一下大家在设计email service的时候怎么能确认user收到了email?

熊: 回执?

丹尼: a给b发email,然后

丹尼: a想知道b是否收到email?

1点50分: 这个没有reliable way

1点50分: 几年前考过一次。就是在email里面嵌入一个小的透明image

1点50分: 当client 打开时 发request back to server

Kirk张: 假如由于网络问题 收不到回执呢?怎么办?

Super🍋Ariel: 如果有很大的volume呢? 用queue嘛?

1点50分: 这就是说为什么没有reliable way的原因

1点50分: 很大volume 有双11那么大吗

懒懒的低调: 美国handle不了双11[旺柴]

Super🍋Ariel: 没有双十一那么大,就正常like amazon 发邮件

Windson: @Super🍋Ariel 发送成功与用户有没有打开是两种不一样的场景。

Super🍋Ariel: 愿闻其详, 用户打开这个use case感觉比较像snap

丹尼: 最近有两个面试,专门有一轮叫concurrent programming。我正在恶补一下相关的知识。

针对这一轮,大家脑中闪过的常见问题是啥?

(目前我见得比较多的就是:dining philosophers和delayed queue)

TianPan.co: bounded blocking queue

丹尼: 嗯,这个我也见过。anything more?

周宇超: delayed queue是linkedin面经

周宇超: blocking queue也是经典题

周宇超: 爬虫可以引申到producer consumer

丹尼: 还能想到其它的吗

周宇超: 好像不多了

熊: 哇居然还有这种面试

熊: 第一次听说。。

周宇超: linkedin system和dropbox会问

熊: soga

懒懒的低调: 丢盒子多线程考的蛮多

周宇超: dead lock应该也算一个考点

丹尼: purestorage也会问

熊: 这样

八意: delayed queue这道题有什么好的资料参考吗

懒懒的低调: 。。。java doc

懒懒的低调: 官方就有实现

丹尼: 是的,看源码

我的体会是:高档,看源码;低档,看medium

丹尼: 高档,看源码;低档,看文章

八意: 噢 我是说按linkedin的高频system design,delayed task scheduler

八意: 跟delayed queue 可能还是有些不一样

Wei Liao 🏠Realtor®🏡: 是distribute delayed queue 是吧

Wei Liao 🏠Realtor®🏡: 不是单机

Windson: @Super🍋Ariel 其实网上都有很多资料,如果是确定发送成功的话可以通过,1. 使用的库的自带异常处理,例如Python自带库如果发送失败会返回异常,2. 邮箱服务器的日志。

Windson: 大家有在GitHub看到整理数学基础知识的仓库吗?我在做一个但是担心早已经有了。

Natee: 看到过

Natee: 很早就有了

Windson: 有链接吗

车少: 你想找一个没人做过的方向。只能是超级难的。。

Windson: 那我只能做得比他们好[Smart]

luke: 这样一个库的意义是什么呢,scope是什么,要解决什么问题[Scowl]

TianPan.co: 直接看 1brown3blue 的教学视频

Windson: 其实是类似 math-cheat-sheet 以及常用算法例如 gcd 和牛顿法。等我整理完分享给各位[Smart]

TianPan.co: Math for hackers?

luke: scope开始清晰了

Windson: 之前hackernews 有个很高upvote的math-cheat-sheet的电子书,不过涉及太广,所以我打算结合mathematics for computer science 这本书抽出一些程序员常用的数学部分。

TianPan.co: 赞👍 如果内容质量高,可以上架 tianpan.co 或者 硅谷io,卖出去的收入归你

Windson: 谢谢,我完成了一部分了,不过应该是非盈利的[旺柴]

丹尼: windson,放github?

Windson: 对啊,大家一起贡献嘛。

TianPan.co: 硅谷io支持 latex ,github 不支持 latex

丹尼: [ThumbsUp]

谨言慎行: [ThumbsUp][ThumbsUp]

Yep: 大家好,很高兴加入,本人略小白,所以就先虚心求教学习。目前我们公司会计对账的数据需要本人提供,因为我们电商销售渠道有点多,每个渠道拉出来的excel信息不完全对称,还有的事人工输入销售数据到销售report中去,对账非常麻烦,想要管理上自动化,所以有想要设计个系统,因为这方面接触不多,就想请问需要学习以及注意些什么问题,谢谢🙏

车少: 强撸即可

Yep: 大致意思是?

Windson: 如果是自己做的话学习python自动化即可

Yep: [ThumbsUp]了解了,多谢

Windson:

Windson: 如果只是简单的数据处理,可以看看这本书,

懒懒的低调: 语言重要么😂为啥必须python

1点50分: 语言重要么😂为啥必须python

Windson: 没有必须 只是建议

Yep: 哈哈谢谢各位,我回去研究一下先😄

车少: 库多

车少: 库多就能任性。。

🎃炫酷的大高个🎃: 在做一个跨语言的通用框架,java可以实体驼峰法映射数据库下划线法;但是php不行(用的tp),弄了一圈,最后把数据库直接字段一键全部下划线改成驼峰法了。

🎃炫酷的大高个🎃: 这样咋样

🎃炫酷的大高个🎃: 数据库->语言->接口json->前端语言

🎃炫酷的大高个🎃: 全部统一驼峰法

华哲: 除了自己造轮子,也可以试试用aws 里面的工具。比如呀把数据直接放s3然后athena 拿自己想要啥。你既然已经是excel了说明时间已经相对干净。

我有一个现成的记账系统 http://beancount.io/ 如果你需要的是系统设计, 核心概念是 double-entry bookkeeping https://tianpan.co/notes/167-designing-paypal-money-transfer#features-and-components

Natee: 请教一下大家,我们使用的Elasticsearch,由于数据量太大,出现搜索卡顿情况,所以想通过时间段来做索引,减少索引上的数据量

Natee: 但是如果这样遇到搜索时间包括两个时间段的话,这里的排序翻页应该怎么实现呀

熊: aggregator merge下?

TianPan.co: 赞分享,这么多年过去了,分布式系统还是有很多新东西的 @richard

MIT 6.824: Distributed Systems

https://pdos.csail.mit.edu/6.824/schedule.html

metacpp: 大家会做作业吗?

Yuan: [ThumbsUp]

华哲: 有点意思。[Chuckle]

https://guigu.io/bbs/t/topic/138

TianPan.co: https://guigu.io/bbs/t/topic/135

TianPan.co:

TianPan.co: 答案好像是“是的,是两种不同的概念”

A: 一个是database层面的4种锁,一个是service层面的可重入锁

TianPan.co: 赞

may: 那个tx是什么意思呢?

纳罕: transaction

TianPan.co: 新版的硅谷io加入了 dark mode,小伙伴们可以在黑夜里刷题啦

TianPan.co:

Windson: [Smart][Smart][Smart]

丹尼:

丹尼: 讨论一下,那个文件处理的follow up:文件特别大怎么分布式处理。

metacpp: 啥公司啊

丹尼: 我感觉要点是如何partition数据。单一reader+多worker vs 多reader + 多worker。哪种更好呢?个人感觉是第一种

丹尼: Pinterest

熊: 第一种吧

熊: 感觉就是n行分成一块先内部处理下,再统一处理下分块的边界

熊: 不过感觉处理边界对一些case可能有点tricky

丹尼: 我也是这样想的。讨论下相邻块的merge思路

丹尼: 注:块3可能不光与块2,块4有关系。块3还可能与块1有关系。因为会出现某一列全是|,而且奇长无比

丹尼: 所以每一块结束后要把最后一行的状态回报给总控程序。对吧

丹尼: 同时把这一块第一行待定的问题也回报

A: @丹尼

丹尼: 看上面那个截图哦

A: 是那个graph的follow up?

A: 没看到有单独的一轮design

A: 如果是 graph那个题的follow up的话,按行distribute到不同机器,行之间的edge放到当前机器。

木易: 请教下在线实时表格这种, 是不是直接在redis处理然后同步到DB这种方案比较好, 还是这种有其他的方案. 这种方案难道要把每个表格的数据都缓存起来吗, 比如其实每次编辑其实只是更改了某一个cell的值.

Windson: @木易 多人还是单人编辑?

木易: 多人

Windson: 多个人可以同时操作一个cell?类似 google docs?

木易: 对

木易: 我现在由于用户量不多 直接是操作mysql

木易: 但这个肯定是不行的

Windson: 像Google docs 使用的是 operational transformation 算法来解决并发写的问题。你的情况要根据对实时性的要求来设计。

车少: 来几个灵魂拷问,为什么一定要stateless?为什么一定要把数据放redis?为什么一定要实时写?

车少: 这三条基本上是做app都要遵循的准则,但是真的必须吗?

A: 这个cell的读写可以用push模式同步。redis做缓存。写的顺序需要加入queue或者时间戳决定是不是更新

A: 写到数据库人少的时候ok,耍流氓的话可以现在同时在线编辑同一个文档的人数

木易: 写的顺序没必要在乎 因为毕竟客户端的网络环境都不一致

A: 那如何决定同时写最后保留谁的修改呢?

A: 网络环境不用考虑。只考虑request到service的时间是不是好一些?

木易: 会好一些

木易: response time不一致又会导致差异 这个怎么处理比较好了

A: response不用返回具体数据,只返回是否成功修改。直接让service push给每个client。client端和service端保持长连接

A: response不用返回具体数据,只返回是否成功修改+service第一次收到的时间戳。可以添加一个retry logic+第一次发送到service的时戳。修改内容直接让service push给每个client。client端和service端保持长连接

木易: 比如A 先发送 但是比B晚到达

木易: 用户端会以为B

木易: Thanks各位

Qiang: 请问对于大量并发写的话 有什么的好的解决办法?或者什么的database专门为这个设计的?

车少: 列式数据库库

TianPan.co: 带 LSM tree 的基本上都是为了写做优化的

Qiang: NoSql吗 但是这样一致性是不是无法保证?

车少: Nosql跟一致性会有冲突吗?

懒懒的低调: tidb?

Qiang: 有的NoSQL是最后一致性吧

懒懒的低调: nosql acid够呛

懒懒的低调: 看你用途吧

车少: aciid是acid,一致性是一致性。

懒懒的低调: 金融来说sql是不可避免的

TianPan.co: 我听说 Stripe 跑了世界上最大的 MongoDB 集群,不知道会不会放账本数据

懒懒的低调: stripe是我司竞争对手😂

TianPan.co: 贵司是 Square / Paypal braintree ?

懒懒的低调: stripe是Gateway

懒懒的低调: 后者

懒懒的低调: sq最近股价跌的略惨啊😂

车少: 金融行业需要用到事务,会经常发生执行失败然后回滚事务?

TianPan.co: 大家改一下 姓名-公司或行业-title 吧,显得我们群专业一点,而且找到同道互通有无

周宇超: Mongo集群这个不太靠谱吧

王博睿: “TianPan.co-blockchain-eng: 大家改一下 姓名-公司或行业-title 吧,显得我们群专业一点,而且找到同道互通有无”


可以发个群公告

Paradox-JSA: 支持

慕清: 支持

不靠谱: 支持

姜景康: AWS Lambda的设计惊为天人

姜景康: 小弟看完实在是佩服

TianPan.co: @姜景康 来分享一下感悟吧[Smart]

姜景康: 好的,我计划写一篇文章分享,后续整理给大家

TianPan.co: 赞 👍

周宇超: 有链接吗

Paradox-JSA: 愿闻其详,个人感觉FaaS的执行效率是很大的瓶颈

周宇超: 主要还是太贵了

周宇超: 能用worker pattern都自己host了

York: FaaS跑流量稳定的workload确实非常贵,跑那些胶水脚本或一些流量非常不定的东西还是很便宜的。FaaS是一个很好的辅助,但扛不了大梁。AWS的lambda是我认知里最牛逼的FaaS了,还真的有个朋友他们组的后端全跑在lambda上😓

华哲: amzn内部太多东西跑在lambda上。

华哲: 有这个lambda,除了有持续性大量的请求。基本都能用它。很香啊

叮当锤: Aws lamba 和azure function 有什么不同啊

may: 请问有朋友面过亚麻vo吗

Windson: 朋友上两个月面完

八意: 想问下 fb那道distributed crawl wikipedia的题里强调minimize individual node traffic是想要我们怎么答呢

八意: 不是为了减少network bandwidth吗

姜景康: “may: 请问有朋友面过亚麻vo吗”


我面了AWS的线下onsite,有一些经验或许可以帮到你

A: 流量怎么算?

八意: 是啊 我也只想到了dedeup

Windson: 要考虑是bfs还是dfs还有使用布隆过滤器来防止重复

丹尼: 讨论一下,如何实现社交平台的hashtag feature

丹尼: 我的理解是,冗余存储。弄一个k/v db。key是hashtag,value是tweetid list。

丹尼: 这里就有好几个use case clarification的问题了。

丹尼: 1 hashtag除了cover tweet还要不要cover tweet reply comments。2 一个hashtag显示的entries是不是有个max limit。例如,最多显示1000条。如果可以,就可以把原问题变成了一个相对简单的topk问题

丹尼: 欢迎讨论

Kirk张: 像那种下载百度网盘的工具是怎么实现的呀?需要哪些知识和技术栈和原理?

懒懒的低调: 类似dropbox吧

Kirk张: 很好奇 (不想充钱)

TianPan.co: https://opensource.builders/ 看google drive 那一栏

Windson: 单纯使用哈希表有些问题解决不了,(例如自定义排序,个性化,显示最符合用户的语言),twitter 使用的是自己开发的反向索引系统 Omnisearch,可以看看这里(https://blog.twitter.com/engineering/en_us/topics/infrastructure/2016/omnisearch-index-formats.html)

Windson: @丹尼 . infra . swe

丹尼: 我看看。多谢, windson

Windson: @丹尼 . infra . swe twitter也使用了这个系统进行推文的排序,值得学习的[Smart]

丹尼: 嗯,Internet company有很多工业界的best practice。值得理一理

Windson: 文章里面的图片好像挂了,@丹尼 . infra . swe 可以看到没

Windson: 文章里面的图片好像挂了,@丹尼 . infra . swe 可以看到吗?

丹尼: 刚试过,可以看到图片

Windson: https://blog.twitter.com/engineering/en_us/a/2014/building-a-complete-tweet-index.html

Windson: @丹尼 . infra . swe 这篇与hashtag更接近

1点50分: [ThumbsUp]

谨言慎行: [ThumbsUp][ThumbsUp]

懒懒的低调: 我知道hikari默认是20

TianPan.co: @Windson-Resumejob-Founder 感谢分享,已star

Original Post

If you find this article helpful

follow me on Github :)

Download TianPan.co App

Learn startup engineering anywhere, anytime