questions
如何设计一个高并发系统
- 高并发系统的目的是处理网络请求和数据的关系,瓶颈主要在内存,网络IO
如何解决10万非结构化数据查询请求
这个问题要解决的主要是网络IO和非结构化存储的瓶颈问题。
- 首先数据库要支持非结构化的存储比如使用MongoDB的文档存储使用gridFS进行分布式存储
- 然后对于每秒的十万的网络请求,最常见的方法,以及目前的主流方法是拆分微服务,使用负载均衡策略将请求有效分发到不同
- 对于数据的存储和查询,现在主流也是分布式数据库,比如ES和MongoDB,PG的集群都可以创建非结构化数据的索引,在业务逻辑中优化sql查询语句等
- 使用redis做缓存,对于某些大型的非结构化数据,可以使用cdn去存储静态资源
如果是百台以内的机器
Consistency(一致性)、Availability(可用性)、Partition Tolerance(分区容错性)
raft理论
leader选举、日志复制、日志压缩、成员变更
- Leader Selection
Raft使用 (心跳机制)来触发选举。当server节点启动时,初始状态都是 follower。每一个server都有一个定时器,超时时间为 (时间长 度一般为150ms~300ms),如果某server没有超时的情况下收到来自leader或者 candidate的任何RPC,则定时器重启,如果超时,它就开始一次选举。leader给 followers发RPC要么复制日志,要么就是用来告诉followers自己是leader,不用选举的 心跳(告诉followers对状态机应用日志的消息夹杂在心跳中)。如果某个candidate获 得了超过半数节点的选票(自己投了自己),就称为新leader
如果leader节点出现了故障
用raft共识算法来做的
- Log Relocation
leader 在每个 heartbeat 向 follower 发送AppendEntries RPC同步日志,follower如果发现没问题,复制成功后会 给leader一个表示成功的ACK,leader收到超过半数的ACK后应用该日志,返回客户 端执行结果。若 follower 节点宕机、运行缓慢或者丢包,则 leader 节点会不断重试 AppendEntries RPC,直到所有 follower 节点最终都复制所有日志条目。
乐观锁:
每个对象有一个版本号或者时间戳,当对象被修改时,版本号会更新。在提交更新时,检查版本号是否匹配,如果不匹配则说明有冲突发生,需要进行相应的处理。
悲观锁:
在操作对象时,先锁定该对象,其他用户无法修改该对象直到锁被释放。这种方法可以保证同时只有一个用户能够修改对象,但可能会导致并发性能下降。
- 服务注册与发现 consul
- 负载均衡,consul,用wrr算法实现的
- APi网关 gateway
- 熔断器 circuitbreaker
raft算法流程
Raft算法分为两个阶段,首先是选举过程,然后在选举出来的领导人带领进行正常操作,主要用于管理复制日志的一致性算法。
Raft算法三模块:领导人选举、日志复制、安全性。
领导人Leader选举
Raft通过选举一个领导人,然后给予他全部的管理复制日志的责任来实现一致性。
三个角色(任何服务器都可以当三个角色之一):
领导者(leader):处理客户端交互,日志复制等动作,一般一次只有一个领导者
候选者(candidate):候选者就是在选举过程中提名自己的实体,一旦选举成功,则成为领导者
跟随者(follower):类似选民,完全被动的角色,这样的服务器等待被通知投票
理解:当服务启动的时候,所有服务器follower都是初始状态,每个服务器都有一个定时器,超时时间为election timeout(一般为150-300ms),当某个服务器达到超时时间,他就成为了候选者,先给自己投上一票,然后发送消息给其他服务器,当其他服务器超过半数收到了他的消息,相当于获取到了选票,他就成了领导者,而其他服务器全部成了跟随者,这时候领导者就开始根据间隔时间向跟随者发送心跳检测包,证明我还活在,也就是心跳机制,而跟随者每次接受到消息,就初始化自己内部的定时器,当某个服务器定时器达到超时时间,没有收到领导者的消息,那么跟随者会觉得领导者挂了,他就摇身一变称为候选者,开始篡位,重复之前的过程,成为领导者,当他成为领导者之后,当前任领导者就算回来了,也只能变成跟随者。
特殊情况:四个服务器,当其中两个服务器同时达到超时成为候选者,并且每个服务器拿到自己一票,另外一个服务器一票,这时候的机制就是这两个服务器重新定时,先达到超时的服务器成为候选者,并发送通知进一步成为选举者。
日志复制(保证数据一致性)
Leader选出后,就开始接收客户端的请求。Leader把请求作为日志条目(Log entries)加入到它的日志中,然后并行的向其他服务器发起 AppendEntries RPC复制日志条目。当这条日志被复制到大多数服务器上,Leader将这条 日志应用到它的状态机并向客户端返回执行结果。
1)客户端的每一个请求都包含被复制状态机执行的指令。
2)leader把这个指令作为一条新的日志条目添加到日志中,然后并行发起 RPC 给其他的服务器,让他们复制这条 信息。
3)跟随者响应ACK,如果 follower 宕机或者运行缓慢或者丢包,leader会不断的重试,直到所有的 follower 最终都 复制了所有的日志条目。
4)通知所有的Follower提交日志,同时领导人提交这条日志到自己的状态机中,并返回给客户端。
分布式session怎么做的,常用的
java有apach shiro这两个中间件有session管理器,它是配置redis共享缓存的服务器中的,使用的是RedisSessionDAO层。
golang有casbin+redis的共享缓存来实现分布式session管理
身份认证和权限管理
https://zhuanlan.zhihu.com/p/150644469
https://www.cnblogs.com/alisapine/p/15080359.html
分布式事务和分布式锁
分布式锁
通常用于控制多个节点或进程之间对共享资源的并发访问,以避免竞态条件和数据损坏。分布式事务
通常涉及多个事务性操作后的一致性,如数据库更新、消息发布等,需要确保这些操作在分布式系统中以事务的方式执行。
场景问题集合
一个外卖平台上有一个外卖单子,现在有多名骑手想接这一单,如何保证只有一个骑手可以接到单子?
如何把一个文件快速下发到100w个服务器?
给每个组分配不同的IP段,怎么设计一种结构使的快速得知IP是哪个组的?
典型TOPk系列的问题:10亿个数,找出最大的10个。等(10万个数,输出从小到大?有十万个单词,找出重复次数最高十个?)
让你设计一个微信发红包的api,你会怎么设计,不能有人领到的红包里面没钱,红包数值精确到分。
分布式多个机器生成id,如何保证不重复?
扫码登录是如何实现的?
分布式集群中如何保证线程安全?
某网站/app首页每天会从10000个商家里面推荐50个商家置顶,每个商家有一个权值,你如何来推荐?第二天怎么更新推荐的商家?
如何设计一个本地缓存?需要考虑哪些方面?
项目开放性问题
1、找个印象最深的项目说说?(简历中不止一个项目)
2、你项目中遇到的最大的问题是什么?你是怎么解决的?
3、你项目中用到的技术栈是如何学习的?
4、为什么做这个项目,技术选型为什么是这样的?
5、登录怎么做的?单点登录说说你的理解?
6、项目遇到的最大挑战是什么?(类似问题2)
7、说说项目中的闪光点和亮点?
8、项目怎么没有尝试部署上线呢?
9、介绍项目具体做了什么?(项目背景)
10、如果让你对这个项目优化,你会从哪几个点来优化呢?