TCC 分布式事件框架只要感知到了任何一个服务的 Try 逻辑失败了,就会跟各个服务内的 TCC 分布式事件框架举行通讯,然后调用各个服务的 Cancel 逻辑。也就是说,会实行各个服务的第二个 C 阶段, Cancel 阶段。
- 好比,订单的付出状态,先把状态修改为" closed "状态。
- 好比,冻结库存的字段, prepare _ remove _ stock 字段,将冻结的库存 2 清零。
- 好比,预增长积分的字段, prepare _ add _ credit 字段,将预备增长的积分 10 清零。
问:事件管理器宕掉了,怎么办?
做冗余,设置多个事件管理器,一个宕掉了,其他的还可以用。
问:怎么包管分布式体系的幂等性?
状态机制。版本号机制。
Redis
问:Redis 有哪些上风?
问:Redis 的存储布局是怎样的?
key-value 键值对。
问:Redis 支持哪些数据布局?
string(字符串), hash(哈希), list(队列), set(聚集)及 zset(sorted set 有序聚集)。
问:Redis 的数据布局,有哪些应用场景?
- string:简朴地 get / set 缓存。
- hash:可以缓存用户资料。好比下令:hmset user1 name "lin" sex "male" age "25" ,缓存用户 user1 的资料,姓名为 lin ,性别为男,年事 25。
- list:可以做队列。往 list 队列内里 push 数据,然后再 pop 出来。
- zset:可以用来做排行榜。
问:Redis 的数据布局,底层分别是由什么实现的?
- Redis 字符串,却不是 C 语言中的字符串(即以空字符 ’0’ 末端的字符数组),它是本身构建了一种名为 简朴动态字符串(simple dynamic string , SDS)的抽象范例,并将 SDS 作为 Redis 的默认字符串表现。
- Redi List ,底层是 ZipList ,不满意 ZipList 就利用双向链表。ZipList 是为了节省内存而开辟的。和各种语言的数组雷同,它是由一连的内存块构成的,如许一来,由于内存是一连的,就淘汰了许多内存碎片和指针的内存占用,进而节省了内存。
问:Redis 怎么包管可靠性?Redis 的长期化方式有哪些?有哪些优缺点?
一个可靠安全的体系,肯定要思量数据的可靠性,尤其对于内存为主的 Redis ,就要思量一旦服务器挂掉,启动之后,怎样规复数据的题目,也就是说数据怎样长期化的题目。
AOF 就是备份操纵记载。AOF 由于是备份操纵下令,备份快、规复慢。
AOF 的长处:AOF 更好包管数据不会被丢失,最多只丢失一秒内的数据。别的重写操纵包管了数据的有用性,纵然日记文件过大也会举行重写。AOF 的日记文件的记载可读性非常的高。
AOF 的缺点:对于雷同数目的数据集而言, AOF 文件通常要大于 RDB 文件。
RDB 就是备份全部数据,利用了快照。RDB 规复数据比力快。
问:AOF 文件过大,怎么处置惩罚?
会举行 AOF 文件重写。
- 随着 AOF 文件越来越大,内里会有大部门是重复下令大概可以归并的下令。
- 重写的利益:淘汰 AOF 日记尺寸,淘汰内存占用,加速数据库规复时间。
实行一个 AOF 文件重写操纵,重写会创建一个当前 AOF 文件的体积优化版本。
问:讲一下 Redis 的事件。
先以 MULTI 开始一个事件, 然后将多个下令入队到事件中, 末了由 EXEC 下令触发事件, 一并实行事件中的全部下令。假如想放弃这个事件,可以利用 DISCARD 下令。
问:Redis 事件无法回滚,那怎么处置惩罚?
问:怎么设置 Redis 的 key 逾期时间?
key 的的逾期时间通过 EXPIRE key seconds 下令来设置数据的逾期时间。返回 1 表明设置乐成,返回 0 表明 key 不存在大概不能乐成设置逾期时间。
问:Redis 的逾期计谋有哪些?
惰性删除:当读/写一个已经逾期的 key 时,会触发惰性删除计谋,直接删撤除这个逾期 key ,并按照 key 不存在去处置惩罚。惰性删除,对内存不太好,已经逾期的 key 会占用太多的内存。
定期删除:每隔一段时间,就会对 Redis 举行查抄,自动删除一批已逾期的 key。
问:为什么 Redis 不利用定时删除?
定时删除,就是在设置 key 的逾期时间的同时,创建一个定时器,让定时器在逾期时间到临时,立刻实行对 key 的删除操纵。
定时删会占用 CPU ,影响服务器的相应时间和性能。
问:Redis 的内存接纳机制都有哪些?
当前已用内存凌驾 maxmemory 限定时,会触发自动清算计谋,也就是 Redis 的内存接纳计谋。
LRU 、TTL。
noeviction :默认计谋,不会删除任何数据,拒绝全部写入操纵并返回客户端错误信息,此时 Redis 只相应读操纵。
- volatitle - lru :根据 LRU 算法删除设置了超时属性的键,知道腾出充足空间为止。假如没有可删除的键对象,回退到 noeviction 计谋。
- allkeys - lru :根据 LRU 算法删除键,不管数据有没有设置超时属性,直到腾出充足空间为止。
- allkeys - random :随机删除全部键,知道腾出充足空间为止。
- volatitle - random :随机删除逾期键,知道腾出充足空间为止。
- volatitle - ttl :根据键值对象的 ttl 属性,删除近来将要逾期数据。假如没有,回退到 noeviction 计谋。
问:手写一下 LRU 算法。
问:Redis 的搭建有哪些模式?
主从模式、哨兵模式、Cluster(集群)模式。最好是用集群模式。
问:你用过的 Redis 是多主多从的,照旧一主多从的?集群用到了多少节点?用到了多少个哨兵?
集群模式。三主三从。
问:Redis 接纳多主多从的集群模式,各个主节点的数据是否同等?
问:Redis 集群有哪些特性
master 和 slaver。主从复制。读写分离。哨兵模式。
问:Redis 是怎么举行程度扩容的?
问:Redis 集群数据分片的原理是什么?
Redis 数据分片原理是哈希槽(hash slot)。
Redis 集群有 16384 个哈希槽。每一个 Redis 集群中的节点都负担一个哈希槽的子集。
哈希槽让在集群中添加和移除节点非常轻易。比方,假如我想添加一个新节点 D ,我必要从节点 A 、B、C 移动一些哈希槽到节点 D。同样地,假如我想从集群中移除节点 A ,我只必要移动 A 的哈希槽到 B 和 C。当节点 A 酿成空的以后,我就可以从集群中彻底删除它。由于从一个节点向另一个节点移动哈希槽并不必要制止操纵,以是添加和移除节点,大概改背叛点持有的哈希槽百分比,都不必要任何停机时间(downtime)。
问:讲一下同等性 Hash 算法。
同等性 Hash 算法将整个哈希值空间构造成一个假造的圆环, 我们对 key 举行哈希盘算,利用哈希后的效果对 2 ^ 32 取模,hash 环上肯定有一个点与这个整数对应。依此确定此数据在环上的位置,今后位置沿环顺时针“行走”,第一台碰到的服务器就是其应该定位到的服务器。
同等性 Hash 算法对于节点的增减都只需重定位环空间中的一小部门数据,具有较好的容错性和可扩展性。
好比,集群有四个节点 Node A 、B 、C 、D ,增长一台节点 Node X。Node X 的位置在 Node B 到 Node C 直接,那么受到影响的仅仅是 Node B 到 Node X 间的数据,它们要重新落到 Node X 上。
以是同等性哈希算法对于容错性和扩展性有非常好的支持。
问:为什么 Redis Cluster 分片不利用 Redis 同等性 Hash 算法?
同等性哈希算法也有一个严峻的题目,就是数据倾斜。
假如在分片的集群中,节点太少,而且分布不均,同等性哈希算法就会出现部门节点数据太多,部门节点数据太少。也就是说无法控制节点存储数据的分配。
问:集群的拓扑布局有没有相识过?集群是怎么毗连的?
无中央布局。Redis-Cluster 接纳无中央布局,每个节点生存数据和整个集群状态,每个节点都和其他全部节点毗连。
问:讲一下 Redis 主从复制的过程。
从机发送 SYNC(同步)下令,主机吸收后会实行 BGSAVE(异步生存)下令备份数据。
主机备份后,就会向从机发送备份文件。主机之后还会发送缓冲区内的写下令给从机。
当缓冲区下令发送完成后,主机实行一条写下令,就会往从机发送同步写入下令。
问:讲一下 Redis 哨兵机制。
下面是 Redis 官方文档对于哨兵功能的形貌:
- 监控(Monitoring):哨兵会不停地查抄主节点和从节点是否运作正常。
- 主动故障转移(Automatic Failover):当主节点不能正常工作时,哨兵会开始主动故障转移操纵,它会将失效主节点的此中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。
- 设置提供者(Configuration Provider):客户端在初始化时,通过毗连哨兵来获恰当前 Redis 服务的主节点地点。
- 关照(Notification):哨兵可以将故障转移的效果发送给客户端。
问:讲一下布隆过滤器。
布隆过滤器的重要是由一个很长的二进制向量和多少个(k 个)散列映射函数构成。由于每个元数据的存储信息值固定,而且总的二进制向量固定。以是在内存占用和查询时间上都远远凌驾一样平常的算法。固然存在肯定的禁绝确率(可以控制)和不轻易删除样本数据。
布隆过滤器的长处:大批量数据去重,特殊的占用内存。但是用布隆过滤器(Bloom Filter)会非常的省内存。
布隆过滤器的特点:当布隆过滤器说某个值存在时,那大概就不存在,假如说某个值不存在时,那肯定就是不存在了。
布隆过滤器的应用场景:消息推送(不重复推送)。办理缓存穿透的题目。
缓存
问:缓存雪崩是什么?
假如缓存数据设置的逾期时间是雷同的,而且 Redis 恰恰将这部门数据全部删光了。这就会导致在这段时间内,这些缓存同时失效,全部哀求到数据库中。这就是缓存雪崩。
问:怎么办理缓存雪崩?
办理方法:在缓存的时间给逾期时间加上一个随机值,如许就会大幅度的淘汰缓存在同一时间逾期。
问:缓存穿透是什么?
缓存穿透是指查询一个肯定不存在的数据。由于缓存不掷中,而且出于容错思量,假如从数据库查不到数据则不写入缓存,这将导致这个不存在的数据每次哀求都要到数据库去查询,失去了缓存的意义。
问:怎么办理缓存穿透?
问:什么是缓存与数据库双写同等题目?
问:怎样包管缓存与数据库的同等性?
读的时间,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返反响应。
先删除缓存,再更新数据库。
问:为什么是先删除缓存,而不是先更新缓存?
问:先更新数据库,再删除缓存,会有什么题目?
先更新数据库,再删除缓存。大概出现以下环境:
- 假如更新完数据库, Java 服务提交了事件,然后挂掉了,那 Redis 照旧会实行,如许也会不同等。
- 假如更新数据库乐成,删除缓存失败了,那么会导致数据库中是新数据,缓存中是旧数据,数据就出现了不同等。
先删除缓存,再更新数据库。
- 假如删除缓存失败,那就不更新数据库,缓存和数据库的数据都是旧数据,数据是同等的。
- 假如删除缓存乐成,而数据库更新失败了,那么数据库中是旧数据,缓存中是空的,数据不会不同等。由于读的时间缓存没有,以是去读了数据库中的旧数据,然后更新到缓存中。
问:先删除缓存,在写数据库乐成之前,假如有读哀求发生,大概导致旧数据入缓存,引发数据不同等,怎么处置惩罚?
分布式锁
问:Redis 怎样实现分布式锁?
利用 set key value ex nx 下令。
- 当 key 不存在时,将 key 的值设为 value ,返回 1。若给定的 key 已经存在,则 setnx 不做任何动作,返回 0。
- 当 setnx 返回 1 时,表现获取锁,做完操纵以后 del key ,表现开释锁,假如 setnx 返回 0 表现获取锁失败。
具体的下令如下:
示比方下:
问:为什么不先 set nx ,然后再利用 expire 设置超时时间?
我们必要包管 setnx 下令和 expire 下令以原子的方式实行,否则假如客户端实行 setnx 得到锁后,这时客户端宕机了,那么这把锁没有设置逾期时间,导致其他客户端永久无法得到锁了。
问:利用 Redis 分布式锁, key 和 value 分别设置成什么?
value 可以利用 json 格式的字符串,示例:
问:Redis 实现的分布式锁,假如某个体系获取锁后,宕机了怎么办?
体系模块宕机的话,可以通过设置逾期时间(就是设置缓存失效时间)办理。体系宕机时锁壅闭,逾期后锁开释。
问:设置缓存失效时间,那假如前一个线程把这个锁给删除了呢?
问:假如加锁息争锁之间的业务逻辑实行的时间比力长,凌驾了锁逾期的时间,实行完了,又删除了锁,就会把别人的锁给删了。怎么办?
这两个属于锁超时的题目。
可以将锁的 value 设置为 Json 字符串,在此中参加线程的 id 大概哀求的 id ,在删除之前, get 一下这个 key ,判定 key 对应的 value 是不是当火线程的。只有是当火线程获取的锁,当火线程才可以删除。
问:Redis 分布式锁,怎么包管可重入性?
可以将锁的 value 设置为 Json 字符串,在此中参加线程的 id 和 count 变量。
- 当 count 变量的值为 0 时,表现当前分布式锁没有被线程占用。
- 假如 count 变量的值大于 0 ,线程 id 不是当火线程,表现当前分布式锁已经被其他线程占用。
- 假如 count 变量的值大于 0 ,线程 id 是当火线程的 id ,表现当火线程已经拿到了锁,不必壅闭,可以直接重入,并将 count 变量的值加一即可。
这种思绪,实在就是参考了 ReentrantLock 可重入锁的机制。
问:Redis 做分布式锁, Redis 做了主从,假如设置锁之后,主机在传输到从机的时间挂掉了,从机还没有加锁信息,怎样处置惩罚?
可以利用开源框架 Redisson ,接纳了 redLock。
问:讲一下 Redis 的 redLock。
问:Zookeeper 是怎么实现分布式锁的?
分布式锁:基于 Zookeeper 同等性文件体系,实现锁服务。锁服务分为生存独占实时序控制两类。
- 生存独占:将 Zookeeper 上的一个 znode 看作是一把锁,通过 createznode 的方式来实现。全部客户端都去创建 / distribute _ lock 节点,终极乐成创建的谁人客户端也即拥有了这把锁。用完删除本身创建的 distribute _ lock 节点就开释锁。
- 时序控制:基于/ distribute _ lock 锁,全部客户端在它下面创建暂时次序编号目次节点,和选 master 一样,编号最小的得到锁,用完删除,依次方便。
更具体的答复如下:
实在基于 Zookeeper ,就是利用它的暂时有序节点来实现的分布式锁。
原理就是:当某客户端要举行逻辑的加锁时,就在 Zookeeper 上的某个指定节点的目次下,去天生一个唯一的暂时有序节点, 然后判定本身是否是这些有序节点中序号最小的一个,假如是,则算是获取了锁。假如不是,则阐明没有获取到锁,那么就必要在序列中找到比本身小的谁人节点,并对其调用 exist 方法,对其注册变乱监听,当监听到这个节点被删除了,那就再去判定一次本身当初创建的节点是否酿成了序列中最小的。假如是,则获取锁,假如不是,则重复上述步调。
当开释锁的时间,只需将这个暂时节点删除即可。
Zookeeper
问:Zookeeper 的原理是什么?
问:Zookeeper 是怎么包管同等性的?
zab 协议。
zab 协议有两种模式,它们分别是规复模式(选主)和广播模式(同步)。当服务启动大概在向导者瓦解后, zab 就进入了规复模式,当向导者被推举出来,且大多数 server 完成了和 leader 的状态同步以后,规复模式就竣事了。状态同步包管了 leader 和 server 具有雷同的体系状态。
问:Zookeeper 有哪些应用场景?
Zookeeper 可以作为服务和谐的注册中央。还可以做分布式锁(假如没有效太过布式锁就不要说)。
问:Zookeeper 为什么能做注册中央?
Zookeeper 的数据模子是树型布局,由许多数据节点构成, zk 将全量数据存储在内存中,可谓是高性能,而且支持集群,可谓高可用。别的支持变乱监听(watch 下令)。
问:Zookeeper 的节点有哪些范例?有什么区别?
暂时节点,永世节点。更加细分就是暂时有序节点、暂时无序节点、永世有序节点、永世无序节点。
暂时节点:当创建暂时节点的步伐停掉之后,这个暂时节点就会消散,存储的数据也没有了。
问:Zookeeper 做为注册中央,重要存储哪些数据?存储在那里?
IP、端口、另有心跳机制。数据存储在 Zookeeper 的节点上面。
问:心跳机制有什么用?
问:Zookeeper 的广播模式有什么缺陷?
广播风暴。
问:讲一下 Zookeeper 的读写机制。
- Leader 主机负责读和写。
- Follower 负责读,并将写操纵转发给 Leader。Follower 还到场 Leader 推举投票,到场事件哀求 Proposal 投票。
- Observer 充当观察者的脚色。Observer 和 Follower 的唯一区别在于:Observer 不到场任何投票。
问:讲一下 Zookeeper 的推举机制。
Leader 不可用时,会重新推举 Leader。凌驾半数的 Follower 推举投票即可,Observer 不到场投票。
问:你们的 Zookeeper 集群设置了几个节点?
3 个节点。留意:Zookeeper 集群节点,最好是奇数个的。
集群中的 Zookeeper 节点必要凌驾半数,整个集群对外才可用。
这里所谓的整个集群对外才可用,是指整个集群还能选出一个 Leader 来, Zookeeper 默认接纳 quorums 来支持 Leader 的推举。
假如有 2 个 Zookeeper,那么只要有 1 个死了 Zookeeper 就不能用了,由于 1 没有过半,以是 2 个 Zookeeper 的殒命容忍度为 0 ;同理,要是有 3 个 Zookeeper,一个死了,还剩下 2 个正常的,过半了,以是 3 个 Zookeeper 的容忍度为 1 ;同理你多枚举几个:2 -> 0 ; 3 -> 1 ; 4 -> 1 ; 5 -> 2 ; 6 -> 2 会发现一个规律, 2n 和 2n - 1 的容忍度是一样的,都是 n - 1 ,以是为了更加高效,何须增长那一个不须要的 Zookeeper 呢。
问: Zookeeper 的集群节点,假如不是奇数大概会出现什么题目?
大概会出现脑裂。
- 假死:由于心跳超时(网络缘故原由导致的)以为 master 死了,但实在 master 还存在世。
- 脑裂:由于假死会发起新的 master 推举,推举出一个新的 master ,但旧的 master 网络又通了,导致出现了两个 master ,有的客户端毗连到老的 master 有的客户端链接到新的 master。
消息队列
问:为什么利用消息队列?消息队列有什么长处和缺点?Kafka 、ActiveMQ 、RabbitMq 、RocketMQ 都有什么长处和缺点?
消息队列解耦,削峰,限流。
问:怎样包管消息队列的高可用?(多副本)
问:怎样包管消息不被重复消耗?(怎样包管消息消耗的幂等性)
问:怎样包管消息的可靠性传输?(怎样处置惩罚消息丢失的题目)
问:怎样包管消息的次序性?
问:怎样办理消息队列的延时以及逾期失效题目?消息队列满了以后该怎么处置惩罚?有几百万消息连续积存几小时,说说怎么办理?
问:假如让你写一个消息队列,该怎样举行架构计划啊?说一下你的思绪。
Kafka
问:讲一下 Kafka。
Kafka 的简朴明白
问:Kafka 相对其他消息队列,有什么特点?
- 长期化:Kafka 的长期化本领比力好,通过磁盘长期化。而 RabbitMQ 是通过内存长期化的。
- 吞吐量:Rocket 的并发量非常高。
- 消息处置惩罚:RabbitMQ 的消息不支持批量处置惩罚,而 RocketMQ 和 Kafka 支持批量处置惩罚。
- 高可用:RabbitMQ 接纳主从模式。Kafka 也是主从模式,通过 Zookeeper 管理,推举 Leader ,另有 Replication 副本。
- 事件:RocketMQ 支持事件,而 Kafka 和 RabbitMQ 不支持。
问:Kafka 有哪些模式?
分布式的消息体系。
高吞吐量。纵然存储了很多 TB 的消息,它也保持稳固的性能。
数据保存在磁盘上,因此它是长期的。
问:Kafka 为什么处置惩罚速率会很快?kafka 的吞吐量为什么高?
- 零拷贝:Kafka 实现了"零拷贝"原理来快速移动数据,制止了内核之间的切换。
- 消息压缩、分批发送:Kafka 可以将数据记载分批发送,从生产者到文件体系(Kafka 主题日记)到消耗者,可以端到端的检察这些批次的数据。
- 批处置惩罚可以或许举行更有用的数据压缩并淘汰 I / O 耽误。
- 次序读写:Kafka 接纳次序写入磁盘的方式,制止了随机磁盘寻址的浪费。
问:讲一下 Kafka 中的零拷贝。
数据的拷贝从内存拷贝到 kafka 服务历程那块,又拷贝到 socket 缓存那块,整个过程泯灭的时间比力高, kafka 使用了 Linux 的 sendFile 技能(NIO),省去了历程切换和一次数据拷贝,让性能变得更好。
问:Kafka 的偏移量是什么?
消耗者每次消耗数据的时间,消耗者都会记载消耗的物理偏移量(offset)的位置。比及下次消耗时,他会接着前次位置继承消耗
问:Kafka 的生产者,是怎样发送消息的?
- 生产者的消息是先被写入分区中的缓冲区中,然后分批次发送给 Kafka Broker。
- 生产者的消息发送机制,有同步发送和异步发送。
- 同步发送消息都有个题目,那就是同一时间只能有一个消息在发送,这会造成很多消息。
- 无法直接发送,造成消息滞后,无法发挥效益最大化。
- 异步发送消息的同时可以或许对非常环境举行处置惩罚,生产者提供了 Callback 回调。
问:Kafka 生产者发送消息,有哪些分区计谋?
Kafka 的分区计谋指的就是将生产者发送到哪个分区的算法。有次序轮询、随机轮询、key - ordering 计谋。
key - ordering 计谋:Kafka 中每条消息都会有本身的 key ,一旦消息被界说了 Key ,那么你就可以包管同一个 Key 的全部消息都进入到雷同的分区内里,由于每个分区下的消息处置惩罚都是有次序的,故这个计谋被称为按消息键保序计谋。
问:Kafka 为什么要分区?
假设有 6 个 broker ,计划创建一个包罗 10 个分区的 Topic ,复制系数为 3 ,那么 Kafka 就会有 30 个分区副本,它可以被分配给这 6 个 broker ,如许的话,每个 broker 可以有 5 个副本。
要确保每个分区的每个副天职布在差别的 broker 上面:
假设 Leader 分区 0 会在 broker1 上面, Leader 分区 1 会在 broker2 上面, Leder 分区 2 会在 broker3 上面。
接下来会分配跟随者副本。假如分区 0 的第一个 Follower 在 broker2 上面,第二个 Follower 在 broker3 上面。分区 1 的第一个 Follower 在 broker3 上面,第二个 Follower 在 broker4 上面。
问:Kafka 怎样包管消息的次序性?
Kafka 官网中有如许一句" Consumers label themselves with a consumer group name , and each record published to a topic is delivered to one consumer instance within each subscribing consumer group . "
问:Kafka 出现消息积存,有哪些缘故原由?怎么办理?
出现消息积存,大概是由于消耗的速率太慢。
扩容消耗者。之以是消耗耽误大,就是消耗者处置惩罚本领有限,可以增长消耗者的数目。
扩大分区。一个分区只能被消耗者群组中的一个消耗者消耗。消耗者扩大,分区最很多多少随之扩大。
问:Kafka 消息消耗者宕机了,怎么确认有没有收到消息?
ACK 机制,假如吸收方收到消息后,会返回一个确认字符。
问:讲一下 Kafka 的 ACK 机制。
acks 参数指定了要有多少个分区副本吸收消息,生产者才以为消息是写入乐成的。此参数对消息丢失的影响较大。
假如 acks = 0 ,就表现生产者也不知道本身产生的消息是否被服务器吸收了,它才知道它写乐成了。假如发送的途中产生了错误,生产者也不知道,它也比力懵逼,由于没有返回任何消息。这就雷同于 UDP 的运输层协议,只管发,服务器担当不担当它也不关心。
假如 acks = 1 ,只要集群的 Leader 吸收到消息,就会给生产者返回一条消息,告诉它写入乐成。假如发送途中造成了网络非常大概 Leader 还没推举出来等其他环境导致消息写入失败,生产者会受到错误消息,这时间生产者每每会再次重发数据。由于消息的发送也分为 同步 和 异步, Kafka 为了包管消息的高效传输会决定是同步发送照旧异步发送。假如让客户端等候服务器的相应(通过调用 Future 中的 get 方法),显然会增长耽误,假如客户端利用回调,就会办理这个题目。
假如 acks = all ,这种环境下是只有当全部到场复制的节点都收到消息时,生产者才会吸收到一个来自服务器的消息。不外,它的耽误比 acks = 1 时更高,由于我们要等候不但一个服务器节点吸收消息。
问:Kafka 怎样制止消息丢失?
1、生产者丢失消息的环境
生产者(Producer) 调用 send 方法发送消息之后,消息大概由于网络题目并没有发送已往。
以是,我们不能默认在调用 send 方法发送消息之后消息消息发送乐成了。为了确定消息是发送乐成,我们要判定消息发送的效果。
可以接纳为其添加回调函数的情势,获取回调效果。
假如消息发送失败的话,我们查抄失败的缘故原由之后重新发送即可!
可以设置 Producer 的 retries(重试次数)为一个比力公道的值,一样平常是 3 ,但是为了包管消息不丢失的话一样平常会设置比力大一点。
设置完成之后,当出现网络题目之后可以或许主动重试消息发送,制止消息丢失。
2、消耗者丢失消息的环境
当消耗者拉取到了分区的某个消息之后,消耗者会主动提交了 offset。主动提交的话会有一个题目,
试想一下,当消耗者刚拿到这个消息预备举行真正消耗的时间,忽然挂掉了,消息现实上并没有被消耗,但是 offset 却被主动提交了。
手动关闭闭主动提交 offset ,每次在真正消耗完消息之后之后再本身手动提交 offset 。
3 、Kafka 丢失消息
a、如果 leader 副本地点的 broker 忽然挂掉,那么就要从 follower 副本重新选出一个 leader ,但是 leader 的数据另有一些没有被 follower 副本的同步的话,就会造成消息丢失。因此可以设置 ack = all。
b、设置 replication . factor >= 3 。为了包管 leader 副本能有 follower 副本能同步消息,我们一样平常会为 topic 设置 replication . factor >= 3。如许就可以包管每个
分区(partition) 至少有 3 个副本。固然造成了数据冗余,但是带来了数据的安全性。
问:Kafka 怎么包管可靠性?
多副本以及 ISR 机制。
在 Kafka 中重要通过 ISR 机制来包管消息的可靠性。
ISR(in sync replica):是 Kafka 动态维护的一组同步副本,在 ISR 中有成员存活时,只有这个组的成员才可以成为 leader ,内部生存的为每次提交信息时必须同步的副本(acks = all 时),每当 leader 挂掉时,在 ISR 聚集中推举出一个 follower 作为 leader 提供服务,当 ISR 中的副本被以为坏掉的时间,会被踢出 ISR ,当重新跟上 leader 的消息数据时,重新进入 ISR。
问:什么是 HW ?
HW(high watermark):副本的高水印值, replica 中 leader 副本和 follower 副本都会有这个值,通过它可以得知副本中已提交或已备份消息的范围, leader 副本中的 HW ,决定了消耗者能消耗的最新消息能到哪个 offset。
问:什么是 LEO ?
LEO(log end offset):日记末了位移,代表日记文件中下一条待写入消息的 offset ,这个 offset 上现实是没有消息的。不管是 leader 副本照旧 follower 副本,都有这个值。
问:Kafka 怎么包管同等性?(存疑)
同等性界说:若某条消息对 client 可见,那么纵然 Leader 挂了,在新 Leader 上数据依然可以被读到。
HW - HighWaterMark : client 可以从 Leader 读到的最大 msg offset ,即对外可见的最大 offset , HW = max(replica . offset)
对于 Leader 新收到的 msg , client 不能立即消耗, Leader 会等候该消息被全部 ISR 中的 replica 同步后,更新 HW ,此时该消息才气被 client 消耗,如许就包管了假如 Leader fail ,该消息仍旧可以重新推举的 Leader 中获取。
对于来自内部 Broker 的读取哀求,没有 HW 的限定。同时, Follower 也会维护一份本身的 HW , Folloer . HW = min(Leader . HW , Follower . offset).
问:Kafka 怎么处置惩罚重复消息?怎么制止重复消耗?
偏移量 offset :消耗者每次消耗数据的时间,消耗者都会记载消耗的物理偏移量(offset)的位置。比及下次消耗时,他会接着前次位置继承消耗。
一样平常环境下, Kafka 重复消耗都是由于未正常提交 offset 造成的,好比网络非常,消耗者宕机之类的。
利用的是 spring-Kafka ,以是把 Kafka 消耗者的设置 enable.auto. commit 设为 false ,克制 Kafka 主动提交 offset ,从而利用 spring-Kafka 提供的 offset 提交计谋。
sprin-Kafka 中的 offset 提交计谋可以包管一批消息数据没有完成消耗的环境下,也能提交 offset ,从而制止了提交失败而导致永久重复消耗的题目。
问:怎么制止重复消耗?
将消息的唯一标识生存起来,每次消耗时判定是否处置惩罚过即可。
问:怎样包管消息不被重复消耗?(怎样包管消息消耗的幂等性)
怎么包管消息队列消耗的幂等性?实在照旧得联合业务来思索,有几个思绪:
好比你拿个数据要写库,你先根据主键查一下,假如这数据都有了,你就别插入了, update 一下好吧。
好比你是写 Redis ,那没题目了,反正每次都是 set ,自然幂等性。
假如是复杂一点的业务,那么每条消息加一个全局唯一的 id ,雷同订单 id 之类的东西,然后消耗到了之后,先根据这个 id 去好比 Redis 里查一下,之前消耗过吗?
假如没有消耗过,你就处置惩罚,然后这个 id 写 Redis。假如消耗过了,那你就别处置惩罚了,包管别重复处置惩罚雷同的消息即可。
问:Kafka 消息是接纳 pull 模式,照旧 push 模式?
pull 模式。
问:pull 模式和 push 模式,各有哪些特点?
pull 模式,正确性?可以较大包管消耗者能获取到消息。
push 模式,即时性?可以在 broker 获取消息后立刻送达消耗者。
问:Kafka 是怎样存储消息的?
Kafka 利用日记文件的方式来生存生产者和发送者的消息,每条消息都有一个 offset 值来表现它在分区中的偏移量。
Kafka 中存储的一样平常都是海量的消息数据,为了制止日记文件过大,
一个分片并不是直接对应在一个磁盘上的日记文件,而是对应磁盘上的一个目次。
数据存储计划的特点在于以下几点:
问:讲一下 Kafka 集群的 Leader 推举机制。
Kafka 在 Zookeeper 上针对每个 Topic 都维护了一个 ISR(in - sync replica ---已同步的副本)的聚集,聚集的增减 Kafka 都会更新该记载。假如某分区的 Leader 不可用, Kafka 就从 ISR 聚集中选择一个副本作为新的 Leader。
分库分表
问:数据库怎样处置惩罚海量数据?
分库分表,主从架构,读写分离。
问:数据库分库分表,何时分?怎么分?
水中分库/分表,垂直分库/分表。
- 水中分库/表,各个库和表的布局千篇一律。
- 垂直分库/表,各个库和表的布局不一样。
问:读写分离怎么做?
主机负责写,从机负责读。
体系计划
1、分布式、高并发场景
碰到高并发场景,可以利用 Redis 缓存、Redis 限流、MQ 异步、MQ 削峰等。
问:在实践中,碰到过哪些并发的业务场景?
秒杀。好比抢商品,抢红包。
2、秒杀
问:怎样计划一个秒杀/抢券体系?
- 可以通过队列共同异步处置惩罚实现秒杀。
- 利用 redis 的 list ,将商品 push 进队列, pop 出队列。
- 异步操纵不会壅闭,不会斲丧太多时间。
问:怎样进步抢券体系的性能?
- 利用多个 list。
- 利用多线程从队列中拉取数据。
- 集群进步可用性。
- MQ 异步处置惩罚,削峰。
问:秒杀怎么制止少卖或超卖?
redis 是单历程单线程的,操纵具有原子性,不会导致少卖大概超卖。别的,也可以设置一个版本号 version ,乐观锁机制。
问:考勤打卡,如果高峰期有几万人同时打卡,那么怎么应对这种高并发?
利用 Redis 缓存。员工点击签到,可以在缓存中 set 状态。将工号作为 key ,打卡状态作为 value ,打卡乐成为 01 ,未打卡大概打卡失败为 00 ,然后再将数据异步地写入到数据库内里就可以了。
问:怎样应对高峰期的超高并发量?
Redis 限流。Redis 可以用计数器限流。利用 INCR 下令,每次都加一,处置惩罚完业务逻辑就减一。然后设置一个最大值,当到达最大值后就直接返回,不处置惩罚后续的逻辑。
Redis 还可以用令牌桶限流。利用 Redis 队列,每十个数据中 push 一个令牌桶,每个哀求进入后会先从队列中 pop 数据,假如是令牌就可以通行,不是令牌就直接返回。
3、短链接
问:怎样将长链接转换成短链接,并发送短信?
短 URL 从天生到利用分为以下几步:
- 有一个服务,将要发送给你的长 URL 对应到一个短 URL 上.比方 www.baidu.com -> www.t.cn/1。
- 把短 url 拼接到短信等的内容上发送。
- 用户点击短 URL ,欣赏器用 301 / 302 举行重定向,访问到对应的长 URL。
- 展示对应的内容。
问:长链接和短链接怎样相互转换?
思绪是创建一个发号器。每次有一个新的长 URL 进来,我们就增长一。而且将新的数值返回.第一个来的 url 返回"www.x.cn/0",第二个返回"www.x.cn/1".
问:长链接和短链接的对应关系怎样存储?
假如数据量小且 QPS 低,直接利用数据库的自增主键就可以实现。
还可以将近来/最热门的对应关系存储在 K-V 数据库中,如许子可以节流空间的同时,加速相应速率。
体系架构与计划
问:怎样进步体系的并发本领?
- 利用分布式体系。
- 摆设多台服务器,并做负载平衡。
- 利用缓存(Redis)集群。
- 数据库分库分表 + 读写分离。
- 引入消息中心件集群。
问:计划一个红包体系,必要思量哪些题目,怎样办理?(本质上也是秒杀体系)
问:假如让你计划一个消息队列,你会怎么计划?
项目履历及数据量
问:这个项目标亮点、难点在那里?
问:假如这个模块挂掉了怎么办?
问:你们的项目有多少台呆板?
问:你们的项目有多少个实例?
4 个实例。
问:你们的体系 QPS(TPS)是多少?
QPS ,每秒查询量。QPS 为几百/几千,已经算是比力高的了。
TPS ,每秒处置惩罚事件数。TPS 即每秒处置惩罚事件数,包罗:”用户哀求服务器”、”服务器本身的内部处置惩罚”、”服务器返回给用户”,这三个过程,每秒可以或许完成 N 个这三个过程, TPS 也就是 3。
问:一个接口,多少秒相应才正常?
快的话几毫秒。慢的话 1-2 秒。非常环境大概会 10 几秒;最好包管 99 %以上的哀求是正常的。
问:这个接口的哀求时间,大概多久?重要耗时在那里?
问:体系的数据量多少?有没有分库分表?
正常环境下,几百万的数据量没有须要分库分表。只有凌驾几万万才必要分库分表。
问:插入/更新一条数据要多久?更新十万/百万条数据要多久?
插入/更新一条数据一样平常要几毫秒;更新十万条数据最幸亏 10 秒以内;
百万条数据最幸亏 50-100 秒以内。
40张图看懂分布式追踪体系原理及实践
一文读懂Redis常见对象范例的底层数据布局
拜托,口试请不要再问我TCC分布式事件的实现原理!
一口吻说出 9 种分布式 ID 天生方式,口试官有点懵了 返回搜狐,检察更多