关于分布式:深入解读分布式体系的架构设计-超话区块链第84期

大家好!欢送大家报名观看本周四晚8点的精彩直播,直播完结后,还会公布精彩回顾文章,欢送关注! 什么是超话区块链超话区块链是由FISCO BCOS 开源社区推出的每周四晚8点的直播流动,目前超话区块链曾经举办近百场,从技术研究到产业利用均有触达,每期咱们都会邀请一位生态搭档,他们可能是技术极客也可能是利用先锋,到直播现场和咱们分享。也欢送大家自荐或举荐敌人作客直播间。 6月24日直播预报本期6月24日咱们邀请到的是柏链教育CTO李骜华和大家分享分布式体系中的架构设计,欢送大家报名,观看精彩直播!

June 22, 2021 · 1 min · jiezi

关于分布式:共识算法Paxos-算法

1. 目录[TOC] 2. 共识问题 1什么是共识问题?粗略地说,该问题是在一个或多个过程提议了一个值该当是什么后,使过程对这个值达成统一协定。解决什么问题? 在一个计算机提议一个动作后,管制引擎的所有计算机要决定“持续”还是“放弃”。在互斥中,过程对哪个过程能够进入临界区达成协定。在选举中,过程对入选过程达成协定。在全排序组播中,过程对消息传递程序达成协定。2.1 一个例子:问题形容 2假如有两支(或多支)军队,他们必须做到同时防御或同时防守,否则就会失败。所有军队组成一个零碎,他们必须独特动作。问题是,如何让他们各自为政? 当初无妨把军队看做”过程“,把防御或防守看做一个变量”口头“。 在单机零碎中,这个问题很容易解决。用一个互斥量就搞定了,相似于多线程。在分布式系统中,这个问题就麻烦啦。假如每个过程都在不同的服务器上,他们就无奈通过共享内存达到同步。如果过程是军队的话,军队之间只能通过通信兵来进行通信(消息传递)。基于消息传递的分布式军队零碎会有这些问题: 如何确定另一支军队是否被干掉?(服务器解体)如何晓得通信兵是否被杀死(音讯失落)或久久未达到其余军队(提早不可预知)?如果马路等通信信道被切断怎么办?(网络宰割)2.2 另一个例子在一个分布式数据库系统中,如果各节点(server,或过程)的初始状态统一,每个节点都执行雷同的操作序列,那么他们最初能失去一个统一的状态。为保障每个节点执行雷同的命令序列,须要在每一条指令上执行一个“一致性算法”以保障每个节点看到的指令统一,是分布式计算中的重要问题。 3. Paxos 的一致性准则 3Safety (坏的事件肯定不会产生) 只有被提议的值才会被抉择;只能有一个值被批准,不能呈现第二个值把第一个笼罩的状况;每个节点只能学习到曾经被批准的值,不能学习没有被批准的值 。Liveness (好的事件最终肯定会产生) 最终会批准某个被提议的值;一个值被批准了,其余过程最终会学习到这个值。Paxos 只保障Safety,而不能保障Liveness。 4. Paxos算法形容4.1 假如 3每个server都能够负责三种角色:提案者(Proposer)、接受者(Acceptor)、学习者(Learner)。提案者负责提出提案(proposal),接受者负责通过提案,而学习者负责更新提案。 每个提案都会被调配一个自然数$n$作为ID,以及一个须要提出的值$v$。 4.2 抉择一个值(Choosing a Value) 3阶段一a. 提案者抉择一个提案(proposal)编号$n$,向接受者多数派组播一个prepare申请。b. 如果一个接受者收到一个prepare申请,并且编号$n$是所有他曾经通过的prepare申请中最大的,那么他会批准这个新的prepare申请,并承诺不会再批准任何比$n$小的prepare申请和accept申请。 阶段二a. 如果提案者收到一个接受者多数派的回应prepare_ok(n,na, va),那么他就选出最大的$n_a$所对应的$v_a$。或者,若所有回应中$v_a$都为空,也就是还没有批准过任何提案,那么就抉择本人的$v$。而后发送accept(n,v)申请。b. 如果一个接受者收到一个 accept(n,v) 申请,并且$n$大于所有它 prepare 过的$n_p$,那么他就承受这个$v$,而后回复 accept_ok(n)。 4.3 学习一个值(Learning a Chosen Value)当一个提案被多数派通过,这提案者就向所有人(servers)发送decided(v),贯彻与落实这个$v$。 4.4 Paxos伪代码4# Proposerproposer(v): while not decided: n = heigher(N[:]) # 尝试调配一个以后最大的n值给这个proposal send prepare(n) # 向所有acceptor发送prepare request # 若大部分返回ok: if prepare_ok(n, na, va) from majority: # 从{na...}中选出最大的那个和对应的va,令v=va;否则,就选本人的v v = va with heighest na; otherwise choose its own v send accept(n, v) to all # 向所有acceptor发送accept request if accept_ok(n) from majority: send decided(v) to all # 决定v并告诉所有成员# Acceptoracceptor state on each node (persistent): np # 最大的promise值 na, va # 最大的accepted值 prepare(n) handler: if n > np: n = np send prepare_ok(n) # 承诺不再承受任何比 n 小的proposal else: send prepare_reject accept(n, v) handler: if n >= np: na = n va = v send accept_ok(n) else: send accept_reject直观了解 ...

June 12, 2021 · 1 min · jiezi

关于分布式:带你认识大模型训练关键算法分布式训练Allreduce算法

摘要:当初的模型以及其参数更加简单,仅仅一两张的卡曾经无奈满足现如今训练规模的要求,分布式训练应运而生。本文分享自华为云社区《分布式训练Allreduce算法》,原文作者:我抽签必中。 当初的模型以及其参数更加简单,仅仅一两张的卡曾经无奈满足现如今训练规模的要求,分布式训练应运而生。 分布式训练是怎么的?为什么要应用Allreduce算法?分布式训练又是如何进行通信的?本文就带你理解大模型训练所必须的分布式训练Allreduce算法。 通信概念咱们了解计算机的算法都是基于一个一个函数操作组合在一起失去的,那么咱们在解说分布式算法之前,咱们必须先理解一下组成这种算法所利用于硬件的函数操作——汇合通信的基本概念, Broadcast(播送):将根服务器(Root Rank)上的数据散发播送给所有其余服务器(Rank) 如图所示,当一台服务器计算实现了本人局部的参数数据,在分布式训练中想要把本人这部分数据同时发送给其余所有服务器,那么这种操作形式就叫做播送(broadcast)。 Scatter(散射):将根服务器上的数据散射为等同大小的数据块,每一个其余服务器失去一个数据块 如图所示,当一台服务器计算实现本人局部的参数数据,然而因为有时候服务器上全副的参数数据过大,于是咱们想要把这台服务器上的数据切分成几个等同大小的数据块(buffer),再依照序列(rank index)向其余服务器发送其中的一个数据块,这就叫做散射(Scatter)。 Gather(汇集):将其余服务器上的数据块间接拼接到一起,根服务器(Root Rank)获取这些数据 如图所示,当服务器都做了散射之后,每个服务器取得了其余服务器的一个数据块,咱们将一台服务器取得的数据块拼接在一起的操作就叫做汇集(Gather)。 AllGather(全汇集):所有的服务器都做上述Gather的操作,于是所有服务器都取得了全副服务器上的数据 如图所示,所有的服务器都将本人收到的数据块拼接在一起(都做汇集的操作),那么就是全汇集(AllGather)。 Reduce(规约):对所有服务器上的数据做一个规约操作(如最大值、求和),再将数据写入根服务器 如图所示,当所有服务器都做播送或散射的时候,咱们作为接管方的服务器收到各服务器发来的数据,咱们将这些收到的数据进行某种规约的操作(常见如求和,求最大值)后再存入本人服务器内存中,那么这就叫规约(Reduce) AllReduce(全规约):对所有服务器上的数据做一个规约操作(如最大值、求和),再将数据写入根服务器 如图所示,同样每一个服务器都实现上述的规约操作,那么就是全规约(Allreduce)。这也就是分布式训练最根底的框架,将所有的数据通过规约操作集成到各个服务器中,各个服务器也就取得了完全一致的、蕴含本来所有服务器上计算参数的规约数据。 ReduceScatter(散射规约):服务器将本人的数据分为等同大小的数据块,每个服务器将依据index失去的数据做一个规约操作即,即先做Scatter再做Reduce。 概念中,咱们也经常遇到散射规约(ReduceScatter)这样的名词,简略来讲,就是先做散射(Scatter),将服务器中数据切分成等同大小的数据块,再依照序列(Rank Index),每一个服务器所取得的参数数据做规约(Reduce)。这就相似于全汇集,只不过咱们将数据不是简略拼接到一起而是做了规约操作(求和或最大值等操作)。 了解各种硬件测的基本概念当前,咱们对于分布式训练也应该有有一些了解了,即是分布式通过切分训练数据,让每一台服务器计算他所属的min-batch数据,再通过上述的reduce等操作进行同步,从而使得每个服务器上的参数数据都是雷同的。 分布式通信算法Parameter Server(PS)算法:根服务器将数据分成N份分到各个服务器上(Scatter),每个服务器负责本人的那一份mini-batch的训练,失去梯度参数grad后,返回给根服务器上做累积(Reduce),失去更新的权重参数后,再播送给各个卡(broadcast)。 这是最后的分布式通信框架,也是在几卡的较小规模的训练时,一种罕用的办法,然而不言而喻的当规模变大模型上则会呈现重大问题: 每一轮的训练迭代都须要所有卡都将数据同步完做一次Reduce才算完结,并行的卡很多的时候,木桶效应就会很重大,一旦有一张卡速度较慢会拖慢整个集群的速度,计算效率低。Reducer服务器工作过重,成为瓶颈,所有的节点须要和Reducer进行数据、梯度和参数的通信,当模型较大或者数据较大的时候,通信开销很大,根节点收到巨量的数据,从而造成瓶颈。Halving and doubling(HD)算法:服务器间两两通信,每步服务器都能够取得对方所有的数据,从而一直进行,使得所有服务器全副数据。 这种算法躲避了单节点瓶颈的问题,同时每个节点都将它的发送、承受带宽都使用起来,是目前极大大规模通信罕用的形式,然而它也有着它的问题,即是在最初步数中会有大量数据传递,使得速度变慢。 如果服务器数为非二次幂的状况下,如下图13台服务器,多出的5台会在之前与之后做单向全副数据的通信,其余服务器依照二次幂HD的形式进行通信,详情请参考Rabenseifner R.的Optimization of Collective Reduction Operations论文。然而在实用场景下,最初是将HD计算后含有所有参数数据的最大块的数据间接粗犷地向多进去的那几台服务器发送,导致这步的通信工夫占比极大。 Ring算法:以环形相连,每张卡都有左手卡和右手卡,一个负责接管,一个负责发送,循环实现梯度累积,再循环做参数同步。分为Scatter Reduce和All Gather两个环节。 更为具体的图解 Ring算法在中等规模的运算中十分有劣势,较小的传输数据量,无瓶颈,带宽齐全利用起来。毛病则是在大型规模集群运算中,微小的服务器内数据,极长的Ring环,Ring的这种切分数据块的形式就不再占优势。 参考:http://research.baidu.com/bri...https://docs.nvidia.com/deepl...https://zhuanlan.zhihu.com/p/...Rabenseifner R. (2004) Optimization of Collective Reduction Operations. In: Bubak M., van Albada G.D., Sloot P.M.A., Dongarra J. (eds) Computational Science - ICCS 2004. ICCS 2004. Lecture Notes in Computer Science, vol 3036. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3...点击关注,第一工夫理解华为云陈腐技术~ ...

June 2, 2021 · 1 min · jiezi

关于分布式:使用-docker-运行-RocketMQ-Canal-ElasticSearch-Golang-示例

0 引言在很多业务状况下,咱们都会在零碎中引入ElasticSearch搜索引擎作为做全文检索的优化计划。 如果数据库数据产生更新,这时候就须要在业务代码中写一段同步更新ElasticSearch的代码。 上面我会以一个blog文章治理为例来演示canal+RocketMQ用Golang实现MySQL与ElasticSearch的数据同步。 示例地址:https://gitee.com/thepoy/Rock... 尽量不要在 macOS 中应用,创立的容器多多少少会有问题,出问题时很难找到症结所在,而在 linux 零碎中应用则一切正常。 1 RocketMQRocketMQ是没有官网镜像的,所以须要在本地创立: cd rocketMQdocker build --no-cache -f Dockerfile -t rocketmq:4.8.0 --build-arg version=4.8.0 .可依据本人的需要对 Dockerfile 进行批改批改环境变量文件.env中的主机地址为本人的 ip 地址,而后应用 rocketMQ 目录中的配置文件创立容器: docker-compose --file compose.yml up2 Canal2.1 创立容器应用我的项目根目录中的配置文件创立mysql、canal-admin和canal-server容器: cd ..docker-compose --file compose.yml up也有一个环境变量文件须要批改,另外,compos 文件中的信息也须要依据须要批改,如 mysql 的 root 明码。 2.2 为 canal 账号受权创立 mysql 容器时也创立了 canal 账号,须要为这个账号受权。 GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';FLUSH PRIVILEGES;2.3 关上 canal 治理后盾http://localhost:8089,关上后...admin账号登录,默认明码为123456,治理后盾的界面如下图所示: 因为 compose.yml 文件中曾经配置了 canal-server,所以在后盾中能看见曾经启动的一个 server。 ...

May 28, 2021 · 3 min · jiezi

关于分布式:分布式-dble-纯读写分离功能隐式提交支持度汇总

作者:马莹乐 爱可生研发团队成员,负责 mysql 中间件的测试。自己是测试技术爱好者,欢送大家试用 dble 新性能~ 本文起源:原创投稿 *爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。 一、dble 介绍dble 是上海爱可生信息技术股份有限公司基于 mysql 的高可扩展性的分布式中间件,存在以下几个劣势个性: 数据程度拆分 随着业务的倒退,您能够应用 dble 来替换原始的单个 MySQL 实例。 兼容 Mysql 与 MySQL 协定兼容,在大多数状况下,您能够用它替换 MySQL 来为你的应用程序提供新的存储,而无需更改任何代码。 高可用性 dble 服务器能够用作集群,业务不会受到单节点故障的影响。 SQL 反对 反对 SQL 92 规范和 MySQL 方言。咱们反对简单的 SQL 查问,如 group by,order by,distinct,join,union,sub-query 等等。 简单查问优化 优化简单查问,包含但不限于全局表连贯分片表,ER 关系表,子查问,简化选择项等。 分布式事务反对 应用两阶段提交的分布式事务。您能够为了性能抉择一般模式或者为了数据安全采纳 XA 模式。当然,XA 模式依赖于 MySQL-5.7 的 XA Transaction,MySQL 节点的高可用性和数据的可靠性。 我的项目地址:https://github.com/actiontech...二、dble 在版本 3.20.10.0 中引入了纯读写拆散性能dble 在版 3.20.10.0 中引入了独立于分库分表业务性能的纯读写拆散性能,详见Release Notes,并在刚公布的 3.21.02.0 版本中做了进一步的欠缺~ 三、dble 读写拆散中隐式提交反对度No.触发隐式提交的 sql是否反对1ALTER EVENT test反对2ALTER FUNCTION test反对3ALTER PROCEDURE test反对4ALTER SERVER test反对5ALTER TABLE test反对6ALTER VIEW test反对7CREATE DATABASE test反对8CREATE EVENT test反对9CREATE FUNCTION test反对10CREATE INDEX test反对11CREATE PROCEDURE test反对12CREATE ROLE test反对(MySQL8.0)13CREATE SERVER test反对14CREATE SPATIAL REFERENCE SYSTEM反对(MySQL8.0)15CREATE TABLE test反对16CREATE TRIGGER test反对17CREATE VIEW test反对18DROP DATABASE test反对19DROP EVENT test反对20DROP FUNCTION test反对21DROP INDEX test反对22DROP PROCEDURE test反对23DROP ROLE test反对(MySQL8.0)24DROP SERVER test反对25DROP SPATIAL REFERENCE SYSTEM反对(MySQL8.0)26DROP TABLE test反对27DROP TRIGGER test反对28DROP VIEW test反对29INSTALL PLUGIN test反对30RENAME TABLE test反对31TRUNCATE TABLE test反对32UNINSTALL PLUGIN反对33ALTER USER test反对34CREATE USER test反对35DROP USER test反对36GRANT test反对37RENAME USER test反对38REVOKE test反对39SET PASSWORD不反对(受限于 druid)40BEGIN反对41LOCK TABLES test反对42START TRANSACTION test反对43LOAD DATA test不反对44SET autocommit = 1反对45ANALYZE TABLE test不反对46CACHE INDEX test不反对47CHECK TABLE test不反对48FLUSH不反对49LOAD INDEX INTO CACHE不反对50OPTIMIZE TABLE test不反对51REPAIR TABLE test不反对52RESET test不反对53START SLAVE test不反对54STOP SLAVE不反对55RESET SLAVE不反对56CHANGE MASTER TO不反对

May 10, 2021 · 1 min · jiezi

关于分布式:分布式系统的三个断路器框架的原理和实践

分布式系统的三个断路器框架的原理和实际 springboot实战电商我的项目mall4j (https://gitee.com/gz-yami/mall4j) java开源商城零碎 随着微服务的风行,熔断作为其中一项很重要的技术也广为人知。当微服务的运行品质低于某个临界值时,启动熔断机制,暂停微服务调用一段时间,以保障后端的微服务不会因为继续过负荷而宕机。本文介绍了Hystrix、新一代熔断器Resilience4j以及阿里开源的Sentinel如何应用。如有谬误欢送指出。 1. 为什么须要断路器 断路器模式源于Martin Fowler的Circuit Breaker 一文。“断路器”自身是一种开关安装,用于在电路上爱护线路过载,当线路中有电器产生短路时,“断路器”可能及时切断故障电路,避免产生过载、发热甚至起火等严重后果。 在分布式架构中,断路器模式的作用也是相似的,当某个服务单元产生故障(相似用电器产生短路)之后,通过断路器的故障监控(相似熔断保险丝),向调用方返回一个谬误响应,而不是长时间的期待。这样就不会使得线程因调用故障服务被长时间占用不开释,防止了故障在分布式系统中的蔓延。 针对上述问题,断路器是进行实现了断路、线程隔离、流量管制等一系列服务爱护性能的框架。零碎、服务和第三方库的节点,从而对提早和故障提供更弱小的容错能力。 2. Hystrix2.1什么是Hystrix Hystrix是一款Netfix开源的框架,具备依赖隔离,零碎容错降级等性能,这也是其最重要的两种用处,还有申请合并等性能。 2.2 Hystrix简略案例2.2.1 新建一个hystrix工程引入依赖<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>2.2.2 在启动类的上加上注解@EnableCircuitBreaker //启用断路器@EnableCircuitBreakerpublic class TestApplication extends SpringBootServletInitializer{ public static void main(String[] args) { SpringApplication.run(ApiApplication.class, args); }}2.2.3 在 TestProductController中退出断路逻辑@RequestMapping("/get/{id}") @HystrixCommand(fallbackMethod="errorCallBack") //测试没有这个数据时,服务降级 public Object get(@PathVariable("id") long id){ Product p= productService.findById(id); if( p==null){ throw new RuntimeException("查无此商品"); } return p; } //指定一个降级的办法 public Object errorCallBack( @PathVariable("id") long id ){ return id+"不存在,error"; }2.3 总结 简略介绍了Hystrix工作原理以及简略案例,不过Hystrix官网曾经进行开发,就不深刻介绍了。 ...

April 23, 2021 · 2 min · jiezi

关于分布式:深入剖析共识性算法-Raft

一、 Raft简介1.1 Raft简介Raft 是一种为了治理日志复制的分布式一致性算法。Raft 呈现之前,Paxos 始终是分布式一致性算法的规范。Paxos 难以了解,更难以实现。Raft 的设计指标是简化 Paxos,使得算法既容易了解,也容易实现。 Paxos 和 Raft 都是分布式一致性算法,这个过程如同投票选举首领(Leader),参选者(Candidate)须要压服大多数投票者(Follower)投票给他,一旦选举出首领,就由首领发号施令。Paxos 和 Raft 的区别在于选举的具体过程不同。 Raft 能够解决分布式 CAP 实践中的 CP,即 一致性(C:Consistency) 和 分区容忍性(P:Partition Tolerance),并不能解决 可用性(A:Availability) 的问题。 1.2 散布一致性分布式一致性 (distributed consensus) 是分布式系统中最根本的问题,用来保障一个分布式系统的可靠性以及容错能力。简略来说,分布式一致性是指多个服务器的放弃状态统一。 在分布式系统中,可能呈现各种意外(断电、网络拥塞、CPU/内存耗尽等等),使得服务器宕机或无法访问,最终导致无奈和其余服务器放弃状态统一。为了应答这种状况,就须要有一种一致性协定来进行容错,使得分布式系统中即便有局部服务器宕机或无法访问,整体仍然能够对外提供服务。 以容错形式达成统一,天然不能要求所有服务器都达成统一状态,只有超过半数以上的服务器达成统一就能够了。假如有 N 台服务器, 大于等于 N / 2 + 1 台服务器就算是半数以上了 。 1.3 复制状态机复制状态机(Replicated State Machines) 是指一组服务器上的状态机产生雷同状态的正本,并且在一些机器宕掉的状况下也能够持续运行。一致性算法治理着来自客户端指令的复制日志。状态机从日志中解决雷同程序的雷同指令,所以产生的后果也是雷同的。 复制状态机通常都是基于复制日志实现的,如上图。每一个服务器存储一个蕴含一系列指令的日志,并且依照日志的程序进行执行。每一个日志都依照雷同的程序蕴含雷同的指令,所以每一个服务器都执行雷同的指令序列。因为每个状态机都是确定的,每一次执行操作都产生雷同的状态和同样的序列。 保障复制日志雷同就是一致性算法的工作了。在一台服务器上,一致性模块接管客户端发送来的指令而后减少到本人的日志中去。它和其余服务器上的一致性模块进行通信来保障每一个服务器上的日志最终都以雷同的程序蕴含雷同的申请,只管有些服务器会宕机。一旦指令被正确的复制,每一个服务器的状态机依照日志程序解决他们,而后输入后果被返回给客户端。因而,服务器集群看起来造成一个高牢靠的状态机。 理论零碎中应用的一致性算法通常含有以下个性: 安全性保障(相对不会返回一个谬误的后果):在非拜占庭谬误状况下,包含网络提早、分区、丢包、冗余和乱序等谬误都能够保障正确。 可用性:集群中只有有大多数的机器可运行并且可能互相通信、和客户端通信,就能够保障可用。因而,一个典型的蕴含 5 个节点的集群能够容忍两个节点的失败。服务器被进行就认为是失败。他们当有稳固的存储的时候能够从状态中复原回来并重新加入集群。 不依赖时序来保障一致性:物理时钟谬误或者极其的音讯提早只有在最坏状况下才会导致可用性问题。 通常状况下,一条指令能够尽可能快的在集群中大多数节点响应一轮近程过程调用时实现。小局部比较慢的节点不会影响零碎整体的性能。 1.4 RAFT利用通过 RAFT 提供的复制状态机,能够解决分布式系统的复制、修复、节点治理等问题。Raft 极大的简化以后分布式系统的设计与实现,让开发者只关注于业务逻辑,将其形象实现成对应的状态机即可。基于这套框架,能够构建很多分布式应用: 分布式锁服务 分布式存储系统,比方分布式音讯队列、分布式块零碎、分布式文件系统、分布式表格零碎等,比方赫赫有名的 Redis 就是基于 Raft 实现分布式一致性 高牢靠元信息管理,比方各类 Master 模块的 HA 二、 Raft根底Raft 将一致性问题分解成了三个子问题:选举 Leader、日志复制、安全性。 在后续章节,会具体解说这个子问题。当初,先理解一下 Raft 的一些外围概念。 ...

April 19, 2021 · 3 min · jiezi

关于分布式:从两个模型带你了解DAOS-分布式异步对象存储

摘要:分布式异步对象存储 (DAOS) 是一个开源的对象存储系统,专为大规模分布式非易失性内存 (NVM, Non-Volatile Memory) 设计,利用了 SCM(Storage-Class Memory) 和 NVMe(Non-Volatile Memory express) 等的下一代 NVM 技术。本文分享自华为云社区《DAOS 分布式异步对象存储》,原文作者:debugzhang 。 分布式异步对象存储 (DAOS) 是一个开源的对象存储系统,专为大规模分布式非易失性内存 (NVM, Non-Volatile Memory) 设计,利用了 SCM(Storage-Class Memory) 和 NVMe(Non-Volatile Memory express) 等的下一代 NVM 技术。 DAOS 是一种横向扩大的对象存储,能够为高性能计算利用提供高带宽、低提早和高 IOPS 的存储容器,并反对联合仿真、数据分析和机器学习的下一代以数据为核心的工作流程。 与次要针对旋转介质设计的传统存储堆栈不同,DAOS 针对全新 NVM 技术进行了从新构建,可在用户空间中端对端地运行,并能齐全绕开操作系统,是一套轻量级的零碎。 DAOS 提供了一种为拜访高细粒度数据提供原生反对的 I/O 模型,而不是传统的基于高提早和块存储设计的 I/O 模型,从而开释下一代存储技术的性能。 与传统的缓冲区不同,DAOS 是一个独立的高性能容错存储层,它不依赖其它层来治理元数据并提供数据恢复能力。DAOS 服务器将其元数据保留在长久内存中,而将批量数据间接保留在 NVMe 固态盘中。 DAOS 个性DAOS 依附 OFI(OpenFabric Interface) 绕过操作系统,将 DAOS 操作交付给 DAOS 存储服务器,充分利用架构中的任何近程间接内存拜访 (RDMA, Remote Direct Memory Access) 性能,进行低提早、高音讯速率的用户空间通信,并将数据存储在长久内存和 NVMe 固态盘中。 ...

March 31, 2021 · 4 min · jiezi

关于im:从新手到专家如何设计一套亿级消息量的分布式IM系统

本文原作者Chank,原题“如何设计一个亿级音讯量的 IM 零碎”,为了晋升内容品质,本次有订正和改变。 1、写有后面本文将在亿级音讯量、分布式IM零碎这个技术前提下,剖析和总结实现这套零碎所须要把握的知识点,内容没有浅近的技术概念,尽量做到老手新手皆能读懂。 本文不会给出一套通用的IM计划,也不会评判某种架构的好坏,而是探讨设计IM零碎的常见难题跟业界的解决方案。 因为也没有所谓的通用IM架构计划,不同的解决方案都各有其优缺点,只有最满足业务的零碎才是一个好的零碎。 在人力、物力、工夫资源无限的前提下,通常须要做出很多衡量,此时,一个可能反对疾速迭代、不便扩大的IM零碎才是最优解。 学习交换: 即时通讯/推送技术开发交换5群:215477170 [举荐]挪动端IM开发入门文章:《新手入门一篇就够:从零开发挪动端IM》开源IM框架源码:https://github.com/JackJiang2011/MobileIMSDK2、相干文章与本文相似,以下两篇也非常适合同时浏览,有趣味能够一并学习。 《一套亿级用户的IM架构技术干货(上篇):整体架构、服务拆分等》《一套亿级用户的IM架构技术干货(下篇):可靠性、有序性、弱网优化等》3、IM常见术语_0)_用户:零碎的使用者。 _1)_音讯:是指用户之间的沟通内容(通常在IM零碎中,音讯会有以下几类:文本音讯、表情音讯、图片音讯、视频音讯、文件音讯等等)。 _2)_会话:通常指两个用户之间因聊天而建设起的关联。 _3)_群:通常指多个用户之间因聊天而建设起的关联。 _4)_终端:指用户应用IM零碎的机器(通常有Android端、iOS端、Web端等等)。 _5)_未读数:指用户还没读的音讯数量。 _6)_用户状态:指用户以后是在线、离线还是挂起等状态。 _7)_关系链:是指用户与用户之间的关系,通常有单向的好友关系、双向的好友关系、关注关系等等(这里须要留神与会话的区别:用户只有在发动聊天时才产生会话,但关系并不需要聊天能力建设。对于关系链的存储,能够应用图数据库(Neo4j等等),能够很天然地表白事实世界中的关系,易于建模)。 _8)_单聊:一对一聊天。 _9)_群聊:多人聊天。 _10)_客服:在电商畛域,通常须要对用户提供售前征询、售后征询等服务(这时,就须要引入客服来解决用户的征询)。 _11)_音讯分流:在电商畛域,一个店铺通常会有多个客服,此时决定用户的征询由哪个客服来解决就是音讯分流(通常音讯分流会依据一系列规定来确定音讯会分流给哪个客服,例如客服是否在线(客服不在线的话须要从新分流给另一个客服)、该音讯是售前征询还是售后征询、以后客服的忙碌水平等等)。 _12)_信箱:本文的信箱咱们指一个Timeline、一个收发音讯的队列。 4、读扩散 vs 写扩散IM零碎里常常会波及到读扩散和写扩散这两个技术概念,咱们来看看。 4.1 读扩散 如上图所示:A与每个聊天的人跟群都有一个信箱(有些博文会叫Timeline,见《古代IM零碎中聊天音讯的同步和存储计划探讨》),A在查看聊天信息的时候须要读取所有有新音讯的信箱。 须要留神与Feeds零碎的区别:在Feeds零碎中,每个人都有一个写信箱,写只须要往本人的写信箱里写一次就好了,读须要从所有关注的人的写信箱里读。但IM零碎里的读扩散通常是每两个相关联的人就有一个信箱,或者每个群一个信箱。 读扩散的长处: 1)写操作(发消息)很轻量,不论是单聊还是群聊,只须要往相应的信箱写一次就好了;2)每一个信箱人造就是两个人的聊天记录,能够不便查看聊天记录跟进行聊天记录的搜寻。读扩散的毛病:读操作(读音讯)很重,在简单业务下,一条读扩散音讯源须要简单的逻辑能力扩散成指标音讯。 4.2 写扩散接下来看看写扩散。 如上图所示:在写扩散中,每个人都只从本人的信箱里读取音讯。 但写(发消息)的时候,对于单聊跟群聊解决如下: 1)单聊:往本人的信箱跟对方的信箱都写一份音讯,同时,如果须要查看两个人的聊天历史记录的话还须要再写一份(当然,如果从集体信箱也能回溯出两个人的所有聊天记录,但这样效率会很低);2)群聊:须要往所有的群成员的信箱都写一份音讯,同时,如果须要查看群的聊天历史记录的话还须要再写一份。能够看出,写扩散对于群聊来说大大地放大了写操作。PS:实际上群聊中音讯扩散是IM开发中的技术痛点,有趣味倡议具体浏览:《无关IM群聊技术实现的文章汇总》。 写扩散长处: 1)读操作很轻量;2)能够很不便地做音讯的多终端同步。写扩散毛病:写操作很重,尤其是对于群聊来说(因为如果群成员很多的话,1条音讯源要扩散写成“成员数-1”条指标音讯,这是很恐怖的)。 在Feeds零碎中: 1)写扩散也叫:Push、Fan-out或者Write-fanout;2)读扩散也叫:Pull、Fan-in或者Read-fanout。5、惟一ID的技术计划5.1 基础知识通常状况下,ID设计次要有以下几大类: 1)UUID;2)基于Snowflake算法的ID生成形式;3)基于申请DB步长的生成形式;4)基于Redis或者DB的自增ID生成形式;5)非凡的规定生成惟一ID。... ...具体的实现办法跟优缺点能够参考以下IM音讯ID的专题文章: 《IM音讯ID技术专题(一):微信的海量IM聊天音讯序列号生成实际(算法原理篇)》《IM音讯ID技术专题(二):微信的海量IM聊天音讯序列号生成实际(容灾计划篇)》《IM音讯ID技术专题(三):解密融云IM产品的聊天音讯ID生成策略》《IM音讯ID技术专题(四):深度解密美团的分布式ID生成算法》《IM音讯ID技术专题(五):开源分布式ID生成器UidGenerator的技术实现》《IM音讯ID技术专题(六):深度解密滴滴的高性能ID生成器(Tinyid)》在IM零碎中须要惟一Id的中央次要是: 1)聊天会话ID;2)聊天音讯ID。5.2 音讯ID咱们来看看在设计音讯ID时须要思考的三个问题。 5.2.1)音讯ID不递增能够吗? 咱们先看看不递增的话会怎么: 1)应用字符串,节约存储空间,而且不能利用存储引擎的个性让相邻的音讯存储在一起,升高音讯的写入跟读取性能;2)应用数字,但数字随机,也不能利用存储引擎的个性让相邻的音讯存储在一起,会加大随机IO,升高性能;而且随机的ID不好保障ID的唯一性。因而,音讯ID最好是递增的。 5.2.3)全局递增 vs 用户级别递增 vs 会话级别递增: 全局递增:指音讯ID在整个IM零碎随着工夫的推移是递增的。全局递增的话个别能够应用Snowflake(当然,Snowflake也只是worker级别的递增)。此时,如果你的零碎是读扩散的话为了避免音讯失落,那每一条音讯就只能带上上一条音讯的ID,前端依据上一条音讯判断是否有失落音讯,有音讯失落的话须要从新拉一次。 用户级别递增:指音讯ID只保障在单个用户中是递增的,不同用户之间不影响并且可能反复。典型代表:微信(见《微信的海量IM聊天音讯序列号生成实际(算法原理篇)》)。如果是写扩散零碎的话信箱工夫线ID跟音讯ID须要离开设计,信箱工夫线ID用户级别递增,音讯ID全局递增。如果是读扩散零碎的话感觉应用用户级别递增必要性不是很大。 会话级别递增:指音讯ID只保障在单个会话中是递增的,不同会话之间不影响并且可能反复。典型代表:QQ。 5.2.3)间断递增 vs 枯燥递增: 间断递增是指ID按 _1,2,3...n_ 的形式生成;而枯燥递增是指只有保障前面生成的ID比后面生成的ID大就能够了,不须要间断。 据我所知:QQ的音讯ID就是在会话级别应用的间断递增,这样的益处是,如果失落了音讯,当下一条音讯来的时候发现ID不间断就会去申请服务器,防止失落音讯。 此时,可能有人会想,我不能用定时拉的形式看有没有音讯失落吗?当然不能,因为音讯ID只在会话级别间断递增的话那如果一个人有上千个会话,那得拉多少次啊,服务器必定是抗不住的。 对于读扩散来说,音讯ID应用间断递增就是一种不错的形式了。如果应用枯燥递增的话以后音讯须要带上前一条音讯的ID(即聊天音讯组成一个链表),这样,能力判断音讯是否失落。 5.2.4)小结一下: 写扩散:信箱工夫线ID应用用户级别递增,音讯ID全局递增,此时只有保障枯燥递增就能够了。 读扩散:音讯ID能够应用会话级别递增并且最好是间断递增。 ...

March 29, 2021 · 2 min · jiezi

关于分布式:数据系统派生数据系统批处理系统

Web和越来越多基于HTTP/REST的API使得申请/响应的交互模式变得如此广泛,以至于很容易将其视为天经地义。然而咱们该当记住,这并不是构建零碎的惟一路径,其余办法也有其长处。上面咱们来辨别三种不同类型的零碎: 在线服务(或称在线零碎) 服务期待客户申请或指令的达到。当收到申请或指令时,服务试图尽可能快地解决它,并发回一个响应。响应工夫通常是服务性能的次要掂量指标,而可用性同样十分重要。 批处理零碎(或称离线零碎) 批处理零碎接管大量的输出数据,运行一个作业来解决数据,并产生输入数据。作业往往须要执行一段时间,所以用户通常不会期待作业实现。相同,批量作业通常会定期运行(例如,每天一次)。批处理作业的次要性能衡量标准通常是吞吐量(解决肯定大小的输出数据集所需的工夫)。 流解决零碎(或称近实时零碎) 流解决介于在线与离线/批处理之间(所以有时称为近实时或近线解决)。与批处理零碎相似,流解决零碎解决输出并产生输入(而不是响应申请)。然而,流式作业在事件产生后不久即可对事件进行解决,而批处理作业则应用固定的一组输出数据进行操作。这种差别使得流解决零碎比批处理零碎具备更低的提早。流解决是在批处理的根底上进行的。 批处理是构建牢靠、可扩大与可保护利用的重要组成部分。例如,2004年发表的驰名批处理算法MapReduce“使得Google具备如此大规模的可扩展性能力”。该算法随后在各种开源数据系统中被陆续实现,包含Hadoop、CouchDB和MongoDB。 应用UNIX工具进行批处理咱们从一个简略的例子开始。假如有一个Nginx服务器,每次响应申请时都会在日志文件中追加一行记录,应用的是默认的拜访日志格局。 简略日志剖析假如想找出网站中前五个最受欢迎的网页,能够在UNIX shell中执行下列操作: cat /var/log/nginx/access.log | ①awk '{print $7}' | ②sort | ③uniq -c | ④sort -r -n | ⑤head -n 5 ⑥① 读取日志文件。② 将每一行按空格宰割成不同的字段,每行只输入第七个字段,即申请的URL地址。③ 按字母顺序排列URL地址列表。如果某个URL被申请过n次,那么排序后,后果中将蕴含间断n次的反复URL。④ uniq命令通过查看两条相邻的行是否雷同来过滤掉其输出中的反复行。-c选项为输入一个计数器:对于每个不同的URL,它会报告输出中呈现该URL的次数。⑤ 第二种排序按每行起始处的数字(-n)排序,也就是URL的申请次数。而后以反向(-r)程序输入后果,即后果中最大的数字首先返回。⑥ 最初,head只输入输出中的前五行(-n 5),并抛弃其余数据。 该命令序列的输入如下所示: 4189 /favicon.ico3631 /2013/05/24/improving-security-of-ssh-private-keys.html2124 /2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html1369 /915 /css/typography.css该命令行的功能强大,将在几秒钟内解决千兆字节的日志文件,你能够轻松批改剖析指令以满足本人的需要。例如,如果要省略CSS文件,将awk参数更改为'$7 !~ /\.css$/ {print $7}'即可。如果想得到申请次数最多的客户端IP地址而不是页面,那么就将awk参数更改为'{print $1}'。 排序与内存中聚合你也能够写一个简略的程序来做同样的事件,例如Ruby。Ruby脚本须要一个URL的内存哈希表,其中每个URL地址都会映射到被拜访的次数。UNIX流水线例子中则没有这样的哈希表,而是依赖于对URL列表进行排序,在这个URL列表中屡次呈现的雷同URL仅仅是简略反复。 哪种办法更好呢?这取决于有多少个不同的网址。对于大多数中小型网站,兴许能够在内存中存储所有不同的URL,并且能够为每个URL提供一个计数器。在此示例中,作业的工作集仅取决于不同URL的数量:如果单个URL有一百万条日志条目,则哈希表中所需的空间表依然只是一个URL加上计数器的大小。如果这个工作集足够小,那么内存哈希表工作失常。 如果作业的工作集大于可用内存,则排序办法的长处是能够高效地应用磁盘。这与“SSTables和LSM-Tree”中探讨的原理雷同:数据块能够在内存中排序并作为段文件写入磁盘,而后多个排序的段能够合并为一个更大的排序文件。归并排序在磁盘上有良好的程序拜访模式。 GNU Coreutils (Linux)中的sort实用程序通过主动唤出到磁盘的形式反对解决大于内存的数据集,且排序能够主动并行化以充分利用多核。这意味着之前简略的UNIX命令链能够很容易地扩大到大数据集,而不会耗尽内存。从磁盘读取输出文件倒可能会成为瓶颈。 UNIX设计哲学咱们能够非常容易地应用相似例子中命令链来剖析日志文件,这是UNIX的要害设计思维之一。通过管道将程序连接起来的想法成为现在的UNIX哲学,一系列的在开发人员和UNIX用户中逐步变得风行的设计准则。 对于这种哲学有更为残缺的形容: 每个程序做好一件事。如果要做新的工作,则建设一个全新的程序,而不是通过减少新“特色”使旧程序变得更加简单。期待每个程序的输入成为另一个尚未确定的程序的输出。不要将输入与无关信息混同在一起。防止应用严格的表格状或二进制输出格局。不要应用交互式输出。尽早尝试设计和构建软件,甚至是操作系统。须要扔掉那些蠢笨的局部时不要犹豫,并立刻进行重建。优先应用工具来加重编程工作,即便你不得不额定破费工夫去构建工具,并且预期在应用实现后会将其中一些工具扔掉。这种哲学(自动化、疾速原型设计、增量式迭代、测试敌对、将大型项目合成为可治理的模块等)听起来十分像麻利开发与DevOps静止。 像bash这样的UNIX shell能够让咱们轻松地将这些小程序组合成弱小的数据处理作业。只管这些程序中是由不同人所编写的,但它们能够灵便地联合在一起。那么,UNIX是如何实现这种可组合性的呢? 对立接口如果心愿某个程序的输入成为另一个程序的输出,也就意味着这些程序必须应用雷同的数据格式,换句话说,须要兼容的接口。如果你心愿可能将任何程序的输入连贯到任何程序的输出,那意味着所有程序都必须应用雷同的输出/输入接口。 在UNIX中,这个接口就是文件(更精确地说,是文件描述符),文件只是一个有序的字节序列。这是一个非常简单的接口,因而能够应用雷同的接口示意许多不同的货色:文件系统上的理论文件,到另一个过程(UNIX socket,stdin,stdout)的通信通道,设施驱动程序(比方/dev/audio或/dev/lpo),示意TCP连贯的套接字等。 依照常规,许多(但不是全副)UNIX程序将这个字节序列视为ASCII文本。awk,sort,uniq和head都将它们的输出文件视为由\n(换行符,ASCII OxOA)字符分隔的记录列表,所有这些程序都应用规范雷同的记录分隔符以反对交互操作。对每条记录(即一行输出)的解析则没有明确定义。 逻辑与布线拆散UNIX工具的另一个特点是应用规范输出和规范输入。如果运行一个程序而不指定任何参数,那么规范输出来自键盘,规范输入为屏幕。当然,也能够将文件作为输出或将输入重定向到文件。管道容许将一个过程的stdout附加到另一个过程的stdin(具备小的内存缓冲区,而不须要将全副两头数据流写入磁盘)。 程序依然能够在须要时间接读取和写入文件。但如果程序不依赖特定的文件门路,只应用stdin和stdout,则UNIX工具能够达到最佳成果。这容许shell用户以任何他们想要的形式连贯输出和输入,程序并不知道也不关怀输出来自哪里以及输入到哪里。也能够说这是一种松耦合,前期绑定或管制反转。将输出/输入的布线连贯与程序逻辑离开,能够更容易地将小工具组合成更大的零碎。 用户甚至能够编写本人的程序,并将它们与操作系统提供的工具组合在一起。程序只须要从stdin读取输出并输入至stdout,从而参加数据处理流水线。 ...

March 27, 2021 · 1 min · jiezi

关于分布式:gozeroegojupitergomicro-对比

go-zero、ego(jupiter)、go-micro 比照go-zero文档地址有欠缺的社区和生态系统:包含熔断限流,监控,k8s,运维.开源的比较完善 ego(jupiter)文档地址劣势有比较完善的运维监控零碎:普罗米修斯+grafana服务治理平台缺点文档不全社区比拟沉闷go-micro文档地址[无]劣势集体手上有成熟的零碎可能应用构建简略缺点最新v3曾经定性为商用,v2版本曾经废除性能有问题

March 25, 2021 · 1 min · jiezi

关于分布式:数据系统分布式系统一致性与共识

为了构建容错零碎,最好先建设一套通用的形象机制和与之对应的技术保障,这样只需实现一次,其上的各种应用程序都能够平安地信赖底层的保障。这与事务的情理雷同:通过事务,应用程序能够伪装没有解体(原子性),没有与其他人并发拜访数据库(隔离性),且存储设备是齐全牢靠的(持久性)。总之,形象的事务机制能够屏蔽零碎外部很多简单的问题,使得应用层轻松无忧。 当初持续沿着这个思路,尝试建设能够让分布式应用疏忽外部各种问题的形象机制。例如,分布式系统最重要的形象之一就是共识:所有的节点就某一项提议达成统一。 一旦解决了共识问题,就能够服务于应用层很多的指标需要。例如,对于一个主从复制的数据库,如果主节点产生生效,就须要切换到另一个节点,此时数据库节点能够采纳共识算法来选举新的主节点。某一时刻必须只有一个主节点,所有的节点必须就此达成统一。如果有两个节点都自认为是主节点,就会产生脑裂,导致数据失落。正确实现共识算法则能够防止此类问题。 咱们须要理解零碎能力的边界,即哪些可行,哪些不可行。在什么状况下,零碎能够容忍故障并持续工作;而其余状况,却无奈保障。 一致性保障在复制环境下,如果在同一时刻查询数据库的两个节点,则可能会看到不同的数据,这次要是因为写申请会在不同的工夫点达到不同的节点。无论数据库采纳何种复制办法,都无奈完全避免这种不统一状况。 大多数多正本的数据库都至多提供了最终的一致性,这意味着如果进行更新数据库,并期待一段时间之后,最终所有读申请会返回雷同的内容。换句话说,不统一景象是临时的,最终会达到统一。换言之,最终一致性意味着“收敛”,即预期所有的正本最终会收敛到雷同的值。 然而,这是一个十分弱的保障,它无奈通知咱们零碎何时会收敛。而在收敛之前,读申请可能会返回任何值甚至读失败。 当面对只提供了弱保障的数据库时,须要苏醒地认清零碎的局限性,切不可过于乐观。利用可能在大多数状况下都运行良好,但数据库外部可能曾经产生了十分奥妙的谬误,只有当零碎呈现故障或高并发压力时,最终一致性的临界条件或者谬误才会对外裸露进去,因此测试与发现错误变得十分艰难。 咱们将摸索更强的一致性模型。不过,这也意味着更多的代价,例如性能升高或容错性差。尽管如此,更强的保障的益处是使下层应用逻辑更简略,更不容易出错。当理解、比照了多种不同的一致性模型之后,能够联合本身需要,从中抉择最合适的。 可线性化在最终一致性数据库中,同时查问两个不同的正本可能会失去两个不同的答案。这会使应用层感到困惑。如果数据库可能对上提供只有单个正本的假象,状况会不会大为简化呢?这样让每个客户端都领有雷同的数据视图,而不用放心复制滞后。 这就是可线性化(也称为原子一致性,强一致性等)的思维。其根本的想法是让一个零碎看起来如同只有一个数据正本,且所有的操作都是原子的。 在一个可线性化的零碎中,一旦某个客户端胜利提交写申请,所有客户端的读申请肯定都能看到刚刚写入的值。这种看似繁多正本的假象意味着它能够保障读取最近最新值,而不是过期的缓存。换句话说,可线性化是一种就近的保障。 如何达到线性化?可线性化背地的根本思维很简略:使零碎看起来如同只有一个数据正本。 如图展现了三个客户端在线性化数据库中同时读写雷同的主键x。在分布式语义下,x被称为寄存器,例如,它能够是键-值存储中的一个键,关系数据库中的一行或文档数据库中的一个文档。 每条线代表一个客户端申请,虚线的开始示意发送申请的工夫,结尾则是收到响应的工夫。因为网络提早不确定,客户端并不分明数据库具体何时解决申请,而只晓得它是在发送之后、响应之前的某个两头工夫点。 在这个例子中,寄存器有两类操作:读和写(写可能会产生失败)。x的初始值为0,客户端C提交写申请将其设置为1。同时,客户端A和B在重复轮询数据库以读取最新值。A和B可能会别离读到什么样的返回值呢? 客户端A的第一个读取操作在写入开始之前已实现,因而返回的是旧值0。客户端A的最初一次读操作是在写操作实现之后才开始的,如果数据库是可线性化的,它必定会返回新值1。与写操作有时间重叠的任何读取操作则可能返回0或者1,这是因为读写之间存在并发,无奈确切晓得在执行读取时,写入是否曾经失效。然而,这还没有准确形容线性化:如果与写并发的读操作可能返回旧值或新值,那么在这个过程中,不同的读客户端会看到旧值和新值之间来回跳变的状况。 为使零碎可线性化,咱们须要增加一个重要的束缚:一旦某个读操作返回了新值,之后所有的读(包含雷同或不同的客户端)都必须返回新值。 能够进一步细化时序图来可视化每步操作具体在哪个工夫点失效,如图所示。除了读写之外,咱们引入了第三种类型的操作cas:示意一个原子比拟-设置操作。 图中的每个操作都有一条竖线,示意可能的执行工夫点。这些标记以前后关系顺次连接起来,最终的后果必须是一个无效的寄存器读写程序,即每个读操作须返回最近写操作所设置的值。 可线性化要求,如果连贯这些标记的竖线,它们必须总是按工夫箭头(从左到右)向前挪动,而不能向后挪动。这个要求确保了之前所探讨的就近性保障:一旦新值被写入或读取,所有后续的读都看到的是最新的值,直到被再次笼罩。 图中有一些乏味的细节值得仔细分析: 客户端B首先发送读x的申请,接下来客户端D发送申请将x置为0,紧接着客户端A又发送申请将x置为1,而最终返回给B的值为1。这是可能的,它意味着数据库执行的程序是:首先解决D的写入0,而后是A的写入1,最初是B的读取。尽管这并不是申请发送的程序,但思考到申请并发以及网络提早等状况,这是一个非法的可承受的解决程序。客户端A在收到数据库写响应之前,客户端B即读到了值1,这表明写入已胜利。这是可能的,但它并不代表执行读产生在执行写之前,只是意味着很可能因为网络提早而耽误了客户端A承受响应。模型没有假设事务间的隔离,即另一个并发客户端可能随时会批改值。例如,C首先读取到1,而后读到2,起因是两次读取之间值被客户端B批改了。咱们能够应用cas操作来查看值是否被其余并发客户端批改,例如客户端B和C的cas申请胜利,然而D的cas操作失败。客户B的最初一次读取不满足线性化。该操作与C的cas写操作同时产生,后者将x从2更新为4。在没有其余申请时,B读取能够返回2。然而在B读取开始之前,客户端A曾经读取了新值4,所以不容许B读到比A更老的值。依赖线性化的场景加锁与主节点选举主从复制的零碎须要确保有且只有一个主节点,否则会产生脑裂。选举新的主节点常见的办法是应用锁:即每个启动的节点都试图取得锁,其中只有一个能够胜利即成为主节点。不论锁具体如何实现,它必须满足可线性化:所有节点都必须批准哪个节点持有锁,否则就会呈现问题。 提供协调者服务的零碎如ZooKeeper和etcd等通常用来实现分布式锁和主节点选举。它们都应用了反对容错的共识算法确保可线性化。 束缚与唯一性保障唯一性束缚在数据库中很常见。例如,用户名或电子邮件地址必须惟一标识一个用户,文件存储服务中两个文件不能具备雷同的门路和文件名。如果要在写入数据时强制执行这些束缚,则也须要线性化。 这种状况实质上与加锁十分相似:用户注册等同于试图对用户名进行加锁操作。该操作也相似于原子比拟和设置:如果以后用户名尚未被应用,就设置用户名与客户ID进行关联。 其余相似束缚包含银行账户余额不应呈现负值,或者防止发售库存里曾经没有的商品,或者不能同时预约航班或者剧院的雷同的座位。这样的约束条件都要求所有节点就某个最新值达成统一(例如账户余额,库存程度,座位占用率)。 硬性的唯一性束缚,常见如关系型数据库中主键的束缚,则须要线性化保障。其余如外键或属性束缚,则并不要求肯定线性化。 跨通道的工夫依赖有些时候,线性化违例之所以被留神到,是因为零碎中存在其余的通信渠道。例如,用户能够上传照片到某网站,有一个后盾过程将照片调整为更低的分辨率(即缩略图)以不便更快下载。该网站架构和数据流如图所示。 这里须要明确告诉图像调整模块来调整哪些图片,零碎采纳了音讯队列将此命令从Web服务器发送到调整器。因为大多数音讯队列零碎并不适宜大数据流,而思考到照片的大小可能到数兆字节,因而Web服务器并不会把照片间接放在队列中。相同,照片会先写入文件存储服务,当写入实现后,把调整的命令放入队列。 如果文件存储服务是可线性化的,那么零碎应该能够失常工作。否则,这里就会引入竞争条件:音讯队列可能比存储服务外部的复制执行更快。在这种状况下,当调整模块在读取图像时,可能会看到图像的某个旧版本,或者基本读不到任何内容。如果它碰巧读到了旧版本的图像并进行解决,会导致文件存储中的全尺寸图片与调整之后图片呈现永恒的不统一。 实现线性化零碎因为线性化实质上意味着“体现得如同只有一个数据正本,且其上的所有操作都是原子的”,所以最简略的计划天然是只用一个数据正本。但显然,该办法无奈容错:如果仅有的正本所在的节点产生故障,就会导致数据失落,或者至多在重启之前都无法访问服务。 零碎容错最常见的办法就是采纳复制机制。咱们回顾一下各种复制计划,看看哪些满足可线性化: 主从复制(局部反对可线性化) 在主从复制的零碎中,只有主节点承当数据写入,从节点则在各自节点上保护数据的备份正本。如果从主节点或者同步更新的从节点上读取,则能够满足线性化。但并非每个主从复制的具体数据库实例都是可线性化的,次要是因为它们可能采纳了快照隔离的设计,或者实现时存在并发方面的bug。 而从主节点上读取的前提是你确定晓得哪个节点是主节点。某节点可能自认为是主节点,但事实并非如此,这个“自以为是”的主节点如果对外提供服务,就会违反线性化。如果应用了异步复制,故障切换过程中甚至可能会失落一些已提交的写入,后果是同时违反持久性和线性化。 共识算法(可线性化) 共识算法与主从复制机制类似,不过共识协定通常内置一些措施来避免脑裂和过期的正本。正是因为这些专门的设计,共识算法能够平安地实现线性化存储。 多主复制(不可线性化) 具备多主节点复制的零碎通常无奈线性化,次要因为它们同时在多个节点上执行并发写入,并将数据异步复制到其余节点。因而它们可能会产生抵触的写入,须要额定的解决方案。 无主复制(可能不可线性化) 对于无主节点复制的零碎,有些人认为只有配置法定读取和写入满足 (w + r > n)就能够取得“强一致性”。但这齐全取决于具体的quorum的配置,以及如何定义强一致性,它可能并不保障线性化。 例如基于墙上时钟的“最初写入获胜”抵触解决办法简直必定是非线性化,因为这种工夫戳无奈保障与理论事件程序统一(例如因为时钟偏移)。不标准的quorum也会毁坏线性化。甚至即便是严格的quorum,也会产生违反线性化的状况。 线性化与quorum直觉上,对于无主复制模型,如果读写听从了严格quorum,应该是可线性化的。然而如果遭逢不确定的网络提早,就会呈现竞争条件,如图所示。 x的初始值为0,写客户端向所有三个正本(n = 3,w = 3)发送写申请将x更新为1。与此同时,客户端A从两个节点(r = 2)读取数据,而后在其中一个节点上看到新值1。与此同时,客户端B从两个节点的读取,两者都返回了旧值0。 咱们发现它尽管满足了仲裁条件(w + r > n),但很显著这不是线性化的:B的申请在A的申请实现之后才开始,A返回了新值,但B却失去了旧值。 不过,能够以就义性能为代价来满足线性化:读操作在返回后果给利用之前,必须同步执行读修复;而写操作在发送后果之前,必须读取quorum节点以获取最新值。而且,如果应用了“最初写入获胜”抵触解决方案,当呈现同一个主键的并发写入时,就会丢失线性化。 此外,这种形式只能实现线性化读、写操作,但无奈反对线性化的“比拟和设置”操作,后者须要共识算法的反对。 总而言之,最平安的假设是无主复制零碎无奈保障线性化。 线性化的代价咱们曾经探讨了不同复制计划各自适宜的场景。例如,多主复制非常适合多数据中心。如果两个数据中心之间产生网络中断,会产生什么状况?基于多主复制的数据库,每个数据中心内都能够持续失常运行:因为从一个数据中心到另一个数据中心的复制是异步,期间产生的写操作都暂存在本地队列,等网络复原之后再持续同步。 ...

March 21, 2021 · 2 min · jiezi

关于分布式:谈一谈分布式系统中数据的安全和性能

在分布式系统中,咱们晓得CAP定理和BASE实践,数据的平安和性能是负相关的,数据的安全性进步了,那他的性能就会降落,相干,他的性能进步了,数据的安全性就会降落。咱们从几个中间件来探讨这个问题。 mysql当mysql性能呈现瓶颈时,咱们会做分库分表、读写拆散等,读写拆散须要咱们做主从复制,对读的操作,咱们指向从库,对写的操作,咱们指向主库,上面看看主从复制的原理。当业务零碎提交数据的时候,master会将这变更的数据保留到binlog文件,写入成后,事务提交胜利。slave中会有一个线程,他会从master中读取binlog信息,而后写入relay文件。而后他还会有其余线程,读取relay文件的信息,把这个信息从新在slave库执行一遍。也就是说,如果在master中执行了一个update的语句,那在slave中同样也执行截然不同的update语句,这样两边的数据就会保持一致,因为master先执行,而后slave再执行,所以会有略微的提早。如果执行的语句比拟久,那这个延时也会比拟长,当然零碎的压力也会影响提早的工夫。除了延时以外,他还有一个比拟大的问题,当写入binlog后,代表事务提交胜利,此时master挂了,导致slave没方法读取这部分的binlog,所以就会呈现数据的失落,两边的数据就没方法放弃一致性,所以咱们通常会把下面的异步复制模式设置半同步复制,也就是semi-sync。半同步复制与异步复制不同的是,当master写入到binlog后,他会被动的把数据同步到从库,从库把信息写入到relay文件,会返回ACK给master,此时master才会认为他的事务是提交的。如果有多个slave的状况,则至多返回1个ACK才认为事务的提交的。半同步复制尽管解决了数据安全的问题,然而他须要从库写入relay文件并返回ACK才算提交事务,与异步复制比照,他的性能是降落的。 单体在单体中,也同样存在着数据安全和性能的负相关问题。这里简述一下mysql对update语句的一个流程。 当执行update的时候,会先从磁盘里把数据读取到缓存。写入undo文件,这里是在咱们事务回滚的时候用的。批改缓存数据,比方把id为1的name由张三改为李四。写入redo缓存,redo次要是为了宕机重启时,复原数据用的。写入redo缓存后,写入到磁盘。写入binlog文件。写入binlog后,提交commit给redo,跟redo说曾经写入到binlog了。定期把缓存的数据写入到磁盘。咱们对数据的更新,都是在缓存中进行的,这样能够保障性能的进步。同时为了数据的安全性,还引入了undo、redo、binlog等货色。咱们能够看redo和binlog两种写入磁盘的策略。在redo中,咱们能够抉择0,即不把缓存数据写入磁盘,这样能够疾速执行完redo操作,如果此时宕机了,还没写入磁盘的数据就失落了,尽管进步了性能,然而数据安全性没有了。如果抉择1,因为要写入磁盘才能够实现redo操作,尽管保障了数据的安全性,然而性能却降落了。同样的,binlog写入oscache是进步了性能,然而服务器宕机会导致oscache的数据不能及时的写入磁盘,导致数据的安全性没有。如果间接写入磁盘,性能又降落。 redis与mysql已有,redis的复制也是异步复制的,当业务零碎往master写入数据的时候,他就会通过异步复制的形式把数据同步给slave,所以和mysql相似,当业务零碎认为他曾经把数据写入到redis的时候,此时master挂了,然而数据还没同步到slave,他的数据就失落了。另外一个场景,就是产生了脑裂,也就是sentinel认为master挂了,而后从新选举了master,此时业务零碎和master是失常通信的,他把数据提交到原master节点,然而原master节点的数据此时是没方法同步到其余节点,导致数据不统一。在这状况下,咱们会做以下配置: min-replicas-to-write 1min-replicas-max-lag 10这个意思是至多有1个slave曾经有10秒没有同步,则master暂停接管申请。所以不会说master始终写入数据,而slave没有同步。如果产生以上两个场景,最多失落10秒的数据。尽管没有严格的做到数据安全性,然而也保障了数据的不一致性不会超过10秒,超过10秒后,因为不能写数据,写性能降落为0。 RocketMQ咱们看看基于Dledger是怎么做broker同步的。首先,master broker收到音讯后,会把这个音讯置为unconmmited状态,而后把这个音讯发送给slave broker,slave broker收到音讯后,会发送ack进行确认,如果有多个slave broker,当超过一半的slave broker发送ack时,master broker才会把这个音讯置为committed状态。在这种机制下,保障了数据的安全性,当master broker挂了,咱们还有至多超过一半的slave broker的数据是残缺的,因为须要多个slave broker进行ack确认,也升高了性能。从单体上来说,异步刷盘和同步刷盘跟mysql的redo写入磁盘的一样的。另外,kafka的同步机制跟这个相似,而且他也有写入oacache的操作。 ZookeeperZookeeper是CP模型的,那他的数据安全性是能够保障的,那他的性能呢?咱们假如此时master节点挂了,此时须要从新选主,这个时候Zookeeper集群是不可用状态的。那Zookeeper是如何保证数据的一致性呢?咱们假如master同步给5个slave。当master不必确认是否曾经同步给slave就间接返回,这个时候性能是最高的,然而安全性是最低的,因为master数据没同步到slave的时候挂了,那这个数据是失落的。当master确认曾经同步给所有slave(这里是5个)才返回,这个时候,性能是最低的,然而安全性是最高的,因为不论哪个slave,他的数据都是残缺的。不论是RocketMQ还是Zookeeper,都是折中抉择超过一半的slave同步,才算胜利。当咱们拜访Zookeeper的时候,他会依据曾经同步好的slave服务器让咱们来读取对应的信息,这样咱们读取的数据必定都是最新的。

March 15, 2021 · 1 min · jiezi

关于分布式:有道-Kubernetes-容器API监控系统设计和实践

本期文章,咱们将给大家分享有道容器服务API监控计划,这个计划同时具备轻量级和灵活性的特点,很好地体现了k8s集群化治理的劣势,解决了动态配置的监控不满足容器服务监控的需要。并做了易用性和误报消减、可视化面板等一系列优化,目前曾经超过80%的容器服务曾经接入了该监控零碎。 起源/ 有道技术团队微信公众号作者/ 郭超容 王伟静编辑/ hjy 1.背景Kubernetes 曾经成为事实上的编排平台的领导者、下一代分布式架构的代表,其在自动化部署、监控、扩展性、以及治理容器化的利用中曾经体现出独特的劣势。 在k8s容器相干的监控上, 咱们次要做了几块工作,别离是基于prometheus的node、pod、k8s资源对象监控,容器服务API监控以及基于grafana的业务流量等指标监控。 在物理机时代,咱们做了分级的接口性能监控——域名级别接口监控和机器级别监控,以便在某个机器呈现问题时,咱们就能疾速发现问题。 上图中,右边是物理机时代对应的性能监控,包含域名级别接口监控和3台物理机器监控。左边是对应的k8s环境,一个service的流量会由k8s负载平衡到pod1,pod2,pod3中,咱们别离须要增加的是service和各个pod的监控。 因为K8s中的所有资源都是动静的,随着服务版本升级,生成的都是全新的pod,并且pod的ip和原来是不一样的。 综上所述,传统的物理机API不能满足容器服务的监控需要,并且物理机性能监控须要手动运维治理,为此咱们冀望设计一套适配容器的接口性能监控零碎,并且可能高度自动化治理监控信息,实现pod API主动监控。 2.技术选型为了满足以上需要,咱们初期思考了以下几个计划。 1. 手动保护各个service 和pod 监控到目前物理机应用的podmonitor开源监控零碎。2. 重新制定一个蕴含k8s目录树结构的零碎,在这个零碎外面看到的所有信息都是最新的, 在这个零碎外面,能够做咱们的目录树中指定服务的公布、性能监控、测试演练等。 3. 沿用podmonitor框架,反对动静获取k8s集群中最新的服务和pod信息,并更新到监控零碎中。 +计划剖析+针对计划一,思考咱们服务上线的频率比拟高,并且k8s设计思维便是可随时主动用新生成的pod(环境)顶替原来不好用的pod,手动保护pod监控效率太低,该计划不可行。 第二个计划应该是比拟零碎的解决办法,但须要的工作量会比拟大,这种思路根本全本人开发,不能很好的利用已有的性能监控零碎,迁徙老本大。 于是咱们抉择了计划三,既能兼容咱们物理机的接口性能监控计划,又能动静生成和保护pod监控。 3.整体设计思路k8s监控包含以下几个局部:其中API性能监控,是咱们保障业务性能正确性的重要监控伎俩。 通常业务监控零碎都会蕴含监控配置、数据存储、信息展现,告警这几个模块,咱们的API性能监控零碎也不例外。 咱们沿用apimonitor框架性能,并联合了容器服务性能监控特点,和已有的告警体系,造成了咱们容器API性能监控系统结构: 首先介绍下目前咱们物理机应用的apimonitor监控:一个开源的框架https://gitee.com/ecar_team/a... 能够模仿探测http接口、http页面,通过申请耗时和响应后果来判断零碎接口的可用性和正确性。反对单个API和多个API调用链的探测。 如下图所示,第一行监控外面监控的是图片翻译服务域名的地址,后边的是各台物理机的ip:端口。 点开每条监控 咱们沿用apimonitor框架的大部分性能,其中次要的适配和优化包含: 1. 监控配置和存储局部:一是制订容器服务service级别监控命名规定:集群.我的项目.命名空间.服务;(和k8s集群目录树保持一致,不便依据service生成pod监控),二是依据service监控和k8s集群信息动静生成pod级别监控, 2. 监控执行调度器局部不必改变 3. 信息展现局部,减少了趋势图和谬误汇总图表 4. 告警局部,和其它告警应用对立告警组。 4.具体实际操作4.1 增加service 级别API监控告警须要为待监控服务,配置一个固定的容service级别监控。 service级别监控命名规定:集群.我的项目.命名空间.服务 以词典查词服务为例,咱们配置一条service级别的多API监控(也能够是单API监控) · 单API:一个服务只须要加一条case用 · 多API:如果一个服务须要加多条性能case 其中“所属零碎” 是服务所属的告警组,反对电话、短信、popo群、邮件等告警形式(和其它监控告警通用) 工作名称:取名规定,rancher中k8s集群名字.我的项目名字.命名空间名字.service名字(一共四段) 告警音讯的字段含意: docker-dict:告警组,订阅后会收到告警音讯k8s-prod-th:集群dict: 我的项目dict:命名空间data-server:workload名字data-server-5b7d996f94-sfjwn:pod名字{} :接口返回内容, 即:response.contenthttp://dockermonitor.xxx.youdao.com/monitorLog?guid=61bbe71eadf849558344ad57d843409c&name=k8s-prod-th.dict.dict.data-server.data-server-5b7d996f94-sfjwn : 告警具体链接4.2 主动生成pod API监控主动生成上面三行监控工作:(第一行监控是按下面办法配置的容器service ip监控,后边三行是主动生成pod监控工作 ) 监控service级别是单API,则主动生成的是单API,service级别是多API,则主动生成的是多API监控。 ...

March 11, 2021 · 1 min · jiezi

关于分布式:NewSQL分布式数据库例如TIDB用KV的底层逻辑

内容参考对分布式对定义参考这篇文章: 微服务都想用,先把分布式和微服务之间的关系说分明 对分布式架构核心或无核心比照参考这篇文章: 分布式存储单主、多主和无核心架构的特色与趋势 对HDFS对外部机制参考这篇文章: Hadoop分布式文件系统I/O原理机制的深度解读 分布式文件系统HDFS无索引就无K/V首先分布式数据并不是相对的喜爱应用kv存储模式,例如分布式数据库外面mongodb和elasticsearch是文档模式存储,若把HDFS也算进去的话,它是无索引的存储。 上图是HDFS作为分布式数据存储的文件分块存储模式,简略间接,并没有进行任何的kv索引建设。咱们能够看到图中Nginx日志被切割成duo多份,而后散布在三台数据节点上,要留神的是,HDFS的正本个别是三份,图中只做了两份代表正本的意思,但实际上是三份。客户端在进行拜访通信是时候,都是通过数据块scan的形式进行,没有索引,就没有随机拜访机制。 TiDB的架构特色像cockroach,tidb,明明是关系库,为啥非要弄个key,即便业务逻辑不须要表有unique key,也要给每条记录硬加一个key,这是什么目标?其实cockroach,tidb都叫NewSQL,是NoSQL+关系型数据库的合体,认为它们是关系库,说得不失当。 例如:tidb分为PD、TIKV、TIDB,PD管理者kv的关系构造,这部分能够对标关系型数据库。 上图是TIDB的架构图,图中能够看到TIDB造成的集群次要是接管内部利用的SQL,解决SQL的逻辑,与PD交互获取KV地址,与KV交互获取数据; PD组成的集群次要是通过元数据的语义了解kv在集群中的地位,实现对KV集群的调度和负载平衡,调配全局事务ID; TIKV就是咱们说到的重点,通过Key-Value存储引擎,提供分布式事务能力。每个节点有多个Region,Region存储一个范畴Key的数据——Key Range,次要是为了造成间断的小组,在部分提供写入和读取的性能劣势。并且以Region作为原子单元,实现集群跨节点的正本复制,复制形式用Raft协定实现。 实际上TIKV局部就是规范的NoSQL为根底的数据长久化层了,TIKV的长久化数据层就是RocksDB,同样的cockroach长久化数据层也用的是RocksDB,RocksDB的就是LSM-Tree的日志追加形式WAL (write ahead log)疾速写入数据,再通过LSM-Tree的memtable,sstable构造,索引key,获取value,所以就是个规范的key/value数据库。 RocksDB的外围劣势LSM-Tree构造为什么它们不谋而合的都抉择了RocksDB,因为作为外围构造LSM树的WAL,memtable,sstable形式具备写入数据的微小劣势并保证数据可靠性,造成很多小的程序分组,同时又失去部分热点上的惊人查问劣势,在内存中实现查找。 而且LSM-Tree配合Bloom Filter又能将工夫线作为优先级,疾速索引数据在磁盘中的地位范畴,这就大大减少扫描磁盘的动作。 若遇到大范畴随机查找,Bloom Filter有也查不到地位的状况,才会通过二分查找,并在树的不同层进行多路合并,取优先级最高的数据。 那么通过这种思路,就能比关系型数据库的b/b+树索引在写的性能方面带来质的晋升,而且对于部分热点,也就是近期数据带来惊人的查问性能,尽管全局范畴的查问有所升高,数据段合并会带来的资源耗费(rocksdb通过多线程合并晋升了这一过程的效率),但数据库读写的整体性能的平衡性变得更正当了,总之未来通过集群解决读的问题总是比解决写的问题更容易,这就是抉择key/value数据库的底层逻辑。 NewSQL绝对于MySQL的劣势反观关系型数据库,例如要给MySQL加上一条索引,那么索引字段就是key。所以RDBMS也不能说本人跟key/value存储没啥分割。 作为业务逻辑上不须要unique key而非要加一个key,这是因为关系型数据库设计的初衷就不是为了海量数据的疾速写入和查找所设计的,即使没有索引,行集扫描也没有问题,这才是常态是其本质,这和Hadoo HDFS的按块扫描一样,都是一种原始的状态,HDFS之上仍然须要HBase数据库来解决海量数据的随机查找场景,实质上作为列族分类的HBase也是Key/Value模式。 NewSQL抉择了RocksDB,也就是抉择了业务记录中key存在的必须,但换来的是海量数据的高效写入和查找,十分划算。 返回读字节的知乎——理解更多对于大数据的常识公众号“读字节” 分布式,大数据,软件架构的深度,业余解读

March 10, 2021 · 1 min · jiezi

关于分布式:微服务想用好先把分布式和微服务之间的关系搞清楚

一、分布式和微服务架构的定义分布式应用场景涵盖的面十分广,我了解的局部: 不同过程之间的相互通信,不同主机的分布式对象之间调用,用于大数据存储的分布式文件系统,用于网络之间互相辨认的命名服务,集群中计算或存储的无核心对等模型,分布式事务,数据正本在分布式环境中的复制,云计算服务,音视频在网络中的点播和传输....微服务架构的目标是对原来过于大而重的云应用服务进行解耦,伎俩是进行比拟正当的业务模块拆解,拆解的粒度往往由架构师把握,实现细粒度的服务,服务在云端造成分布式状态。 那么微服务就具备了分布式的一些利用场景,比方:不同主机的分布式对象之间调用,以前EJB用RMI(近程办法调用),当初微服务罕用RPC(近程过程调用);再比方:用于网络之间互相辨认的命名服务,以前EJB是JNDI命名服务,当初SpringCloud的Euraka用于微服务的注册和发现,也是分布式是命名服务。 如何艰深地了解「分布式系统」,它解决了哪些问题,有什么优缺点? 了解「分布式系统」已经产生的事件 下面是我另外一个答复,外面比拟具体地形容了历史上过来EJB和Spring的比拟,也是分布式与单体利用的比拟。那时候EJB代表分布式服务,而spring代表单体服务。 下面的图简略的描述了一种最简略的单体服务向微服务拆解的过程。当然微服务面临的挑战不仅仅这么简略,这只是微服务的一种比拟初始的状态。 二、分布式和微服务这两者解决了什么问题分布式是计算、服务、存储在网络中相互交换与合作的模式和状态 分布式到底解决了什么? 上图就是典型的分布式计算,一个大文件被切分成四份,MapReduce分成四个工作(过程),而后在同一主机不同过程,或不同主机上进行数据处理,最终再通过网络汇聚到一个合并工作。那么这个时候到分布式就是工作并行,解决了单任务的效率问题。 上图是个典型的分布式状态协调治理图,是Hadoop HDFS集群的HA高可用架构,主副两个Namonode节点,必须活着一个,当判断主的挂了,必须让副的顶上去,这个时候,三个ZK(zookeeper)组成的集群就是作为主副节点的协调者,通过ZKFC过程实现对Namoenode节点的心跳监控和切换命令下发。 另外三个Journalnode节点造成的集群又是namonode分布式状态数据保留的中央,当主namonode挂了,所有的状态必须疾速的复原到副namenode的下面,所以Journalnode必须继续同步状态,满足hdfs集群状态的疾速复原 那么分布式中十分要害的一个利用场景——集群,上述的Hadoop hdfs集群,就须要有一个或几个角色(zookeeper,Journalnode),作为集群状态的协调者和管理者。有时候这种状态治理是对等的(GlusterFS),有时候这种状态治理是集中的(Hadoop就是这样)。 微服务又解决了什么问题呢? 如果这时候在提微服务的分布式劣势,就不是目标,而是伎俩了。微服务只是借助了分布式架构,达到了本人的目标。所以微服务不是根底技术架构的问题,而是下层利用的架构问题。 下面的例子是个简略的互联网医疗服务单体利用,这时候问诊、药品、订单、即时消息都是互联网医疗最外围的业务,信息推送目标是将互联网医疗平台的各类信息进行互联网信息服务平台的推送、公布和交换,达到自我推广的目标。 可恰好信息推送服务的更新水平很高,因为须要对外连贯的互联网服务平台状况简单,也会有新的服务平台纳入到模块范畴,那么作为单体利用就存在这样一个部署问题,每次更新一个新的信息推送性能,就要整体服务重新部署一次,那么这种影响对于外围服务就造成了很大的困扰,这时候的患者、医生、医院的业务影响都是大规模的。 再看看微服务架构,如果将信息推送服务作为独自的微服务存在,其余微服务只是将须要推送到互联网服务平台的内容进行近程调用即可,甚至用音讯核心的形式,打包成音讯,实现音讯事件驱动,让对外公布服务的部署不会干涉到其余外围服务,使得整体平台因为部署公布而造成的影响降到最低。这种形式是不是看起来就难受多了,十分利于部署、公布,甚至加强了整体零碎的鲁棒性。 当然微服务解决的问题还有很多,团队分工的细粒度、迭代速度的晋升、更易于小范畴重构,利于继续化集成(devops)等等,就不一一具体形容了,只把它很有特点的局部拿进去了解一下。 三、这些架构带来的利弊分布式对应的是就是单机,其长处上节形容了一些,就不赘述了,毛病也很大部署不简略,运维不简略网络瓶颈和故障会有重要的影响,节点若生效,就要有觉察和热替换机制,一致性问题,例如分布式事务始终是世界性难题,不仅要思考平衡负载,更要思考平衡负载的成果。数据进行分布式存储,在有些对等模式下还要思考数据歪斜问题。微服务除了分布式存储毛病6之外,上述前5个毛病基本上都完满的继承了。 四、利用不当所带来的技术债权说说微服务设计不当的麻烦问题吧 (1)微服务解耦后,会将一些业务程序从原来数据库查问的形式,转变成近程对象调用,这个过程我在原来的答复中提过,这是反兽性的。造成复杂度和须要约定的接口都带来了比SQL查问更大的工作量。而且更反兽性的形式就是数据库也跟着微服务进行分库,到底哪些数据须要冗余,哪些数据还能放弃数据库范式,根本都能把高程们烦死。 (2)教训欠缺的微服务架构师,容易将微服务切得太细,如果一个单体若被切分成一千个微服务,而且微服务之间用到了近程对象序列化和反序列化,那么这就成了死穴!因为一旦一个微服务的实体对象进行了调整,那么有多少个关联的微服务被净化了,就要一直定位其余微服务的依赖关系并从新公布,这种工作量曾经超出了本该解决业务问题的工作量。 因而微服务的划分肯定要留神,而且RPC之间的对象传递尽量用简略、涣散的构造来做。微服务划分的水平依据业务不同而粒度不同,有种约定是一个微服务进行大的重构,须要一周的工夫,做为微服务粒度规范。 五、我的项目间接应用微服务架构, 是基于对将来的思考?微服务架构的思考,不应该是对将来的思考,而是对过来单体式利用呈现问题后的一种架构重构,从第一节中的图能够看到其重构过程,在互联网医疗的例子中微服务的重构进一步趋向于音讯驱动、事件驱动。 从以往施行微服务的经验教训中,我总结进去的教训,如果是新我的项目的架构师,能够先抉择单体利用,而后依据业务倒退一点点迭代重构到微服务上来,即使过程中微服务的架构不那么纯正,甚至单体利用和微服务很长一段时间共存,也要谨慎从新的我的项目上间接去设计微服务。 因为谁也不是算命先生,能估算到本人业务零碎会在哪一天,哪个层面,哪个范畴就肯定须要微服务化解耦。只有零碎运行快到那个阶段了,能力让架构师更容易做到正当的微服务化决策。当然了,也有人会有纳闷,零碎设计成单体,谁还有心理持续重构微服务,不如间接做成微服务架构多省事,而我想说的是,若无重构之力行,切勿有微服务之念想。 六、K8s和Spring Cloud有什么区别和分割?Spring Cloud是贯彻微服务架构的一种具体实现框架,包含了springboot作为微服务的独立运行容器,Euraka作为微服务的注册和发现,zuul服务网关,其余的没怎么用,就不提,其实网关我更喜爱用Openresty。 k8s只是容器的一种编排框架,管理者大量的docker容器,然而当初k8s又不集成docker了,晕得很! docker作为微服务的容器,为每一个微服务都提供了独自的网络、文件系统、过程治理等基础设施,这样每个微服务的状态、运行日志能够更好的被监控和治理。另外容器让部署过程变得简略,促成了当初风行的devops开发、公布、部署一体的管理模式,微服务的容器化其实是天生一对。 七、结尾当咱们了解分明分布式下的各种场景是什么的一种存在模式的时候,当咱们了解微服务又是一种什么分布式场景的时候,咱们就更能分明的去做好微服务的设计决策。 返回读字节的知乎——理解更多对于大数据的常识公众号“读字节” 分布式,大数据,软件架构的深度,业余解读

March 8, 2021 · 1 min · jiezi

关于分布式:分布式要点数据分区

采纳数据分区的次要目标是进步可扩展性。不同的分区能够放在一个无共享集群的不同节点上。这样一个大数据集能够扩散在更多的磁盘上,查问负载也随之散布到更多的处理器上。 对单个分区进行查问时,每个节点对本人所在分区能够独立执行查问操作,因而增加更多的节点能够进步查问吞吐量。超大而简单的查问只管比拟艰难,但也可能做到跨节点的并行处理。 分区通常与复制联合应用,即每个分区在多个节点都存有正本。这意味着某条记录属于特定的分区,而同样的内容会保留在不同的节点上以进步零碎的容错性。 一个节点上可能存储了多个分区。每个分区都有本人的主正本,而从正本则调配在其余一些节点。一个节点可能即是某些分区的主正本,同时又是其余分区的从正本。 键-值数据的分区当初假如数据是简略的键-值数据模型,这意味着总是能够通过关键字来拜访记录。 基于关键字区间分区一种分区形式是为每个分区调配一段间断的关键字或者关键字区间范畴(以最小值和最大值来批示)。如果晓得关键字区间的上上限,就能够轻松确定哪个分区蕴含这些关键字。如果还晓得哪个分区调配在哪个节点,就能够间接向该节点发出请求。 关键字的区间段不肯定非要均匀分布,这次要是因为数据自身可能就不平均。分区边界能够由管理员手动确定,或者由数据库主动抉择。每个分区内能够依照关键字排序保留,这样能够轻松反对区间查问,行将关键字作为一个拼接起来的索引项从而一次查问失去多个相干记录。例如,对于一个保留网络传感器数据的利用零碎,抉择测量的工夫戳(年-月-日-时-分-秒)作为关键字,此时区间查问会十分有用,它能够疾速取得某个月份内的所有数据。 然而,基于关键字的区间分区的毛病是某些拜访模式会导致热点。如果关键字是工夫戳,则分区对应于一个工夫范畴,例如每天一个分区。然而,当测量数据从传感器写入数据库时,所有的写入操作都集中在同一个分区(即当天的分区),这会导致该分区在写入时负载过高,而其余分区始终处于闲暇状态。 为了防止上述问题,须要应用工夫戳以外的其余内容作为关键字的第一项。例如,能够在工夫戳后面加上传感器名称作为前缀,这样首先由传感器名称,而后按工夫进行分区。假如同时有许多传感器处于活动状态,则写入负载最终会比拟平均地散布在多个节点上。接下来,当须要获取一个工夫范畴内、多个传感器的数据时,能够依据传感器名称,各自执行区间查问。 基于关键字哈希值分区对于上述数据歪斜与热点问题,许多分布式系统采纳了基于关键字哈希函数的形式来分区。 一个好的哈希函数能够解决数据歪斜并使其均匀分布。一旦找到适合的关键字哈希函数,就能够为每个分区调配一个哈希范畴(而不是间接作用于关键字范畴),关键字依据其哈希值的范畴划分到不同的分区中。 这种办法能够很好地将关键字平均地调配到多个分区中。分区边界能够是平均距离,也能够是伪随机抉择(在这种状况下,该技术有时被称为一致性哈希)。 然而,通过关键字哈希进行分区,咱们丢失了良好的区间查问个性。即便关键字相邻,但通过哈希之后会扩散在不同的分区中,区间查问就失去了原有的有序相邻的个性。 负载歪斜与热点如前所述,基于哈希的分区办法能够加重热点,但无奈做到完全避免。一个极其状况是,所有的读/写操作都是针对同一个关键字,则最终所有申请都将被路由到同一个分区。 这种负载或者并不广泛,但也并非不可能:例如,社交媒体网站上,一些名人用户有数百万的粉丝,当其公布一些热点事件时可能会引发一场拜访风暴,呈现大量的对雷同关键字的写操作(其中关键字可能是名人的用户ID,或者人们正在评论的事件ID)。此时,哈希起不到任何帮忙作用,因为两个雷同ID的哈希值依然雷同。 大多数的零碎明天依然无奈主动打消这种高度歪斜的负载,而只能通过应用层来加重歪斜水平。例如,如果某个关键字被确认为热点,一个简略的技术就是在关键字的结尾或结尾处增加一个随机数。只需一个两位数的十进制随机数就能够将关键字的写操作散布到100个不同的关键字上,从而调配到不同的分区上。 然而,随之而来的问题是,之后的任何读取都须要些额定的工作,必须从所有100个关键字中读取数据而后进行合并。因而通常只对大量的热点关键字附加随机数才有意义;而对于写入吞吐量低的绝大多数关键字,这些都意味着不必要的开销。此外,还须要额定的元数据来标记哪些关键字进行了非凡解决。 分区与二级索引在分区方案设计中,如果波及二级索引,状况会变得复杂。二级索引通常不能惟一标识一条记录,而是用来减速特定值的查问。二级索引是关系数据库的必备个性,在文档数据库中利用也十分广泛。 二级索引带来的次要挑战是它们不能规整的地映射到分区中。有两种次要的办法来反对对二级索引进行分区:基于文档的分区和基于词条的分区。 基于文档的二级索引在这种索引办法中,每个分区齐全独立,各自保护本人的二级索引,且只负责本人分区内的文档而不关怀其余分区中数据。每当须要写数据库时,包含增加,删除或更新文档等,只须要解决蕴含指标文档ID的那一个分区。因而文档分区索引也被称为本地索引,而不是全局索引。 但读取时须要留神:除非对文档ID做了特地的解决,否则不太可能所有特定查问条件的数据都放在一个分区中。因而须要将查问发送到所有的分区,而后合并所有返回的后果。 这种查问分区数据库的办法有时也称为扩散/汇集,显然这种二级索引的查问代价昂扬。即便采纳了并行查问,也容易导致读提早显著放大。 基于词条的二级索引另一种办法,咱们能够对所有的数据构建全局索引,而不是每个分区保护本人的本地索引。而且,为防止成为瓶颈,不能将全局索引存储在一个节点上,否则就毁坏了设计分区平衡的指标。所以,全局索引也必须进行分区,且能够与数据关键字采纳不同的分区策略。 和后面探讨的办法一样,能够间接通过关键词来全局划分索引,或者对其取哈希值。间接分区的益处是能够反对高效的区间查问;而采纳哈希的形式则能够更平均的划分分区。 这种全局的词条分区相比于文档分区索引的次要长处是,它的读取更为高效,即它不须要采纳scatter/gather对所有的分区都执行一遍查问,相同,客户端只须要向蕴含词条的那一个分区收回读申请。然而全局索引的不利之处在于,写入速度较慢且非常复杂,次要因为单个文档的更新时,外面可能会波及多个二级索引,而二级索引的分区又可能齐全不同甚至在不同的节点上,由此势必引入显著的写放大。 实际中,对全局二级索引的更新往往都是异步的。 分区再均衡迁徙负载的过程称为再均衡(或者动态平衡)。无论对于哪种分区计划,分区再均衡通常至多要满足: 均衡之后,负载、数据存储、读写申请等应该在集群范畴更平均地散布。再均衡执行过程中,数据库应该能够持续失常提供读写服务。防止不必要的负载迁徙,以放慢动静再均衡,并尽量减少网络和磁盘I/O影响。动静再均衡的策略为什么不必取模?对节点数取模办法的问题是,如果节点数N产生了变动,会导致很多关键字须要从现有的节点迁徙到另一个节点。这种频繁的迁徙操作大大增加了再均衡的老本。 固定数量的分区有一个相当简略的解决方案:首先,创立远超理论节点数的分区数,而后为每个节点调配多个分区。例如,对于一个10节点的集群,数据库能够从一开始就逻辑划分为1000个分区,这样大概每个节点承当100个分区。 接下来,如果集群中增加了一个新节点,该新节点能够从每个现有的节点上匀走几个分区,直到分区再次达到全局均衡。如果从集群中删除节点,则采取相同的平衡措施。 选中的整个分区会在节点之间迁徙,但分区的总数量仍维持不变,也不会扭转关键字到分区的映射关系。这里惟一要调整的是分区与节点的对应关系。思考到节点间通过网络传输数据总是须要些工夫,这样调整能够逐渐实现,在此期间,旧的分区依然能够接管读写申请。 原则上,也能够将集群中的不同的硬件配置因素思考进来,即性能更弱小的节点将调配更多的分区,从而分担更多的负载。 如果数据集的总规模高度不确定或可变,此时如何抉择适合的分区数就有些艰难。每个分区蕴含的数据量的下限是固定的,理论大小应该与集群中的数据总量成正比。如果分区里的数据量十分大,则每次再均衡和节点故障复原的代价就很大;然而如果一个分区太小,就会产生太多的开销。分区大小应该“恰到好处”,不要太大,也不能过小,如果分区数量固定了但总数据量却高度不确定,就难以达到一个最佳取舍点。 动静分区对于采纳关键字区间分区的数据库,如果边界设置有问题,最终可能会呈现所有数据都挤在一个分区而其余分区根本为空,那么设定固定边界、固定数量的分区将十分不便,而手动去重新配置分区边界又十分繁琐。 因而,一些数据库如HBase等采纳了动态创建分区。当分区的数据增长超过一个可配的参数阈值,它就拆分为两个分区,每个承当一半的数据量。如果大量数据被删除,并且分区放大到某个阈值以下,则将其与相邻分区进行合并。该过程相似于B树的决裂操作。 每个分区总是调配给一个节点,而每个节点能够承载多个分区,这点与固定数量的分区一样。当一个大的分区产生决裂之后,能够将其中的一半转移到其余某节点以均衡负载。 动静分区的一个长处是分区数量能够主动适配数据总量。如果只有大量的数据,大量的分区就足够了,这样零碎开销很小;如果有大量的数据,每个分区的大小则被限度在一个可配的最大值。 按节点比例分区采纳动静分区策略,拆分和合并操作使每个分区的大小维持在设定的最小值和最大值之间,因而分区的数量与数据集的大小成正比关系。另一方面,对于固定数量的分区形式,其每个分区的大小也与数据集的大小成正比。两种状况,分区的数量都与节点数无关。 Cassandra和Ketama则采纳了第三种形式,使分区数与集群节点数成正比关系。换句话说,每个节点具备固定数量的分区。此时,当节点数不变时,每个分区的大小与数据集大小放弃反比的增长关系;当节点数减少时,分区则会调整变得更小。较大的数据量通常须要大量的节点来存储,因而这种办法也使每个分区大小保持稳定。 当一个新节点退出集群时,它随机抉择固定数量的现有分区进行决裂,而后拿走这些分区的一半数据量,将另一半数据留在原节点。随机抉择可能会带来不太偏心的分区决裂,然而当均匀分区数量较大时,新节点最终会从现有节点中拿走相当数量的负载。 随机抉择分区边界的前提要求采纳基于哈希分区(能够从哈希函数产生的数字范畴里设置边界)。这种办法也最合乎本章结尾所定义一致性哈希。一些新设计的哈希函数也能够以较低的元数据开销达到相似的成果。 申请路由概括来讲,这个问题有以下几种不同的解决策略(别离如图所示的三种状况): 容许客户端连贯任意的节点(例如,采纳循环式的负载均衡器)。如果某节点恰好领有所申请的分区,则间接解决该申请;否则,将申请转发到下一个适合的节点,接管回答,并将回答返回给客户端。将所有客户端的申请都发送到一个路由层,由后者负责将申请转发到对应的分区节点上。路由层自身不解决任何申请,它仅充一个分区感知的负载均衡器。客户端感知分区和节点分配关系。此时,客户端能够间接连贯到指标节点,而不须要任何中介。 这其实是一个很有挑战性的问题,所有参与者都要达成共识这一点很重要。否则申请可能被发送到谬误的节点,而没有失去正确处理。分布式系统中有专门的共识协定算法,但通常难以正确实现。 许多分布式数据系统依附独立的协调服务(如ZooKeeper)跟踪集群范畴内的元数据。每个节点都向ZooKeeper中注册本人,ZooKeeper保护了分区到节点的最终映射关系。其余参与者(如路由层或分区感知的客户端)能够向ZooKeeper订阅此信息。一旦分区产生了扭转,或者增加、删除节点,ZooKeeper就会被动告诉路由层,这样使路由信息放弃最新状态。 Cassandra和Riak则采纳了不同的办法,它们在节点之间应用gossip协定来同步群集状态的变动。申请能够发送到任何节点,由该节点负责将其转发到指标分区节点。这种形式减少了数据库节点的复杂性,然而防止了对ZooKeeper之类的内部协调服务的依赖。 当应用路由层或随机抉择节点发送申请时,客户端依然须要晓得指标节点的IP地址。IP地址的变动往往没有分区-节点变动那么频繁,采纳DNS通常就足够了。

March 7, 2021 · 1 min · jiezi

关于分布式:分布式要点数据复制

复制次要指通过互联网在多台机器上保留雷同数据的正本。通过数据复制计划,人们通常心愿达到以下目标: 使数据在地理位置上更靠近用户,从而升高拜访提早。当局部组件呈现故障,零碎仍然能够持续工作,从而进步可用性。扩大至多台机器以同时提供数据拜访服务,从而进步读吞吐量。主节点与从节点每个保留数据库残缺数据集的节点称之为正本。对于每一笔数据写入,所有正本都须要随之更新;否则,某些正本将呈现不统一。最常见的解决方案是基于主节点的复制(也称为被动/被动,或主从复制)。主从复制的工作原理如下: 指定某一个正本为主正本。当客户写数据库时,必须将写申请首先发送给主正本,主正本首先将新数据写入本地存储。主正本把新数据写入本地存储后,而后将数据更改作为复制的日志或更改流发送给所有从正本。每个从正本取得更改日志之后将其利用到本地,且严格放弃与主正本雷同的写入程序。客户端从数据库中读数据时,能够在主正本或者从正本上执行查问。只有主正本才能够承受写申请,从正本都是只读的。同步复制与异步复制复制十分重要的一个设计选项是同步复制还是异步复制。对于关系数据库系统,同步或异步通常是一个可配置的选项。 如下图,网站用户须要更新首页的头像图片。其根本流程是,客户将更新申请发送给主节点,主节点接管到申请,接下来将数据更新转发给从节点。最初,由主节点来告诉客户更新实现。 从节点1的复制是同步的,即主节点需期待直到从节点1确认实现了写入,而后才会向用户报告实现,并且将最新的写入对其余客户端可见。而从节点2的复制是异步的:主节点发送完音讯之后立刻返回,不必期待从节点2的实现确认。 同步复制的长处是,一旦向用户确认,从节点能够明确保障实现了与主节点的更新同步,数据曾经处于最新版本。万一主节点产生故障,总是能够在从节点持续拜访最新数据。毛病则是,如果同步的从节点无奈实现确认(例如因为从节点产生解体,或者网络故障,或任何其余起因),写入就不能视为胜利。主节点会阻塞其后所有的写操作,直到同步正本确认实现。 因而,把所有从节点都配置为同步复制有些不切实际。因为这样的话,任何一个同步节点的中断都会导致整个零碎更新停滞不前。实际中,如果数据库启用了同步复制,通常意味着其中某一个从节点是同步的,而其余节点则是异步模式。万一同步的从节点变得不可用或性能降落,则将另一个异步的从节点晋升为同步模式。这样能够保障至多有两个节点(即主节点和一个同步从节点)领有最新的数据正本。这种配置有时也称为半同步。 主从复制还常常会被配置为全异步模式。此时如果主节点产生失败且不可复原,则所有尚未复制到从节点的写申请都会失落。这意味着即便向客户端确认了写操作,却无奈保证数据的长久化。但全异步配置的长处则是,不论从节点上数据如许滞后,主节点总是能够持续响应写申请,零碎的吞吐性能更好。 配置新的从节点如果须要减少新的从节点,如何确保新的从节点和主节点保持数据统一呢?逻辑上的次要操作步骤如下: 在某个工夫点对主节点的数据正本产生一个一致性快照,这样防止长时间锁定整个数据库。将此快照拷贝到新的从节点。从节点连贯到主节点并申请快照点之后所产生的数据更改日志。因为在第一步创立快照时,快照与零碎复制日志的某个确定地位相关联,这个地位信息在不同的零碎有不同的称说,如MySQL将其称为“binlog coordinates”。取得日志之后,从节点来利用这些快照点之后所有数据变更,这个过程称之为追赶。接下来,它能够失常解决主节点上新的数据变动。解决节点生效从节点生效:追赶式复原从节点的本地磁盘上都保留了正本收到的数据变更日志。如果从节点产生解体,而后顺利重启,或者主从节点之间的网络产生临时中断(闪断),则复原比拟容易,依据正本的复制日志,从节点能够晓得在产生故障之前所解决的最初一笔事务,而后连贯到主节点,并申请自那笔事务之后中断期间内所有的数据变更。在收到这些数据变更日志之后,将其利用到本地来追赶主节点。之后就和失常状况一样继续接管来自主节点数据流的变动。 主节点生效:节点切换解决主节点故障的状况则比拟辣手:抉择某个从节点将其晋升为主节点;客户端也须要更新,这样之后的写申请会发送给新的主节点,而后其余从节点要承受来自新的主节点上的变更数据,这一过程称之为切换。 故障切换能够手动进行,或者以主动形式进行。主动切换的步骤通常如下: 确认主节点生效。有很多种出错可能性,所以大多数零碎都采纳了基于超时的机制:节点间频繁地相互产生发送心跳存活音讯,如果发现某一个节点在一段比拟长时间内(例如30s)没有响应,即认为该节点产生生效。选举新的主节点。能够通过选举的形式(超过少数的节点达成共识)来选举新的主节点,或者由之前选定的某管制节点来指定新的主节点。候选节点最好与原主节点的数据差别最小,这样能够最小化数据失落的危险。重新配置零碎使新主节点失效。客户端当初须要将写申请发送给新的主节点。如果原主节点之后从新上线,这时零碎要确保原主节点降级为从节点,并认可新的主节点。然而,上述切换过程仍然充斥了很多变数: 如果应用了异步复制,且生效之前,新的主节点并未收到原主节点的所有数据;在选举之后,原主节点很快又从新上线并退出到集群,接下来新的主节点很可能会收到抵触的写申请。这是因为原主节点未意识的角色变动,还会尝试同步其余从节点,但其中的一个当初曾经接管成为现任主节点。常见的解决方案是,原主节点上未实现复制的写申请就此抛弃,但这可能会违反数据更新长久化的承诺。如果在数据库之外有其余零碎依赖于数据库的内容并在一起协同应用,抛弃数据的计划就特地危险。例如,在GitHub的一个事变中,某个数据并非齐全同步的MySQL从节点被晋升为主正本,数据库应用了自增计数器将主键调配给新创建的行,然而因为新的主节点计数器落后于原主节点,它从新应用了已被原主节点调配进来的某些主键,而恰好这些主键已被内部Redis所援用,后果呈现MySQL和Redis之间的不统一。在某些故障状况下,可能会产生两个节点同时都自认为是主节点。这种状况被称为脑裂,它十分危险:两个主节点都可能承受写申请,并且没有很好解决抵触的方法,最初数据可能会失落或者毁坏。作为一种平安应急计划,有些零碎会采取措施来强制敞开其中一个节点。然而,如果设计或者实现考虑不周,可能会呈现两个节点都被敞开的状况。如何设置适合的超时来检测主节点生效?主节点生效后,超时工夫设置得越长也意味着总体复原工夫就越长。但如果超时设置太短,可能会导致很多不必要的切换。例如,突发的负载峰值会导致节点的响应工夫变长甚至超时,或者因为网络故障导致提早减少。如果零碎此时曾经处于高负载压力或网络曾经呈现重大拥塞,不必要的切换操作只会使总体状况变得更糟。对于这些问题没有简略的解决方案。因而,即便零碎可能反对主动故障切换,有些运维团队依然更违心以手动形式来管制整个切换过程。 复制日志的实现基于语句的复制主节点记录所执行的每个写申请(操作语句)并将该操作语句作为日志发送给从节点。对于关系数据库,这意味着每个INSERT、UPDATE或DELETE语句都会转发给从节点,并且每个从节点都会剖析并执行这些SQL语句,如同它们是来自客户端那样。 但这种复制形式有一些不实用的场景: 任何调用非确定性函数的语句,如NOW()获取以后工夫,或RAND()获取一个随机数等,可能会在不同的正本上产生不同的值。如果语句中应用了自增列,或者依赖于数据库的现有数据(例如,UPDATE ...WHERE<某些条件>),则所有正本必须依照完全相同的程序执行,否则可能会带来不同的后果。进而,如果有多个同时并发执行的事务时,会有很大的限度。有副作用的语句(例如,触发器、存储过程、用户定义的函数等),可能会在每个正本上产生不同的副作用。基于预写日志传输无论是日志构造的存储引擎,还是B-tree构造的存储引擎,所有对数据库写入的字节序列都被记入日志。因而能够应用完全相同的日志在另一个节点上构建正本:除了将日志写入磁盘之外,主节点还能够通过网络将其发送给从节点。 从节点收到日志进行解决,建设和主节点内容完全相同的数据正本。其次要毛病是日志形容的数据后果十分底层:一个WAL蕴含了哪些磁盘块的哪些字节产生扭转,诸如此类的细节。这使得复制计划和存储引擎严密耦合。如果数据库的存储格局从一个版本改为另一个版本,那么零碎通常无奈反对主从节点上运行不同版本的软件。 基于行的逻辑日志复制另一种办法是复制和存储引擎采纳不同的日志格局,这样复制与存储逻辑剥离。这种复制日志称为逻辑日志,以辨别物理存储引擎的数据表示。 关系数据库的逻辑日志通常是指一系列记录来形容数据表行级别的写申请: 对于行插入,日志蕴含所有相干列的新值。对于行删除,日志里有足够的信息来惟一标识已删除的行,通常是靠主键,但如果表上没有定义主键,就须要记录所有列的旧值。对于行更新,日志蕴含足够的信息来惟一标识更新的行,以及所有列的新值(或至多蕴含所有已更新列的新值)。如果一条事务波及多行的批改,则会产生多个这样的日志记录,并在前面跟着一条记录,指出该事务曾经提交。MySQL的二进制日志binlog(当配置为基于行的复制时)应用该形式。 因为逻辑日志与存储引擎逻辑解耦,因而能够更容易地放弃向后兼容,从而使主从节点可能运行不同版本的软件甚至是不同的存储引擎。 复制滞后问题主从复制要求所有写申请都经由主节点,而任何正本只能承受只读查问。在这种扩大体系下,只需增加更多的从正本,就能够进步读申请的服务吞吐量。然而,这种办法实际上只能用于异步复制,如果试图同步复制所有的从正本,则单个节点故障或网络中断将使整个零碎无奈写入。而且节点越多,产生故障的概率越高,所以齐全同步的配置事实中反而十分不牢靠。 如果一个利用正好从一个异步的从节点读取数据,而该正本落后于主节点,则利用可能会读到过期的信息。这会导致数据库中呈现显著的不统一,这种不统一只是一个临时的状态,如果进行写数据库,通过一段时间之后,从节点最终会赶上并与主节点保持一致。这种效应也被称为最终一致性。 总的来说,正本落后的水平实践上并没有下限。失常状况下,主节点和从节点上实现写操作之间的时间延迟(复制滞后)可能有余1秒,这样的滞后,在实践中通常不会导致太大影响。然而,如果零碎已靠近设计下限,或者网络存在问题,则滞后可能轻松减少到几秒甚至几分钟不等。 读本人的写许多利用让用户提交一些数据,接下来查看他们本人所提交的内容。提交新数据须发送到主节点,然而当用户读取数据时,数据可能来自从节点。 对于异步复制存在这样一个问题,如图所示,用户在写入不久即查看数据,则新数据可能尚未达到从节点。对用户来讲,看起来仿佛是刚刚提交的数据失落了。 基于主从复制的零碎该如何实现写后读一致性呢?有多种可行的计划,以下例举一二: 如果用户拜访可能会被批改的内容,从主节点读取;否则,在从节点读取。这背地就要求有一些办法在理论执行查问之前,就曾经晓得内容是否可能会被批改。例如,社交网络上的用户首页信息通常只能由所有者编辑,而其他人无奈编辑。因而,这就造成一个简略的规定:总是从主节点读取用户本人的首页配置文件,而在从节点读取其余用户的配置文件。如果利用的大部分内容都可能被所有用户批改,那么上述办法将不太无效,它会导致大部分内容都必须经由主节点,这就丢失了读操作的扩展性。此时须要其余计划来判断是否从主节点读取。例如,跟踪最近更新的工夫,如果更新后一分钟之内,则总是在主节点读取;并监控从节点的复制滞后水平,防止从那些滞后工夫超过一分钟的从节点读取。客户端还能够记住最近更新时的工夫戳,并附带在读申请中,据此信息,零碎能够确保对该用户提供读服务时都应该至多蕴含了该工夫戳的更新。如果不够新,要么交由另一个副原本解决,要么期待直到正本接管到了最近的更新。工夫戳能够是逻辑工夫戳(例如用来批示写入程序的日志序列号)或理论零碎时钟(在这种状况下,时钟同步又成为一个关键点)。如果正本散布在多数据中心(例如思考与用户的天文靠近,以及高可用性),状况会更简单些。必须先把申请路由到主节点所在的数据中心(该数据中心可能离用户很远)。如果同一用户可能会从多个设施拜访数据,例如一个桌面Web浏览器和一个挪动端的利用,状况会变得更加简单。此时,要提供跨设施的写后读一致性,即如果用户在某个设施上输出了一些信息而后在另一台设施上查看,也应该看到刚刚所输出的内容。在这种状况下,还有一些须要思考的问题: 记住用户上次更新工夫戳的办法实现起来会比拟艰难,因为在一台设施上运行的代码齐全无奈晓得在其余设施上产生了什么。此时,元数据必须做到全局共享。如果正本散布在多数据中心,无奈保障来自不同设施的连贯通过路由之后都达到同一个数据中心。例如,用户的台式计算机应用了家庭宽带连贯,而挪动设施则应用蜂窝数据网络,不同设施的网络连接线路可能齐全不同。如果计划要求必须从主节点读取,则首先须要想方法确保将来自不同设施的申请路由到同一个数据中心。枯燥读假设用户从不同正本进行了屡次读取,如图所示,用户刷新一个网页,读申请可能被随机路由到某个从节点。用户2345先后在两个从节点上执行了两次完全相同的查问(先是大量滞后的节点,而后是滞后很大的从节点),则很有可能呈现以下状况。第一个查问返回了最近用户1234所增加的评论,但第二个查问因为滞后的起因,还没有收到更新因此返回后果是空。 实现枯燥读的一种形式是,确保每个用户总是从固定的同一正本执行读取(而不同的用户能够从不同的正本读取)。例如,基于用户ID的哈希的办法而不是随机抉择正本。但如果该正本产生生效,则用户的查问必须从新路由到另一个正本。 前缀统一读如果Poons学生与Cake夫人之间进行了如下对话: Poons学生:Cake夫人,您能看到多远的将来?Cake夫人:通常约10s,Poons学生。 这两句话之间存在因果关系:Cake夫人首先是听到了Poons学生的问题,而后再去答复该问题。 不过,Cake夫人所说的话经验了短暂的滞后达到该从节点,但Poons学生所说的经验了更长的滞后才达到。对于观察者来说,仿佛在Poon学生提出问题之前,Cake夫人就开始了答复问题。 这是分区(分片)数据库中呈现的一个非凡问题。如果数据库总是以雷同的程序写入,则读取总是看到统一的序列,不会产生这种反常。然而,在许多分布式数据库中,不同的分区独立运行,因而不存在全局写入程序。这就导致当用户从数据库中读数据时,可能会看到数据库的某局部旧值和另一部分新值。 一个解决方案是确保任何具备因果程序关系的写入都交给一个分区来实现,但该计划实在实现效率会大打折扣。当初有一些新的算法来显式地追踪事件因果关系。 多主节点复制主从复制存在一个显著的毛病:零碎只有一个主节点,而所有写入都必须经由主节点。如果因为某种原因,例如与主节点之间的网络中断而导致主节点无奈连贯,主从复制计划就会影响所有的写入操作。 对主从复制模型进行天然的扩大,则能够配置多个主节点,每个主节点都能够承受写操作,前面复制的流程相似:解决写的每个主节点都必须将该数据更改转发到所有其余节点。这就是多主节点(也称为主-主,或被动/被动)复制。此时,每个主节点还同时表演其余主节点的从节点。 实用场景多数据中心为了容忍整个数据中心级别故障或者更靠近用户,能够把数据库的正本横跨多个数据中心。而如果应用惯例的基于主从的复制模型,主节点势必只能放在其中的某一个数据中心,而所有写申请都必须通过该数据中心。 有了多主节点复制模型,则能够在每个数据中心都配置主节点,如下图所示的根本架构。在每个数据中心内,采纳惯例的主从复制计划;而在数据中心之间,由各个数据中心的主节点来负责同其余数据中心的主节点进行数据的替换、更新。 在多数据中心环境下,部署单主节点的主从复制计划与多主复制计划之间的差别: 性能 对于主从复制,每个写申请都必须经由广域网传送至主节点所在的数据中心。这会大大增加写入提早,并根本偏离了采纳多数据中心的初衷(即就近拜访)。而在多主节点模型中,每个写操作都能够在本地数据中心疾速响应,而后采纳异步复制形式将变动同步到其余数据中心。 容忍数据中心生效 对于主从复制,如果主节点所在的数据中心产生故障,必须切换至另一个数据中心,将其中的一个从节点被晋升为主节点。在多主节点模型中,每个数据中心则能够独立于其余数据中心持续运行,产生故障的数据中心在复原之后更新到最新状态。 容忍网络问题 数据中心之间的通信通常经由广域网,它往往不如数据中心内的本地网络牢靠。对于主从复制模型,因为写申请是同步操作,对数据中心之间的网络性能和稳定性等更加依赖。多主节点模型则通常采纳异步复制,能够更好地容忍此类问题,例如长期网络闪断不会障碍写申请最终胜利。 只管多主复制具备上述劣势,但也存在一个很大的毛病:不同的数据中心可能会同时批改雷同的数据,因此必须解决潜在的写抵触。 离线客户端操作另一种多主复制比拟适宜的场景是,利用在与网络断开后还须要持续工作。每个设施都有一个充当主节点的本地数据库,而后在所有设施之间采纳异步形式同步这些多主节点上的正本,同步滞后可能是几小时或者数天,具体工夫取决于设施何时能够再次联网。 从架构层面来看,上述设置基本上等同于数据中心之间的多主复制,只不过是个极其状况,即一个设施就是数据中心,而且它们之间的网络连接十分不牢靠。 合作编辑咱们通常不会将合作编辑齐全等价于数据库复制问题,但二者的确有很多相似之处。当一个用户编辑文档时,所做的更改会立刻利用到本地正本(Web浏览器或客户端应用程序),而后异步复制到服务器以及编辑同一文档的其余用户。 解决写抵触同步与异步冲突检测如果是主从复制数据库,第二个写申请要么会被阻塞直到第一个写实现,要么被停止。然而在多主节点的复制模型下,这两个写申请都是胜利的,并且只能在稍后的工夫点上能力异步检测到抵触,那时再要求用户层来解决抵触为时已晚。 实践上,也能够做到同步冲突检测,即期待写申请实现对所有正本的同步,而后再告诉用户写入胜利。然而,这样做将会失去多主节点的次要劣势:容许每个主节点独立承受写申请。如果的确想要同步形式冲突检测,或者应该思考采纳单主节点的主从复制模型。 防止抵触解决抵触最现实的策略是防止发生冲突,即如果应用层能够保障对特定记录的写申请总是通过同一个主节点,这样就不会产生写抵触。事实中,因为不少多主节点复制模型所实现的抵触解决方案存在瑕疵,因而,防止抵触反而成为大家广泛举荐的首选计划。 例如,一个利用零碎中,用户须要更新本人的数据,那么咱们确保特定用户的更新申请总是路由到特定的数据中心,并在该数据中心的主节点上进行读/写。不同的用户则可能对应不同的主数据中心(例如依据用户的地理位置来抉择)。从用户的角度来看,这根本等价于主从复制模型。 然而,有时可能须要扭转当时指定的主节点,例如因为该数据中心产生故障,不得不将流量从新路由到其余数据中心,或者是因为用户曾经漫游到另一个地位,因此更凑近新数据中心。此时,抵触防止形式不再无效,必须有措施来解决同时写入抵触的可能性。 收敛于统一状态如果每个正本都只是依照它所看到写入的程序执行,那么数据库最终将处于不统一状态。这相对是不可承受的,所有的复制模型至多应该确保数据在所有正本中最终状态肯定是统一的。因而,数据库必须以一种收敛趋同的形式来解决抵触,实现收敛的抵触解决有以下可能的形式: 给每个写入调配惟一的ID,例如,一个工夫戳,一个足够长的随机数,一个UUID或者一个基于键-值的哈希,筛选最高ID的写入作为胜利者,并将其余写入抛弃。如果基于工夫戳,这种技术被称为最初写入者获胜。尽管这种办法很风行,然而很容易造成数据失落。为每个正本调配一个惟一的ID,并制订规定,例如序号高的正本写入始终优先于序号低的正本。这种办法也可能会导致数据失落。以某种形式将这些值合并在一起。例如,按字母程序排序,而后拼接在一起。利用预约义好的格局来记录和保留抵触相干的所有信息,而后依附应用层的逻辑,预先解决抵触(可能会提醒用户)。自定义抵触解决逻辑解决抵触最合适的形式可能还是依附应用层,所以大多数多主节点复制模型都有工具来让用户编写利用代码来解决抵触。能够在写入时或在读取时执行这些代码逻辑: 在写入时执行:只有数据库系统在复制变更日志时检测到抵触,就会调用应用层的抵触处理程序。在读取时执行:当检测到抵触时,所有抵触写入值都会临时保留下来。下一次读取数据时,会将数据的多个版本读返回给应用层。应用层可能会提醒用户或主动解决抵触,并将最初的后果返回到数据库。抵触解决通常用于单个行或文档,而不是整个事务。如果有一个原子事务蕴含多个不同写申请,每个写申请依然是离开思考来解决抵触。 什么是抵触?有些抵触是不言而喻的。两个写操作同时批改同一个记录中的同一个字段,并将其设置为不同的值。毫无疑问,这就是一个抵触。 而其余类型的抵触可能会十分奥妙,更难以发现。例如一个会议室预订零碎,它次要记录哪个房间由哪个人在哪个时间段所预订。这个应用程序须要确保每个房间只能有一组人同时预约(即不得有雷同房间的反复预订)。如果为同一个房间创立两个不同的预订,可能会发生冲突。只管利用在预订时会查看房间是否可用,但如果两个预订是在两个不同的主节点上进行,则还是存在抵触的可能。 ...

March 2, 2021 · 1 min · jiezi

关于分布式:用-Docker-在单台宿主机启动多个-etcd-节点

在学习和开发基于 etcd 的服务和性能时,须要本人在本地部署一套 etcd 集群。原以为这是一个简略的事件,但意外地花了我几个小时才搞定……本文介绍无效的部署办法和踩过的一些坑。 网络筹备咱们以三个节点为例。首先,默认的 etcd 监听 2370 端口,提供 HTTP API;另外采纳 2380 端口实现节点之间(peer)的通信。 其次,官网文档采纳的是在多个 IP 地址上部署不同的节点。但我只想在手头的一台 MacBook 上部署多个 etcd 容器。 第三,网上的教程应用的都是 docker-compose 来部署多节点,但这也不合乎我的需要,因为我须要动静启动和敞开节点,模仿节点故障,从而察看 etcd 的状态。 综上所述,我须要给这个 etcd 集群调配总共 6 个端口,举例如下: 节点名称httppeeretcd-node-12137921380etcd-node-22237922380etcd-node-32337923380启动脚本我的操作系统是 maxOS v11.2.1,Docker 是 Docker Desktop 3.1.0 版,shell 是 zsh,脚本如下: # For each machine# SUDO=sudoSUDO=ETCD_VERSION=v3.2.30TOKEN=amc-etcd-tokenCLUSTER_STATE=newNAMES=(etcd-node-0 etcd-node-1 etcd-node-2)HOSTS=(host.docker.internal host.docker.internal host.docker.internal)CLIENT_PORTS=(21379 22379 23379)PARTNER_PORTS=(21380 22380 23380)# test array index start_first=0if [ -z ${NAMES[0]} ]; then _first=1;fiCLUSTER=${NAMES[_first]}=http://${HOSTS[_first]}:${PARTNER_PORTS[_first]}for (( i=1; i < ${#NAMES[@]}; i++)) do CLUSTER=${CLUSTER},${NAMES[$i+${_first}]}=http://${HOSTS[$i+${_first}]}:${PARTNER_PORTS[$i+${_first}]};done;echo CLUSTER=${CLUSTER}# For each node 1for (( i=0; i < ${#NAMES[@]}; i++)) do THIS_NAME=${NAMES[$i+${_first}]}; THIS_HOST=${HOSTS[$i+${_first}]}; THIS_CLIENT_PORT=${CLIENT_PORTS[$i+${_first}]}; THIS_PARTNER_PORT=${PARTNER_PORTS[$i+${_first}]}; ${SUDO} docker run -d --name ${THIS_NAME} \ -p ${THIS_PARTNER_PORT}:2380 -p ${THIS_CLIENT_PORT}:2379 \ quay.io/coreos/etcd:${ETCD_VERSION} \ /usr/local/bin/etcd \ --data-dir=data.etcd --name ${THIS_NAME} \ --initial-advertise-peer-urls http://${THIS_HOST}:${THIS_PARTNER_PORT} --listen-peer-urls http://0.0.0.0:2380 \ --advertise-client-urls http://${THIS_HOST}:${THIS_CLIENT_PORT} --listen-client-urls http://0.0.0.0:2379 \ --initial-cluster ${CLUSTER} \ --initial-cluster-token ${TOKEN} \ --initial-cluster-state ${CLUSTER_STATE};done;脚本逻辑阐明读者只须要批改上文的脚本中前置的几个变量即可,如下: ...

February 24, 2021 · 2 min · jiezi

关于分布式:分布式基础数据模型与查询语言

大多数应用程序是通过一层一层叠加数据模型来构建的。每一层都面临的关键问题是:如何将其用下一层来示意?例如: 作为一名应用程序开发人员,观测事实世界(其中包含人员、组织、货物、行为、资金流动、传感器等),通过对象或数据结构,以及操作这些数据结构的API来对其建模。这些数据结构往往特定于该利用。当须要存储这些数据结构时,能够采纳通用数据模型(例如JSON或XML文档、关系数据库中的表或图模型)来示意。数据库工程师接着决定用何种内存、磁盘或网络的字节格局来示意上述JSON/XML/关系/图形数据。数据表示须要反对多种形式的查问、搜寻、操作和解决数据。在更下一层,硬件工程师则须要思考用电流、光脉冲、磁场等来示意字节。简单的应用程序可能会有更多的中间层,例如基于API来构建下层API,然而根本思维雷同:每层都通过提供一个简洁的数据模型来暗藏上层的复杂性。有许多不同类型的数据模型,每种数据模型都有其最佳应用的若干假如。 关系模型与文档模型当初最驰名的数据模型可能是SQL,它基于Edgar Codd于1970年提出的关系模型:数据被组织成关系(relations),在SQL中称为表(table),其中每个关系都是元组(tuples)的无序汇合(在SQL中称为行)。 NoSQL采纳NoSQL数据库有这样几个驱动因素,包含: 比关系数据库更好的扩展性需要,包含反对超大数据集或超高写入吞吐量。NoSQL广泛是收费和开源软件。关系模型不能很好地反对一些特定的查问操作。关系模型具备一些限制性,NoSQL是更具动静和表达力的数据模型。对象—关系不匹配当初大多数利用开发都采纳面向对象的编程语言,因为兼容性问题,广泛对SQL数据模型存在埋怨:如果数据存储在关系表中,那么应用层代码中的对象与表、行和列的数据库模型之间须要一个蠢笨的转换层。 例如,如何在关系模式中示意简历。整个简历能够通过惟一的标识符user_id来标识。像first_name和last_name这样的字段在每个用户中只呈现一次,所以能够将其建模为users表中的列。然而,大多数人在他们的职业中有一个以上的工作,并且可能有多个教育阶段和任意数量的分割信息。用户与这些我的项目之间存在一对多的关系,能够用多种形式来示意: 在传统的SQL模型(SQL: 1999之前)中,最常见的规范化示意是将职位、教育和分割信息放在独自的表中,并应用外键援用users表,如下图所示。之后的SQL规范减少了对结构化数据类型和XML数据的反对。这容许将多值数据存储在单行内,并反对在这些文档中查问和索引。Oracle、IBM DB2、MSSQL Server和PostgreSQL都不同水平上反对这些性能。一些数据库也反对JSON数据类型,例如IBM DB2、MySQL和PostgreSQL。第三个选项是将工作、教育和分割信息编码为JSON或XML文档,将其存储在数据库的文本列中,并由应用程序解释其构造和内容。对于此办法,通常不能应用数据库查问该编码列中的值。 对于像简历这样的数据结构,它次要是一个自蕴含的文档(document),因而用JSON示意十分适合,参见如下示例。与XML相比,JSON的吸引力在于它更简略。面向文档的数据库(如MongoDB、 RethinkDB、CouchDB和Espresso)都反对该数据模型。 { "user_id": 251, "first_name" : "Bill", "last_name" : "Gates", "summary": "Co-chair of the Bill & Melinda Gates... Active blogger.", "region_id" : "us:91", "industry_id" : 131, "photo_url": "/p/7/000/253/05b/308dd6e.jpg", "positions" : [ {"job_title":"Co-chair", "organization":"Bill 8 Melinda Gates Foundation"}, {"job_title":"Co-founder,Chairman", "organization" : "Microsoft"} ], "education":[ {"school_name":"Harvard University","start" : 1973,"end": 1975}, {"school_name":"Lakeside School,Seattle", "start": null,"end": null} ], "contact_info": { "blog": "http: /lthegatesnotes.com", "twitter" :"http: //twitter.com/BillGates" }}多对一与多对多的关系在下面的示例中,region_id和industry_id定义为ID,而不是纯文本字符串模式,例如"Greater Seattle Area"和"Philanthropy"。为什么这样做呢? ...

February 18, 2021 · 1 min · jiezi

关于分布式:分布式基础可靠可扩展与可维护的应用系统

当今许多新型利用都属于数据密集型(data-intensive),而不是计算密集型(compute-intensive)。对于这些类型利用,CPU的解决能力往往不是第一限制性因素,关键在于数据量、数据的复杂度及数据的疾速多变性。 数据密集型利用通常也是基于规范模块构建而成,每个模块负责繁多的罕用性能。例如,许多利用零碎都蕴含以下模块: 数据库:用以存储数据,这样之后利用能够再次拜访。缓存:缓存那些简单或操作代价低廉的后果,以放慢下一次拜访。索引:用户能够按关键字搜寻数据并反对各种过滤。流式解决:继续发送音讯至另一个过程,解决采纳异步形式。批处理:定期解决大量的累积数据。数据系统咱们通常将数据库、队列、缓存等视为不同类型的零碎。尽管数据库和音讯队列存在某些相似性,例如两者都会保留数据(至多一段时间),但他们却有着截然不同的拜访模式,这就意味着不同的性能特色和设计实现。 假设某个利用蕴含缓存层(例如Memcached)与全文索引服务器(如Elasticsearch或Solr),二者与主数据库放弃关联,通常由利用代码负责缓存、索引与主数据库之间的同步,如图所示。 在下面例子中,组合应用了多个组件来提供服务,而对外提供服务的界面或者API会暗藏很多外部实现细节。这样基本上咱们基于一个个较小的、通用的组件,构建而成一个全新的、专用的数据系统。这样的集成数据系统会提供某些技术保障,例如,缓存要正确刷新以保障内部客户端看到统一的后果。 设计数据系统时,会碰到很多辣手的问题。这里将专一与对大多数软件系统都极为重要的三个问题: 可靠性(Reliability):当出现意外状况如硬件、软件故障、人为失误等,零碎应能够持续失常运行:尽管性能可能有所升高,但确保性能正确。可扩展性(Scalability):随着规模的增长,例如数据量、流量或复杂性,零碎应以正当的形式来匹配这种增长。可维护性(Maintainability):随着工夫的推移,许多新的人员参加到零碎开发和运维,以保护现有性能或适配新场景等,零碎都应高效运行。可靠性对于软件,典型的冀望包含: 应用程序执行用户所冀望的性能。能够容忍用户呈现谬误或者不正确的软件应用办法。性能能够应答典型场景、正当负载压力和数据量。零碎可避免任何未经受权的拜访和滥用。如果所有上述指标都要反对才算“失常工作”,那么咱们能够认为可靠性大抵意味着:即便产生了某些谬误,零碎仍能够持续失常工作。 硬件故障当咱们思考系统故障时,对于硬件故障总是很容易想到:硬盘解体,内存故障,电网停电,甚至有人误拔掉了网线。当有很多机器时,这类事件迟早会产生。 咱们的第一个反馈通常是为硬件增加冗余来缩小零碎故障率。例如对磁盘配置RAID,服务器装备双电源,甚至热插拔CPU,数据中心增加备用电源、发电机等。当一个组件产生故障,冗余组件能够疾速接管,之后再更换生效的组件。这种办法能并不能齐全避免硬件故障所引发的生效,但还是被广泛采纳,且在理论中也的确以让零碎不间断运行长达数年。 直到最近,采纳硬件冗余计划对于大多数利用场景还是足够的,它使得单台机器齐全生效的概率降为非常低的程度。只有能够将备份迅速复原到新机器上,故障的停机工夫在大多数利用中并不是灾难性的。而多机冗余则只对大量的要害利用更有意义,对于这些利用,高可用性是相对必要的。 通过软件容错的形式来容忍多机生效也逐步成为新的伎俩,或者至多成为硬件容错的无力补充。这样的零碎更具备操作便利性,例如当须要重启计算机时为操作系统打安全补丁,能够每次给一个节点打补丁而后重启,而不须要同时下线整个零碎。 软件谬误导致软件故障的bug通常会长工夫处于引而不发的状态,直到碰到特定的触发条件。这也意味着系统软件其实对应用环境存在某种假如,而这种假如少数状况都能够满足,然而在特定状况下,假如条件变得不再成立。 软件系统问题有时没有疾速解决办法,而只能认真思考很多细节,包含认真查看依赖的假如条件与零碎之间交互,进行全面的测试,过程隔离,容许过程解体并主动重启,重复评估,监控并剖析生产环节的行为表现等。如果零碎提供某些保障,例如,在音讯队列中,输入音讯的数量应等于输出音讯的数量,则能够一直地查看确认,发现差别则立刻告警。 人为失误如果咱们假设人是不牢靠的,那么该如何保证系统的可靠性呢?能够尝试联合以下多种办法: 以最小出错的形式来设计零碎。例如,精心设计的形象层、API以及治理界面,使“做正确的事件”很轻松,但搞坏很简单。然而,如果限度过多,人们就会想法来绕过它,这会对消其侧面作用。因而解决之道在于很好的均衡。想方法拆散最容易出错的中央、容易引发故障的接口。特地是,提供一个功能齐全但非生产用的沙箱环境,使人们能够释怀的尝试、体验,包含导入实在的数据,万一呈现问题,不会影响实在用户。充沛的测试:从各单元测试到全系统集成测试以及手动测试。自动化测试已被宽泛应用,对于笼罩失常操作中很少呈现的边界条件等尤为重要。当呈现人为失误时,提供疾速的复原机制以尽量减少故障影响。例如,疾速回滚配置改变,滚动公布新代码(这样任何意外的谬误仅会影响一小部分用户),并提供校验数据的工具(避免旧的计算形式不正确)。设置具体而清晰的监控子系统,包含性能指标和错误率。监控能够向咱们发送告警信号,并查看是否存在假如不成立或违反约束条件等。这些检测指标对于诊断问题也十分有用。推广治理流程并加以培训。可扩展性可扩展性是用来形容零碎应答负载减少能力的术语。然而请留神,它并不是掂量一个零碎的一维指标,议论“X是可扩大”或“Y不扩大”没有太大意义。相同,探讨可扩展性通常要思考这类问题:“如果零碎以某种形式增长,咱们应答增长的措施有哪些”,“咱们该如何增加计算资源来解决额定的负载”。 形容负载首先,咱们须要简洁地形容零碎以后的负载,只有这样能力更好地探讨后续增长问题(例如负载加倍会意味着什么)。负载能够用称为负载参数的若干数字来形容。参数的最佳抉择取决于零碎的体系结构,它可能是Web服务器的每秒申请解决次数,数据库中写入的比例,聊天室的同时流动用户数量,缓存命中率等。有时平均值很重要,有时零碎瓶颈来自于多数峰值。 以Twitter为例,Twitter的两个典型业务操作是: 公布tweet音讯:用户能够疾速推送新音讯到所有的关注者,均匀大概4.6k request/sec,峰值约12k requests/sec。主页工夫线(Home timeline)浏览:均匀300k request/sec 查看关注对象的最新消息。仅仅解决峰值约12k的音讯发送听起来并不难,然而,Twitter扩展性的挑战重点不于音讯大小,而在于微小的扇出 (fan-out)构造:每个用户会关注很多人,也会被很多人圈粉。此时大略有两种解决计划: 1.将发送的新tweet插入到全局的tweet汇合中。当用户查看工夫线时,首先查找所有的关注对象,列出这些人的所有tweet,最初以工夫为序来排序合并。如果以下图的关系型数据模型,能够执行下述的SQL查问语句: SELECT tweets.*,users.* FROM tweetsJOIN users ON tweets.sender_id = users.idJOIN follows ON follows.followee_id = users.idWHERE follows.follower_id = current_user 2.对每个用户的工夫线保护一个缓存,如图所示,相似每个用户一个tweet邮箱。当用户推送新tweet时,查问其关注者,将tweet插入到每个关注者的工夫线缓存中。因为曾经事后将后果取出,之后拜访工夫线性能十分快。 Twitter在其第一个版本应用了办法1,但发现主页工夫线的读负载压力一劳永逸,系统优化颇费周折,因而转而采纳第二种办法。实际发现这样更好,因为工夫线浏览tweet的压力简直比公布tweet要高出两个数量级,基于此,在公布时多实现一些事件能够减速读性能。 然而,办法2的毛病也很显著,在公布tweet时减少了大量额定的工作。思考均匀75个关注者和每秒4.6k的tweet,则须要每秒4.6 × 75 = 345k速率写入缓存。然而,75这个均匀关注者背地还暗藏其余事实,即关注者其实偏差微小,例如某些用户领有超过3000万的追随者。这就意味着峰值状况下一个tweet会导致3000万笔写入!而且要求尽量快,Twitter的设计指标是5s内实现,这成为一个微小的挑战。 在Twitter的例子中,每个用户关注者的散布状况(还能够联合用户应用Twitter频率状况进行加权)是该案例可扩大的要害负载参数,因为它决定了扇出数。其余利用可能具备不同的个性,但能够采纳相似的准则来钻研具体负载。 Twitter故事最初的终局是:办法2曾经失去了稳固实现,Twitter正在转向联合两种办法。大多数用户的tweet在公布时持续以一对多写入工夫线,然而多数具备超多关注者(例如那些名人)的用户除外,对这些用户采纳相似计划1,其推文被独自提取,在读取时才和用户的工夫线主表合并。这种混合办法可能提供始终如一的良好体现。 形容性能形容零碎负载之后,接下来构想如果负载减少将会产生什么。有两种思考形式: 负载减少,但系统资源(如CPU、内存、网络带宽等)放弃不变,零碎性能会产生什么变动?负载减少,如果要放弃性能不变,须要减少多少资源?这两个问题都会关注性能指标,所以咱们先简要介绍一下如何形容零碎性能。 在批处理零碎如Hadoop中,咱们通常关怀吞吐量(throughput),即每秒可解决的记录条数,或者在某指定数据集上运行作业所需的总工夫;而在线零碎通常更看重服务的响应工夫(response time),即客户端从发送申请到接管响应之间的距离。 咱们常常考查的是服务申请的均匀响应工夫。然而,如果想晓得更典型的响应工夫,平均值并不是适合的指标,因为它覆盖了一些信息,无奈通知有多少用户理论经验了多少提早。 因而最好应用百分位数(percentiles)。如果曾经收集到了响应工夫信息,将其从最快到最慢排序,中位数(median)就是列表两头的响应工夫。例如,如果中位数响应工夫为200 ms,那意味着有一半的申请响应不到200 ms,而另一半申请则须要更长的工夫。 为了弄清楚异样值有多蹩脚,须要关注更大的百分位数如常见的第95、99和99.9(缩写为p95、p99和p999)值。作为典型的响应工夫阈值,它们别离示意有95%、99%或99.9%的申请响应工夫快于阈值。例如,如果95百分位数响应工夫为1.5s,这意味着100个申请中的95个申请快于1.5s,而5个申请则须要1.5s或更长时间。 采纳较高的响应工夫百分位数(tail latencies,尾部提早或长尾效应)很重要,因为它们间接影响用户的总体服务体验。例如,亚马逊采纳99.9百分位数来定义其外部服务的响应工夫规范,或者它仅影响1000个申请中的1个。然而思考到申请最慢的客户往往是购买了更多的商品,因而数据量更大换言之,他们是最有价值的客户。让这些客户始终保持愉悦的购物体验显然十分重要:亚马逊还留神到,响应工夫每减少100ms,销售额就会降落了约1%,其余钻研则表明,1s的提早减少等价于客户满意度降落16%。 排队提早往往在高百分数响应工夫中影响很大。因为服务器并行处理的申请无限(例如,CPU内核数的限度),正在解决的多数申请可能会阻挡后续申请,这种状况有时被称为队头阻塞。即便后续申请可能解决很简略,但它阻塞在期待先前申请的实现,客户端将会察看到极慢的响应工夫。因而,很重要的一点是要在客户端来测量响应工夫。 因而,当测试零碎可扩展性而人为产生负载时,负载生成端要独立于响应工夫来继续发送申请。如果客户端在发送申请之前总是期待先前申请的实现,就会在测试中人为地缩短了服务器端的累计队列深度,这就带来了测试偏差。 应答负载减少的办法当初议论更多的是如何在垂直扩大(即降级到更弱小的机器)和程度扩大(行将负载散布到多个更小的机器)之间做取舍。在多台机器上调配负载也被称为无共享体系结构。在单台机器上运行的零碎通常更简略,然而高端机器可能十分低廉,且扩大程度无限,最终往往还是无奈防止须要程度扩大。实际上,好的架构通常要做些理论取舍,例如,应用几个强悍的服务器仍能够比大量的小型虚拟机来得更简略、便宜。 某些零碎具备弹性特色,它能够自动检测负载减少,而后主动增加更多计算资源,而其余零碎则是手动扩大(人工剖析性能体现,之后决定增加更多计算)。如果负载高度不可预测,则主动弹性零碎会更加高效,但或者手动形式能够缩小执行期间的意外状况。 ...

January 31, 2021 · 1 min · jiezi

关于分布式:zookeeper笔记

zookeeper作用:分布式协调服务框架,解决分布式集群中利用零碎的一致性问题,实质是一个文件存储系统,与es不同他仅有一套主从,主节点负责事务相干,从节点收到事务的申请转发给主节点,从节点负责读性质 全局一致性:每个服务器保留一份雷同的数据可靠性:音讯被一台接管,将被所有接管程序性 全局有序,在服务端,先插入的肯定在后插入的后面偏序,客户端将数据插入a到zookeeper,在插入b到zookeeper,客户端在看数据时a在b前数据更新原子性:数据更新要么全副胜利要么失败实时性:主节点数据产生扭转后,其余结点会立刻感知数据变动信息,以及实时能感知到服务器一些状态与一般文件系统类似,外部各节点存在命名空间,是一种树形构造,在zookeeper中各个节点被称为znode然而zookeeper的节点和一般零碎节点存在区别 节点具备兼具文件和目录两种特点,一般文件系统二者拆散 create -s /test/child1 acl # 能够配置子节点就像目录一样,acl为权限create -s /test aaaaa acl # 也能够输出文件内容,acl为权限原子性操作大小又限度znode<1M,理论应用远小于此值通过绝对路径援用节点类型,在创立时就曾经决定 永恒节点,只有用户真正执行删除操作才会被删除 非序列化节点序列化节点。 create -s 建设文件a.txt会在后边追加序列号10位初始为0,长期会话节点,会话完结长期节点删除,且不容许构建子节点 非序列化节点序列化节点操作 创立节点 create /zk01 aaaaa # 永恒create -s /zk02 bbbbb # 永恒序列化create -e /zk03 ccccc # 长期create -e -s /zk04 dd # 长期序列化create /zk05/zk06 aaa # 带子节点的须要从父节点开始建ls,get和ls2 ls path [watch] # 查看根目录下有哪些节点ls2 path [watch] # 查看根目录下的详细信息#ls2 /#dataVersion 数据版本号,每次set+1,即便设置雷同值仍会扭转#cversion 子节点的版本号, znode子节点变动时cversion减少1#cZxid znode创立事务id#mZxid znode批改的事务id#ctime 创立的工夫戳#mtime 更新产生的工夫戳#ephemeralOwner 长期节点有该sessionid,不是长期节点get path [watch] # 指定节点的数据内容和属性信息Set 更新 ...

January 23, 2021 · 1 min · jiezi

关于分布式:DCache-分布式存储系统|安装部署与应用创建

作者 | Eaton 导语 | 随着微服务与云的倒退,分布式架构的需要变得越来越广泛,Web 上的数据类型不再繁多,数据量呈爆发式增长。传统的 SQL 结构化存储计划曾经跟不上脚步, NoSQL 便呈现了。DCache 作为基于 TARS 的分布式 NoSQL 缓存零碎,完满反对 TARS 服务,可能不便地在 TARS 服务中应用,本系列文章将着重介绍 DCache 的装置与应用。那么如何领有这套零碎呢?本文将对 DCache 的装置和利用创立形式进行介绍。 目录简介 背景SQL 与 NoSQLDCache装置 DCache 环境依赖编译构建部署创立 DCache 利用总结简介背景随着挪动互联网和云的倒退,用户量一直增长,业务访问量一劳永逸,光靠资源的扩容曾经无奈解决所有的问题。特地是像电商平台、音视频点播等,存在大规模的数据拜访,对查问效率要求很高,传统的数据库磁盘 IO 曾经很难满足。 为了解决这一问题,NoSQL 数据库诞生了,它通过将数据缓存到内存中,应用时间接从内存中调用,大大减少磁盘 IO 的开销,晋升查问效率,与分布式联合还可能实现海量数据的解决。这个NoSQL,具体No在哪呢? SQL 与 NoSQLSQL 是指数据库的结构化查询语言,它是数据库的操作命令集,传统的关系型数据库都应用规范的 SQL 语句操作解决数据。 NoSQL 是指一类数据库,次要用于高性能解决超海量数据,它的一大特点是数据结构简略,以 key-value 为主,数据之间非关联,容易做程度扩大。 从字面上看,NoSQL 仿佛是与 SQL 对抗的,做 NoSQL 仿佛就意味着放弃 SQL,然而实际上 NoSQL 本意是 Not Only SQL,它不仅仅是 SQL,那么也就能够蕴含 SQL 的能力。 DCacheDCache 是一个基于 TARS 框架开发的分布式 NoSQL 存储系统,数据采纳内存存储,同时反对连贯后端 DB 实现数据长久化,联合了 NoSQL 和 SQL 的劣势,具备以下特点 ...

January 22, 2021 · 2 min · jiezi

关于分布式:Dubbo中的统一契约是如何实现的

写在后面之前,很多小伙伴私信我:如何能力疾速的把握Dubbo的外围原理和源码。所以,我写了一篇《我是如何在短期内疾速把握Dubbo的原理和源码的(纯干货)?》。对于Dubbo的源码解析系列文章,我也在思考如何让源码解析的文章变得更加简略易懂,所以,我调整了写Dubbo源码解析文章的策略,力求让小伙伴们可能以更简略、易懂的形式彻底把握Dubbo源码。明天,咱们先说说Dubbo中的对立契约是如何实现的。 文章已收录到: https://github.com/sunshinelyz/technology-binghe https://gitee.com/binghe001/technology-binghe 不得不说的URLURL全称为对立资源定位符,它可能在互联网中定位到惟一的一个网络地址。URL的格局如下所示。 protocol://username:password@host:port/path?key=value&key=value其中,各个局部的简要阐明如下所示。 protocol:URL的协定。最常见的协定就是HTTP和HTTPS,其余的还有FTP、WS、FILE、SMTP等。username:用户名。password:明码。host:主机,通常是域名或者IP地址。port:主机的端口号。path:申请的指标文件的门路。parameters:申请的具体参数信息,这里为key=value&key=value。这就是咱们互联网中的URL的简略阐明。 那么,在Dubbo外部,大量的办法接管的参数都是以URL进行封装的,那么,URL在Dubbo外部到底起到了什么作用呢?咱们持续往下看。 Dubbo中的URL总的来说,在Dubbo外部,服务提供者Provider会将本身的相干信息封装成URL注册到Zookeeper或其余注册核心中,从而对外裸露本人提供的服务。而服务消费者Consumer也会通过URL的模式向Zookeeper或其余注册核心订阅本人想要调用的服务。而在Dubbo的SPI实现中,URL又会参加扩大实现的逻辑解决。所以说,URL在Dubbo的实现中是十分重要的。也能够这么说,Dubbo中的URL就是Dubbo的对立契约。 咱们先来看一下Dubbo中的URL具体长什么样吧,通过调试Dubbo自带Provider的示例源码,咱们能够看到在Dubbo中的URL如下所示。 dubbo://192.168.175.1:20880/org.apache.dubbo.demo.DemoService?anyhost=true&application=dubbo-demo-annotation-provider&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=org.apache.dubbo.demo.DemoService&methods=sayHello,sayHelloAsync&pid=15012&release=&side=provider&timestamp=1610857629484这也是Provider注册到Zookeeper或者其余注册核心的信息。各个局部的阐明如下所示。 dubbo:应用的是dubbo协定。host:主机的IP地址为192.168.175.1。port:端口号为20880。path:这里的申请门路为:org.apache.dubbo.demo.DemoServiceparameters:申请的参数信息,这里为:anyhost=true&application=dubbo-demo-annotation-provider&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=org.apache.dubbo.demo.DemoService&methods=sayHello,sayHelloAsync&pid=15012&release=&side=provider&timestamp=1610857629484。既然Dubbo是向Zookeeper或其余注册核心注册这些信息的,那Dubbo外部是如何对URL进行封装的呢。 在dubbo-common模块中,有一个URL类专门用于封装URL,如下所示。 在URL类中,咱们来看一个外围构造函数,如下所示。 public URL(String protocol, String username, String password, String host, int port, String path, Map<String, String> parameters, Map<String, Map<String, String>> methodParameters) { if (StringUtils.isEmpty(username) && StringUtils.isNotEmpty(password)) { throw new IllegalArgumentException("Invalid url, password without username!"); } this.protocol = protocol; this.username = username; this.password = password; this.host = host; this.port = Math.max(port, 0); this.address = getAddress(this.host, this.port); // trim the beginning "/" while (path != null && path.startsWith("/")) { path = path.substring(1); } this.path = path; if (parameters == null) { parameters = new HashMap<>(); } else { parameters = new HashMap<>(parameters); } this.parameters = Collections.unmodifiableMap(parameters); this.methodParameters = Collections.unmodifiableMap(methodParameters);}能够看到,Dubbo对于URL的外围封装,根本与互联网中的URL封装是统一的。 ...

January 22, 2021 · 1 min · jiezi

关于分布式:从0到1学习边缘容器系列4弱网环境利器之分布式节点状态判定机制

导语边缘场景下网络经常不牢靠,容易误触发 Kubernetes 驱赶机制,引起不合乎预期的 Pod 驱赶动作,TKE Edge 独创分布式节点状态断定机制,该机制能够更好地辨认驱赶机会,保障系统在弱网络下失常运行,防止服务中断和稳定。 边缘计算情境下,边缘节点与云端的网络环境十分复杂,网络品质无奈保障,容易呈现 APIServer 和节点连贯中断的场景。如果不加革新间接应用原生 Kubernetes,节点状态会常常出现异常,进而引起 Kubernetes 驱赶机制失效,导致 Pod 的驱赶和 Endpoint 的缺失,最终造成服务的中断和稳定。为了解决这个问题,TKE 边缘容器团队在边缘集群弱网环境下提出了边缘节点分布式节点状态断定机制,能够更好地辨认驱赶机会。 背景不同于核心云,边缘场景下,首先要面对云边弱网络的环境,边缘设施经常位于边缘云机房、挪动边缘站点,与云端连贯的网络环境十分复杂,不像核心云那么牢靠。这其中既蕴含云端(管制端)和边缘端的网络环境不牢靠,也蕴含边缘节点之间的网络环境不牢靠,即便是同一区域不同机房之间也无奈假如节点之间网络品质良好。 以智慧工厂为例,边缘节点位于厂房仓库和车间,管制端 Master 节点在腾讯云的核心机房内。 仓库和车间内的边缘设施同云端集群之间的网络较简单,因特网、5G、WIFI 等状态均有可能,网络品质差次不齐没有保障;然而,相比于和云端的网络环境,因为仓库和车间内的边缘设施之间是本地网络,因而网络品质必定要优于同云端集群之间的连贯,相对而言更加牢靠。 造成的挑战原生 Kubernetes 解决形式云边弱网络带来的问题是影响运行在边缘节点上的 kubelet 与云端 APIServer 之间通信,云端 APIServer 无奈收到 kubelet 的心跳或者续租,无奈精确获取该节点和节点上pod的运行状况,如果持续时间超过设置的阈值,APIServer 会认为该节点不可用,并做出如下一些动作: 失联的节点状态被置为 NotReady 或者 Unknown 状态,并被增加 NoSchedule 和 NoExecute 的 taints失联的节点上的 Pod 被驱赶,并在其余节点上进行重建失联的节点上的 Pod 从 Service 的 Endpoint 列表中移除需要场景再看一个音视频拉流场景,音视频服务是边缘计算的一个重要利用场景,如图所示: 思考到用户体验及公司老本,音视频拉流常常须要进步边缘缓存命中率缩小回源,将用户申请的同一文件调度到同一个服务实例以及服务实例缓存文件均是常见的做法。 然而,在原生 Kubernetes 的状况下,如果 Pod 因为网络稳定而频繁重建,一方面会影响服务实例缓存成果,另一方面会引起调度零碎将用户申请调度到其余服务实例。无疑,这两点都会对 CDN 成果造成极大的影响,甚至不能承受。 事实上,边缘节点齐全运行失常,Pod 驱赶或重建其实是齐全不必要的。为了克服这个问题,放弃服务的继续可用,TKE 边缘容器团队提出了分布式节点状态断定机制。 解决方案设计准则显然,在边缘计算场景中,仅仅依赖边缘端和 APIServer 的连贯状况来判断节点是否失常并不合理,为了让零碎更强壮,须要引入额定的判断机制。 ...

January 18, 2021 · 1 min · jiezi

关于分布式:IDC分布式云报告发布

近日,IDC正式公布《分布式云之——本地云服务市场钻研》报告,从概念与特色、产品与模式、利用场景及发展趋势等多个方面,对分布式云组合中的本地云服务模式进行剖析及解读。其中,浪潮云作为典型服务商之一被纳入报告剖析。IDC在报告中指出,企业IT基础设施的倒退在经验了从硬件定义到软件定义再到服务定义的演进过程后,无不处在的云曾经成为了最为要害的IT基础设施,为此云的部署和经营形式日趋多样化,灵便的本地云服务模式也因而应运而生,并且具备低时延、可定制、高平安、高灵便、统一体验5大特色,既能满足私有云的弹性、疾速扩大、迭代优化,又能节约自建数据中心一次性投资的巨额老本,并补救企业客户IT技术能力的欠缺。 以后,国内外次要云服务商纷纷推出了本地云服务或本地部署的软硬件解决方案,轻量化部署和规模化部署成为本地云服务模式的次要代表。其中,轻量化部署次要面向繁多企业客户,其在云基础设施构建时通常会以私有云为主本地云为辅,通过买通本地云与私有云资源晋升客户的统一体验。该种模式目前在国内市场还处于萌芽和培养期,互联网、制作、服务等或将成为首批试水行业。规模化部署是本地云服务模式的另一代表,该种模式次要面向某一客户集群,通过与私有云资源买通进行对立的治理和降级,用户在基础设施构建时通常会以本地云为主,私有云为辅,适宜于对数据主权、网络提早、服务质量、平安合规等有特定要求的行业用户。以后应用该服务的次要以中央政府、垂直部委、金融、工业龙头企业为主。在这一模式下,浪潮云成为典型服务商代表被IDC体现在报告中,并认为在本地云服务畛域已具备肯定的先发劣势。 作为国内当先的云计算服务商,浪潮云通过交融多业务场景提供IaaS、PaaS、DaaS、SaaS间断体服务的分布式云,保持做以分布式云平台为外围载体的云服务运营商,实现从技术、产品到计划、服务的全栈业务链接。其中,浪潮云ICP作为次要产品和服务,具备疾速部署、专享合规、平滑迁徙等特点。不仅可能疾速部署上线为客户提供服务,还能依据用户抉择业务,灵便定制,弹性交付,实现自动化集成、自动化部署与动静扩容,同时也能反对独享整体资源池,享有更加平安稳固的网络服务,为用户打造平安协同进攻体系,用户也能够依据本人的网络或者平安需要自由选择服务节点的部署地位,或者间接部署在客户的数据中心,多区域基于VxLAN网络技术打造虚拟化的大二层播送域,在业务跨三层任意部署的同时,实现无感知的平滑迁徙与浪潮私有云组成人造交融的混合云。目前,浪潮云ICP已利用在政府、电商、批发、金融、制作等对数据敏感性高、隐衷性强、安全性有要求的相干行业。在谈到本地云服务市场的利用场景时,IDC认为平安敏感、本地交互、商业翻新、云边一体成为用户最为关注的几个方面。 平安敏感方面 作为山东省政务云服务商,浪潮云为山东省提供征询、布局、建设、经营等“一站式”服务,基于浪潮分布式云对不同架构下的各资源体系进行了整合和对立经营治理,全面晋升政务云服务水平和平安防护能力,构建起“1+X”全省一体化政务云服务框架体系,实现全省一朵云。 云边一体方面 浪潮云联合5G网络革新降级,在工业互联网建设中实现了对企业研发设计、组装生产、供给销售的全生命周期智能化服务撑持,生态搭档利用核心云弱小的算力和丰盛的智能服务,孵化工业互联网各类场景的智慧利用,并按需向边缘云散发,通过分布式云实现智能工厂的高效能翻新、推广、利用闭环,通过浪潮分布式云“云边一体”数据服务,边缘星散中治理厂内外围数据,本地云连贯政企和厂间协同数据,在充沛保障企业数据安全前提下,买通了云边协同智能制作建设的各项环节,并且本地云与多个边缘云所形成的云边一体架构,可由OpsCenter进行对立纳管,极大加重了各个智能工厂的运维、经营老本。 IDC中国企业级研究部高级钻研经理刘丽辉示意:“中国本地云经营服务初具规模且增长迅速,软硬件技术背景云服务商已具备肯定先发劣势。本地云服务将成为将来云服务的重要抉择,分布式部署对立治理成为客户和服务商的统一诉求。因而,对于服务商而言,也要进一步放慢本地云服务基础设施生产或交付的速度,重视本地云服务经营体验的晋升,思考本地云服务的久远继续倒退”。

January 11, 2021 · 1 min · jiezi

关于分布式:IDC分布式云报告发布-浪潮云作为典型服务商被纳入报告

近日,IDC正式公布《分布式云之——本地云服务市场钻研》报告,从概念与特色、产品与模式、利用场景及发展趋势等多个方面,对分布式云组合中的本地云服务模式进行剖析及解读。其中,浪潮云作为典型服务商之一被纳入报告剖析。IDC在报告中指出,企业IT基础设施的倒退在经验了从硬件定义到软件定义再到服务定义的演进过程后,无不处在的云曾经成为了最为要害的IT基础设施,为此云的部署和经营形式日趋多样化,灵便的本地云服务模式也因而应运而生,并且具备低时延、可定制、高平安、高灵便、统一体验5大特色,既能满足私有云的弹性、疾速扩大、迭代优化,又能节约自建数据中心一次性投资的巨额老本,并补救企业客户IT技术能力的欠缺。 以后,国内外次要云服务商纷纷推出了本地云服务或本地部署的软硬件解决方案,轻量化部署和规模化部署成为本地云服务模式的次要代表。其中,轻量化部署次要面向繁多企业客户,其在云基础设施构建时通常会以私有云为主本地云为辅,通过买通本地云与私有云资源晋升客户的统一体验。该种模式目前在国内市场还处于萌芽和培养期,互联网、制作、服务等或将成为首批试水行业。规模化部署是本地云服务模式的另一代表,该种模式次要面向某一客户集群,通过与私有云资源买通进行对立的治理和降级,用户在基础设施构建时通常会以本地云为主,私有云为辅,适宜于对数据主权、网络提早、服务质量、平安合规等有特定要求的行业用户。以后应用该服务的次要以中央政府、垂直部委、金融、工业龙头企业为主。在这一模式下,浪潮云成为典型服务商代表被IDC体现在报告中,并认为在本地云服务畛域已具备肯定的先发劣势。 作为国内当先的云计算服务商,浪潮云通过交融多业务场景提供IaaS、PaaS、DaaS、SaaS间断体服务的分布式云,保持做以分布式云平台为外围载体的云服务运营商,实现从技术、产品到计划、服务的全栈业务链接。其中,浪潮云ICP作为次要产品和服务,具备疾速部署、专享合规、平滑迁徙等特点。不仅可能疾速部署上线为客户提供服务,还能依据用户抉择业务,灵便定制,弹性交付,实现自动化集成、自动化部署与动静扩容,同时也能反对独享整体资源池,享有更加平安稳固的网络服务,为用户打造平安协同进攻体系,用户也能够依据本人的网络或者平安需要自由选择服务节点的部署地位,或者间接部署在客户的数据中心,多区域基于VxLAN网络技术打造虚拟化的大二层播送域,在业务跨三层任意部署的同时,实现无感知的平滑迁徙与浪潮私有云组成人造交融的混合云。目前,浪潮云ICP已利用在政府、电商、批发、金融、制作等对数据敏感性高、隐衷性强、安全性有要求的相干行业。在谈到本地云服务市场的利用场景时,IDC认为平安敏感、本地交互、商业翻新、云边一体成为用户最为关注的几个方面。 平安敏感方面 作为山东省政务云服务商,浪潮云为山东省提供征询、布局、建设、经营等“一站式”服务,基于浪潮分布式云对不同架构下的各资源体系进行了整合和对立经营治理,全面晋升政务云服务水平和平安防护能力,构建起“1+X”全省一体化政务云服务框架体系,实现全省一朵云。 云边一体方面 浪潮云联合5G网络革新降级,在工业互联网建设中实现了对企业研发设计、组装生产、供给销售的全生命周期智能化服务撑持,生态搭档利用核心云弱小的算力和丰盛的智能服务,孵化工业互联网各类场景的智慧利用,并按需向边缘云散发,通过分布式云实现智能工厂的高效能翻新、推广、利用闭环,通过浪潮分布式云“云边一体”数据服务,边缘星散中治理厂内外围数据,本地云连贯政企和厂间协同数据,在充沛保障企业数据安全前提下,买通了云边协同智能制作建设的各项环节,并且本地云与多个边缘云所形成的云边一体架构,可由OpsCenter进行对立纳管,极大加重了各个智能工厂的运维、经营老本。 IDC中国企业级研究部高级钻研经理刘丽辉示意:“中国本地云经营服务初具规模且增长迅速,软硬件技术背景云服务商已具备肯定先发劣势。本地云服务将成为将来云服务的重要抉择,分布式部署对立治理成为客户和服务商的统一诉求。因而,对于服务商而言,也要进一步放慢本地云服务基础设施生产或交付的速度,重视本地云服务经营体验的晋升,思考本地云服务的久远继续倒退”。

January 11, 2021 · 1 min · jiezi

关于分布式:深入浅出-ZooKeeper

ZooKeeper 是一个分布式协调服务 ,由 Apache 进行保护。ZooKeeper 能够视为一个高可用的文件系统。 ZooKeeper 能够用于公布/订阅、负载平衡、命令服务、分布式协调/告诉、集群治理、Master 选举、分布式锁和分布式队列等性能 。 一、ZooKeeper 简介1.1 ZooKeeper 是什么ZooKeeper 是 Apache 的顶级我的项目。ZooKeeper 为分布式应用提供了高效且牢靠的分布式协调服务,提供了诸如对立命名服务、配置管理和分布式锁等分布式的根底服务。在解决分布式数据一致性方面,ZooKeeper 并没有间接采纳 Paxos 算法,而是采纳了名为 ZAB 的一致性协定。 ZooKeeper 次要用来解决分布式集群中利用零碎的一致性问题,它能提供基于相似于文件系统的目录节点树形式的数据存储。然而 ZooKeeper 并不是用来专门存储数据的,它的作用次要是用来保护和监控存储数据的状态变动。通过监控这些数据状态的变动,从而能够达到基于数据的集群治理。 很多赫赫有名的框架都基于 ZooKeeper 来实现分布式高可用,如:Dubbo、Kafka 等。 1.2 ZooKeeper 的个性ZooKeeper 具备以下个性: 程序一致性:所有客户端看到的服务端数据模型都是统一的;从一个客户端发动的事务申请,最终都会严格依照其发动程序被利用到 ZooKeeper 中。具体的实现可见下文:原子播送。原子性:所有事务申请的处理结果在整个集群中所有机器上的利用状况是统一的,即整个集群要么都胜利利用了某个事务,要么都没有利用。实现形式可见下文:事务。繁多视图:无论客户端连贯的是哪个 Zookeeper 服务器,其看到的服务端数据模型都是统一的。高性能:ZooKeeper 将数据全量存储在内存中,所以其性能很高。须要留神的是:因为 ZooKeeper 的所有更新和删除都是基于事务的,因而 ZooKeeper 在读多写少的利用场景中有性能体现较好,如果写操作频繁,性能会大大下滑。高可用:ZooKeeper 的高可用是基于正本机制实现的,此外 ZooKeeper 反对故障复原,可见下文:选举 Leader。1.3 ZooKeeper 的设计指标简略的数据模型能够构建集群程序拜访高性能二、ZooKeeper 外围概念2.1  数据模型ZooKeeper 的数据模型是一个树形构造的文件系统。 树中的节点被称为 znode,其中根节点为 /,每个节点上都会保留本人的数据和节点信息。znode 能够用于存储数据,并且有一个与之相关联的 ACL(详情可见 ACL)。ZooKeeper 的设计指标是实现协调服务,而不是真的作为一个文件存储,因而 znode 存储数据的大小被限度在 1MB 以内。 ZooKeeper 的数据拜访具备原子性。其读写操作都是要么全副胜利,要么全副失败。 znode 通过门路被援用。znode 节点门路必须是绝对路径。 ...

December 29, 2020 · 4 min · jiezi

关于分布式:冰河能不能讲讲如何实现MySQL数据存储的无限扩容

写在后面随着互联网的高速倒退,企业中积淀的数据也越来越多,这就对数据存储层的扩展性要求越来越高。当今互联网企业中,大部分企业应用的是MySQL来存储关系型数据。如何实现MySQL数据存储层的高度可扩展性成为了互联网企业必须要解决的问题。那么,如何实现真正意义上的MySQL有限扩容呢?明天,冰河就来以实战的角度为大家讲讲如何实现MySQL数据库的有限扩容。文章已收录到:https://github.com/sunshinelyz/technology-binghe 和 https://gitee.com/binghe001/technology-binghe,小伙伴们别忘记给个小星星哦~~ 概述本文是在《海量数据架构下如何保障Mycat的高可用?》一文的根底上进一步扩大,从而实现数据存储层每一个环节的高可用,从而实现MySQL的有限扩容。 要解决的问题在《海量数据架构下如何保障Mycat的高可用?》一文中,咱们的架构图如下: 由上图能够看出,HAProxy存在单点隐患,一旦这个HAProxy服务宕机,那么整个服务架构将不可用。那么,如何解决HAProxy存在的单点隐患问题呢?这就是这篇博文要解决的问题。 软件版本操作系统:CentOS-6.8-x86_64JDK版本:jdk1.8HAProxy版本:haproxy-1.5.19.tar.gzMycat版本:Mycat-server-1.6(自行下载源码编译)keepalived版本:keepalived-1.2.18.tar.gzMySQL版本:mysql-5.7.tar.gz部署布局 高可用负载平衡集群部署架构 上图中简化了数据存储局部的架构细节。例如,其中对于架构中的每一个局部,咱们都能够独自进行扩大,独立成集群对外提供服务,而不会存在单点故障的问题。 图解阐明: (1) HAProxy 实现了 Mycat 多节点的集群高可用和负载平衡, 而 HAProxy 本身的高可用则能够通过Keepalived 来实现。 因而, HAProxy 主机上要同时装置 HAProxy 和 Keepalived, Keepalived 负责为该服务器抢占 vip(虚构 ip,图中的 192.168.209.130),抢占到 vip 后,对该主机的拜访能够通过原来的 ip(192.168.209.135)拜访,也能够间接通过 vip(192.168.209.130)拜访。 (2) Keepalived 抢占 vip 有优先级, 在 keepalived.conf 配置中的 priority 属性决定。然而个别哪台主机上的 Keepalived服务先启动就会抢占到 vip,即便是 slave,只有先启动也能抢到(要留神防止 Keepalived的资源抢占问题)。 (3) HAProxy 负责将对 vip 的申请散发到 Mycat 集群节点上, 起到负载平衡的作用。 同时 HAProxy 也能检测到 Mycat 是否存活, HAProxy 只会将申请转发到存活的 Mycat 上。 ...

December 19, 2020 · 5 min · jiezi

关于分布式:大规模分布式存储系统原理解析与架构实战pdf

关注“Java后端技术全栈” 回复“面试”获取全套面试材料 分布式存储系统,将数据扩散存储在多台独立的设施上。 传统的网络存储系统采纳集中的存储服务器寄存所有数据,存储服务器成为零碎性能的瓶颈,也是可靠性和安全性的焦点,不能满足大规模存储利用的须要。 分布式网络存储系统采纳可扩大的系统结构,利用多台存储服务器分担存储负荷,利用地位服务器定位存储信息,它岂但进步了零碎的可靠性、可用性和存取效率,还易于扩大。 越来越多的企业被动拥抱分布式存储系统,程序员们也须要理解相干的技术。 最近很多小伙伴问我要一些 分布式存储系统 相干的材料,于是我翻箱倒柜,找到了这本十分经典的电子书——《大规模分布式存储系统:原理解析与架构实战》。 材料介绍 《大规模分布式存储系统:原理解析与架构实战》是分布式系统畛域的经典著作,全书系统地解说了大规模分布式存储系统的核心技术和基本原理,还对谷歌、微软和阿里巴巴等国际型大互联网公司的大规模分布式存储系统进行了剖析;此外,本书实战方面,通过对阿里巴巴的分布式数据库OceanBase的实现细节的深刻分析,残缺地展现了大规模分布式存储系统的架构与设计过程。 如何获取? 1.辨认二维码并关注公众号「Java后端技术全栈」; 2.在公众号后盾回复关键字「934」。

December 13, 2020 · 1 min · jiezi

关于分布式:看了-5种分布式事务方案我司最终选择了-Seata真香

原本不晓得写点啥,正好手头有个新我的项目试着用阿里的 Seata 中间件做分布式事务,那就做一个实际分享吧! 介绍 Seata 之前在简略回顾一下分布式事务的基本概念。 分布式事务的产生咱们先看看百度上对于分布式事务的定义:分布式事务是指事务的参与者、反对事务的服务器、资源服务器以及事务管理器别离位于不同的分布式系统的不同节点之上。 额~ 有点形象,简略的画个图好了解一下,拿下单减库存、扣余额来说举例: 当零碎的体量很小时,单体架构齐全能够满足现有业务需要,所有的业务共用一个数据库,整个下单流程或者只用在一个办法里同一个事务下操作数据库即可。此时做到所有操作要么全副提交 或 要么全副回滚很容易。 分库分表、SOA可随着业务量的一直增长,单体架构慢慢扛不住微小的流量,此时就须要对数据库、表做分库分表处理,将利用SOA服务化拆分。也就产生了订单核心、用户核心、库存核心等,由此带来的问题就是业务间互相隔离,每个业务都保护着本人的数据库,数据的替换只能进行RPC调用。 当用户再次下单时,需同时对订单库order、库存库storage、用户库account进行操作,可此时咱们只能保障本人本地的数据一致性,无奈保障调用其余服务的操作是否胜利,所以为了保障整个下单流程的数据一致性,就须要分布式事务染指。 Seata 劣势实现分布式事务的计划比拟多,常见的比方基于 XA 协定的 2PC、3PC,基于业务层的 TCC,还有利用音讯队列 + 音讯表实现的最终一致性计划,还有明天要说的 Seata 中间件,下边看看各个计划的优缺点。 2PC 基于 XA 协定实现的分布式事务,XA 协定中分为两局部:事务管理器和本地资源管理器。其中本地资源管理器往往由数据库实现,比方 Oracle、MYSQL 这些数据库都实现了 XA 接口,而事务管理器则作为一个全局的调度者。 两阶段提交(2PC),对业务侵⼊很小,它最⼤的劣势就是对使⽤⽅通明,用户能够像使⽤本地事务⼀样使⽤基于 XA 协定的分布式事务,可能严格保障事务 ACID 个性。 可2PC的毛病也是不言而喻,它是一个强一致性的同步阻塞协定,事务执⾏过程中须要将所需资源全副锁定,也就是俗称的刚性事务。所以它比拟适⽤于执⾏工夫确定的短事务,整体性能比拟差。 一旦事务协调者宕机或者产生网络抖动,会让参与者始终处于锁定资源的状态或者只有一部分参与者提交胜利,导致数据的不统一。因而,在⾼并发性能⾄上的场景中,基于 XA 协定的分布式事务并不是最佳抉择。 3PC 三段提交(3PC)是二阶段提交(2PC)的一种改良版本 ,为解决两阶段提交协定的阻塞问题,上边提到两段提交,当协调者解体时,参与者不能做出最初的抉择,就会始终放弃阻塞锁定资源。 2PC中只有协调者有超时机制,3PC在协调者和参与者中都引入了超时机制,协调者呈现故障后,参与者就不会始终阻塞。而且在第一阶段和第二阶段中又插入了一个筹备阶段(如下图,看着有点啰嗦),保障了在最初提交阶段之前各参加节点的状态是统一的。 尽管 3PC 用超时机制,解决了协调者故障后参与者的阻塞问题,但与此同时却多了一次网络通信,性能上反而变得更差,也不太举荐。 TCC所谓的TCC编程模式,也是两阶段提交的一个变种,不同的是TCC为在业务层编写代码实现的两阶段提交。TCC别离指Try、Confirm、Cancel,一个业务操作要对应的写这三个办法。 以下单扣库存为例,Try阶段去占库存,Confirm阶段则理论扣库存,如果库存扣减失败Cancel阶段进行回滚,开释库存。 TCC 不存在资源阻塞的问题,因为每个办法都间接进行事务的提交,一旦出现异常通过则Cancel来进行回滚弥补,这也就是常说的补偿性事务。 本来一个办法,当初却须要三个办法来反对,能够看到 TCC 对业务的侵入性很强,而且这种模式并不能很好地被复用,会导致开发量激增。还要思考到网络稳定等起因,为保障申请肯定送达都会有重试机制,所以思考到接口的幂等性。 音讯事务(最终一致性)音讯事务其实就是基于消息中间件的两阶段提交,将本地事务和发消息放在同一个事务里,保障本地操作和发送音讯同时胜利。 下单扣库存原理图: 订单零碎向MQ发送一条准备扣减库存音讯,MQ保留准备音讯并返回胜利ACK 接管到准备音讯执行胜利ACK,订单零碎执行本地下单操作,为避免音讯发送胜利而本地事务失败,订单零碎会实现MQ的回调接口,其内一直的查看本地事务是否执行胜利,如果失败则rollback回滚准备音讯;胜利则对音讯进行最终commit提交。 库存零碎生产扣减库存音讯,执行本地事务,如果扣减失败,音讯会从新投,一旦超出重试次数,则本地表长久化失败音讯,并启动定时工作做弥补。 基于消息中间件的两阶段提交计划,通常用在高并发场景下应用,就义数据的强一致性换取性能的大幅晋升,不过实现这种形式的老本和复杂度是比拟高的,还要看理论业务状况。 Seata Seata 也是从两段提交演变而来的一种分布式事务解决方案,提供了 AT、TCC、SAGA 和 XA 等事务模式,这里重点介绍 AT模式。 既然 Seata 是两段提交,那咱们看看它在每个阶段都做了点啥?下边咱们还以下单扣库存、扣余额举例。 先介绍 Seata 分布式事务的几种角色: Transaction Coordinator(TC): 全局事务协调者,用来协调全局事务和各个分支事务(不同服务)的状态, 驱动全局事务和各个分支事务的回滚或提交。 ...

December 9, 2020 · 1 min · jiezi

关于分布式:CAP理论解读

经验过技术面试的小伙伴想必对这个两个概念曾经再相熟不过了! 我当年加入面试的时候,不夸大地说,只有问到分布式相干的内容,面试官简直是必定会问这两个分布式相干的实践。 并且,这两个实践也能够说是小伙伴们学习分布式相干内容的根底了! 因而,小伙伴们十分十分有必要将这实践搞懂,并且可能用本人的了解给他人讲进去。 这篇文章我会站在本人的角度对这两个概念进行解读! CAP实践CAP 实践/定理起源于 2000年,由加州大学伯克利分校的Eric Brewer传授在分布式计算原理研讨会(PODC)上提出,因而 CAP定理又被称作 布鲁尔定理(Brewer’s theorem) 2年后,麻省理工学院的Seth Gilbert和Nancy Lynch 发表了布鲁尔猜测的证实,CAP实践正式成为分布式畛域的定理。 简介CAP 也就是 Consistency(一致性)、Availability(可用性)、Partition Tolerance(分区容错性) 这三个单词首字母组合。 CAP 实践的提出者布鲁尔在提出 CAP 猜测的时候,并没有具体定义 Consistency、Availability、Partition Tolerance 三个单词的明确定义。 因而,对于 CAP 的民间解读有很多,个别比拟被大家举荐的是上面这种版本的解。 在实践计算机科学中,CAP 定理(CAP theorem)指出对于一个分布式系统来说,当设计读写操作时,只能能同时满足以下三点中的两个: 一致性(Consistence) : 所有节点拜访同一份最新的数据正本可用性(Availability): 非故障的节点在正当的工夫内返回正当的响应(不是谬误或者超时的响应)。分区容错性(Partition tolerance) : 分布式系统呈现网络分区的时候,依然可能对外提供服务。什么是网络分区? 分布式系统中,多个节点之前的网络原本是连通的,然而因为某些故障(比方局部节点网络出了问题)某些节点之间不连通了,整个网络就分成了几块区域,这就叫网络分区。 不是所谓的“3 选 2”大部分人解释这一定律时,经常简略的表述为:“一致性、可用性、分区容忍性三者你只能同时达到其中两个,不可能同时达到”。实际上这是一个十分具备误导性质的说法,而且在 CAP 实践诞生 12 年之后,CAP 之父也在 2012 年重写了之前的论文。 当产生网络分区的时候,如果咱们要持续服务,那么强一致性和可用性只能 2 选 1。也就是说当网络分区之后 P 是前提,决定了 P 之后才有 C 和 A 的抉择。也就是说分区容错性(Partition tolerance)咱们是必须要实现的。简而言之就是:CAP 实践中分区容错性 P 是肯定要满足的,在此基础上,只能满足可用性 A 或者一致性 C。 因而,分布式系统实践上不可能抉择 CA 架构,只能抉择 CP 或者 AP 架构。 ...

December 7, 2020 · 1 min · jiezi

关于分布式:冰河开源了全网首个完全开源的分布式全局有序序列号分布式ID框架

写在后面mykit-serial框架的设计参考了李艳鹏大佬开源的vesta框架,并彻底重构了vesta框架,借鉴了雪花算法(SnowFlake)的思维,并在此基础上进行了全面降级和优化。反对嵌入式(Jar包)、RPC(Dubbo,motan、sofa、SpringCloud、SpringCloud Alibaba等支流的RPC框架)、Restful API(反对SpringBoot和Netty),可反对最大峰值型和最小粒度型两种模式。开源地址: GitHub:https://github.com/sunshinelyz/mykit-serial Gitee:https://gitee.com/binghe001/mykit-serial 为何不必数据库自增字段?如果在业务零碎中应用数据库的自增字段,自增字段齐全依赖于数据库,这在数据库移植,扩容,荡涤数据,分库分表等操作时带来很多麻烦。 在数据库分库分表时,有一种方法是通过调整自增字段或者数据库sequence的步长来达到跨数据库的ID的唯一性,但依然是一种强依赖数据库的解决方案,有诸多的限度,并且强依赖数据库类型,如果咱们想减少一个数据库实例或者将业务迁徙到一种不同类型的数据库上,那是相当麻烦的。 为什么不必UUID?UUID尽管可能保障ID的唯一性,然而,它无奈满足业务零碎须要的很多其余个性,例如:工夫粗略有序性,可反解和可制作型。另外,UUID产生的时候应用齐全的工夫数据,性能比拟差,并且UUID比拟长,占用空间大,间接导致数据库性能降落,更重要的是,UUID并不具备有序性,这就导致B+树索引在写的时候会有过多的随机写操作(间断的ID会产生局部程序写),另外写的时候因为不能产生程序的append操作,须要进行insert操作,这会读取整个B+树节点到内存,而后插入这条记录后再将整个节点写回磁盘,这种操作在记录占用空间比拟大的状况下,性能降落比拟大。所以,不倡议应用UUID。 须要思考的问题既然数据库自增ID和UUID有诸多的限度,咱们就须要思考如何设计一款分布式全局惟一的序列号(分布式ID)服务。这里,咱们须要思考如下一些因素。 全局惟一分布式系统保障全局惟一的一个乐观策略是应用锁或者分布式锁,然而,只有应用了锁,就会大大的升高性能。 因而,咱们能够借鉴Twitter的SnowFlake算法,利用工夫的有序性,并且在工夫的某个单元下采纳自增序列,达到全局的唯一性。 粗略有序UUID的最大问题就是无序的,任何业务都心愿生成的ID是有序的,然而,分布式系统中要做到齐全有序,就波及到数据的汇聚,须要用到锁或者分布式锁,思考到效率,须要采纳折中的计划,粗略有序。目前有两种支流的计划,一种是秒级有序,一种是毫秒级有序,这里又有一个衡量和取舍,咱们决定反对两种形式,通过配置来决定服务应用其中的一种形式。 可反解一个 ID 生成之后,ID自身带有很多信息量,线上排查的时候,咱们通常首先看到的是ID,如果依据ID就能晓得什么时候产生的,从哪里来的,这样一个可反解的 ID 能够帮上很多忙。 如果ID 里有了工夫而且能反解,在存储层面就会省下很多传统的timestamp 一类的字段所占用的空间了,这也是两全其美的设计。 可制作一个零碎即便再高可用也不会保障永远不出问题,出了问题怎么办,手工解决,数据被净化怎么办,洗数据,可是手工解决或者洗数据的时候,如果应用数据库自增字段,ID曾经被起初的业务笼罩了,怎么复原到零碎出问题的工夫窗口呢? 所以,咱们应用的分布式全局序列号(分布式ID)服务肯定要可复制,可复原 ,可制作。 高性能不论哪个业务,订单也好,商品也好,如果有新记录插入,那肯定是业务的外围性能,对性能的要求十分高,ID生成取决于网络IO和CPU的性能,CPU个别不是瓶颈,依据教训,单台机器TPS应该达到10000/s。 高可用首先,分布式全局序列号(分布式ID)服务必须是一个对等的集群,一台机器挂掉,申请必须可能转发到其余机器,另外,重试机制也是必不可少的。最初,如果近程服务宕机,咱们须要有本地的容错计划,本地库的依赖形式能够作为高可用的最初一道屏障。 也就是说,咱们反对RPC公布模式,嵌入式公布模式和REST公布模式,如果某种模式不可用,能够回退到其余公布模式,如果Zookeeper不可用,能够会退到应用本地预配的机器ID。从而达到服务的最大可用。 可伸缩作为一个分布式系统,永远都不能疏忽的就是业务在一直地增长,业务的相对容量不是掂量一个零碎的唯一标准,要晓得业务是永远增长的,所以,零碎设计岂但要思考能接受的相对容量,还必须思考业务增长的速度,零碎的程度伸缩是否能满足业务的增长速度是掂量一个零碎的另一个重要规范。 设计与实现整体架构设计mykit-serial的整体架构图如下所示。 mykit-serial框架各模块的含意如下: mykit-bean:提供对立的bean类封装和整个框架应用的常量等信息。mykit-common:封装整个框架通用的工具类。mykit-config:提供全局配置能力。mykit-core:整个框架的外围实现模块。mykit-db:寄存数据库脚本。mykit-interface:整个框架的外围形象接口。mykit-service:基于Spring实现的外围性能。mykit-rpc:以RPC形式对外提供服服务(后续反对Dubbo,motan、sofa、SpringCloud、SpringCloud Alibaba等支流的RPC框架)。mykit-server:目前实现了Dubbo形式,后续迁徙到mykit-rpc模块。mykit-rest:基于SpringBoot实现的Rest服务。mykit-rest_netty:基于Netty实现的Rest服务。mykit-test:整个框架的测试模块,通过此模块能够疾速把握mykit-serial的应用形式。公布模式依据最终的客户应用形式,可分为嵌入公布模式,RPC公布模式和Rest公布模式。 嵌入公布模式:只实用于Java客户端,提供一个本地的Jar包,Jar包是嵌入式的原生服务,须要提前配置本地机器ID(或者服务启动时,由Zookeeper动态分配惟一的分布式序列号),然而不依赖于核心服务器。RPC公布模式:只实用于Java客户端,提供一个服务的客户端Jar包,Java程序像调用本地API一样来调用,然而依赖于核心的分布式序列号(分布式ID)产生服务器。REST公布模式:核心服务器通过Restful API提供服务,供非Java语言客户端应用。公布模式最初会记录在生成的全局序列号中。 序列号类型依据工夫的位数和序列号的位数,可分为最大峰值型和最小粒度型。 1. 最大峰值型:采纳秒级有序,秒级工夫占用30位,序列号占用20位 字段版本类型生成形式秒级工夫序列号机器ID位数636260-6130-5910-290-92. 最小粒度型:采纳毫秒级有序,毫秒级工夫占用40位,序列号占用10位 字段版本类型生成形式毫秒级工夫序列号机器ID位数636260-6120-5910-190-9最大峰值型可能接受更大的峰值压力,然而粗略有序的粒度有点大,最小粒度型有较粗疏的粒度,然而每个毫秒能接受的实践峰值无限,为1024,同一个毫秒如果有更多的申请产生,必须等到下一个毫秒再响应。 分布式序列号(分布式ID)的类型在配置时指定,须要重启服务能力相互切换。 数据结构1. 序列号 最大峰值型 20位,实践上每秒内均匀可产生2^20= 1048576个ID,百万级别,如果零碎的网络IO和CPU足够弱小,可接受的峰值达到每毫秒百万级别。 最小粒度型 10位,每毫秒内序列号总计2^10=1024个, 也就是每个毫秒最多产生1000+个ID,实践上接受的峰值齐全不如咱们最大峰值计划。 2. 秒级工夫/毫秒级工夫 最大峰值型 30位,示意秒级工夫,2^30/60/60/24/365=34,也就是可应用30+年。 最小粒度型 40位,示意毫秒级工夫,2^40/1000/60/60/24/365=34,同样能够应用30+年。 3. 机器ID 10位, 2^10=1024, 也就是最多反对1000+个服务器。核心公布模式和REST公布模式个别不会有太多数量的机器,依照设计每台机器TPS 1万/s,10台服务器就能够有10万/s的TPS,根本能够满足大部分的业务需要。 然而思考到咱们在业务服务能够应用内嵌公布形式,对机器ID的需求量变得更大,这里最多反对1024个服务器。 4. 生成形式 2位,用来辨别三种公布模式:嵌入公布模式,RPC公布模式,REST公布模式。 ...

December 6, 2020 · 1 min · jiezi

关于分布式:分布式集群如何实现高效的数据分布

一、前言随着互联网的倒退,用户产生的数据越来越多,企业面临着宏大数据的存储问题,目前市面上支流的分布式大数据文件系统,都是对数据切片打散,通过离散办法将数据散列在集群的所有节点上,本文将带你理解DHT(Distributed Hash Table):分布式哈希表是如何实现数据的分布式离散存储的。 DHT(Distributed Hash Table):分布式哈希表二、技术背景互联网倒退晚期,数据通常存储在单个服务器上,初期数据增长较为迟缓,能够通过晋升单机的存储能力满足数据的增长需要;随着互联网遍及水平的推动,用户数、用户产生和拜访的数据呈指数增长;单机已无奈存储用户须要的数据。为此,迫切需要多个服务器独特合作,存储量级更大的数据。 三、传统 Hash传统 Hash 通过算法 hash()=X mod S 来对数据进行扩散,在元数据比拟扩散的状况下,数据可能很好的散列在集群节点中。因为S代表了集群的节点数,当进行集群的扩容缩容时,S的变动会影响到历史数据的命中问题,因而为了进步数据命中率,会产生大量测数据迁徙,性能较差。 四、一个简略的 DHT分布式 Hash 通过结构一个长度为2的32次方(ipv4地址的数量)的环,将节点散列在 Hash环上,依据不同的 Hash算法计算出来的 Hash值有所不同,本文采纳FNV Hash算法来计算 Hash值。 如图所示,先将存储节点通过 Hash计算后增加到 DHT 环上,每个节点间隔上一个节点间的这段区间,作为该节点的数据分区,Hash值落在这个分区的数据将存储到这个节点上; 而后将数据通过 Hash算法散列到DHT环上,数据落到DHT环上后,依照顺时针方向找到离本人最近的节点作为数据存储节点,如下所示,数据 ObjectA 落到节点 NodeA上,数据 ObjectB 落到节点 NodeB 上; 初始化DHT的源码如下: 首先定义了一个寄存集群节点元数据的Map,用来存储接入到DHT环中的物理节点数据。而后定义了一个DHT环——vNodes,用来存储DHT环中的节点地位信息。这样咱们就实现了一个简略的DHT环,通过addPhysicalNode办法能够模仿集群节点的退出。退出时会计算节点的Hash值并存放到vNodes中。 初始化4个存储节点。 通过countNodeValue办法插入100条数据,在写数据的过程中,依据数据的 Hash值找到DHT环上最近的一个节点,而后将数据写入该节点中。 插入100条数据后,各个节点的数据分布如下,能够看见4个节点的数据并不平均,只有一个节点调配到了数据(这与写入的数据也有肯定关系)。 插入100万条数据后,各个节点的数据分布如下,尽管每个节点都调配到了数据,但依然呈现了较大的数据歪斜。这将导致99%的申请都会由Node3进行解决,呈现一核有难三核围观的状况。 呈现如上问题是什么起因呢?通过查看DHT环上各节点的hash值不难看出,各节点间距不平均,插入的数据按顺时针查找节点时都找到了Node3,因而数据都写到了Node3外面,所以节点区间不平均会使某些节点能笼罩更多的数据,导致数据不平衡。 说了一个简略DHT环的基本原理后,再来思考一个问题:简略的DHT环数据离散,但依然存在数据歪斜的状况,还不如用传统的hash形式调配数据。 后面提到传统的hash形式在过后在节点故障后,整个集群的数据会进行大量的迁徙,影响集群性能,那么DHT能解决这一问题吗? 咱们还是用之前调配好的100万条数据,模仿节点4故障,如下图所示,Node4上的数据只迁徙到了Node1,对Node2和Node3不产生数据迁徙,从而升高了节点故障导致每个节点都须要进行数据迁徙带来的影响。 五、DHT 的改良1、虚构节点 大家思考一下,解决数据歪斜的问题能够如何解决? 通过减少集群节点的形式最简略间接,目标是将更多的节点散列到DHT环上,使得环上所有节点散布更加平均,节点间的区间距离尽可能的平衡,以下是10个节点和20个节点集群的数据分布状况。 能够发现,通过减少节点的形式,依然无奈从根本上解决数据歪斜的问题。并且减少节点会进步集群的设施老本和保护老本。同时,这种计划还引出了一个重大的问题,如果Node20故障了,那么Node20的数据会全数迁徙到下一个节点上,最终导致集群呈现数据歪斜,数据较多的节点还将解决更多的IO申请,容易造成数据热点,成为性能瓶颈,引发集群整体的性能降落。 ...

November 18, 2020 · 1 min · jiezi

关于分布式:Mycat作为Mycat核心开发者怎能不来一波Mycat系列文章

写在后面Mycat是基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优良的架构和性能以及泛滥成熟的应用案例使得Mycat一开始就领有一个很好的终点,站在伟人的肩膀上,咱们能看到更远。业界优良的开源我的项目和翻新思路被宽泛融入到Mycat的基因中,使得Mycat在很多方面都当先于目前其余一些同类的开源我的项目,甚至超过某些商业产品。——来自Mycat官网。作为Mycat的外围开发者,怎能不来一波Mycat系列文章呢? 背景介绍作为Mycat的外围开发者之一,明天,终于安顿到Mycat系列文章了。在Mycat系列文章中,咱们一起从一个利用Mycat实现分库分表的案例作为入门程序。后续会继续更新Mycat原理、架构和底层源码解析的文章。心愿Mycat系列文章可能帮忙小伙伴们彻底把握Mycat。 那么,明天,咱们就先来一波应用Mycat实现MySQL分库分表的文章。 注:案例中的MySQL服务器是装置在CentOS6.8服务器上,Mycat Server是装置在本机的Windows零碎上,装置在什么环境上无所谓,这里,我用的是VMWare虚拟机,装置的CentOS零碎,开启多个虚拟机,电脑切实是吃力,所以将Mycat Server装在了本机的Windows零碎上。 计划布局 如上表所示,在局域网的4台主机中,131——133的主机各装置有一台MySQL实例,130主机,也就是本机装置了Mycat Server。 当初假如零碎的数据库为messagedb,外面只有2张表,一张表为音讯表:message,一张示意消息来源的字典表:source,本案例实现的是按天然月分片的规定,因而上述3个mysql实例各自须要创立4个数据库,即 阐明:如果是刚接触Mycat的小伙伴对分片不太了解,简略地说,对于Mycat,一个分片示意某一个MySQL实例上的某一个数据库,即schema@host,于是当咱们原先的一张大表须要分片的时候,mycat就会依照咱们设定的规定,把这张大表中的数据扩散到各个分片上,即所谓的分表分库,因而咱们须要在每个对应的分片上创立雷同名称的数据库,雷同构造的表。 环境筹备留神:这里,我就省略了MySQL的装置过程,小伙伴们可自行装置MySQL。我后续也会在MySQL相干的专题中给大家分享企业级MySQL装置、优化与部署过程。 创立数据库并建表导入数据依据数据库实例和存储的数据库对应关系表创立所有的数据库,并在每个数据库里执行如下脚本: create table source ( id int(11) not null auto_increment primary key comment 'pk', name varchar(10) default '' comment 'source name');create table message ( id int(11) not null auto_increment primary key comment 'pk', content varchar(255) default '' comment 'message content', create_time date default null, source_id int(11) not null, foreign key(source_id) references source(id));insert into `source`(`id`,`name`) values(1,'weibo');insert into `source`(`id`,`name`) values(2,'weixin');insert into `source`(`id`,`name`) values(3,'qq');insert into `source`(`id`,`name`) values(4,'email');insert into `source`(`id`,`name`) values(5,'sms');在message表中,总共有4个字段: ...

November 11, 2020 · 6 min · jiezi

关于分布式:分布式下的主键是怎么生成的

数据库演进之路提到了当数据库的压力瓶颈到了,咱们能够采纳分库分表来分担数据库的压力,分库分表的状况下,主键是怎么设置的? 数据库主键自增长失常状况下,如果每个数据库都自增长,那就会呈现多个数据库id反复的问题,比方下图所示,都呈现了id为1,2,3的主键。为了防止上述的问题,咱们能够在每个数据库设置一个初始值,以及设置每次的增量,如下图所示,第一个数据库初始值是1,增量是3,id就是1,4,7。尽管防止了ID反复,然而id的递增是没有方法保障的,比方数据库1的id是1,4,7,10。数据库2的id是2,5,数据库3的id是3。而且前面如果要扩容,也是很麻烦。既然数据库自身没方法生成id,那咱们能够用一个专门的数据库生成自增长的id。尽管id能够自增长,不反复,递增,但此时所有的压力都在生成id的数据库上。为了缓解数据库的压力,能够一次性生成N个主键,比方100,而后存在缓存利用中,数据库每次须要id的时候,去缓存利用取。毛病就是又多了一层服务。取一个自增长id要缓存服务+数据库。下面的主键生成用redis行不行?尽管redis速度比拟快,然而没有实时长久化,可能造成主键的反复。比方此时为9,incr后变成10,而后挂了,此时还没长久化,再生成id的时候还是9,而后incr为10,就有两个id为10的数据。即使做了故障转移,因为是异步同步数据的,有可能数据还没到slave,master就挂了,此时id还是会反复。除了数据库的压力,自增长的主键还可能泄露商业秘密,他人很容易拆到下一个主键是什么。 UUID才用数据库生成主键,数据库压力就很大,那能够采纳利用来生成。比较简单的就是UUID,性能好,不反复。毛病就是不能保障递增,而且UUID字符串比拟长,索引性能很差。 工夫戳以以后毫秒作为主键,长处就是简略、递增,毛病就是可能反复。比方以后毫秒同时有10个并发,此时就反复了。为了缩小反复,升高到微秒级别,或者在工夫戳前面加个随机字符串,仍然有反复的危险。 snowflakesnowflake是twitter开源的分布式ID生成算法,生成64位的bit,第一位是0,保障id是负数。前面41位是以后工夫戳的二进制模式,再前面10位机器码的二进制,最初12位是计数顺序号,记录同一毫秒内生成的数量。比方以后工夫为2020-01-01 00:00:00,转换工夫戳为1577808000000,再转二进制为10110111101011100101011110111010000000000。此时,后面42位为:假如以后的机器码为100,转为二进制为1100100,因为不满10位,咱们在后面补3个0,后果为0001100100。此时,后面52位为:如果同一毫秒,同一个机器的并发比拟大,此时生成的数据就有反复的,所以snowflake就有前面的12位作为计数器,比方第一个拜访的是1,第二个拜访的是2,假如咱们此时为以后毫秒的第200个获取id的,200转为二进制为11001000,补0后为000011001000,此时,后面64位为:如果感觉前面的12位不够,咱们能够压缩后面机器码的位数,这样计数顺序号的值就能够更大了。毛病也很显著,因为这个算法是依赖工夫戳的,所以当零碎的工夫回拨的时候,就可能造成id的反复

November 11, 2020 · 1 min · jiezi

关于分布式:MIT6824分布式系统课程-翻译学习笔记三GFS

阐明本系列文章是对赫赫有名的 MIT6.824分布式系统课程 的翻译补充和学习总结,算是本人一边学习一边记录了。 如有疏漏谬误,还请斧正:) 继续更新ing。。。 翻译&补充论文The Google File SystemSanjay Ghemawat, Howard Gobioff, and Shun-Tak LeungSOSP 2003 为什么咱们须要读这篇论文?分布式存储是很重要的概念 接口/语义 应该是什么样子的?外部是如何工作的?GFS论文笼罩了6.824中的很多主题:并行,容错,复制,一致性良好的零碎论文——细节从利用始终到网络都笼罩到胜利的理论利用的设计 为什么分布式存储很难?高性能 --> 多台机器间数据分片多台服务器 --> 常常出错容错 --> 复制复制 --> 不统一更好地一致性 --> 低性能 对于一致性,应该怎么解决?现实的模型:和一台服务器一样的行为表现服务器应用硬盘存储服务器在同一时刻只执行一条客户的操作(即使是并发的)读之前所写,即使服务器解体或重启因而:假如C1和C2并发地写,等到写操作结束,C3和C4读。它们会取得什么?C1: Wx1C2: Wx2C3: ---- Rx?C4: -------- Rx?答复:1或者2,然而C3和C4会看到雷同的值。这是一个“强”一致性的模型。然而一台独自的服务器容错性很差。 为了容错的复制,很难实现强一致性一个简略,但有问题的复制计划: 两个复制的服务器,S1和S2多个客户端向两台服务器,并行发送写申请多个客户端向其中一台,发送读申请在咱们的示例中,C1和C2的写申请可能会以不同的程序达到两台服务器 如果C3从S1读取,可能会看到x=1如果C4从S2读取,可能会看到x=2或者如果S1承受了一个读申请,然而在发送写申请到S2时,客户端解体了,会怎么样?这不是强一致性!更好的一致性通常须要通信,来保障复制集的统一 —— 会很慢!性能和一致性之间须要衡量很多,当前会看到 GFS内容:很多谷歌的服务须要大型疾速的对立文件存储系统,比方:Mapreduce,爬虫/索引,日志存储/剖析,Youtube(?)全局来看(对于一个独自的数据中心):任何一个客户端能够读取任意文件,容许多个利用之间共享数据在多个服务器/硬盘上自动化“切片”每个文件,晋升并行的性能,减少空间可用度谬误的主动复原每次部署只有一个数据中心只有谷歌的利用和用户旨在大文件的的程序操作;读或者追加。不是存储小数据的低提早DB 在2003年有什么翻新点?他们是怎么被SOSP承受?不是分布式、分区、容错这些根本的思维大规模在工业界的理论利用教训弱一致性的胜利案例独自master的胜利案例 架构总览客户端(库,RPC —— 但不像Unix文件系统那样可见)每个文件切分为独立的64MB的数据块数据块服务器,每个数据块复制3份每个文件的数据块们散布在多个数据块服务器上,用于并行读写(比方,MapReduce),并且容许大文件只有一个master(!),master也会复制工作的划分:master负责写名称,数据块服务器负责写数据 Master的状态在RAM中(速度,应该是有点小的):在硬盘上: 日志检查点为什么有日志和检查点?为什么是大的数据块?当客户端C想要读数据,是什么步骤?C发送文件名和偏移量到master M(如果没有缓存的话)M找到这个偏移量的数据块handleM回复最新版本的数据块服务器的列表C缓存handle和数据块服务器列表C发送申请到最近的数据块服务器,包含数据块handle和偏移量数据块服务器从硬盘上读取数据块文件,并返回master怎么晓得数据块服务器含有一个指定的数据块?当C想要在记录后追加,是什么步骤?论文的图2 C询问M文件的最初一个数据块如果M发现数据块没有主记录(或者租约过期)2a. 如果没有写数据块服务器的最新版本,谬误2b. 从最新的版本中抉择主节点和备份节点2c. 版本号减少,写到硬盘的日志上2d. 通知主记录和备份的记录他们是谁,以及新版本2e. 在硬盘上复制地写入新版本M通知C主记录和备份记录C向全副发送数据(只是临时的。。。),并期待C通知P须要追加P查看租约是否过期,数据块是否有空间P确定偏移量(数据块的完结)P写数据块文件(一个Linux文件)P通知所有备份节点偏移量,通知它们须要追加到数据块文件P期待所有备份节点的回复,超时则为谬误,例如:硬盘空间有余P通知C ok或谬误如果出错,C从头重试GFS提供给客户端的是什么样的一致性保障须要通知利用以某种模式应用GFS。 这是一种可能性:如果主节点通知客户端一条记录胜利追加,则所有的读者随后关上这个文件,都能够看到追加的记录。(然而并非失败的追加就不可见,或者说,所有的读者都会看到雷同的文件内容,雷同程序的记录) 咱们怎么晓得GFS是否实现了这些保障?看它对不同种谬误的解决形式:解体,解体+重启,解体+代替,信息失落,分区。请想一想GFS是怎么保障要害个性的。 * 一个追加的客户端在不适合的时刻失败了,怎么办?有没有不适合的时刻存在? * 一个追加客户端缓存了一个过期的(谬误的)主节点,怎么办?* 一个读的客户端缓存了一个过期的备份节点列表,怎么办?* 一个主节点解体+重启,会导致文件的失落吗?或者遗记哪些数据块服务器存储指定的数据块? * 两个客户端在同一时间进行记录追加。他们会笼罩彼此的记录吗? ...

November 9, 2020 · 1 min · jiezi

关于分布式:分布式事务面试官问我MySQL中的XA事务崩溃了如何恢复

写在后面前段时间搭建了一套MySQL分布式数据库集群,数据库节点有12个,用来测试各种分布式事务计划的性能和优缺点。测试MySQL XA事务时,正当测试脚本向数据库中批量插入数据时,强制服务器断电!留神:是间接拔电源,使其霎时断电,再次重启服务器后,MySQL数据库报错了。特此记录MySQL XA事务的复原。MySQL XA事务问题服务器强制断电后重启,此时MySQL报错,查看MySQL启动日志时,发现如下所示的错误信息。 InnoDB: The log sequence number in ibdata files does not matchInnoDB: the log sequence number in the ib_logfiles!100224 23:24:20 InnoDB: Database was not shut down normally!InnoDB: Starting crash recovery.InnoDB: Reading tablespace information from the .ibd files...InnoDB: Restoring possible half-written data pages from the doublewriteInnoDB: buffer...InnoDB: Transaction 0 4497755 was in the XA prepared state.InnoDB: Transaction 0 4468551 was in the XA prepared state.InnoDB: Transaction 0 4468140 was in the XA prepared state.InnoDB: 3 transaction(s) which must be rolled back or cleaned upInnoDB: in total 0 row operations to undoInnoDB: Trx id counter is 0 5312768InnoDB: Starting in background the rollback of uncommitted transactions100224 23:24:20 InnoDB: Rollback of non-prepared transactions completed100224 23:24:20 InnoDB: Started; log sequence number 0 3805002509100224 23:24:20 InnoDB: Starting recovery for XA transactions...100224 23:24:20 InnoDB: Transaction 0 4497755 in prepared state after recovery100224 23:24:20 InnoDB: Transaction contains changes to 8 rows100224 23:24:20 InnoDB: Transaction 0 4468551 in prepared state after recovery100224 23:24:20 InnoDB: Transaction contains changes to 1 rows100224 23:24:20 InnoDB: Transaction 0 4468140 in prepared state after recovery100224 23:24:20 InnoDB: Transaction contains changes to 1 rows100224 23:24:20 InnoDB: 3 transactions in prepared state after recovery100224 23:24:20 [Note] Found 3 prepared transaction(s) in InnoDB100224 23:24:20 [Warning] Found 3 prepared XA transactions100224 23:24:20 [Note] Event Scheduler: Loaded 0 events100224 23:24:20 [Note] /opt/mysql/bin/mysqld: ready for connections.Version: '8.0.18' socket: '/tmp/mysql.sock' port: 3306 MySQL Community Server (GPL) 从下面的日志信息中,能够看出有三个XA的事务没有提交或回滚。那该如何复原MySQL的XA事务呢? ...

October 31, 2020 · 2 min · jiezi

关于分布式:MIT6824分布式系统课程-翻译学习笔记二基础架构RPC和线程持续更新中

阐明本系列文章是对赫赫有名的 MIT6.824分布式系统课程 的翻译补充和学习总结,算是本人一边学习一边记录了。 如有疏漏谬误,还请斧正:) 继续更新ing。。。 翻译&补充内容Go中的线程和RPC,看一下试验 为什么抉择Go?对线程良好的反对不便的RPC类型平安垃圾回收(没有内存开释后再被应用的问题)线程+垃圾回收十分棒绝对简略在教程学习后,请浏览 effective go 线程很有用的结构工具,然而有时候会很辣手在Go里叫做“goroutines”;其余中央叫做线程 线程 = “执行线程”线程容许一个程序同时做很多事件每一个线程依序执行,就像没有线程的一般程序一样线程之间共享内存每个线程包含本人的状态:程序计数器,寄存器和栈 为什么抉择线程?它们可能解决并发,在分布式系统中很有用I/O并发 客户端并行地发送申请到许多服务器,并期待回复;服务端解决多个客户端的申请,每个申请会阻塞;在期待客户端X从磁盘读取数据的申请时,会解决客户端Y的申请。多核的性能:在多个核上并行地执行代码方便性:在后盾,每隔1秒,查看每个worker是否仍旧存活。 有没有线程的替代品?有的:在一个独自的线程里,用代码明确地退出流动;通常称为“事件驱动”维持每个流动的状态信息,比方每个客户端申请一个“事件”的过程如下: 查看每个流动的新输出(比方,服务器的回应)执行每个流动的下个步骤更新状态事件驱动实现I/O并发: 打消线程的耗费(可能会比拟大)然而并没有应用到多核带来的减速对代码来说很苦楚线程带来的挑战:共享数据: 比方,如果两个线程同时执行 n = n + 1 会怎么样?或者一个线程减少一个线程读数据?--> 应用锁(Go里的sync.Mutex)--> 防止共享会批改的数据线程中的协同工作: 比方,一个线程生产数据,另一个线程生产。怎么让消费者期待(开释CPU)?怎么让生产者告诉消费者?--> 应用go中的channel,或sync.Cond,或 WaitGroup死锁: 加锁有环形依赖,或通信有环形依赖(比方:RPC或Go的channel)让咱们看教程中的网络爬虫,把它作为一个线程示例 为什么是网络爬虫?目前是获取所有的网页,比方:用于建设索引网页和链接组成图多个链接指向雷同的页面图中有环形 爬虫带来的挑战:须要应用I/O并发: 网络提早比网络容量更受限须要同时获取多个URL。为了减少每秒的URL获取数目,须要应用并发的多线程每个URL仅“获取一次” 避免浪费网络带宽对近程服务器更敌对须要记住每个拜访过的URL晓得何时完结 咱们看下两种解决形式【课程表页面的crawler.go】Serial 爬虫:通过递归Serial调用实现深度遍历“fetched” map防止了反复,突破环形;一个简略的map,通过传递援用,调用者能够看到并调用者的更新然而,一个时刻只能获取一个页面;咱们能够间接在Serial()函数前加“go”吗?咱们能够试下,看看会产生什么? ConcurrentMutex 爬虫:创立一个线程用于获取每个页面,启动很多并发的获取,放慢获取速度“go func”创立并执行协程,func能够是匿名办法多个线程共享“fetched” map,所以同一时刻只有一个线程能够获取任意的指定页面为什么应用Mutex(Lock()和Unlock())? 起因一: * 两个不同的web页面可能蕴含雷同的URL链接* 两个线程可能会同步获取这两个页面* T1读取fetched[url],T2也读取一样内容* 它们会同时发现这个url没有获取(already==false)* 它们会同时获取,这是谬误的* 锁会让检查和更新操作原子化,所以只有一个线程看到already==false起因二: * 从外部来看,map是个简单的数据结构(tree?就还是可扩大的hash?)* 并发更新会毁坏外部变量* 并发读写会导致读失败如果我正文掉 Lock()/Unlock(),会怎么样? * go run crawler.go会工作吗?* go run -race crawler.go 会检测出资源竞争,即便输入是正确的ConcurrentMutex爬虫怎么判断完结? sync.WaitGroupWait()会期待所有的Add()数目和Done()始终,即,期待所有的子线程完结[图表:环形URL图上的协程树];每个树的节点上都有一个WaitGroup这个爬虫会创立多少个并发的线程? ConcurrentChannel 爬虫:一个Go channel: ...

October 30, 2020 · 1 min · jiezi

关于分布式:美团内部讲座|北航全权一种城市空中移动性管理分布式控制框架

无人机交通以及最近衰亡的地面移动性治理失去了宽泛的关注。为此,波音、空客、霍尼韦尔和贝尔等传统航空巨头以及Uber等新兴世界级影响力的企业纷纷退出。本报告提出了地面高速公路计划以及仿真测试。该计划基于时空大数据,思考了交通网络、航线布局和分布式管制设计。在地面高速公路上,每架无人机都有本人的布局的航线,能够自主地自在航行,从而反对密集平面的航行交通。 1. 背景明天我给大家带来咱们实验室(北航牢靠航行管制研究组)做的一些工作,次要内容是讲一种城市地面移动性治理分布式管制框架。 置信美团的同学肯定也很十分期待实现无人机配送的一天早日到来。将来无人机配送服务将会极大地扭转咱们目前的生存形式。只管在人群密集的区域,咱们依然须要靠人来实现配送服务,然而在人口比拟稠密,比方市区等地带,应用无人机配送会更好。报告表明,网联无人机将为产业带来7~10倍的产业机会,这也是咱们在大略三年前就开始着手做这方面相干的工作的起因。 无人机的交通网和交通管理,是否能够利用现有的交通形式呢?咱们通过钻研发现,像传统的民航网其实是不适宜的,民航的飞行器其实十分稠密,在三维空间,整个网络的变动频率是比拟低的,有入网申请时,基本上是通过集中式的布局。而公路网络只管很密集,然而二维空间,因而交通网络管理也是偏自主的。铁路同样也是二维的。网络动态变化是说就像咱们上互联网一样,咱们须要接入网络,而公路不可能马上为咱们修一条公路进去。无人机交通与公路、铁路具备共同点,不同的是无人机处于三维空间, 网络动态变化比拟高。因而咱们在设计无人机航行管制框架时,心愿设计一种可能适应包含无人机的减少、网络的扩大等变动的框架。对于门路布局,其实能够采纳集中式加自主的形式来进行。对于这部分的内容咱们往年发表了一篇综述文章《低空无人机交通管理概览与倡议综述》,感兴趣的同学能够参阅。 咱们心愿可能为低空持续增长无人机及利用提供一个低空的智能大脑。对于技术钻研来谈话,低空低空的区别没有那么大,但目前咱们次要是思考低空多一些。比如说凋谢120米以下的低空,它的特点在于这些中央会有十分多的修建,如果无人机掉下来的话,会对下方区域的人身及财产平安造成一些危害,这是对咱们城市交通的一个十分大的挑战。因而咱们次要思考以下三个需要: 布局无人机的航线、起飞时间,确保无人机在防止抵触的前提下腾飞:无人机航线起飞时间跟咱们目前坐飞机的感觉是一样的,有时候飞机会停在某个中央提早腾飞,目标是为了不与其余飞机在航路上产生碰撞及抵触,当然有时候也会因为天气等起因,须要飞机提早腾飞,因为飞机在高空期待,代价是最小的。在防止碰撞的前提下顺利完成航行工作应答天气、禁飞区等不确定因素的影响:无人机长期在航行过程中,咱们有时须要切断某些航线,这种状况下,咱们心愿飞行器依然可能可能飞到目的地,至多它能平安的回到左近的机场。 2. 地面高速公路根底:网络和时空大数据发展地面高速公路钻研,咱们须要有网络和时空大数据的一些钻研根底。 首先咱们须要有通信、导航、监督性能等基础设施,这些性能充当着整个无人机交通管理零碎的眼睛、耳朵和神经系统,负责态势感知和信息传输。其中,通信就是4G/5G、卫星通信等,这是咱们的网络。导航是咱们飞行器须要导航,比如说通过基站定位、雷达、卫星、惯导以及视觉的导航。而监督跟导航的区别在于导航是给飞行器用的,监督是咱们作为官网须要理解飞行器在地面的动静。有些飞行器可能会本人导航,通过导航或者通信通知公开的地面站,这样的话咱们能够监督。但有些飞行器是航模,没有通信的性能,只能被动的被看到,那么咱们能够通过一些可见光、声波等来监督,还有飞行器可能通过一些ADS-B等来播送本人的信息。因而通过以上这些性能,能够实现咱们对飞行器航行周边环境的理解,高空对地面环境的理解,这是咱们做地面高速公路钻研的一个根底。 另一方面,咱们须要时空大数据的撑持。首先咱们须要理解所有禁飞区,禁飞区也会动静的变动。其次咱们须要理解气象大数据,以便咱们布局飞行器避开极其天气。同时咱们也须要获取天文大数据的信息,比方通过天文大数据咱们能够理解什么地位有障碍物,哪些区域下方是草地等,依据这些信息能够进一步的提取一些信息,来布局飞行器的航路、航路网等以及布局飞行器的航线。另外咱们还能够通过挪动互联网晓得哪些地方人口密集,这样在布局航路网或者航线的时候,就能避开这些人口密集的中央。以上这些都是咱们钻研须要的时空大数据根底。 后面提到,网络是咱们钻研地面高速公路的根底,目前在空中交通,次要是通过网络来分享信息。然而网络会有网络品质,那么网络品质与航行平安是什么样的关系呢?网络品质通常由三个因素决定:噪声,提早,丢包(Packet Loss)。因为网络品质起因,无人机获取到的障碍物地位,和障碍物理论的地位可能就不一样了。以下图为例,无人机预计本身的地位产生了偏差,随之预计障碍物地位也产生了偏差。因而咱们须要设计一个航行的平安间隔,以应答网络品质造成的这种不确定性。这跟咱们在高速公路上开车须要放弃车间距是一个情理,咱们车间距这个概念用到无人机的空中交通,心愿以此来应答这些丢包提早。当然也有人通过一些管制的办法来解决这些问题,咱们这种办法应该更适宜交通的场景。 传统的空中交通的间隔没有这么简单,飞机之间的间隔距离十分远,那么无人机之间的间隔应该怎么来管制呢?通过钻研,咱们认为无人机的平安半径应该满足上图中的关系,rm是飞行器自身的半径,ro是障碍物自身的半径,rv是跟飞行器速度以及机动性相干的,re示意网络的影响。网络影响怎么来了解?提早丢包率是,如果丢包率为1的话,那就示意飞机齐全失联了。从激进角度来说,飞行器可能在任何地位。所以越靠近于1,平安半径越大,d示意提早,网络传递会有提早。有些同学可能认为像咱们当初打电话的提早曾经十分小了,然而在地面,咱们通过试验证实网络存在肯定的提早,另一方面丢包率会随着间隔的减少而减少。因而,咱们须要对网络影响进行评估,依据评估后果设计飞行器平安半径。在平安半径下,能够认为飞行器没有网络噪声,是齐全准确的,只有保障两个飞行器的平安半径不相交,那么飞机器必定不会相撞,这就是咱们平安半径的设计。 另一方面,咱们须要通过一些数据做危险评估,如下图所示,至多有两个因素:事变概率评估(fGIA)和事变伤亡评估。事变概率评估就是说飞行器不连续飞行就坠落的可能性,能够通过统计办法预估。无人机相比于飞机的一个益处是,即便坠落也未必会砸伤人。飞行器坠落有一个裸露模型,比如说掉落到树上或者房顶上对人的影响就会比拟小。因而咱们须要有地理信息撑持,一旦飞行器须要迫降,咱们能够通过地理信息找到比方草坪等适宜迫降的地带。同时裸露模型也与人口密度相干。而挫伤模型与飞行器设计相干,与飞行器着落的动量相干。以上这些因素独特失去危险评估,能够用来进行航路网布局、门路布局、紧急迫降等。制订相干规范,相干法律法规的部门会比较关心飞行器的危险评估,一些危险评估公司也会基于危险评估后果去举证飞行器的危险到底有多大。 3. 地面高速公路地面高速公路分为模型建设,算法设计,试验验证三局部为大家介绍。其中,模型建设分为两种:航路网模型和无人机模型,咱们治理无人机须要对无人机进行建模,而高空也须要给无人机发送指令,这相当于一个规范的模型;算法方面能够分为集中式空中交通管制和分布式空中交通管制,集中式能够认为所有的指令都是由地面站给飞行器发的,飞行器之间互不通信,通信齐全通过高空来协调,而分布式相对来说更加灵便一些。最初是咱们的仿真和试验。 3.1 模型建设3.1.1 航路网模型 航路网模型能够认为是节点和边形成的一个网络。咱们的设计指标是不同航路的无人机互相不烦扰,放弃平安间隔。如果飞行器在不同航道下面,比如说一条公路下面有两个方向,但不同航道下面的飞行器,须要放弃相应的平安间隔,相似两条路,它们之间的夹角十分小,要往一个节点过来,如果夹角小到肯定水平的话,那么不同航道上的两个飞行器之间的间隔就很近了,就可能会有危险。在理论过程中,咱们无奈得悉无人机的具体位置,只能晓得一个大略的不是特地精准的地位,因而就须要无人机之间放弃平安间隔。 航路网建网须要对空域有理解,刚刚后面咱们提到的地理信息,人口信息。如下图所示,能够认为彩色区域为禁飞区,它有两种,一种是比拟稠密的,一种是比拟密集的。无论哪一种,都能够通过节点把它们连贯在一起,这些节点可能是飞行器的起降点,还有一些节点可能是航路的交叉点,就像公路的交叉路口一样。 航路网建网有两个优化指标,一是心愿航路网的总长度越短越好,因为建设航路网,这也相当于一个基建工程,须要保障航路网下面的通信、导航、监督,这些都须要老本;二是心愿航路网的危险最低,思考到比方人口密度等因素,咱们心愿画出下图所示的航路网,然而这是一个多指标的优化问题。 咱们在航路网建模上做了一些工作,用了下图的几种办法。 首先是形态学骨架法,这个跟图像处理的骨架相似,给定一张图片须要生成它的骨架。原理很简略,彩色是危险的边界,生成的骨架就是这些航路,航路和两边的间隔要尽可能的远。其次是三角剖分法,连贯3个点的最短门路不是把三个边连成一个三角形,可能是通过费马点把它们连在一起。最初是综合法,形态学骨架法适宜密集的地图,而三角法更适宜稠密的地图,综合法兼顾密集与稠密两种状况,通过半自动的形式建成航路网。 形态学骨架法的实现过程如下图所示,首先是骨架提取,有些同学可能会问为什么骨架提取之后会产生这些变量,这是是因为咱们要保障提取进去的骨架间隔两边彩色危险区的间隔要大于肯定的阈值,如果不满足的话,就要断开去除,之后再进行直线拟合。当然还要在外面退出一些指标点,与整个网络连接在一起。最初须要提取图的构造,把节点和边的关系依照图论的建模形式提取进去。 三角剖分法就是通过费马点把这些节点连贯在一起,有些边会穿过障碍物,咱们再通过优化办法避开,最初造成一个网络。另外,咱们能够将人口密度等因素等效为彩色禁飞区增加到地图中。通常在地图中,“1”示意有障碍物,“0”示意没有障碍物。咱们在航路网建模中做了一个进一步的工作,用0~1之间的概率来示意,有些禁飞区比方墙等是相对不能飞进去的,然而有些区域人口稠密一些,就不适宜用“1”来示意,这种状况下能够应用0.4、0.5这样的概率来示意。咱们心愿可能通过这种形式来构建航路网,这在下图中没有体现。 综合法就是在下图这种状况下,咱们在障碍物密集区外部应用形态学骨架法来做,在内部稠密区使用费马点来做,最初把它们联立成网络。有时候我本人的学生会问我,什么叫密集的,什么叫稠密的?我感觉不要思考这个问题,本人来判断,因为航路网建模不是肯定要齐全自动化的过程,而且一旦建成之后当前就不须要扭转了,所以在建模的过程中须要人为的去确定每个区域的航路网是什么形态。这样就能很好的兼顾上述两种办法,最终造成不同的航路网。 下图是航道的形象构造示意图,航道外部咱们参考了目前的高速公路,两头有一个隔离带,这个隔离带就是咱们后面提到的两架飞行器之间的平安间隔,它能够是双向的。 另一方面,航路网的节点也有构造,如下图所示,咱们个别是以圆柱形构造。节点有多个航道相接,须要思考不同航道的飞行器不能距离太近,因而须要减少节点的半径,确保不同航道的飞行器距离足够远。 航路网有形象的构造,外部也有具体的构造,通过一些约束条件,确保不同飞行器在任何状况下都能大于平安间隔,这就让咱们晓得怎么去设计整个航路网。 3.1.2 无人机模型 咱们须要对无人机收回指令,这就须要有肯定的规范的接口,接口咱们有一些模态比方断电模态、期待受权模态、预位模态、航行模态、避障模态、迫降模态给无人机发指令,这样的话,无人机就相当于被咱们的交通控制系统管制了。这个接口咱们目前还不是那么规范,我心愿最终咱们能有一套空中交通零碎的规范。 3.2 算法设计低空交通控制算法包含集中式空中交通管制和分布式空中交通管制。 3.2.1 集中式空中交通管制 集中式管制能够分为两个局部:离线布局和在线管制。离线布局就是说飞机起飞前须要申报本人的航行打算,而后承受审核。如果以后的航路网十分梗塞的话,那么审核就不会通过,就须要期待或者从新申报航行打算。如果审核通过的话,就会产生一个蕴含起飞时间、地点等信息的待飞打算,将待飞打算写入空中交通管理系统的数据库中,进而对空中交通状况进行预测。 然而飞行器在航行过程中受天气、自身状态等因素影响会有很多不确定性,飞行器的飞行速度变动就会产生抵触。因而在飞行器航行过程中,咱们须要对飞机进行一些定量的管制,这就是飞行器的在线管制。咱们能够通过管制飞行器的高度、速度等,使它可能防止抵触,如果在整个航路网中抵触无奈防止,那么咱们必定不心愿产生多米勒骨牌一样的效应,因为部分一个因素,使整个航路网都发生变化。防止抵触最简略的办法就是避障,一个飞行器向上飞,一个飞行器向下飞,这是空中交通的劣势,汽车没有方法做到,大略是这样一个逻辑。 以下是基于集中式的低空交通控制系统中几个要害模块的算法过程: 打算审核求解算法 步骤一:获取新退出的无人机 ???? 的避障间隔 ????a和打算信息合集 ???????? ;步骤二:更新航路网信息????和以后时刻 ???? ,通过Dijkstra算法失去无人机的航路点 ℎ????,并计算飞齐全程所需的工夫 ???????? ;步骤三:对无人机 ???? 解优化问题;步骤四:若有解则间接执行步骤五;若无解且起因是抵触问题,则判断与其发生冲突的无人机们优先级???????????????????????????????????? , ???? ∈ ???????? ,collision是否均小于本人。若是则回绝无人机 ???? 的申请后执行步骤五 ,否则回绝无人机 ???? 的申请 , 期待 ???????????????????? 时长后执行步骤二;若无解且起因是容量问题, 则临时先令超容对应的航路固定容量为 0 ,再执行步骤二;其余状况均倡议过 ????????????????????时长后执行步骤二 ;步骤五:如果满足超时约束条件,则反馈无人机航路点和起飞时间;否则倡议过 ????????????????????时长后执行步骤二。 ...

October 30, 2020 · 1 min · jiezi

关于分布式:分布式事务

常见分布式事务计划(1) XA分布式事务:单零碎多数据库(2) TCC分布式事务:服务链式调用、解决大多数分布式事务场景,次要用于同步实时后果返回场景。留神:对于bytetcc简化版本次要针对于一个接口状况,简化版本通过不同注解代表的不同办法表明confirm、cancel、try,针对于多个接口都须要满足tcc事务的话,须要应用非简化版本的tcc,非简化版本应用不同的类实例实现的同一接口办法示意不同的conform、cancel、try。(3) 可靠消息最终一致性:多用于耗时、异步 并且音讯必须执行胜利的场景(4) 最大致力告诉计划:多用于耗时、异步 并且音讯可有可无的场景;比方:短信, 分布式事务详解3.可靠消息最终一致性可靠消息最终一致性分布式事务分为以下步骤:1、上游服务发送“待确认音讯”给可靠消息服务2、可靠消息服务获取到上游服务的音讯,进行逻辑数据库存储操作。3、上游服务执行相干业务逻辑操作,胜利则发送确认音讯。失败则发送勾销音讯(这一步骤是基于1步骤的,1步骤是同步调用,所以晓得待确认音讯调用没出错)

October 25, 2020 · 1 min · jiezi

关于分布式:听说你还不会缓存

灵魂拷问缓存是什么?(没听说过你能够走了)哪些场景须要用到缓存呢?缓存能够分类吗?缓存的实现形式有哪些?缓存缓存也被称为Cache,实质上是数据交换的一段缓冲区,也能够称为一种存储数据的组件,缓存次要用于减小数据交换单方速度不匹配的问题。缓存在计算机世界里是一个常见并且不可漠视的一个重要因素,它简直遍布于你所知的各个领域。例如cpu的一级缓存,二级缓存;浏览器的缓存等。咱们在应用缓存的时候要革除的意识到缓存的数据是有有效期的,也就是说可能随时会隐没。有的同学会说了,相似redis这些组件都提供了数据长久化的性能,这样数据就不会隐没了。至于这个问题其实我想说两点: 当组件提供了长久化性能的时候,必然会产生磁盘的IO操作,而磁盘IO的操作必然会大大降低缓存组件的性能,那缓存的价值还有吗?缓存的数据在工夫定义上是一种临时性的数据,如果做了长久化,这种临时性的意义就不存在了,而且还占用了磁盘的存储空间缓存最常见的存储介质是内存,但这并不象征只有内存能够存储缓存数据,这也是初学者常常会犯的谬误。缓存的作用是提供高速的读写性能,所以如果你的设施足够快,实践上都能够作为缓存应用,比方当初的SSD,在一些性能不太严格和敏感的场景下就能够作为存储缓存数据的介质,至于计算机的各种硬件之间的速度差距能够参考之前的文章: 高并发下为什么更喜爱过程内缓存 缓存利用场景从实践上来说,任何须要进步访问速度的环节都能够退出缓存然而零碎退出缓存模块会在肯定水平上减少零碎的复杂度,所以在是否引入缓存的问题上,须要依据业务场景来均衡。个别合乎以下几种特色的数据能够思考引入缓存模块: 数据很少变动这类数据最适宜缓存的利用场景,因为它根本不波及到负责的缓存更新操作,所以只有将其加载到缓存中即可。最具备代表性的像网站用到的js,css等这些动态资源,用户登录之后生成的session信息等。 说到数据很少变动,不得不提CDN这种服务了,很多大型网站都会利用CDN来减速一些不变资源的访问速度,比方一些图片,视频等。因为用户拜访这些资源的根源须要逾越多个主干网,在速度上较慢,而CDN恰好补救了这个缺点,所以这里也能够把CDN看成是一种缓存的服务。 热点数据这种数据是咱们平时开发中要加缓存的次要起因数据,最有可能导致系统瘫痪的也是这种数据。它最大的特点是产生工夫不确定,流量峰值不确定。大家可能还依稀记得微博因为两个明星出轨而挂掉的事件,尽管微博的零碎架构起初通过革新能够同时抗住N个明星出轨,然而在不确定这个因素上仍然无能为力。 热点数据的缓存并不容易设计,因为它带有单点属性,什么意思呢?假如咱们的缓存服务器有100个节点,这个时候产生了某个热点新闻,而这个热点新闻的缓存在0号节点,大量的申请会被路由到0号节点,很有可能会导致0号节点垮掉,如果0号节点垮掉,基于故障转移策略,流量霎时会转移到另外一个节点,而后这个节点会垮掉,以此类推.....缓存尽管进步了零碎的整体吞吐量,然而在应答有针对性的流量顶峰的时候须要独自针对。这其实也是分布式系统要解决的问题,既然一个节点扛不住流量顶峰,零碎能够设计多个节点一起来抗,至于以上的热点数据场景,最简略粗犷的形式就是缓存正本,一份缓存数据会存在多份正本,相似于MySQL的读写拆散计划,多份正本同时提供读取操作。除此之外,这种场景下我举荐应用过程内缓存代替分布式缓存,因为过程内缓存在访问速度上要比须要逾越网络的分布式缓存要快很多,具体能够查看之前的推文: 高并发下为什么更喜爱过程内缓存 耗时操作某些计算代价或者获取代价很大的数据在特定的条件下也适宜进行缓存。为什么要加特定条件呢?如果系统对这些数据的一致性有着严格的要求,而且会频繁的变动,尽管获取数据代价比拟大,然而你也要充分考虑缓存带来的副作用。像咱们最罕用的报表服务,个别生成报表都比拟耗时,如果报表的数据是绝对稳固的,那咱们就能够思考用缓存来进步零碎的性能。 缓存的淘汰存储缓存的设施限度了缓存是有大小限度的,如果以16G内存来存储缓存,那缓存的下限实践上就是16G(然而实际上要小的多),而且缓存带有时效性,所以当要缓存的数据大于介质容量的时候就须要一种淘汰数据的策略来保障新数据能失常被缓存。 最好的淘汰策略就是把零碎不必的数据淘汰进来,然而什么数据是无用数据,这是策略的难点所在,基于用户行为的不确定性,这种数据所以很难用程序去预测。鉴于零碎的惯例实践,当初支流的有以下几种淘汰策略: LFU(Least Frequently Used):缓存零碎会记住每条缓存数据被拜访的频率,会优先淘汰最不罕用的数据。LRU(Least Recently Used):缓存零碎会记住每条数据最初的拜访工夫,会优先淘汰长时间未被拜访的数据ARC(Adaptive Replacement Cache):这个缓存算法同时跟踪记录LFU和LRU,以及驱赶缓存条目,来取得可用缓存的最佳应用,它被认为是性能最好的缓存算法之一,介于LRU和LFU之间,可能记忆成果和自调,当然开发必定会比较复杂。FIFO:基于队列的原理的淘汰算法,先进先出。这种算法比较简单,事实中应用比拟少是因为这种业务场景比拟少。缓存实现形式零碎中实现缓存的形式大体上能够分为两种: 过程内缓存过程内缓存是指缓存和应用程序在同一个过程内,在获取缓存数据的时候不须要逾越网络,所以过程内缓存是访问速度最快的一种形式。 过程内缓存个别用在单机或者小型零碎中,然而,在整体架构实现了一致性的前提下,也可用于大型零碎,什么意思呢?举个栗子:在多个服务器节点的状况下,如果用户A的信息缓存在0号节点,如果有一种机制能保障用户A的所有申请都只会达到0号节点,这个时候利用过程内缓存就齐全没有问题。最典型的像Actor模型利用,能够参见之前的文章 分布式高并发下Actor模型如此优良???? 过程外缓存顾名思义,过程外缓存的意思是缓存数据和应用程序是隔离的,位于不同的过程内。当然这里又能够把过程外缓存划分为单机版和分布式版本,单机版本这里就不多说了,会存在单机故障问题。 过程外的分布式版本通常被称为分布式缓存,是基于分布式实践的一种架构模式。它冲破了单机缓存的容量限度和单机故障问题,尽管在访问速度上比过程内缓存要慢很多,然而相比拟磁盘IO操作要快的多,所以当初很多大型零碎都喜爱用分布式缓存来进步性能。像用的最多的Redis在3.0版本之后就提供了集群计划。 写在最初在面对缓存带给零碎的劣势之后,也要留神到缓存也会有一些有余。 缓存和数据源的一致性问题缓存命中问题缓存的雪崩穿透问题缓存的并发竞争问题缓存适宜读多写少的零碎引入缓存组件会给零碎设计带来肯定的复杂度缓存会加大运维的胜利以及排查bug的老本尽管缓存带来了不少问题,然而相比拟缓存带给零碎性能的晋升是毋庸置疑的。咱们在设计一个高并发零碎的时候,缓存曾经成为了一种必备设计,在正确设计了缓存各种策略之后,能力最大施展缓存的劣势 更多精彩文章 分布式大并发系列架构设计系列趣学算法和数据结构系列设计模式系列

October 22, 2020 · 1 min · jiezi

关于分布式:架构师必备的那些分布式事务解决方案

为了保障分布式环境下数据强一致性,须要引入分布式事务,而分布式事务因为网络环境的不确定性,天生就很难实现。具体能够见上一篇。 分布式下,我想要强一致性 为了保障分布式事务的正确性,目前互联网畛域有几种风行的解决方案,然而大部分都没有像XA事务一样造成规范的工业标准。然而这些计划在某些特定的行业或者业务场景下却失去了越来越多的开发者的认可。 防止分布式事务此计划提倡尽量避免分布式事务,不仅仅是因为分布式事务的难度,更是因为实现分布式事务须要更多的高级人才。如果一个操作设计到事务操作,而这些事务操作能够利用单机事务来解决,举荐首选单机事务。 当然,是否能够防止分布式事务还要看具体业务,在微服务流行的当下,更多的还要看畛域的划分规范,如果两个微服务能够合并成一个微服务,肯定水平上在畛域划分规范承受范畴之内,能够思考利用合并的形式来防止分布式服务。 举一个很简略的栗子:一个用户根本信息服务和用户资产服务(比方:用户经验值),当用户批改材料的时候给用户加奉献值这个业务场景下,因为波及到用户材料批改和加奉献值两个不同服务的操作,这个时候就能够思考将两个服务合并为一个服务,用单机的数据库事务来代替分布式事务。 在能够防止分布式事务的状况下,首选防止分布式事务二阶段提交二阶段(2PC)提交计划是基于X/OpenDTP标准规范的,最大的毛病在于它在第一阶段须要锁定资源,会大大降低零碎的性能,大型的互联网利用并不举荐这种计划,那种对性能不敏感的企业级利用能够尝试应用。 在asp.net中,微软曾经提供了分布式事务的治理类型:TransactionScope,它依赖DTC(Distributed Transaction Coordinator)服务实现事务一致性。当它包裹的代码中如果设计到多个不同物理地位的数据库的时候,它会主动降级为分布式事务,应用起来十分不便。 using (TransactionScope ts = new TransactionScope()) { 数据库A操作(); 数据库B操作(); 数据库C操作(); ts.Complete(); }TCCTCC实质上是一种编程模型,它提倡的是弥补操作,所以个别状况下它会有重试机制,它约定参加事务的每个业务方都须要提供三个接口,具体情况请查看上一篇文章。因为TCC的接口重试个性,所以提供的提交和勾销接口必须实现幂等性。 2PC次要是针对数据库操作,而TCC次要是针对业务层面来进行操作,这在性能上比2PC要高很多,例如一个提交订单的场景,商品服务须要扣除库存,而订单零碎须要创立订单,代码相似以下,请不要纠结命名和参数: //订单服务public interface IOrderService{ //创立一个不可见的订单,返回订单号 Task<string> CreateOrder(); //依据订单号提交订单,使订单可见 Task<int> SubmitOrder(string orderNo); //依据订单号勾销订单 Task<int> CancleOrder(string orderNo);} //商品服务public interface IProductService{ //依据商品id,锁定库存,返回锁定的id Task<int> LockProductStock(int productId); //依据锁定的库存id,提交事务,扣除商品库存 Task<int> SubmitLockStock(int lockId); //依据锁定的库存id,勾销事务,商品库存回滚 Task<int> CancleLockStock(int lockId);}其实TCC实现过程中,还有很多细节。比方:当提交事务阶段,有一个节点因为网络起因或者down机提交失败,该怎么办呢?这个时候咱们要在本地引入本地音讯机制,或者叫做业务流动管理器,把每个业务参加分布式事务的每个操作都记录下来,当某个过程的某个节点操作失败,无论是主动发动重试,还是手动重试都能够达到最终数据的一致性。 基于音讯的事务基于音讯的分布式事务实现的是最终一致性,它是基于BASE实践的一个解决方案,最早由eBay提出并施行,它采纳了音讯队列来辅助实现事务管制流程,核心思想是将须要分布式解决的工作通过MQ分发给每个业务去异步执行,如果工作失败,则能够发动零碎主动重试或者人工重试的纠正流程。 还是以上边的创立订单和扣减库存为栗子: 首先调用订单服务的创立订单接口创立订单,如果创立胜利,则发送须要扣减库存的音讯(也能够看做创立订单胜利的音讯)到MQ。商品服务监听扣减库存音讯队列,如果收到扣减库存音讯,则执行扣减库存操作,如果操作胜利,则回复MQ删除该音讯。如果没有操作胜利,则筹备接管同样音讯的下次投递。 这个流程看似很完满,其实有很多破绽。 创立订单是第一步操作,能够看做是单纯的单机操作,这个并没有问题,然而接着发送MQ音讯这一步须要和创立订单保障事务性,因为会产生创立订单胜利,发送mq音讯失败的状况。如果不能用技术手段来保障这两步的事务,也能够采纳引入本地音讯的计划,在创立订单的时候,用订单数据库来保障订单创立胜利和创立订单音讯表的一致性。而后发送mq胜利之后,批改订单音讯表的状态为发送胜利,如果发送mq音讯失败,则启用另外一个线程或者过程进行重试。商品服务扣减库存相似,扣减库存这个操作和回复mq音讯这两个操作也能够利用本地音讯表的形式来解决一致性问题。当收到扣减库存音讯的时候,扣减库存和增加音讯胜利解决记录能够利用数据库的事务来保障一致性,如果回复音讯队列ack失败,就算是有反复音讯,也能够依据本地的生产音讯表来过滤反复音讯基于音讯的分布式解决方案还有一个劣势,如果一个事务的业务参与方十分多,音讯的发送可能会非常复杂,须要十分审慎的设计。比方以上订单的栗子,当初引入了优惠券服务,在订单创立胜利,须要同时扣减库存和优惠券,如果优惠券扣减失败,须要同时回滚库存和勾销订单,这也只是三个业务参与方,如果是四个,五个呢?当然这在业务中兴许并不常见。 基于音讯的分布式事务解决方案,因为引入了重试机制,也须要接口在实现的时候反对幂等性。但从开发的角度,这种计划要比tcc以及2pc都要有劣势,把每个零碎之间的耦合度降到了最低,而且每个业务方的实现技术能够非常灵活,无论是采纳java还是c#活着是golang都无所谓。 当然市面上基于音讯的分布式解决方案各式各样,但总体来说都属于最终一致性计划。如果引入音讯通道MQ的不稳定性,那还须要在各个业务方引入查问机制来确保音讯的ack机制。举个栗子:如果商品服务曾经失常扣减库存,因为mq问题,始终不能失常ack。这个时候订单服务是否会被动查问商品服务是否曾经失常扣库存?这个时候整个架构可能就非当初这个样子了,这个要是扯起来又是一篇文章了 更多精彩文章 分布式大并发系列架构设计系列趣学算法和数据结构系列设计模式系列

October 21, 2020 · 1 min · jiezi

关于分布式:分布式下我想要一致性

每一个程序员架构梦的实现之路上,总是绕不开分布式系统CAP这个实践的学习。如果你还没有理解过,能够翻看之前的文章,置信我,如果你想成为架构师,这个实践无论是在工作中还是面试中吹水,你始终都是须要的 艰涩难懂的CAP CAP实践作为分布式的重要实践根底,指出了在分布式环境下,其实只有AP和CP两种模型去抉择。BASE实践作为CAP实践的一个延长,主张就义一致性去换取可用性。反之,一个分布式系统也能够去就义可用性去换取一致性。 分布式事务说到一致性就不能不提事务,事务这个词当初常常用于数据库,然而有一点要留神,站在肯定的角度,事务并非只实用于数据库。如果站在数据库角度非要下一个定义的话: 事务(Transaction),个别是指要做的或所做的事件。在计算机术语中是指拜访并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务完结(end transaction)之间执行的整体操作组成。为了更好的意识并实现事务,形象出了ACID实践,换句话说,如果一个零碎能实现ACID个性,那么就实现了事务个性。 Atomic原子性: 一个事务的所有系列操作步骤被看成是一个动作,所有的步骤要么全副实现要么一个也不会实现。Consistent一致性:事物实现时,必须所有数据保持一致状态Isolated隔离性:次要用于实现并发管制, 隔离可能确保并发执行的事务可能程序一个接一个执行,通过隔离,一个未实现事务不会影响另外一个未实现事务。Durable持久性:持久性是指一个事务一旦被提交,它对数据库中数据的扭转就是永久性的,接下来即便数据库产生故障也不应该对其有任何影响在单机上实现ACID并不艰难,通常能够利用锁、工夫序列或者程序日志等机制来保障。这里多说一句,一般而言,隔离性能够利用锁机制来实现,而原子性、一致性和持久性都能够利用日志来实现,一致性算法Raft也是通过日志模式来保障一致性的。 然而在分布式环境下,网络环境却比单机要简单的多,起因在于网络通信的不可靠性,处于不同网络的多个节点要想保障一致性,网络提早、网络故障等因素都须要思考。 二阶段提交协定二阶段(2PC)提交协定是依据业界首个分布式事务标准规范X/OpenDTP提出的,顾名思义,它通过两个阶段来协商一个提交操作。 X/OpenDTP设计了一个模型来形容分布式事务的各个角色以及标准: AP:用户程序,负责触发分布式事务,在这个过程中采纳了非凡的事务指令(XA指令),这些指令由TM接管并发送给相干的RM去执行RM:资源管理器,个别指数据库,每个RM只执行本人相干的指令。映射到程序级别如:ODBC,ADO.Net,JDBC等。TM:事务管理器或者说是事务协调者,它负责接管AP发动的指令,调度和协调参加事务的所有RM,确保事务失常实现或者回滚。二阶段提交协定最早用来实现数据库的分布式事务,当初大部分数据库的分布式事务都采纳了XA协定。在二阶段提交协定中,一个事务的提交过程被分为两个过程: 告诉阶段。在这个阶段会告诉所有参加事务的资源管理器(RM)进行资源的预留和其余筹备工作,其中包含了长久化日志文件和资源的锁定。所以这个阶段在整个事务过程中占据了大部分工夫,筹备实现并把后果返回给事务管理器(TM)。提交阶段。在该阶段,事务管理器(TM)会依据上一步的后果来决定是提交还是回滚操作。仅当全副资源管理器(RM)都批准提交的时候,事务管理器(TM)才告诉所有的资源管理器(RM)正式提交事务,否则TM将会告诉所有的RM勾销事务。 二阶段协定的精华在于,它通过两个阶段来把不牢靠事务提交失败的几率升高到了最小,在一个真正的二阶段提交事务的过程中,第一阶段其实占据了整个事务的大部分工夫,而真正提交事务的第二阶段简直是霎时实现的,所以这正是二阶段的奇妙之处。 然而事实中咱们很少应用二阶段提交协定来保障事务性,为什么呢? 在事实场景中,很少有强一致性的业务,最罕用的是基于BASE实践的最终一致性二阶段提交协定须要锁定资源,在性能上会有肯定损失,这在高并发的场景中是不适宜的。二阶段提交协定引入了事务管理器(TM),减少了零碎的复杂性,而且少数开发人员并不精通TM以及RM的技能。TCC因为二阶段提交协定的一系列缺点,TCC被引入分布式事务。TCC是Try(预留)、Confirm(确认)、Cancel(撤销)3个操作的简称,它蕴含了预留、确认或撤销这2个阶段。TCC针对分布式事务大体过程是这样的: 预留阶段:事务发起者别离向所有参加事务的业务方发动申请,要求预留业务资源,业务方并给予回复。提交阶段:事务发起者收到每个参加事务的业务方的回复,如果都是ok,则告诉每个业务方提交事务操作,如果至多有一个业务方返回后果非ok,则告诉所有的业务方撤销事务操作。 TCC实质上是弥补事务,从操作上就可以看进去,每个业务方针对以后事务须要注册三个操作:预留操作,确认操作,勾销操作。这三个操作是须要参加事务的每个业务来编码实现的。对应到编码层面,每个业务方都须要提供三个操作的接口,为了一致性,确认操作和勾销操作必须是幂等的,因为这两个操作可能会系统性的重试或者人为干涉的重试。 写在最初TCC在操作上更像是一种编程模型,它次要针对业务层面,所以它在性能上要比次要针对数据库层面的二阶段提交要高很多。目前二阶段提交协定次要的利用场景还是在数据库上,所以它实质上应用的是数据库的锁机制,这也是在高并发的互联网利用中很少应用二阶段提交协定的重要起因之一。 说了那么多,在实在的业务场景中,如果能用单机数据库的事务来代替分布式事务,那就首选单机数据库事务。如果业务容许放弃强一致性,那就采纳最终一致性准则来保障一致性,而最终一致性最罕用的解决方案是利用牢靠的MQ音讯,这个有工夫咱们详聊。 更多精彩文章 分布式大并发系列架构设计系列趣学算法和数据结构系列设计模式系列

October 21, 2020 · 1 min · jiezi

关于分布式:第八阶段-第一模块

October 20, 2020 · 0 min · jiezi

关于分布式:简约而不简单的分布式通信基石

分布式系统能够总结为是处于不同物理地位的多个过程组成的整体,为了确保这个整体无效并且高效的对外提供服务,每个节点之间都有可能须要进行通信来替换信息,而这个替换信息的过程少数应用的是tcp协定。tcp协定是位于ip层之上的传输层协定,在这个传输层里有两个比拟重要的协定:tcp和udp。对于应用层的开发人员来说,用的最多的就是这两个协定,这也是一些面试官必问的知识点之一 无论是tcp还是udp,都是建设在ip+端口的规定之上,什么意思呢?也就是说采纳tcp和udp的过程都须要一个端口来读取和写入数据。 TCP协定tcp协定是牢靠的协定,而且是面向连贯的,建设连贯的过程会通过三次握手。为什么会是三次握手而不是二次或者四次呢? 说到这个问题,能够形象出一个场景,怎么样能力确定一端是和另外一端互通的呢?其实很简略,一端发送给另一端的音讯能顺利给我回答,这就阐明两端是联通的。tcp协定的三次握手恰好阐明了这一点,A和B通信,只有三次握手,A能失去B的回答,B也能失去A的回答。 基于ip层发送的报文,在网络中是无奈确定是否正确达到对方的。tcp协定在ip协定之上增加了一系列数据结构和算法来保障tcp的数据正确达到。 tcp的数据包是有编号的,这么做次要是为了解决程序问题,如果没有编号,对方怎么确定程序呢?另外一点,编号是为了发送方来确认哪些包曾经正确达到对方当tcp的数据包被接管方接管,接管方须要发送确认包给发送方,发送方在接管到确认包之后会把对应的数据包做状态批改,因为每个数据包其实有超时机制,在超时之后,发送方会进行重试tcp是面向字节流的,发送的时候发的是一个字节流,这是tcp本人的状态保护的事件。说了这么多,其实能够把tcp看做是一个有状态的协定,它能够依据网络情况,对方接管状况等诸多因素来调整本人的发送状态。UPP协定绝对于tcp协定来说,udp要简略很多 udp协定不须要建设连贯,这就意味着发送方只有晓得对方的ip和端口,就能够发送,基于这一点能够做播送。2.udp协定不负责牢靠交付,因为它不像tcp协定那样有一堆的算法和数据结构来做保障。 udp是基于数据报模式的,一个一个的发,一个一个的接管。而且udp数据的发送不会依据因为网络环境的阻塞而扭转udp基于以上个性能够在网络环境比拟好或者对于丢包不敏感的利用中应用。udp在舍弃了重传,程序等一些列个性之后,处理速度特地快,在一些不敏感然而实时性要求比拟高的场景中利用十分宽泛。 Socket在有了tcp和udp协定之后,过程间通信的基石就有了。然而总不能每次通信本人都须要写tcp的三次握手等这些简单过程吧。为了屏蔽这些简单的过程,使通信程序简略,在tcp和udp协定之上,便形象进去了socket这个概念。 所谓套接字(Socket),就是对网络中不同主机上的利用过程之间进行双向通信的端点的形象。一个套接字就是网络上过程通信的一端,提供了应用层过程利用网络协议替换数据的机制。从所处的位置来讲,套接字上联利用过程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口socket是辨别服务端和客户端的,本地的socket与近程的一个socket建设连贯的过程,其实就是tcp协定三次握手的过程。一旦socket连贯建设,就能够利用socket形象进去的read或者write办法来进行通信了。 socket须要指定应用的IP协定,还须要指定应用的是tcp还是udp协定。基于tcp协定的服务端的socket须要bind一个端口来listen并且accept客户端的socket连贯。这也是服务端socket和客户端socket的一个区别。 对于udp来说,过程有点不一样。udp是没有连贯的,一是不须要三次握手,二是不须要listen和connect,然而依然须要ip和端口bind,要不然远端的数据到来的时候,零碎会找不到接管程序的。UDP是没有连贯状态的,因此不须要每次连贯都建设一组Socket,而是只用一个Socket,就可能和多个客户端通信。也正是因为没有连贯状态,每次通信的时候,调用sendto和recvfrom,都须要传入 IP 地址和端口。 基于tcp的socket在内核中都有一个发送缓冲区和接收缓冲区,tcp的双工工作模式以及tcp的滑动窗口就是依赖于这两个独立的buffer以及buffer的数据填充状态。接收缓冲区把数据缓存入内核之中,如果对应的利用始终没有调用socket的read办法进行数据读取,则此数据会始终被缓存在接收缓冲区中,如果接收缓冲区满了,便会告诉对方socket,以调整对方socket的发送窗口大小,这就是滑动窗口的实现。如果对方依然继续发送数据,接管方在接收缓冲区没有被读取的状况下将抛弃后到的数据,这就是tcp的流量管制。对于udp来说,它没有真正的发送缓冲区,只有有数据就会发送,无论对方是否失常正确接管,这也是udp丢包的起因之一,然而udp的socket 和tcp的socket一样都会有接收缓冲区,而且行为也一样。 写在最初有的面试官吹水,号称http长连贯,这个说法其实是不精确的,长连贯和短连贯是针对tcp协定而言,http只是建设在tcp/ip协定之上的应用层的一个协定。总体而言,tcp和udp设计的数据结构和算法有很多,这里只是粗略的说了一下,有趣味的同学能够去钻研tcp协定那本书。 更多精彩文章 分布式大并发系列架构设计系列趣学算法和数据结构系列设计模式系列

October 20, 2020 · 1 min · jiezi

关于分布式:有了容器为什么kubernetes还需要Pod

简介容器并不是软件开发的银弹,没有任何一种技术能解决软件开发中的所有问题当咱们采纳容器化技术的时候,摒弃了传统的物理机或者虚拟机的部署形式,以一种更加轻快,便捷的形式来部署咱们的利用。到容器化的进阶,再加上kubernetes对容器的编排技术,使得容器化的利益进一步扩充。然而对于kubernetes来说,间接调度编排治理的根本单位并非容器,而是另外一种构造体。 假如容器中同时运行着多个不相干的过程,这些过程的继续运行,治理,以及输入输出日志会是容器的责任。如果这些不相干的过程同时都有规范的输入,而此时咱们很难确定每个过程具体输入了什么内容。另一方面,每个容器是一个逻辑的运行单位,有着本人的命名空间,IP以及端口和其余信息,如果非一个团队开发的不同过程监听了雷同的端口号,必将产生资源的抢夺抵触。尽管多个过程运行在同一个容器中,无论是通过过程间通信还是通过存储文件进行共享文件都很容易,然而Docker和kubernetes还是冀望每个过程都运行在本人的容器中,除非是和本人相干的子过程。如果你的多个过程有着依赖关系(例如:一个过程的启动依赖于另外一个过程),这样的多个过程举荐运行在雷同的容器中。 因为不举荐将无关的过程运行在同一个容器中,然而非凡状况下还存在要求多个相干过程运行于同一个容器的需要,kubernetes提供了一种更高级的构造来把容器捆绑在一起,并将这种构造作为调度部署的根本单元,这个构造就是Pod。 Pod是一组并置的容器,是kubernetes中根本的构建模块。然而这并不意味着一个Pod总是蕴含多个容器,在理论利用中每个Pod只有一个容器是最常见的部署形式。这里要留神一点,尽管对于kubernetes来说,并不关怀Pod位于哪个节点上,然而一个Pod的多个容器位于多个节点是不容许的,换句话说,同一个Pod的多个容器总是运行在同一个集群节点上。 kubernetes部署和操作的根本单位是Pod隔离雷同Pod下运行的容器之间能够共享一些资源,然而并非全副资源(话句话说,这些容器并非齐全隔离的),kubernetes通过配置能够让同一个Pod内的容器共享雷同的linux命名空间和network等资源,所以这些容器共享雷同的主机名和网络接口,话句话说,这些容器在Pod中能够进行IPC通信,就像在局域网中一样。既然共享雷同的IP和端口号,那么多个容器就不能绑定到雷同的端口,否则会呈现端口抵触,所以这也是官网举荐一个Pod只运行一个容器的起因之一。 每个Pod都有本人独立的Ip和端口空间,所以不同的Pod内的容器永远不会产生端口抵触。同一个Pod中的容器具备雷同的loopback,因而能够通过localhost与同一Pod中的其余容器进行通信 Pod网络在同一个kubernetes集群中的Pod就和局域网内的每台服务器一样,他们共享一个网络地址空间,这个网络是通过软件基于实在链路来实现的。所以只有晓得一个Pod的IP地址就能够进行拜访,这个通信过程不通过网关,在通信上性能十分好。因为kubernetes把资源进行了形象,所以Pod无论位于哪个服务器节点上,对于同一个集群内的Pod来说都一样。 Pod应用多个容器在少数状况下,我还是倡议每个Pod运行一个容器,然而如果你的多个容器有相互依赖关系(比方一个容器的启动依赖于另外一个容器),就须要把多个容器部署到一个Pod。一个Pod中运行一个容器更多的是基于利用分层的思考,例如:一个利用的容器须要调用一个数据库的容器,这两个容器应该调配到不同的Pod中,不仅仅是为了进步集群机器的利用率,更是为了之后不同档次的扩容。对于kubernetes来说,操作和部署的根本单位是Pod,所以kubernetes扩容的单位是Pod并非容器,如果咱们的应用层有性能瓶颈,咱们就能够独自的对应用层的Pod进行独自扩容,其余层的Pod放弃不变,这不仅仅是节俭资金老本的问题了,而是横向扩大的灵活性问题。 更多精彩文章 分布式大并发系列架构设计系列趣学算法和数据结构系列设计模式系列

October 19, 2020 · 1 min · jiezi

关于分布式:编程体系结构09分布式系统架构

本文源码:GitHub·点这里 || GitEE·点这里 一、根底概念 1、单服务 所有业务服务和利用组件部署在一台服务上,节省成本,这是单服务构造,实用于并发低,业务繁多的场景。 2、集群模式 业务量逐步增大,并发高,把一台服务进行程度扩大,做一个服务群,申请压力扩散到不同的服务上解决,每台服务称为集群的一个节点,到这就是集群服务。 3、分布式架构 分布式构造就是依照业务性能,拆分成独立的子服务,独立的库表,能够独立运行,且服务之间通信和交互,带来的益处升高业务间的耦合度,不便开发保护,程度扩大,复用性低等等。 4、技术体系 服务基础架构:Dubbo框架,SpringCloud框架; 容器化运维:Docker、Kubernetes; 数据存储:关系型MySQL,NoSQL数据库,OLAP引擎; 罕用组件:Zookeeper协调,MQ异步,Redis缓存; 二、分布式框架1、Dubbo框架 垂直利用越来越多,利用之间交互不可避免,将外围业务抽取进去,作为独立的服务,逐步造成稳固的服务中心,使前端利用能更疾速的响应多变的市场需求。此时,用于进步业务复用及整合的分布式服务框架(RPC)是要害。Dubbo框架的外围能力:面向接口的近程办法调用,智能容错和负载平衡,以及服务主动注册和发现。 2、SpringCloud框架 分布式架构下最成熟的框架,SpringCloud是一系列框架的有序汇合。它利用SpringBoot的开发便利性奇妙地简化了分布式系统基础设施的开发,如服务发现注册、配置核心、音讯总线、负载平衡、断路器、数据监控等,都能够用SpringBoot的开发格调做到一键启动和部署。 https://github.com/cicadasmile/spring-cloud-base外围组件 注册核心:具备服务发现、服务记录、查问、动静治理的机制。罕用的注册核心,Zookeeper、Eureka、Consul、Nacos等。 熔断降级:限度流量忽然高并发冲垮零碎,使这类报文以比拟平均的速度流动发送,达到爱护零碎绝对稳固的目标。罕用算法令牌桶、漏斗;罕用组件Nginx、CDN、Hystrix、Sentinel,通过不同节点管制流量。 服务网关:在整个架构体系上也是一个服务,作为申请的惟一入口,与外观模式非常相似,在网关层解决所有的非业务性能,为客户端提供定制的API。罕用组件Zuul、Tyk、Kong。 https://github.com/cicadasmile/husky-spring-cloud3、业务型组件 消息中间件:RocktMQ、Kafka、RabbitMQ等; 缓存中间件:Redis、Eache等; 分布式事务:Seata、Hmily、TCC-transaction等; 三、架构细节1、全局ID策略 业务场景产生的数据,都须要一个惟一ID作为外围标识,用来流程化治理。比方常见的:UUID、雪花算法、自增主键、ID容器等。 2、接口幂等性 幂等操作的特点是其任意屡次执行所产生的影响均与一次执行的影响雷同。就是说,一次和屡次申请某一个资源会产生同样的作用影响。在接口、重试、弥补的场景下尤其要保障操作的幂等性。 3、缓存解决 业务零碎中,查问时最容易呈现性能问题的模块,查问面对的数据量大,筛选条件简单,所以在零碎架构中引入缓存层,则是十分必要的,用来缓存热点数据、归档数据、首页查问等,达到疾速响应的目标。 4、异步解决流程 异步是一种设计理念,异步操作不等于多线程,MQ中间件,或者音讯播送,这些是能够实现异步解决的形式,异步解决不必阻塞以后线程来期待解决实现,而是容许后续操作,直至其它线程将解决实现,并回调告诉此线程。 5、高并发与资源锁 高并发业务外围还是流量管制,管制流量下沉速度,或者管制承接流量的容器大小,多余的间接溢出,这是绝对简单的流程。一方面能够通过流量整形的形式解决申请量,另一方面能够通过加锁解决并发拜访资源的问题。 6、分布式事务 不同的服务不同数据库的多个细节操作组成,这些无感知的细节操作散布在不同服务上,甚至属于不同的地区和利用,事务的参与者、反对事务的服务器、资源服务器以及事务管理器别离位于不同的分布式系统的不同节点,如何保障这些操作全副胜利或者全副失败,即保障不同数据库间的数据一致性,这就是分布式事务须要解决的外围问题。 https://github.com/cicadasmile/data-manage-parent四、数据源组件1、关系型数据库 采纳了关系模型来组织数据的数据库,其以行和列的模式存储数据,例如MySQL、Oracle。在分布式系统下,为了保障外围流程的稳定性,在要害业务上根本都采纳关系型数据库,当业务实现后,如果数据量大,会把数据同步到其余查问性能高组件中。 2、NoSQL数据库 NoSQL意即"不仅仅是SQL"。对不同于传统的关系型数据库的数据库管理系统的统称。NoSQL用于超大规模数据的存储。这些类型的数据存储不须要固定的模式,无需多余操作就能够横向扩大。例如MongoDB、Cassandra等。 3、数据管理策略 读写库拆散、查问数据分库分表、分布式下业务分库、基于用户流量分库。 https://github.com/cicadasmile/data-manage-parent五、服务监控1、生产故障 在分布式的简单架构下,应用服务、软件服务、硬件服务,任何层面出问题都可能导致申请不能残缺执行,引发一系列效应,做好全链路的监控,疾速定位问题是十分要害的。 2、应用层监控 应用层为开发的业务逻辑服务,也是最容易突发问题的一个层面,通常从申请流量、服务链路熔断、零碎异样日志几个方面做监控指标,察看零碎是否稳固。 3、软件层监控 这里通常指,数据库层面,例如Druid的监控剖析;罕用中间件,例如RocketMQ的控制台;Redis缓存:提供命令获取相干监控数据等。 4、硬件层监控 硬件层面,关注的三大核心内容:CPU、内存、网络。底层硬件资源暴发的故障,来自下层的应用服务或者中间件服务触发的可能性偏高。成熟的监控框架,例如zabbix,grafana等。 六、源代码地址GitHub·地址https://github.com/cicadasmileGitEE·地址https://gitee.com/cicadasmile举荐浏览:编程体系整顿 序号项目名称GitHub地址GitEE地址举荐指数01Java形容设计模式,算法,数据结构GitHub·点这里GitEE·点这里☆☆☆☆☆02Java根底、并发、面向对象、Web开发GitHub·点这里GitEE·点这里☆☆☆☆03SpringCloud微服务根底组件案例详解GitHub·点这里GitEE·点这里☆☆☆04SpringCloud微服务架构实战综合案例GitHub·点这里GitEE·点这里☆☆☆☆☆05SpringBoot框架根底利用入门到进阶GitHub·点这里GitEE·点这里☆☆☆☆06SpringBoot框架整合开发罕用中间件GitHub·点这里GitEE·点这里☆☆☆☆☆07数据管理、分布式、架构设计根底案例GitHub·点这里GitEE·点这里☆☆☆☆☆08大数据系列、存储、组件、计算等框架GitHub·点这里GitEE·点这里☆☆☆☆☆

October 16, 2020 · 1 min · jiezi

关于分布式:容器技术为什么会这么流行

容器的诞生在传统的软件部署形式中,程序员须要把要公布的应用程序打成包发给运维人员,而后由运维人员在生产环境进行部署。当随着利用的版本迭代越来越多,利用的依赖库版本盘根错节,往往会呈现开发环境和生产环境不统一的状况产生,而且因为少数状况下采纳微服务的架构,每个团队都有可能应用不同版本的依赖库,并有可能在降级的时候替换掉他们,因此同一个应用程序采纳雷同版本的依赖库是如许的重要。 当应用程序比拟少或者都是一些单体利用的时候,能够利用虚拟机来隔离每个服务,通过虚拟机的虚拟化技术来为每个应用程序提供不同的运行环境。然而当拆分为微服务之后,每个服务会变的小而多,这个时候如果为每个应用程序调配一个虚拟机,资源消耗是相当多的,然而每个虚拟机上运行多个微服务又会产生依赖库版本的问题,如果有一种起到相似虚拟机隔离作用,然而老本比虚拟机低很多的技术该有多好? 容器技术得益于linux的容器技术,古代开发者曾经由传统的虚拟机形式转向linux容器技术。容器相似虚拟机,但比虚拟机开销要小的多,并且同样把每个利用都隔离开来。容器技术容许你在同一台服务器上运行多个服务,而且还能够依据每个服务提供不同的运行环境。 虚拟机中的过程运行在虚拟机的操作系统中,而运行在容器中的过程理论是运行在宿主机的操作系统中,只是外表看来如同运行在容器的沙盒一样,但实际上的确是和其余过程互相隔离的。 linux之所以能实现容器这种性能,得益于它的命名空间和控制组。linux命名空间时每个过程互相隔离,只能看到它本人的系统资源,例如:文件,过程,网络等,而linux的控制组技术可能限度每个过程能够应用的资源的最大量。一个技术进行隔离,一个技术进行限度,这就导致了容器技术要比虚拟机要灵便的多。 虚拟机和容器一个虚拟机的失常运行,须要运行本人的一系列零碎过程,只是这些零碎过程就消耗了大量资源。容器和虚拟机相比拟就显得轻量的多,它容许在雷同配置的硬件根底上运行更多数量的利用。尽管容器自身也有耗费,然而和虚拟机零碎的耗费比起来要小的多。 虚拟机是利用软件技术将物理硬件虚拟化为多个虚构硬件资源,从而被每个虚拟机的操作系统应用。虚拟机里的过程会进行虚拟机的零碎调用,虚拟机的指令会通过软件技术变为宿主机上真正的cpu指令,而容器中的过程执行的指令不须要任何的虚拟化过程,间接会被cpu执行,所以单纯在执行指令的过程中,虚拟机要比容器的执行过程要长,资源消耗要多。 docker介绍Docker 是一个开源的利用容器引擎,让开发者能够打包他们的利用以及依赖包到一个可移植的镜像中,而后公布到任何风行的 Linux或Windows 机器上,也能够实现虚拟化。容器是齐全应用沙箱机制,相互之间不会有任何接口Docker容器平台的呈现把linxu容器化技术推向了一个低潮,它不仅简化了程序部署的形式,更简化了打包利用和依赖,使容器真正做到了在不同的操作系统之间移植,甚至一个残缺的操作系统也能够被打包成一个可移植的镜像。 运行docker包的前提是,指标机器肯定要运行docker。当你的利用被打包成docker镜像之后,无论在什么操作系统中运行,它都能看见雷同的文件,雷同的依赖库,因为这些依赖库曾经被一起打包到了docker镜像中,即便指标机器上装置了正确的版本的依赖库,它也会只用镜像中的依赖库,这就是程序员期盼的无论何时何地的环境一致性呀 更多精彩文章 分布式大并发系列架构设计系列趣学算法和数据结构系列设计模式系列

October 14, 2020 · 1 min · jiezi

关于分布式:做好微服务架构并非易事

概念微服务(Microservices Architecture)是一种架构格调,一个大型简单软件应用由一个或多个微服务组成。零碎中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于实现一件工作并很好地实现该工作。在所有状况下,每个微服务代表着一个小的业务能力。微服务是依据具体业务畛域边界划分进去的能独立运行的程序,并且能够独立部署,能够依据业务量横向扩大,批改不会影响其余程序失常运行。简略一句话:微服务是有肯定边界的有本人上下文的服务架构理念。 微服务长处微服务更容易的扩大,它基本上是独立的。应答互联网利用中大并发的零碎能够做到主动弹性应答。每个微服务能够由不同的团队,采纳不同的技术栈开发,只有遵循约定的协定即可,每个微服务的批改不会影响到其余服务的失常运行。微服务的架构思维摒弃了中心化的架构格调,进一步升高了零碎间的耦合度,无论是在开发阶段或部署阶段都是独立的。微服务因为能够疾速开发和交付,所以在新技术的接管能力上要远远高于其余零碎,例如:将一个传统的零碎批改微服务能够疾速上云,能够疾速采纳k8s部署。每个微服务都遵循雷同的协定规范,所以再团队之间的沟通上能够缩小很多不必要的麻烦。微服务毛病微服务虽好,但也并非完满。 服务数量微服务从字面意思就能够晓得强调服务的“微”,然而这个微的粒度,少数人都了解谬误,有人说:微到不能再微是微服务划分的理念。我不这样认为,微服务的畛域边界是依据具体业务来划分,适度的划分,只会导致微服务的数量急剧减少,团队的效率急剧下降。有的团队只有5~6集体,然而却拆分出几十个微服务零碎,均匀每个人要保护5~10个微服务,这样做给团队带来的只有负面效应。无论是开发,测试,还是运维都须要在多个微服务之间不停的切换。 当微服务上线之后,几十个微服务须要启动几十个过程,在退出了负载平衡与消息中间件后,过程的数量还会继续增加。运维与编排全副这些服务是个“令人望而生畏的工作”。 当微服务粒度过细,会造成代码复用度进一步升高,一些通用的代码你可能须要在多个服务间进行copy,如果某段代码有问题,你同时须要批改多个服务代码,当然同种语言能够应用代码共享库来解决,然而在多语言的状况下是行不通的。 事务管理无论微服务怎么样划分边界,业务上无奈防止在多个服务间的事务性操作。最简略的下单场景:很多状况下订单和用户资产是不同的微服务,当用户领取胜利,扣除用户资产和更改订单状态(还有缩小商品库存)应该是一个原子性操作,如果在以前的单体利用专用一个数据库的状况下,用DB的事务很容易实现原子性操作,然而在微服务环境下,实现事务有肯定的难度,尤其是当服务间采纳异步操作的时候,这就很简单了,这要求咱们得“治理好相关联的ID以及分布式事务,将各种动作绑定在一起”。 服务关系服务划分过细,单个服务的复杂度的确降落了,但整个零碎的复杂度却回升了,因为微服务将零碎内的复杂度转移为零碎间的复杂度了。从实践的角度来计算,n 个服务的复杂度是n×(n-1)/2,整体零碎的复杂度是随着微服务数量的减少呈指数级减少的。下图形象了阐明了整体复杂度: 调用链太长服务间的通信都采纳规范的Http或者Rpc协定,只有是通过网络的调用,就会消耗资源,就会破费更多的执行工夫。如果一个申请须要程序的调用N层服务,那么这个申请所破费的工夫是不容忽视的,这在大并发的零碎中是致命的性能损耗存在,零碎的吞吐量会大幅降落。尽管减少硬件在肯定水平上会缓解这种问题,然而却在基本上解决不了问题,而且在老本上会大幅度回升。 另外,服务的调用链太长,定位系统问题很难。一个业务申请会通过N个微服务,任何一个服务有问题,都有可能会导致业务失败。因为调用的微服务过多,而且异样有扩散的属性,疾速定位服务问题对于开发以及测试来说,是一件很简单并且很难的事件。如下图所示: 如果服务C产生故障,开发定位问题的时候须要从服务A开始追踪,而后追踪服务B,而后是服务C,如果调用链更长的话,还须要持续追踪。当定位到问题之后,可能曾经过来了几个小时,这在一些敏感的零碎中是不容许的。如果服务的复杂性如下图所示,该怎么办呢? 微服务的架构设计中,做好服务的追踪是很重要的自动化撑持如果没有相应的自动化零碎进行撑持,都是靠人工去操作,那么微服务岂但达不到疾速交付的目标,甚至还不如一个大而全的零碎效率高。 没有自动化测试撑持,每次测试时须要测试大量接口。没有自动化部署撑持,每次部署 6 ~ 7 个服务,几十台机器,运维人员敲 shell 命令逐台部署,手都要敲麻。没有自动化监控,每次故障定位都须要人工查几十台机器几百个微服务的各种状态和各种日志文件。当服务的数量达到肯定水平,如果如上图所示,服务的治理难度就会被提上日程。当微服务的品种和数量越来越多,如果没有微服务的治理零碎去撑持,微服务的劣势就会变为劣势,包含每个服务的注册和发现,每个服务的部署,每个服务的隔离,甚至每个服务的路由。 如果还是人工去干涉这些,最终服务零碎将会变的一片凌乱,微服务推重的疾速交付,横向扩大等个性也将变的简单。 微服务的重点不止在边界的划分,还有服务的治理。就像容器一样,容器很重要,然而容器编排同样重要。参考文档:从0开始学架构 更多精彩文章 分布式大并发系列架构设计系列趣学算法和数据结构系列设计模式系列

October 12, 2020 · 1 min · jiezi

关于分布式:分布式相关文章

raftzookeeper

October 10, 2020 · 1 min · jiezi

关于分布式:八面阿里成功吊打面试官看完这份阿里面试官手册我懂了

不晓得各位看官有没有面过阿里?阿里就像一个大型的IT人才加工厂,每年有很多进去,又有很多人进去,同时阿里也为社会输送了很多的IT精英人才。 这不,前一阵子小编的一位敌人破费两个月的工夫胜利八面面进了阿里,定级P7,当我晓得这个音讯的时候我也替他开心,同时他还通知我,本人“偷学”了一份阿里的面试官手册,外面问的绝大部分的内容都是来自这个手册上,根本就是换汤不换药!明天就把这份阿里面试官手册分享进去,心愿对行将或者想要面阿里的同学有所帮忙! 这份阿里面试官手册的收费获取形式在我个人主页个签处! 阿里面试官手册目录纲要 分布式 中间件 大数据与高并发 数据库 设计模式与实际 数据结构与算法 面试题举例 须要收费支付这份阿里面试官手册敌人,收费获取形式在我个人主页个签处!

September 25, 2020 · 1 min · jiezi

关于分布式:聊聊分布式下的WebSocket解决方案

前言 最近本人搭建了个我的项目,我的项目自身很简略,然而外面有应用WebSocket进行音讯揭示的性能,大体状况是这样的。 公布音讯者在零碎中发送音讯,实时的把音讯推送给对应的一个部门下的所有人。 这外面如果是单机利用的状况时,咱们能够通过部门的id和用户的id组成一个惟一的key,与应用服务器建设WebSocket长连贯,而后就能够接管到公布音讯者发送的音讯了。 然而真正把我的项目利用于生产环境中时,咱们是不可能就部署一个单机利用的,而是要部署一个集群。 所以我通过Nginx+两台Tomcat搭建了一个简略的负载平衡集群,作为测试应用 然而问题呈现了,咱们的客户端浏览器只会与一台服务器建设WebSocket长连贯,所以公布音讯者在发送音讯时,就没法保障所有指标部门的人都能接管到音讯(因为这些人连贯的可能不是一个服务器)。 本篇文章就是针对于这么一个问题展开讨论,提出一种解决方案,当然解决方案不止一种,那咱们开始吧。 WebSocket单体利用介绍 在介绍分布式集群之前,咱们先来看一下王子的WebSocket代码实现,先来看java后端代码如下: import javax.websocket.*;import javax.websocket.server.PathParam;import javax.websocket.server.ServerEndpoint; import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import java.io.IOException;import java.util.Map;import java.util.concurrent.ConcurrentHashMap; @ServerEndpoint("/webSocket/{key}")public class WebSocket { private static int onlineCount = 0;/** * 存储连贯的客户端 */private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>();private Session session;/** * 发送的指标科室code */private String key;@OnOpenpublic void onOpen(@PathParam("key") String key, Session session) throws IOException { this.key = key; this.session = session; if (!clients.containsKey(key)) { addOnlineCount(); } clients.put(key, this); Log.info(key+"已连贯音讯服务!");}@OnClosepublic void onClose() throws IOException { clients.remove(key); subOnlineCount();}@OnMessagepublic void onMessage(String message) throws IOException { if(message.equals("ping")){ return ; } JSONObject jsonTo = JSON.parseObject(message); String mes = (String) jsonTo.get("message"); if (!jsonTo.get("to").equals("All")){ sendMessageTo(mes, jsonTo.get("to").toString()); }else{ sendMessageAll(mes); }}@OnErrorpublic void onError(Session session, Throwable error) { error.printStackTrace();}private void sendMessageTo(String message, String To) throws IOException { for (WebSocket item : clients.values()) { if (item.key.contains(To) ) item.session.getAsyncRemote().sendText(message); }}private void sendMessageAll(String message) throws IOException { for (WebSocket item : clients.values()) { item.session.getAsyncRemote().sendText(message); }}public static synchronized int getOnlineCount() { return onlineCount;}public static synchronized void addOnlineCount() { WebSocket.onlineCount++;}public static synchronized void subOnlineCount() { WebSocket.onlineCount--;}public static synchronized Map<String, WebSocket> getClients() { return clients;}} ...

September 22, 2020 · 3 min · jiezi

关于分布式:分布式系统实践解读丨详解高内聚低耦合

摘要:做好高内聚低耦合,思路也很简略:定职责、做归类、划边界。上面的这个场景你可能会感觉很相熟(Z哥我又要出演了): Z哥:@All 兄弟姐妹们,这次我这边有个需要须要给「商品上架」减少一道审核,会影响到大家和我交互的接口。大家抽空配合改一下,今天一起更新个版本。 小Y:哥,我这几天很忙啊,昨天刚配合老王改过促销! 小X:行~当所有已成习惯。 作为被告诉人,如果在你的事实工作中也产生了相似事件,我置信哪怕嘴上不说,心里也会有不少想法和埋怨:“md,改的是你,我也要公布,好冤啊!”。 这个问题的根本原因就是多个我的项目之间的耦合度过于重大。 越大型的我的项目越容易陷入到这个昭潭中,难以自拔。 而解决问题的形式就是进行更正当的分层,并且继续保障分层的合理性。 一提到分层,必然离不开6个字「高内聚」和「低耦合」。 什么是高内聚低耦合在z哥之前的文章中有屡次提到,分布式系统的实质就是「分治」和「冗余」。 其中,分治就是“合成 -> 治理 -> 归并”的三部曲。「高内聚」、「低耦合」的概念就来源于此。 须要留神的是,当你在做「合成」这个操作的时候,务必要关注每一次的「合成」是否满足一个最重要的条件:不同分支上的子问题,不能相互依赖,须要各自独立。 因为一旦蕴含了依赖关系,子问题和父问题之间就失去了能够被「归并」的意义。 比方,一个「问题Z」被分解成了两个子问题,「子问题A」和「子问题B」。然而,解问题A依赖于问题B的答案,解问题B又依赖于问题A的答案。这不就等于没有合成吗? 题外话:这里的“如何更正当的合成问题”这个思路也能够用到你的生存和工作中的任何问题上。 所以,当你在做「合成」的时候,须要有一些很好的着力点去切入。 这个着力点就是后面提到的「耦合度」和「内聚度」,两者是一个此消彼长的关系。 越合乎高内聚低耦合这个规范,程序的保护老本就越低。为什么呢?因为依赖越小,各自的变更对其余关联方的影响就越小。 所以,「高内聚」和「低耦合」是咱们该当继续一直谋求的指标。 题外话:耦合度,指的是软件模块之间相互依赖的水平。比方,每次调用办法 A 之后都须要同步调用办法 B,那么此时办法 A 和 B 间的耦合度是高的。 内聚度,指的是模块内的元素具备的共同点的类似水平。比方,一个类中的多个办法有很多的共同之处,都是做领取相干的解决,那么这个类的内聚度是高的。 怎么做好高内聚低耦合做好高内聚低耦合,思路也很简略:定职责、做归类、划边界。 首先,定职责就是定义每一个子系统、每一个模块、甚至每一个class和每一个function的职责。 比方,在子系统或者模块层面能够这样。 又比方,在class或者function层面能够这样。 我想这点大家平时都会无意识的去做。 做好了职责定义后,内聚性就会有很大的晋升,同时也进步了代码/程序的复用水平。 至此,咱们才谈得上「繁多职责(SRP)」这种设计准则的使用。 其次,做归类。梳理不同模块之间的依赖关系。 像下面提到的案例1能够归类为3层: 根底层:商品根底服务、会员根底服务、促销根底服务聚合层:购物车服务、商品详情服务、登陆服务接入层:快闪店API、综合商城API 案例2也能够归类为3层: 数据拜访层:拜访会员表数据、拜访会员积分表数据、拜访会员等级表数据业务逻辑层:会员登陆逻辑、会员应用积分逻辑、会员降级逻辑应用层:接管用户输出的账户明码、接管用户输出的应用积分数、接管用户的付款信息 最初就是划边界。好不容易梳理分明,为了防止轻易被再次毁坏,所以须要设立好正当清晰的边界。 否则你想的是这样参差。 理论会缓缓变成这样凌乱。 那么应该怎么划边界呢? class和function级别。这个层面能够通过codereview或者动态代码检测工具来进行,能够关注的点比方: 1.调用某些class必须通过interface而不是implement 2.拜访会员表数据的class中不能存在拜访商品数据的function 模块级别。能够抉择以下计划: 1.给每一种类型的class调配不同project,打包到各自的dll(jar)中 2.每次代码push上来的时候检测其中的依赖是否有超出规定的依赖。例如,不能逆向依赖(检测dal是否蕴含bll);不能在根底层做聚合业务(检测商品根底服务是否蕴含其余根底服务的dll(jar))。 零碎级别。及时辨认子系统之间的调用是否合乎预期,能够通过接入一个调用链跟踪零碎(如,zipkin)来剖析申请链路是否非法。 让边界更清晰、稳固的最佳实际很多时候不同的模块或者子系统会被调配到不同的小组中负责,所以z哥再分享几个最佳实际给你。它能够让零碎之间的沟通更稳固。 首先是:模块对外裸露的接口局部,数据类型的抉择上尽量做到宽进严出。比方,应用long代替byte之类的数据类型;应用弱类型代替强类型等等。 举个「宽进严出」的例子: //应用long代替byte之类的数据类型。void Add(long param1, long param2){ if(param1 <1000&& param2 < 1000){ //先接管进来,到外面再做逻辑校验。 //do something... } else{ //do something... }}其次是:写操作接口,接管参数尽可能少;读操作接口,返回参数尽可能多。 ...

September 22, 2020 · 1 min · jiezi

关于分布式:架构设计-分布式体系下服务分层监控策略

本文源码:GitHub·点这里 || GitEE·点这里 一、分布式故障分布式系统的架构,业务开发,这些在良好的思路和设计文档标准之下,是相对来说好解决的,这里的绝对是指比拟分布式架构下生产环境的忽然故障。 在理论的开发中,有这样一个很妖娆的状况:越是外围简单的业务,越是放心出问题,越容易出问题。 所以当外围服务的链路呈现故障时,如何疾速定位问题就是一件很头疼的事件,尤其是一些非凡状况下,问题很含糊很难复现,外加客户或者领导督促,这种场景心里暗影是大部分开发都有的。更有甚者,可能问题产生的切入点的开发是某人负责的,理论问题是产生在申请链路的其余服务上,这种状况遇多了,甩锅程度会直线回升。 越是简单的零碎,越是经验丰富的开发或者运维,对监控零碎就越是有执念,尤其是全链路的监控,底层,网络,中间件,服务链路,日志察看预警等,用来疾速定位问题,省时省心。 二、全链路监控1、监控档次在分布式系统中,须要监控的体系和档次极其简单,通常整体上划分为三个档次:应用服务,软件服务,硬件服务。 通常状况,运维治理硬件服务,开发治理利用和软件服务。 2、应用服务应用层为开发的业务逻辑服务,也是最容易突发问题的一个层面,当在一家公司待久了,因为开发过多个业务线,就会感觉本人不是开发,是个打杂的,每天都要分出大量工夫解决各种问题。应用层监控波及上面几个外围模块: 申请流量 任何服务,高并发的流量都会裸露各种服务问题,尤其外围接口的流量更是监控的重点。 服务链路 一次申请产生问题,疾速判断问题所在的服务,或者哪些服务之间,这对疾速解决问题是至关重要的。 日志体系 外围接口日志记录也是必备的性能,通常状况下基于日志体系的剖析后果,能够明确零碎的异样点,重点优化。 3、软件服务为了解决分布式系统的各种简单业务场景,通常会引入各种两头软件来做撑持,例如必备的数据库,缓存,音讯MQ等,通常这些中间件都会有自带的监控治理端口。 数据库:较多应用Druid监控剖析; 音讯队列:罕用RocketMQ和控制台; Redis缓存:提供命令获取相干监控数据; 还有一些公司甚至间接在中间件层开发一套治理运维和监控的聚合平台,这样更容易从整体上剖析问题。 4、硬件服务硬件层面,运维最关注的三大核心内容:CPU、内存、网络。底层硬件资源暴发的故障,来自下层的应用服务或者中间件服务触发的可能性偏高。 硬件层面的监控有许多成熟的框架,例如zabbix,grafana等,当然这些组件性能很丰盛,不仅仅在硬件层利用。 5、雪崩效应有些故障导致大面积服务瘫痪,也称为雪崩效应,可能故障源没有疾速解决,也没有熔断机制,导致整个服务链路全副垮掉,这是常见的问题,所以在解决故障时,要学会基于全栈监控信息,全局关联剖析外围故障点,疾速切断单点服务的故障,保障整个零碎的可用性。 三、注意事项监控零碎尽管作用很大,然而理论搭建的时候难度还是很大,须要有较好的意识,不是业务开发那种感觉,方方面面需要都须要解决,做监控零碎的根本策略如下。 1、选择性不是所有服务的所有环境,和所有接口都须要监控,通常都是监控外围链路,外围中间件,和服务所在环境。 例如:交易链路,交易库,和部署的环境;或者大客户高并发业务,一旦出问题须要及时响应,立刻解决。说的间接点,带来收益的服务是须要重点关注的。 非关键服务即便呈现问题,是有缓冲工夫的,所以不须要破费精力增加监控,在做监控零碎的时候存在这样一句话:简略的链路增加监控,简单了容易出错;简单链路增加监控,更简单更容易出错,然而这样却是为了更好的解决故障。 2、独立性监控零碎的自身产生故障,不能影响失常业务流程,即便在肯定状况下没有监控信息,也不能因为监控服务影响失常业务服务。 3、整体性聚合的监控零碎能够察看监控链路的全局状态,这样能够疾速定位故障坐标,能够关联性剖析问题起因。 4、预警性例如CPU忽然升高,某个中间件服务忽然进行,内存占用过高,这些能够基于监控零碎做预警告诉,而后邮件或者音讯告诉到相干负责人,达到疾速响应的目标,这个场景大部分开发都相熟,且有心理暗影。 四、源代码地址GitHub·地址https://github.com/cicadasmile/data-manage-parentGitEE·地址https://gitee.com/cicadasmile/data-manage-parent举荐浏览:架构设计系列 题目架构设计:单服务.集群.分布式,根本区别和分割架构设计:分布式业务零碎中,全局ID生成策略架构设计:分布式系统调度,Zookeeper集群化治理架构设计:接口幂等性准则,防反复提交Token治理架构设计:缓存管理模式,监控和内存回收策略架构设计:异步解决流程,多种实现模式详解架构设计:高并发流量削峰,共享资源加锁机制架构设计:分布式服务,库表拆分模式详解架构设计:分布式事务①概念简介和基础理论架构设计:基于电商交易流程,图解TCC事务分段提交架构设计:基于消息中间件,图解柔性事务一致性架构设计:基于Seata中间件,微服务模式下事务管理

September 17, 2020 · 1 min · jiezi

关于分布式:解决分布式session问题

session说到 session,我置信每个程序员都不生疏,或多或少在我的项目中应用过。session 这个词,其实是一个形象的概念,它不像 Cookie 那样有着明确的定义。当大多数程序员议论 session 的时候,可能指的是服务端存储数据的 session 对象,例如,用户登录胜利之后把用户信息存储在 session 中,相似于这样的程序 Session["UserName"] = new User(); public class User{ public int UserId {get ;set ;} public string UserName {get ;set;} }而在计算机中,尤其是网络应用中,session 被定义为“会话”,能够把它看做客户端和服务端的一条通道连贯,同一个用户的申请应用同一个 session 会话。在大多数利用中,次要用于用户的辨认,艰深来讲,服务端能够通过 session 来记录每一个用户的状态信息。那咱们就以最罕用的服务端 session 对象来啰嗦几句 单机 sessionsession 是存储在服务端的,这是一个很重要的概念。这意味着它须要占用服务器的内存,并且它须要一种开释的机制来保障服务器内存不会被撑爆(例如 LRU)。 在我的项目初期,为了疾速上线,服务器的部署很多状况下只有一台服务器,记录用户的登录状态广泛应用 session 机制。请不要说这样做不合理,至多在我的项目初期这种做法是最简略而且最疾速的计划。随着我的项目的一直迭代降级,用户量的一直减少,你会发现单机零碎成为了我的项目的最大性能瓶颈,这个时候少数架构师会抉择程度扩大计划。 其实说到底,零碎性能的晋升都围绕着一个“分”字,无论是数据库的分库分表,还是当初衰亡的微服务,始终在围绕着一个畛域进行切分当单机的 session 机制进行程度扩大就面临着必须要要解决的问题:session 的亲和性(粘性)要怎么样去解决? 分布式 session一个单机零碎扩大为一个分布式系统,就会面临着分布式 CAP 实践中 AP 和 CP 的抉择,具体能够查看之前的文章: 艰涩难懂的 CAP,是否完全正确? 谈到分布式 session 的一致性问题,其实次要是要解决用户 session 的亲和性,同一个用户的申请怎么样能力保障达到正确存储 session 信息的服务器呢? ...

September 14, 2020 · 1 min · jiezi

关于分布式:架构设计-基于电商交易流程图解TCC事务分段提交

本文源码:GitHub·点这里 || GitEE·点这里 一、场景案例简介1、场景形容分布式事务在业务零碎中是非常常见的,最经典的场景就是电商架构中的交易业务,如图: 客户端通过申请订单服务,执行下单操作,实际上从订单服务上又触发了多个服务链申请,根本步骤如下: 客户端申请在订单服务上创立订单;订单服务调用账户服务扣款;订单服务调用库存服务执行库存扣减;订单通过物流服务,转化为物流运单;这套流程在电商零碎中是根本业务,在理论的开发中远比这里形容的简单。 2、服务时序图上述1中是业务性的流程概念形容,从零碎开发层面,在微服务的架构模式下,通常的时序流如下: 这样服务间的通信时序图在程序设计中非常常见,在分布式系统中,分明的形容各个服务间的通信流程是非常要害的。 上图形容的交易流程是在最现实的状态下,各个服务都执行胜利,然而程序是不能100%保障始终失常,经常出现如下状况: 服务间通信失败;单个节点服务宕掉;服务接口执行失败;这些都是理论开发中经常出现的问题,比方订单创立胜利,扣款胜利,然而库存扣减失败,物流运单生成,那么这笔订单该如何解决?这就是分布式事务要解决的外围问题。 分布式事务机制要保障不同服务之间造成一个整体性的可控的事务,业务流程上的服务除非全副胜利,否则任何服务的操作失败,都会导致所有服务上操作回滚,撤销曾经实现的动作。 二、TCC根底概念1、分段提交协定XA是一个分布式事务协定,大抵分为两局部:事务管理器和本地资源管理器,本地资源管理器根本由数据库实现,大多数关系型数据库都实现XA接口,而事务管理器作为全局事务的调度者,负责整个事务中本地资源的提交和回滚,基本原理如下: 阶段1:事务询问 事务管理器向所有的参加事务的资源管理器发送确认申请,询问是否能够执行事务提交操作,并期待各参与者的响应,如果执事务操作胜利,就反馈给事务管理器示意事务能够执行,如果没有胜利执行事务,就反馈事务不能够执行; 阶段2:事务提交 XA依据第一阶段每个资源管理器是否都筹备提交胜利,判断是要事务整体提交还是回滚,正式执行事务提交操作,并在实现提交之后开释整个事务占用的资源;事务也会存在失败状况,导致流程勾销回滚; XA事务具备强一致性,在两阶段提交的整个过程中,始终会持有资源的锁,性能不现实的毛病很显著,特地是在交易下单链路中,往往并发量很高,XA无奈满足该类高并发场景。 2、TCC概念简介Try(预处理)-Confirm(确认)-Cancel(勾销)模式的简称TCC。 Try阶段 业务查看(一致性)及资源预留(隔离),该阶段是一个初步操作,提交事务前的查看及预留业务资源实现;例如购票零碎中的占位胜利,须要在15分钟内领取; Confirm阶段 确认执行业务操作,不在执行任何业务查看,基于Try阶段预留的业务资源,从现实状态下看只有Try胜利,Confirm也会胜利,因为资源的检查和锁定都曾经胜利;该阶段呈现问题,须要重试机制或者手动解决;购票零碎中的占位胜利并且15分钟内领取实现,购票胜利; Cancel阶段 Cancel阶段是在业务执行谬误须要回滚到状态下执行分支事务的勾销,预留资源的开释;购票零碎中的占位胜利然而15分钟内没有领取,勾销占位; 3、TCC比照XAXA事务的强一致性,导致资源层的锁定; TCC在业务层面谋求最终一致性,不会短暂占用资源; 三、分段事务剖析当初回到模块一中的场景案例,在现实状态下流程全副胜利是好的,但理论状况是突发状况很多,基于TCC模式分析上述电商的具体业务: 1、资源预留在TCC模式下,通常表字段的状态设计思路为:订单(领取中.已领取.勾销订单),账户(金额.解冻金额),库存(库存.解冻库存),物流(出库中.已出库,已撤回),这种状态治理在开发中十分常见。 所以在TCC模式里通常会如下解决资源预留: 假如订单总额为:200,状态:领取中,则此时资源预留状况如下: tc_account账户表:tc_total=1000,tc_ice=200,总金额1000,解冻200;tc_inventory库存表:tc_total=100,tc_ice=20,总库存100件,解冻20件;tc_waybill运单表:tc_state=1,运单状态,出库中;这样下单链路上的相干资源已查看并且预留胜利; 2、资源提交确认资源预留胜利之后,执行资源提交执行: tc_account账户表:tc_total=800,tc_ice=0,即订单扣款胜利;tc_inventory库存表:tc_total=80,tc_ice=0,库存消减胜利;tc_waybill运单表:tc_state=2,运单状态,已出库;这样下单链路上的相干资源已全副提交解决胜利,这是最现实的状态; 3、失败回滚整个过程是可能执行失败的,或者用户间接本人发动回退,则要回滚整个链路上的数据: tc_account账户表:tc_total=1000,tc_ice=0,勾销账户解冻的200;tc_inventory库存表:tc_total=100,tc_ice=0,勾销库存解冻的20件;tc_waybill运单表:tc_state=3,运单状态,已撤回;这样下单链路上的相干数据都基于该笔订单做回退操作,复原; 4、弥补机制整个电商交易流程,不论是胜利,还是残缺的回退失败,都是须要在现实状态下,要求整个服务链路和数据是相对失常的才行。然而在理论分布式架构下是很难保障的,所以在产品的设计上会预留很多操作入口,用来手动做事务弥补或回退操作: 大型简单的业务零碎中,间接批改数据库通常状况下是不容许的,个别外围流程会预留各种操作入口,用来解决突发状况,补救数据的完整性,例如交易链路上,只有扣款胜利,后续的数据无论如何都会补上,是不容许回滚的,当然如果没有扣款胜利,订单有效期完结,该笔交易也就算做完结。 5、写在最初通过电商交易的案例,和TCC模式的概念,形容了分布式事务的流程和解决思路,在开发时通常会抉择现有的分布式组件来具体实现事务管制,这个流程后续再聊。 四、源代码地址GitHub·地址https://github.com/cicadasmile/data-manage-parentGitEE·地址https://gitee.com/cicadasmile/data-manage-parent 举荐浏览:架构设计 序号题目00架构设计:单服务.集群.分布式,根本区别和分割01架构设计:分布式业务零碎中,全局ID生成策略02架构设计:分布式系统调度,Zookeeper集群化治理03架构设计:接口幂等性准则,防反复提交Token治理04架构设计:缓存管理模式,监控和内存回收策略05架构设计:异步解决流程,多种实现模式详解06架构设计:高并发流量削峰,共享资源加锁机制07架构设计:分布式服务,库表拆分模式详解08架构设计:分布式事务①概念简介和基础理论

August 31, 2020 · 1 min · jiezi

关于分布式:MIT6824-Lab2B-TestBackup2B-分析

TestBackup2B 剖析: 1.01234All add a log and commit l1 leader 0 0: <l1,1> 1: <l1,1> 2: <l1,1> 3: <l1,1> 4: <l1,1> 2.2,3,4 offline 0,1 add a log but not commit |0| 1|| --- | --- | 0: <l1,1>, <l2,1> 1: <l1,1>, <l2,1> 2: <l1,1> 3: <l1,1> 4: <l1,1> 3.0,1 offline 2,3,4 reconnect ,maybe leader 2 and leader's term change ,add a log l3 and commit. leader 2 ...

August 30, 2020 · 2 min · jiezi

关于分布式:分布式思想

之前所写的都是单体架构的我的项目,适宜于小我的项目,对于较大一些的我的项目,模块多并发多,所有的业务模块都写在一起,如果呈现问题,可能就会影响整个我的项目的运行; 所以绝对于单体架构,由对应的分布式我的项目思维的呈现; 整体架构图如下: 分布式思维概念将大型的我的项目依照特定的规定进行拆分 目标缩小我的项目架构的耦合性 形式既然分布式的思维就是将大型项目依照特定规定进行拆分,那就有不同的规定: 按业务性能拆分:例如一个商城我的项目能够按:登录零碎/秒杀零碎/购物车零碎等等.按层级拆分:依照我的项目的业务层级分类--前端/controller/service/mapper等.问题依据之前的思路咱们将大型项目进行了分布式拆分,然而拆分后多个小我的项目仍旧是一个整体的我的项目,那咱们分布式系统中的jar包该如何治理?本人编写的工具类API该如何治理? 1.我的项目中的jar包我的项目中对立的jar包治理,咱们能够用一个父级工程导入jar包,而后让咱们的我的项目去继承他-->通过pom.xml文件中<parent>标签的应用-->能够称为我的项目的继承,然而留神最小的单位是jar包,继承的都是第三方的 2.我的项目中的工具类API下面我的项目的继承解决了jar包导入的问题,那工具类API怎么办,首先这些工具类API是咱们本人写的,封装的,其次是要先写类,.java文件,再打包成jar包的,所以就要不能通过继承的形式来解决;通过我的项目的依赖来解决,通过pom.xml中来导入仓库中打包的工具API依赖来引入咱们本人的工具类API. 这仅仅是一个简略的概述,随着我本人学习的深刻,再持续更新.大家加油.

August 28, 2020 · 1 min · jiezi

关于分布式:raft-mit-6824-实现领导者选举LAB2A

1.程序结构lab2的试验是要实现以下接口 // create a new Raft server instance:rf := Make(peers, me, persister, applyCh)// start agreement on a new log entry:rf.Start(command interface{}) (index, term, isleader)// ask a Raft for its current term, and whether it thinks it is leaderrf.GetState() (term, isLeader)// each time a new entry is committed to the log, each Raft peer// should send an ApplyMsg to the service (or tester).type ApplyMsg其中参数在正文中根本都有解释。Make 用来创立点对点server ,peers是所有的server,len(peers)也就是所有的server数量,me就是以后的server,也就是在peers中的下标。persister和applyCh 以及Start函数在2A试验中没有用上。 ...

August 26, 2020 · 4 min · jiezi

关于分布式:分布式框架原理与实践李林峰笔记

loading

August 24, 2020 · 1 min · jiezi

关于分布式:分布式数据库中间件-MyCat-分库分表实践

MyCat 简介MyCat 是一个功能强大的分布式数据库中间件,是一个实现了 MySQL 协定的 Server,前端人员能够把它看做是一个数据库代理中间件,用 MySQL 客户端工具和命令行拜访;而后端人员能够用 MySQL 原生协定与多个 MySQL 服务器通信,也能够用 JDBC 协定与大多数支流数据库服务器通信。能够用作 读写拆散、分库分表(分片)、容灾备份、多租户利用开发、大数据基础设施,使底层数据架构具备很强的适应性和灵活性。 MyCat 的智能优化模块能够使零碎的数据拜访瓶颈和热点高深莫测,并且能够将这些统计分析数据主动或手工调整后端存储,将不同的表映射到不同存储引擎上,而整个利用的代码能够一行也不必变。 具体利用场景读写拆散:反对读写拆散,主从切换,此配置最简略;分库分表:对于超过 1000 万的表进行分片,最大反对 1000 亿的单表分片;多租户利用:每个利用一个库,但应用程序只连贯 MyCat,使程序不必革新自身,实现多租户化;代替 Hbase:用于剖析大数据;报表零碎:借助 MyCat 的分表能力,解决大规模报表的统计;海量数据查问:比方 10 亿条频繁查问的记录须要在 3 秒内查问进去后果,除了基于主键的查问,还可能存在范畴查问或其余属性查问,此时 MyCat 可能是最简略无效的抉择。本文次要实际外围性能 分库分表。 分库分表原理分析指通过某种特定的条件,将寄存在同一个数据库中的数据扩散寄存到多个数据库下面,以达到扩散单台设施负载的成果。 依据切分规定的类型能够分为以下两种切分模式。 垂直切分:最大特点是规定简略,适宜各业务之间的的耦合度非常低、相互影响小、业务逻辑十分清晰的零碎。在这种零碎中,能够很容易 将不同业务模块所应用的的表切到不同的数据库中。程度切分:相对来说简单一些,因为要 将同一个表中的不同数据切分到不同的数据库中,前期的数据保护也更为简单一些。垂直切分一个数据库由很多表形成,每个表对应着不同的业务,垂直切分就是依照业务将表进行分类,从而散布到不同的数据库下面,这样也就将压力分担到不同的数据库上,如图。 一个架构设计好的零碎其总体性能通常是由多个功能模块所组成的,而每一个功能模块的数据对应到数据库中就是一个或多个表。而在架构设计中,各个功能模块相互之间的交互点越少和越对立,零碎的耦合度就越低,零碎各个模块的维护性以及扩展性也就越好,这样的零碎也就越容易实现垂直切分。 然而往往零碎中有些表难以做到齐全的独立,存在跨库 join 的状况,对于这类分库,能够共用一个数据源,业务之间通过接口来调用。 长处:规定明确、业务清晰、更易于整合和扩大、保护简略。 毛病:局部业务表无奈 join,须要通过业务接口方式解决,进步零碎复杂度;各业务存在单库性能瓶颈,不易于数据扩大和性能进步;事务处理简单问题。 因为垂直切分是将表依照业务分类切分到不同的单库中,所有导致某些业务表过于宏大,存在单库读写与存储瓶颈,则须要程度切分来解决。 程度切分程度切分不是将表依照业务分类,而是依照某个字段的某种规定扩散到多个库中,每个表中蕴含一部分数据,如图。 拆分数据须要定义分片规定,拆分的第一准则是找到 拆分维度。比方:从会员的角度来剖析,须要查问会员某天某月某个订单,那么就须要依照日期来拆分,不同的数据依照会员 ID 做分组。 长处:拆分规定形象好;不存在单库数据瓶颈问题;进步零碎稳定性和负载能力。 毛病:事务一致性难以解决;数据扩大和保护的难度极大;跨库 join 性能差。 附:多数据源治理计划第一种:客户端模式,在每个应用程序中配置管理本人须要的一个或多个数据源,间接拜访各个数据库。第二种:通过两头代理层来对立治理所有的数据源。搭建环境均采纳 Docker Compose 搭建服务部署 3 台 MySQL 容器别离创立 3 份 docker-compose.yml 文件 ...

August 20, 2020 · 2 min · jiezi

关于分布式:Volcano带你体验容器与批量计算的碰撞的火花

摘要:往年(2020)7月初,Volcano 公布了1.0版本。1.0做为里程碑版本,在Volcano整个布局中起到了承前启后的作用。此次公布的1.0版本反对了GPU共享,作业动静扩缩容,批工作抢占等性能,并次要增强了稳定性;同时,在1.0公布后 Volcano也在线下探讨了散布式调度零碎的将来倒退的趋势等。历史在剖析趋势之前,咱们先看一下散布式调度零碎的历史。晚期散布式调度零碎以批处理零碎为主,例如九几年的LSF/SGE/PBS等,这些批处理零碎大布局的应用在HPC畛域,而且对作业级的调度进行大量的钻研工作;后续由批处理零碎延长出多集群、多组织资源共享的需要,便成了网络计算。 网络计算与云计算最大的不同是:网络计算强调多组织的资源共享,而云计算强调云厂商的集中式反对;这也是云计算成为支流的次要起因:多组织之间共享须要齐备的协定和足够的平安反对,而云服务仅须要对用户提供相应服务和平安,并不需要在多个云厂商之间进行共享;随着开源社区的倒退,再将利用接口逐渐对立,e.g. Kubernetes。Hadoop呈现后,不仅推动了散布式调度零碎中对数据的解决,同时也推动了开源软件的生态。2012和2014是两个重要的节点,Hadoop将资源管理层与畛域框架层离开,随后的畛域框架也有机会构建本人的生态,e.g. Spark;同时,将资源管理层与畛域框架离开也被宽泛认可。 在容器及Kuberentes风行后,凭借其高资源利用率与隔离,环境标准化等劣势,越来越多的人心愿将这些批量计算利用对立到 Kubernetes 平台上。 将来的趋势多种利用对立调度随着各行各业的倒退,涌现出越来越多的畛域框架来反对业务的倒退;这些框架都在相应的业务畛域有着不可代替的作用,e.g. Spark, Tensorflow, Flink等。在业务复杂性能一直减少的状况下,繁多的畛域框架很难应答当初简单的业务场景;因而当初广泛应用多种框架达成业务指标,如下图所示。 但随着各个领域框架集群的不断扩大,以及单个业务的波动性,各个子集群的资源节约比较严重;因而越来越多的用户心愿通过对立调度零碎来解决资源共享的问题。在技术选型上,Kubernetes凭借其优良的扩展性取得大部分用户青眼。 异构硬件在批量计算工作向云原生环境迁徙的过程中,对云原生环境的算力提出了新的要求;各个厂商为了应答这些新的需要,为各个场景提供了不同架构的硬件,例如 鲲鹏,昇腾,X86,GPU等。当多种利用运行在对立平台上时,须要云原生调度零碎可能对异构硬件资源进行对立的治理与调度,应用各种利用达到最优的资源配比。目前,硬件的信息通过kubernetes的 device plugin 机制提供,但Kubernetes的 device plugin 仍有一些有余,例如 无奈很好的反对硬件拓扑。在调度方面 Volcano 曾经反对支流的调度策略,并在最新的1.0版本中反对了 GPU 共享,大大增加了GPU的利用率,无效升高了GPU的应用老本。 跨集群/跨云跨集群始终是散布调度零碎解决大规模、灾备等问题的次要解决方案;同时,为了升高厂商绑定的危险,并最大限度兼顾不同云厂商的劣势,多云环境下的负载高效散发逐步成为趋势。在多云的环境中,面向数据地位的优化,作业执行工夫预估等问题都是须要调度零碎解决的问题;在 Volcano 中,将通过多个我的项目实现跨集群、跨云的作业调度,例如 JobForward (#880)。 智能化调度算法在散布调度零碎中有大量的钻研,从晚期的批处理零碎到近期的Borg,Volcano等;晚期的批处理零碎以特定场景的算法优化为主,对于简单的场景须要大量的计算,尽管有大量针对HPC和网络的调度优化,但罕用和落地的算法比拟少。随着人工智能的倒退,越来越多的调度零碎将会应用AI相应的能力对算法进行优化;在 Volcano 中,将通过AI的能力驱动 Volcano 中各个调度算法进行优化,并通过AI的能力提供新的调度算法。 总结散布式调度零碎是一个简单的零碎,须要多个组件共合作以进步整体的效率,例如 利用治理,调度,异构硬件治理,存储等,仅靠调度器无奈实现这些工作。Volcano 作为CNCF首个面向批量计算的散布式调度零碎,蕴含了利用治理,作业调度,异构硬件等多个组件和性能;其调度器兼容kubernetes调度策略,同时反对在线、离线两种作业类型;控制器提供了对立的作业管理,反对多种作业的接入,包含 MPI, Tensorflow, MidSpore, Spark 等;设施插件提供了对异构硬件的反对,例如 1.0 版中反对了 GPU 共享。因而,Volcano面向散布式调度零碎的趋势提供了残缺的计划,能够在多种场景下进步作业性能,资源使用率等。 Volcano特训营:六节课学懂容器批量计算由Volcnao我的项目发起者马达主讲的直播课程正在进行中,课程共有6期,从技术原理到实战演练,涵盖Volcano全景。 锁定后续课程信息,获取往期回放与讲师PPT,销假助手微信(k8s2222)并备注“Volcano”。 点击关注,第一工夫理解华为云陈腐技术~

August 18, 2020 · 1 min · jiezi

关于分布式:Volcano带你体验容器与批量计算的碰撞的火花

摘要:往年(2020)7月初,Volcano 公布了1.0版本。1.0做为里程碑版本,在Volcano整个布局中起到了承前启后的作用。此次公布的1.0版本反对了GPU共享,作业动静扩缩容,批工作抢占等性能,并次要增强了稳定性;同时,在1.0公布后 Volcano也在线下探讨了散布式调度零碎的将来倒退的趋势等。历史在剖析趋势之前,咱们先看一下散布式调度零碎的历史。晚期散布式调度零碎以批处理零碎为主,例如九几年的LSF/SGE/PBS等,这些批处理零碎大布局的应用在HPC畛域,而且对作业级的调度进行大量的钻研工作;后续由批处理零碎延长出多集群、多组织资源共享的需要,便成了网络计算。 网络计算与云计算最大的不同是:网络计算强调多组织的资源共享,而云计算强调云厂商的集中式反对;这也是云计算成为支流的次要起因:多组织之间共享须要齐备的协定和足够的平安反对,而云服务仅须要对用户提供相应服务和平安,并不需要在多个云厂商之间进行共享;随着开源社区的倒退,再将利用接口逐渐对立,e.g. Kubernetes。Hadoop呈现后,不仅推动了散布式调度零碎中对数据的解决,同时也推动了开源软件的生态。2012和2014是两个重要的节点,Hadoop将资源管理层与畛域框架层离开,随后的畛域框架也有机会构建本人的生态,e.g. Spark;同时,将资源管理层与畛域框架离开也被宽泛认可。 在容器及Kuberentes风行后,凭借其高资源利用率与隔离,环境标准化等劣势,越来越多的人心愿将这些批量计算利用对立到 Kubernetes 平台上。 将来的趋势多种利用对立调度随着各行各业的倒退,涌现出越来越多的畛域框架来反对业务的倒退;这些框架都在相应的业务畛域有着不可代替的作用,e.g. Spark, Tensorflow, Flink等。在业务复杂性能一直减少的状况下,繁多的畛域框架很难应答当初简单的业务场景;因而当初广泛应用多种框架达成业务指标,如下图所示。 但随着各个领域框架集群的不断扩大,以及单个业务的波动性,各个子集群的资源节约比较严重;因而越来越多的用户心愿通过对立调度零碎来解决资源共享的问题。在技术选型上,Kubernetes凭借其优良的扩展性取得大部分用户青眼。 异构硬件在批量计算工作向云原生环境迁徙的过程中,对云原生环境的算力提出了新的要求;各个厂商为了应答这些新的需要,为各个场景提供了不同架构的硬件,例如 鲲鹏,昇腾,X86,GPU等。当多种利用运行在对立平台上时,须要云原生调度零碎可能对异构硬件资源进行对立的治理与调度,应用各种利用达到最优的资源配比。目前,硬件的信息通过kubernetes的 device plugin 机制提供,但Kubernetes的 device plugin 仍有一些有余,例如 无奈很好的反对硬件拓扑。在调度方面 Volcano 曾经反对支流的调度策略,并在最新的1.0版本中反对了 GPU 共享,大大增加了GPU的利用率,无效升高了GPU的应用老本。 跨集群/跨云跨集群始终是散布调度零碎解决大规模、灾备等问题的次要解决方案;同时,为了升高厂商绑定的危险,并最大限度兼顾不同云厂商的劣势,多云环境下的负载高效散发逐步成为趋势。在多云的环境中,面向数据地位的优化,作业执行工夫预估等问题都是须要调度零碎解决的问题;在 Volcano 中,将通过多个我的项目实现跨集群、跨云的作业调度,例如 JobForward (#880)。 智能化调度算法在散布调度零碎中有大量的钻研,从晚期的批处理零碎到近期的Borg,Volcano等;晚期的批处理零碎以特定场景的算法优化为主,对于简单的场景须要大量的计算,尽管有大量针对HPC和网络的调度优化,但罕用和落地的算法比拟少。随着人工智能的倒退,越来越多的调度零碎将会应用AI相应的能力对算法进行优化;在 Volcano 中,将通过AI的能力驱动 Volcano 中各个调度算法进行优化,并通过AI的能力提供新的调度算法。 总结散布式调度零碎是一个简单的零碎,须要多个组件共合作以进步整体的效率,例如 利用治理,调度,异构硬件治理,存储等,仅靠调度器无奈实现这些工作。Volcano 作为CNCF首个面向批量计算的散布式调度零碎,蕴含了利用治理,作业调度,异构硬件等多个组件和性能;其调度器兼容kubernetes调度策略,同时反对在线、离线两种作业类型;控制器提供了对立的作业管理,反对多种作业的接入,包含 MPI, Tensorflow, MidSpore, Spark 等;设施插件提供了对异构硬件的反对,例如 1.0 版中反对了 GPU 共享。因而,Volcano面向散布式调度零碎的趋势提供了残缺的计划,能够在多种场景下进步作业性能,资源使用率等。 Volcano特训营:六节课学懂容器批量计算由Volcnao我的项目发起者马达主讲的直播课程正在进行中,课程共有6期,从技术原理到实战演练,涵盖Volcano全景。 锁定后续课程信息,获取往期回放与讲师PPT,销假助手微信(k8s2222)并备注“Volcano”。 点击关注,第一工夫理解华为云陈腐技术~

August 18, 2020 · 1 min · jiezi

关于分布式:分布式系统常见问题汇总

1.分布式系统重试机制导致数据库插入多条数据针对于这种状况,常见的是给数据库表中对应字段增加惟一索引 2.分布式系统幂等性问题初期简略做法是应用汇合在内存中来存储记录最近调用的业务参数到汇合中去,如果在接口调用的时候,汇合中曾经存在对应的业务数据,那么咱们将后果间接返回,不做业务解决,并且每隔一段时间清理汇合中的业务数值。<06-215>

August 12, 2020 · 1 min · jiezi

关于分布式:分布式选举算法

1.分布式根本实践cap实践: consistency: 一致性 availablity:可用性 partition tolerance: 分区容错 分布式服务在零碎呈现肯定故障的时候,还能够对外提供服务。根本所有分布式系统都能够满足此要求。c和a之间存在矛盾,如果谋求一致性就须要摈弃可用性,如果谋求可用性,数据一致性就不会被满足。 base实践: basic available:根本可用 softstatue: 软状态 eventually: 最终一致性  零碎能够处于一致性中间状态,但可用,零碎能够达到最终一致性状态,其实现办法能够应用基于消息中间件+定时工作补发音讯来实现。 2.分布式一致性算法     在cap实践中,如果保证数据强一致性,就须要所有正本同步主节点的所有数据,在数据同步过程中,对外不可用,在所有分布式一致性算法中,解决此的思维是大多数正本同步(个别都是过半)主节点的数据后,主节点就能够应用对客户端进行相应。  basic paxos算法 basic paxos算法有prepare、accept和learn三个阶段,以及提案者,决策者和学习者。  prepare阶段:提案者发出请求到过半的决策者,申请中携带生成的全局惟一递增id,该id能够是工夫戳+机器id。 accept阶段:决策者接管到提案者的id信息后,通过比拟保留的id和申请的id大小,如果申请的id大于保留的id,就会把保留中的最大的id及对应的提案值作为响应发送给提案者。而且之后决策者会回绝所有id小于以后的id的提案申请,只承受大于以后id的申请。当提案者接管到决策者过半的响应后,就会在所有响应中获取最大id的提案值作为提案值,发送给过半决策者,此过半决策者能够与提案决策者不同,决策者收到申请后,就会提交申请。 learn阶段:所有learner同步决策者的数据。具体形式能够是每一个learner去申请accept,也能够所有learner抉择一个主learner,主learner同步accept的数据,其余learner同步主learner。 上述paxos算法是basic paxos算法,如果有多个提案者,就会导致活锁问题。为了解决此问题,提出只有一个主提案者,在多个提案者中,先抉择一个主提案者,所有的提案都由该主提案者进行提交。  Raft算法 leader选举 日志同步 zab算法  启动选举leader每台机器发送(myid,zxid)到别的机器,别的机器查看是否是在选举过程中,而后比拟zxid,投票给zxid大的,如果zxid雷同就投票给myid大的,等到有机器接管到一半以上的投票后即成为leader  运行中选举 逻辑大抵同启动时选举leader,只不过换成sid和zxid,过半投票机制。而后再同步数据。  kafka 选举 isr列表 高水位HW 过半机制

August 10, 2020 · 1 min · jiezi

关于分布式:初识分布式MIT-6284系列一

前言本系列是源于「码农翻身」所属常识星球发动的读书流动,由大佬 @我的UDP不丢包 举荐而来,这次的读书流动有一些另类,咱们摈弃了传统的书籍,开始攻略最高学府的研究生顶级课程 <6.824>,该课程是很多年前的蠕虫病毒发明者Robert Morris大佬授课,归属于麻省理工大学,授课形式次要是:视频 + Lab 试验(Go 语言) + 论文,全程英语,难度较大。 分布式系统的判断根据multiple cooperating computers (多台计算机合作)storage for big web sites, MapReduce, peer-to-peer sharing (大规模数据集运算,如:MapReduce,或点对点共享)lots of critical infrastructure is distributed (零碎的绝大部分基础设施是分布式的)MapReduce:大规模数据集计算零碎,比方计算从 1 加到 1000 亿,能够单台计算机计算,也能够利用该技术扩散到多台计算机计算而后合并后果,极大的提高效率为什么须要分布式系统to increase capacity via parallelism (通过并行减少零碎性能)to tolerate faults via replication (通过复制备份减少零碎容错)to place computing physically close to external entities (能够将计算放在离内部实体更近的中央)to achieve security via isolation (能够通过隔离减少零碎的平安)容错:针对于容错,次要是两点,一是可用性,二是可恢复性对于分布式系统来说,个别不会全副服务器同时瘫痪,因而无论是服务可用还是数据安全,都比单体服务更有保障。 分布式的难点须要额定留神并发编程,对开发人员的能力要求直线回升零碎内的相互作用非常复杂意想不到的谬误:部分谬误预期性能和理论性能往往不符部分谬误:假如一台机器每天出故障的概率是千分之一,在单体利用中,可能很长时间能够工作,然而在分布式系统中,设施数量急剧回升,每天都可能有设施呈现故障,这就是所谓的部分谬误,很难排查,也简直无奈防止此处展现一张单体利用和分布式应用的比照图,图片出自:《极客工夫 · 左耳听风》 分布式系统的解决方案宏观指标咱们须要设计一系列可能屏蔽分布式系统复杂性的形象 为什么要设立此指标?因为分布式系统自身已足够简单,因而必须简化应用形式 简化应用形式和形象有什么关系? 我目前认可的最完满形象是:文件 “UNIX 文件实质上就是一大袋字节。” —— 《UNIX 编程艺术》 ...

August 3, 2020 · 1 min · jiezi

关于分布式:分布式理论基础3CAP理论中的P到底是个什么意思

CAP实践中的P到底是个什么意思?一个分布式系统外面,节点组成的网络原本应该是连通的。然而可能因为一些故障,使得有些节点之间不连通了,整个网络就分成了几块区域。数据就分布在了这些不连通的区域中。这就叫分区。 当你一个数据项只在一个节点中保留,那么分区呈现后,和这个节点不连通的局部就拜访不到这个数据了。这时分区就是无奈容忍的。 进步分区容忍性的方法就是一个数据项复制到多个节点上,那么呈现分区之后,这一数据项就可能散布到各个区里。容忍性就进步了。 然而,要把数据复制到多个节点,就会带来一致性的问题,就是多个节点下面的数据可能是不统一的。要保障统一,每次写操作就都要期待全副节点写胜利,而这期待又会带来可用性的问题。 总的来说就是,数据存在的节点越多,分区容忍性越高,但要复制更新的数据就越多,一致性就越难保障。为了保障一致性,更新所有节点数据所须要的工夫就越长,可用性就会升高。 作者:邬江 链接:https://www.zhihu.com/questio... 起源:知乎 著作权归作者所有。商业转载请分割作者取得受权,非商业转载请注明出处。

July 29, 2020 · 1 min · jiezi

关于分布式:分布式Dubbo1负载均衡策略

Dubbo 源码剖析 - 集群容错之 LoadBalance1.简介LoadBalance 中文意思为负载平衡,它的职责是将网络申请,或者其余模式的负载“均摊”到不同的机器上。防止集群中局部服务器压力过大,而另一些服务器比拟闲暇的状况。 通过负载平衡,能够让每台服务器获取到适宜本人解决能力的负载。在为高负载的服务器分流的同时,还能够防止资源节约,两全其美。负载平衡可分为软件负载平衡和硬件负载平衡。 在咱们日常开发中,个别很难接触到硬件负载平衡。但软件负载平衡还是可能接触到一些的,比方 Nginx。 在 Dubbo 中,也有负载平衡的概念和相应的实现。Dubbo 须要对服务消费者的调用申请进行调配,防止多数服务提供者负载过大。服务提供者负载过大,会导致局部服务调用超时。因而将负载平衡到每个服务提供者上,是十分必要的。 Dubbo 提供了4种负载平衡实现,别离是基于权重随机算法的 RandomLoadBalance、基于起码沉闷调用数算法的 LeastActiveLoadBalance、基于 hash 一致性的 ConsistentHashLoadBalance,以及基于加权轮询算法的 RoundRobinLoadBalance。 这几个负载平衡算法代码不是很长,然而想看懂也不是很容易,须要大家对这几个算法的原理有肯定理解才行。如果不是很理解,也没不必太放心。我会在剖析每个算法的源码之前,对算法原理进行简略的解说,帮忙大家建设初步的印象。 我在写 Dubbo 源码剖析系列文章之初,过后 Dubbo 最新的版本为 2.6.4。近期,Dubbo 2.6.5 公布了,其中就有对负载平衡局部代码批改。因而我在剖析完 2.6.4 版本后的源码后,会另外剖析 2.6.5 更新的局部。本篇文章内容十分之丰盛,须要大家急躁浏览。好了,其余的就不多说了,进入正题吧。 2.源码剖析在 Dubbo 中,所有负载平衡实现类均继承自 AbstractLoadBalance,该类实现了 LoadBalance 接口办法,并封装了一些公共的逻辑。所以在剖析负载平衡实现之前,先来看一下 AbstractLoadBalance 的逻辑。首先来看一下负载平衡的入口办法 select,如下: @Overridepublic <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) { if (invokers == null || invokers.isEmpty()) return null; // 如果 invokers 列表中仅有一个 Invoker,间接返回即可,无需进行负载平衡 if (invokers.size() == 1) return invokers.get(0); // 调用 doSelect 办法进行负载平衡,该办法为形象办法,由子类实现 return doSelect(invokers, url, invocation);}protected abstract <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation);select 办法的逻辑比较简单,首先会检测 invokers 汇合的合法性,而后再检测 invokers 汇合元素数量。如果只蕴含一个 Invoker,间接返回该 Inovker 即可。如果蕴含多个 Invoker,此时须要通过负载平衡算法抉择一个 Invoker。具体的负载平衡算法由子类实现,接下来章节会对这些子类进行详细分析。 ...

July 28, 2020 · 14 min · jiezi

关于分布式:Google-File-System

设计零碎由大量便宜机器组成, 组件生效属于常见景象, 须要监测运行状况, 容错以及复原.文件绝大多数超100MB, GB级别常见且是次要优化对象. 反对小文件, 但不保障高效率.读操作包含流式读取(streaming reads)以及随机读取(random reads). 流式读取每次读取上百KB至1MB内容, 而随机读取往往只波及几KB且不保障高效率.写操作包含追加写以及随机写. 追加写下一旦写入, 很少批改. 对随机写不保障高效率.相较于低提早更偏向于继续高带宽.架构 零碎由一个master以及多个chunkserver形成. 一个文件被切分成多个大小固定的chunk(默认64MB)并将多个备份(默认3个)存储在不同的chunkserver上. master存储文件系统的metadata, 包含namespace, access control information, mapping from file to chunks, current locations of chunks. master周期性的与chunkserver通过心跳包下达指令并监测状态. client与master通信取得文件的metadata并缓存后与chunkserver间接通信进行读写. 实现Chunk Size chunk size设置为远超常见的文件系统的64MB, 并且只在须要是调配新的chunk. 较大的chunk size对于零碎既有益处亦有害处. 长处: 缩小多chunk读写时与master的交互次数.操作在单个chunk上更加集中, 缩小了TCP连贯的网络开销.缩小了存储在master上的metadata, 使得master上的元数据能够维持在内存中.毛病: 由一个chunk组成的小文件可能会呈现hot spot. 但零碎内文件往往由多个chunk组成.Metadata master将三类metadata维持在内存中, 包含namespace, access control information, mapping from file to chunks, current locations of chunks. namespace以及access control information通过operation log长久化存储在master的本地磁盘上并在远端备份. ...

July 24, 2020 · 2 min · jiezi

关于分布式:Google-File-System

设计零碎由大量便宜机器组成, 组件生效属于常见景象, 须要监测运行状况, 容错以及复原.文件绝大多数超100MB, GB级别常见且是次要优化对象. 反对小文件, 但不保障高效率.读操作包含流式读取(streaming reads)以及随机读取(random reads). 流式读取每次读取上百KB至1MB内容, 而随机读取往往只波及几KB且不保障高效率.写操作包含追加写以及随机写. 追加写下一旦写入, 很少批改. 对随机写不保障高效率.相较于低提早更偏向于继续高带宽.架构 零碎由一个master以及多个chunkserver形成. 一个文件被切分成多个大小固定的chunk(默认64MB)并将多个备份(默认3个)存储在不同的chunkserver上. master存储文件系统的metadata, 包含namespace, access control information, mapping from file to chunks, current locations of chunks. master周期性的与chunkserver通过心跳包下达指令并监测状态. client与master通信取得文件的metadata并缓存后与chunkserver间接通信进行读写. 实现Chunk Size chunk size设置为远超常见的文件系统的64MB, 并且只在须要是调配新的chunk. 较大的chunk size对于零碎既有益处亦有害处. 长处: 缩小多chunk读写时与master的交互次数.操作在单个chunk上更加集中, 缩小了TCP连贯的网络开销.缩小了存储在master上的metadata, 使得master上的元数据能够维持在内存中.毛病: 由一个chunk组成的小文件可能会呈现hot spot. 但零碎内文件往往由多个chunk组成.Metadata master将三类metadata维持在内存中, 包含namespace, access control information, mapping from file to chunks, current locations of chunks. namespace以及access control information通过operation log长久化存储在master的本地磁盘上并在远端备份. ...

July 24, 2020 · 2 min · jiezi

关于分布式:一文总结分布式一致性技术是如何演进的

简介: 分布式一致性(Consensus)作为分布式系统的基石,始终都是计算机系统畛域的热点。近年来随着分布式系统的规模越来越大,对可用性和一致性的要求越来越高,分布式一致性的利用也越来越宽泛。纵观分布式一致性在工业界的利用,从最开始的鼻祖Paxos的一统天下,到横空出世的Raft的风行,再到现在Leaderless的EPaxos开始备受关注,背地的技术是如何演进的?本文将从技术角度探讨分布式一致性在工业界的利用,并从可了解性、可用性、效率和实用场景等几个角度进行比照剖析。 分布式一致性分布式一致性,简略的说就是在一个或多个过程提议了一个值后,使零碎中所有过程对这个值达成统一。 为了就某个值达成统一,每个过程都能够提出本人的提议,最终通过分布式一致性算法,所有正确运行的过程学习到雷同的值。 工业界对分布式一致性的利用,都是为了构建多正本状态机模型(Replicated State Machine),实现高可用和强统一。 分布式一致性使多台机器具备雷同的状态,运行雷同的确定性状态机,在多数机器故障时整体仍能失常工作。 PaxosPaxos达成一个决定至多须要两个阶段(Prepare阶段和Accept阶段)。 Prepare阶段的作用: 争取提议权,争取到了提议权能力在Accept阶段发动提议,否则须要从新争取。学习之前曾经提议的值。Accept阶段使提议造成多数派,提议一旦造成多数派则决定达成,能够开始学习达成的决定。Accept阶段若被回绝须要从新走Prepare阶段。 Multi-PaxosBasic Paxos达成一次决定至多须要两次网络来回,并发状况下可能须要更多,极其状况下甚至可能造成活锁,效率低下,Multi-Paxos正是为解决此问题而提出。 Multi-Paxos选举一个Leader,提议由Leader发动,没有竞争,解决了活锁问题。提议都由Leader发动的状况下,Prepare阶段能够跳过,将两阶段变为一阶段,提高效率。Multi-Paxos并不假如惟一Leader,它容许多Leader并发提议,不影响安全性,极其状况下进化为Basic Paxos。 Multi-Paxos与Basic Paxos的区别并不在于Multi(Basic Paxos也能够Multi),只是在同一Proposer间断提议时能够优化跳过Prepare间接进入Accept阶段,仅此而已。 Raft不同于Paxos间接从分布式一致性问题登程推导进去,Raft则是从多正本状态机的角度提出,应用更强的假如来缩小须要思考的状态,使之变的易于了解和实现。 Raft与Multi-Paxos有着千头万绪的关系,上面总结了Raft与Multi-Paxos的异同。 Raft与Multi-Paxos中类似的概念: Raft的Leader即Multi-Paxos的Proposer。Raft的Term与Multi-Paxos的Proposal ID实质上是同一个货色。Raft的Log Entry即Multi-Paxos的Proposal。Raft的Log Index即Multi-Paxos的Instance ID。Raft的Leader选举跟Multi-Paxos的Prepare阶段实质上是雷同的。Raft的日志复制即Multi-Paxos的Accept阶段。Raft与Multi-Paxos的不同: Raft假如零碎在任意时刻最多只有一个Leader,提议只能由Leader收回(强Leader),否则会影响正确性;而Multi-Paxos尽管也选举Leader,但只是为了提高效率,并不限度提议只能由Leader收回(弱Leader)。 强Leader在工程中个别应用Leader Lease和Leader Stickiness来保障: Leader Lease:上一任Leader的Lease过期后,随机期待一段时间再发动Leader选举,保障新旧Leader的Lease不重叠。Leader Stickiness:Leader Lease未过期的Follower回绝新的Leader选举申请。Raft限度具备最新已提交的日志的节点才有资格成为Leader,Multi-Paxos无此限度。 Raft在确认一条日志之前会查看日志连续性,若查看到日志不间断会回绝此日志,保障日志连续性,Multi-Paxos不做此查看,容许日志中有空洞。 Raft在AppendEntries中携带Leader的commit index,一旦日志造成多数派,Leader更新本地的commit index即实现提交,下一条AppendEntries会携带新的commit index告诉其它节点;Multi-Paxos没有日志连接性假如,须要额定的commit音讯告诉其它节点。 EPaxosEPaxos(Egalitarian Paxos)于SOSP'13提出,比Raft还稍早一些,但Raft在工业界大行其道的工夫里,EPaxos却长期无人问津,直到最近,EPaxos开始被工业界所关注。 EPaxos是一个Leaderless的一致性算法,任意正本均可提交日志,通常状况下,一次日志提交须要一次或两次网络来回。 EPaxos无Leader选举开销,一个正本不可用可立刻拜访其余正本,具备更高的可用性。各正本负载平衡,无Leader瓶颈,具备更高的吞吐量。客户端可抉择最近的正本提供服务,在跨AZ跨地区场景下具备更小的提早。 不同于Paxos和Raft,当时对所有Instance编号排序,而后再对每个Instance的值达成统一。EPaxos不当时规定Instance的程序,而是在运行时动静决定各Instance之间的程序。EPaxos不仅对每个Instance的值达成统一,还对Instance之间的绝对程序达成统一。EPaxos将不同Instance之间的绝对程序也做为一致性问题,在各个正本之间达成统一,因而各个正本可并发地在各自的Instance中发动提议,在这些Instance的值和绝对程序达成统一后,再对它们依照绝对程序从新排序,最初按程序利用到状态机。 从图论的角度看,日志是图的结点,日志之间的程序是图的边,EPaxos对结点和边别离达成统一,而后应用拓扑排序,决定日志的程序。图中也可能造成环路,EPaxos须要解决循环依赖的问题。 EPaxos引入日志抵触的概念(与Parallel Raft相似,与并发抵触不是一个概念),若两条日志之间没有抵触(例如拜访不同的key),则它们的绝对程序无关紧要,因而EPaxos只解决有抵触的日志之间的绝对程序。 若并发提议的日志之间没有抵触,EPaxos只须要运行PreAccept阶段即可提交(Fast Path),否则须要运行Accept阶段能力提交(Slow Path)。 PreAccept阶段尝试将日志以及与其它日志之间的绝对程序达成统一,同时保护该日志与其它日志之间的抵触关系,如果运行完PreAccept阶段,没有发现该日志与其它并发提议的日志之间有抵触,则该日志以及与其它日志之间的绝对程序曾经达成统一,间接发送异步的Commit音讯提交;否则如果发现该日志与其它并发提议的日志之间有抵触,则日志之间的绝对程序还未达成统一,须要运行Accept阶段将抵触依赖关系达成多数派,再发送Commit音讯提交。 EPaxos的Fast Path Quorum为2F,可优化至F + [ (F + 1) / 2 ],在3正本和5正本时,与Paxos、Raft统一。Slow Path 为Paxos Accept阶段,Quorum固定为F + 1。 ...

July 24, 2020 · 1 min · jiezi

关于分布式:分布式-ID-解决方案之美团-Leaf

分布式 ID在宏大简单的分布式系统中,通常须要对海量数据进行惟一标识,随着数据日渐增长,对数据分库分表当前须要有一个惟一 ID 来标识一条数据,而数据库的自增 ID 显然不能满足需要,此时就须要有一个可能生成全局惟一 ID 的零碎,须要满足以下条件: 全局唯一性:最根本的要求就是不能呈现反复的 ID。递增:保障下一个 ID 肯定大于上一个 ID。信息安全:如果 ID 是间断的,用户就能够依照程序进行歹意爬取数据,所以 ID 生成无规则。上述的 2 和 3 点需要是互斥的,无奈应用同一个计划满足。解决方案数据库生成以 MySQL 为例,利用给字段设置 auto_increment_increment 和 auto_increment_offset 来实现 ID 自增。每次业务能够应用下列 SQL 进行读写失去 ID: begin; REPLACE INTO Tickets64 (stub) VALUES ('a'); SELECT LAST_INSERT_ID(); commit; 长处:应用非常简单,ID 枯燥递增。毛病:十分依赖数据库,当数据库异样时则整个零碎不可用。UUID长处:本地生成,没有网络耗费,性能高。毛病:过长不易于存储;造成信息不平安,基于 MAC 地址生成可能会造成 MAC 地址泄露。SnowflakeSnowflake(雪花算法)是由 Twitter 公布的分布式 ID 生成算法,它可能保障不同过程主键的不重复性,以及雷同过程主键的有序性。它是通过工夫位实现枯燥递增,且各个服务器如果都做了工夫同步,那么生成的 ID 能够认为是总体有序的。 LeafLeaf 最晚期需要是各个业务线的订单 ID 生成需要。在美团晚期,有的业务间接通过数据库自增的形式生成 ID,有的业务通过 Redis 缓存来生成 ID,也有的业务间接用 UUID 这种形式来生成 ID。以上的形式各自有各自的问题,因而决定实现一套分布式 ID 生成服务来满足需要。 ...

July 22, 2020 · 1 min · jiezi

关于分布式:分布式事务解决方案之-Alibaba-Seata

对于事务的几点常识本地事务该类事务须要满足四大个性:ACID(原子性、一致性、隔离性、持久性),仅限于对繁多数据库资源的访问控制。 原子性(Atomicity):指事务作为整体来执行,要么全副执行,要么全副不执行。一致性(Consistency):指事务应确保数据从一个统一的状态转变为另一个统一状态。隔离性(Isolation):指多个事务并发时,一个事务的执行不应影响其它事务的执行。持久性(Durability):指已提交的事务批改数据会被长久保留。柔性事务如果将实现了 ACID 的四大事务个性的事务成为刚性事务的话,那么基于 BASE 事务因素的事务则成为柔性事务。 BASE 是根本可用、柔性状态和最终一致性这三个个性的缩写。 根本可用(Basically Available):容许分布式事务参与方不肯定要同时在线。柔性状态(Soft state):则容许零碎状态更新有肯定的延时。最终一致性(Eventually consistent):通常是通过消息传递的形式保证系统的 最终一致性。在 ACID 事务中对隔离性的要求很高,在事务执行过程中,必须将所有的资源锁定。而柔性事务的理念则是通过业务逻辑将互斥锁操作从资源层面移至业务层面。通过放宽对 强一致性 的要求,来换取零碎吞吐量的晋升。 基于 XA 标准的两阶段提交通过形象进去的 AP(应用程序)、TM(事务管理器)、RM(资源管理器) 的概念能够保障事务的 强一致性。其中 TM 和 RM 间采纳 XA 的协定进行双向通信。 与传统的本地事务相比,XA 协定减少了 Prepare 阶段,数据库除了被动承受提交指令以外,还能够反向告诉调用方事务是否能够被提交。 TM 能够收集所有分支事务的 Prepare 后果,最初进行原子的提交,保障事务的强一致性。 Alibaba Seata 简介概述Seata 是一款开源的分布式事务解决方案,提供高性能和简略易用的分布式事务服务,提供了 AT、SAGA 和 XA 事务模式。 术语TC 事务协调者:保护全局和分支事务的状态,驱动全局事务提交或回滚。TM 事务管理器:定义全局事务的范畴,从开始全局事务 > 提交或回滚事务。RM 资源管理器:治理分支事务处理的资源,与 TC 单干以注册分支事务和报告分支事务的状态,驱动分支事务提交或回滚。接入 Seata 分布式事务首先咱们用到的是 Seata 的 AT 模式,该模式的特点就是对业务无入侵式,分二阶段提交。 一阶段:业务数据和回滚日志记录在同一个本地事务中提交,开释本地锁和连贯资源。二阶段:提交异步化,十分疾速,回滚通过一阶段的回滚日志进行反向弥补。启动 Seata Server下载地址:https://seata.io/zh-cn/blog/download.html创立表在我的项目数据库中增加事务所要用到的表: CREATE TABLE IF NOT EXISTS `undo_log` ( `id`            BIGINT(20)   NOT NULL AUTO_INCREMENT COMMENT 'increment id', `branch_id`     BIGINT(20)   NOT NULL COMMENT 'branch transaction id', `xid`           VARCHAR(100) NOT NULL COMMENT 'global transaction id', `context`       VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization', `rollback_info` LONGBLOB     NOT NULL COMMENT 'rollback info', `log_status`    INT(11)      NOT NULL COMMENT '0:normal status,1:defense status', `log_created`   DATETIME     NOT NULL COMMENT 'create datetime', `log_modified`  DATETIME     NOT NULL COMMENT 'modify datetime', PRIMARY KEY (`id`), UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`) ) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table'; ...

July 22, 2020 · 2 min · jiezi

架构设计-分布式事务①概念简介和基础理论

本文源码:GitHub·点这里 || GitEE·点这里 一、分布式事务简介1、转账经典案例跨地区和机构的转账的业务在理论生存中十分常见,根底流程如下: 账户01通过一系列服务和领取的流程,把钱转入账户02,在这一过程中,如果账户01呈现出账胜利,然而账户02没有入账,这就导致数据不统一,违反了根本的事务准则。基于数据归属在不同服务和不同的数据库中,这种状况下的事务出错被称为分布式事务问题。 2、基本概念分布式事务是指事务的参与者、反对事务的服务器、资源服务器以及事务管理器别离位于不同的分布式系统的不同节点之上。 如上的转账案例,看似只有一次的转账操,实际上由不同的服务不同数据库的多个细节操作组成,这些无感知的细节操作散布在不同服务上,甚至属于不同的地区和利用,如何保障这些操作全副胜利或者全副失败,即保障不同数据库间的数据一致性,这就是分布式事务须要解决的外围问题。 3、分布式事务特点基于如下电商业务场景,根本分布式的架构思路: 数据库基于业务特点,进行分库分表;数据库拆分,随之就是业务的服务化(SOA);基于电商业务进行拆分,会呈现常见的:订单,用户,库存,物流等一系列的服务,治理不同的业务数据库,在理论的下单领取利用场景下,须要同时操作用户,订单,库存等多个服务,就必须保证数据一致性,下单领取胜利,库存必须就须要用到分布式事务。 二、CAP基础理论1、根底简介说到分布式事务问题,必然会说下CAP实践,分布式系统的三大指标: Consistency:一致性 单个事务执行更新写操作,操作完结胜利返回,在同一时间的其余事务读取的数据完全一致,不存在中间状态。在分布式的零碎中形容:用户下单领取,扣款,减库存,生成物流,必须统一。例如限量打折促销中,用户下单后库存没缩小,这就导致不统一问题。 Availability:可用性 服务必须始终处于可用的状态,收到用户的申请,服务器必须在无限的工夫给出回应,不论后果是解决胜利或者解决失败。 Partition tolerance:分区容错 艰深说,在分布式系统中,一个流程里可能呈现某个服务出错状况,这是无奈相对防止的,在程序设计上要能容忍这种谬误产生。 2、CP和AP模式分布式系统很难同时满足一致性、可用性、分区容错性三个特点,在大部分的零碎架构中,都会抉择CP或者AP模式,即须要摈弃一个特点,阐明一点,为何P没有摈弃,对于分布式系统而言,分区容错是该架构模式下的根本准则,不同的SOA服务和数据库是比方会被部署到不同的节点下。所以如何解决C(一致性)和A(可用性)就成分布式系统的最大痛点。 为何不能同时满足C和A,这也是基于分布式架构特点看,不同服务间接不能保障通信是100%胜利,一旦呈现失败状况,一致性和可用性就无奈满足。 既然强一致性无奈保障,那退一步,给解决工夫,最初后果保障一致性,也能够,这就波及到BASE实践。 三、BASE基础理论1、根底简介BASE实践是由eBay公司的架构师提出的,次要是对上述的CAP实践中一致性和可用性做的衡量后果,基于CAP定律逐渐演变而来,核心思想;即便无奈做到强一致性,但每个利用都能够依据本身业务特点,采纳适当策略实现数据的最终一致性。 Basically Available:根本可用 分布式系统在产生故障的时,容许损失局部可用性。例如常见电商清仓甩卖时,为保障主业务能够,一些不重要的服务间接降级提醒。 Soft State:软状态 容许零碎中的数据存在中间状态,并认为该中间状态的存在不会影响零碎的整体可用性。绝对于原子性而言,要求多个节点的数据正本都是统一的,这是一种硬状态。 Eventual Consistency:最终统一 强调的数据更新操作,即软状态必须有个工夫期限,在通过一段时间的同步之后,最终都可能达到一个统一的状态。因而,最终一致性的实质是须要零碎保障最终数据可能达到统一,而不须要实时保证系统数据的强一致性。工夫期限长短取决于延时、负载、数据同步等各种因素。 BASE实践提出是基于大规模高可用可扩大的分布式系统架构,不同于关系型数据库事务特点(ACID)的强一致性模型,通过就义强一致性来获取更高的可用性,并容许数据在一段时间内是不统一的,但最终达到统一状态。理论的业务场景下事物(ACID)根本个性和BASE实践也是要衡量思考。 2、柔性事务遵循BASE实践,利用业务特点,在指定期限内让事务放弃最终一致性,柔性事务是一种思维,从根本上看,就是业务模式对于事务过程中不一致性有肯定的容忍度,能够留出足够的工夫执行事务最终统一的办法。 3、PAXOS算法Paxos算法一种保障分布式系统最终一致性的共识算法,利用的是选举策略,多数遵从少数的思维。PAXOS不要求对所有节点做实时同步,本质上是思考到了分区状况下的可用性,通过缩小实现一次事务须要的参与者个数,来保障系统的可用性。 例如:N个服务节点,有(N/2)+1个节点达成共识,则认为零碎达到了统一,并且依照Paxos准则,最终实践上也达到了统一,不会再扭转,如此一来,只有保障有半数以上的服务存活,容许小局部服务挂掉,客户能够与大部分服务节点通信,那么就不会影响整体操作流程,也不需确保服务器全副处于工作状态,容错性十分好。操作影响的数据和后果随后会被异步的同步到其余节点上,从而保障最终一致性。 分布式事务的各种具体实现案例,后续再说。 四、源代码地址GitHub·地址https://github.com/cicadasmile/data-manage-parentGitEE·地址https://gitee.com/cicadasmile/data-manage-parent 举荐浏览:架构设计系列 序号题目00架构设计:单服务.集群.分布式,根本区别和分割01架构设计:分布式业务零碎中,全局ID生成策略02架构设计:分布式系统调度,Zookeeper集群化治理03架构设计:接口幂等性准则,防反复提交Token治理04架构设计:缓存管理模式,监控和内存回收策略05架构设计:异步解决流程,多种实现模式详解06架构设计:高并发流量削峰,共享资源加锁机制07架构设计:分布式服务,库表拆分模式详解

July 9, 2020 · 1 min · jiezi

ElasticJob-的产品定位与新版本设计理念

导读:调度(Scheduling)在计算机领域是个宏大概念,CPU 调度、内存调度、过程调度等都可称之为调度。它是指在特定的机会调配正当的资源去解决预先确定的工作,用于在适当的机会触发一个蕴含业务逻辑的利用。调度无论在单机还是分布式环境中都是很重要的课题。在单机环境,调度与底层操作系统脱离不了干系;而在分布式环境中,调度间接决定运行集群的投入和产出。调度的两个外围因素是资源治理和触发机会。背景ElasticJob 诞生于 2015 年,过后业界尽管有 QuartZ 等超群绝伦的定时工作框架,但不足分布式方面的摸索。散布式调度云平台产品的缺失,使得 ElasticJob 从呈现伊始便备受关注。它无效的补救了作业在分布式畛域的短板,并且提供了一站式的自动化运维管控端。 ElasticJob 在技术选型时,抉择站在了伟人的肩膀上而不是反复制作轮子的理念,将定时工作事实标准的 QuartZ 与 分布式协调的利器 ZooKeeper 完满联合,疾速而稳固的搭建了全新概念的散布式调度框架。 ElasticJob 是什么?ElasticJob 是一个散布式调度解决方案,由两个互相独立的子项目 ElasticJob Lite 和 ElasticJob Cloud 组成。ElasticJob Lite 定位为轻量级无中心化解决方案,应用 jar 的模式提供分布式工作的协调服务;ElasticJob Cloud 采纳自研 Mesos Framework 的解决方案,额定提供资源治理、利用散发以及过程隔离等性能。它通过弹性调度、资源管控、以及作业治理的性能,打造一个实用于互联网场景的散布式调度解决方案,并通过凋谢的架构设计,提供多元化的作业生态。 应用 ElasticJob 可能让开发工程师不再放心工作的线性吞吐量晋升等非性能需要,使开发工程师可能更加专一于面向业务编码设计;同时,它可能解放运维工程师,使他们不用再放心工作的可用性和相干治理需要,只通过轻松的减少服务节点即可达到自动化运维的目标。 ElasticJob 调度模型与大部分的作业平台不同,ElasticJob 的调度模型划分为反对线程级别调度的过程内调度 ElasticJob Lite,和过程级别调度的 ElasticJob Cloud。 过程内调度ElasticJob Lite 是面向过程内的线程级调度框架。通过 ElasticJob ,作业可能透明化的与业务利用零碎相结合。它可能不便的与 Spring 、Dubbo 等 Java 框架配合应用,在作业中可自在应用 Spring 注入的 Bean,如数据源连接池、Dubbo 近程服务等,更加不便的贴合业务开发。 ElasticJob Lite 与业务利用部署在一起,其生命周期与业务利用保持一致,是典型的嵌入式轻量级架构。ElasticJob Lite 非常适合于资源应用稳固、部署架构简略的一般 Java 利用,能够了解为 Java 开发框架。 ...

July 9, 2020 · 2 min · jiezi

GitHub上持续冲榜ElasticJob重启

你会误认为 ElasticJob 只是作业管控平台么?创始人为你解读产品定位与新版本设计理念 ——写于 ElasticJob 3.x 版本公布前夕 作者张亮,京东数科数据研发负责人,Apache ShardingSphere 创始人 & 我的项目 VP、ElasticJob 创始人。 酷爱开源,主导开源我的项目 ShardingSphere (原名 Sharding-JDBC) 和 ElasticJob。善于以 Java 为主分布式架构,推崇优雅代码,对如何写出具备展示力的代码有较多钻研。 目前次要精力投入在将 Apache ShardingSphere 打造为业界一流的金融级数据解决方案之上。Apache ShardingSphere 是 Apache 软件基金会旗下的顶级我的项目,也是 Apache 软件基金会首个分布式数据库中间件。 调度(Scheduling)在计算机领域是个十分宏大的概念,CPU 调度、内存调度、过程调度等都能够称之为调度。它是指在特定的机会调配正当的资源去解决预先确定的工作,用于在适当的机会触发一个蕴含业务逻辑的利用。 调度无论在单机还是分布式环境中都是很重要的课题。在单机环境,调度与底层操作系统脱离不了干系;而在分布式环境中,调度间接决定运行集群的投入和产出。调度的两个外围因素是资源治理和触发机会。 ElasticJob 是一个散布式调度解决方案,由两个互相独立的子项目 ElasticJob Lite 和 ElasticJob Cloud 组成。ElasticJob Lite 定位为轻量级无中心化解决方案,应用 jar 的模式提供分布式工作的协调服务;ElasticJob Cloud 采纳自研 Mesos Framework 的解决方案,额定提供资源治理、利用散发以及过程隔离等性能。 本文将介绍 ElasticJob 的产品定位、3.x 设计理念、将来布局以及社区重启的背地故事。 产品定位:面向互联网生态和海量工作ElasticJob 自 2015 年开源,堪称几经沉浮。从开源之初的备受关注,到近年的更新停滞,期间随关注的减少,每个开发者心目中都有对它的了解和定位。 然而,误会也随社区停滞产生,其中最大的误会便是认为 ElasticJob 是定时工作管控平台。诚然,工作管控是 ElasticJob 的一个产品指标,但并非全副。从设计者的角度看,工作管控仅为其中的一个指标。 ElasticJob 的定位是面向互联网生态的海量工作的散布式调度解决方案。短短一句话稀释了 ElasticJob 的大量信息,且容笔者娓娓道来。 ...

July 9, 2020 · 2 min · jiezi

分布式限流之常用算法

令牌桶算法Token Bucket令牌桶算法是目前应用最为广泛的限流算法,顾名思义,它有以下两个关键角色: 令牌 获取到令牌的Request才会被处理,其他Requests要么排队要么被直接丢弃桶 用来装令牌的地方,所有Request都从这个桶里面获取令牌了解了这两个角色之后,让我们来看一下令牌桶算法的图示: 下面我们分别从令牌生成和令牌获取两个流程来解读令牌桶算法: 令牌生成这个流程涉及到令牌生成器和令牌桶,前面我们提到过令牌桶是一个装令牌的地方,既然是个桶那么必然有一个容量,也就是说令牌桶所能容纳的令牌数量是一个固定的数值。 对于令牌生成器来说,它会根据一个预定的速率向桶中添加令牌,比如我们可以配置让它以每秒100个请求的速率发放令牌,或者每分钟50个。注意这里的发放速度是匀速,也就是说这50个令牌并非是在每个时间窗口刚开始的时候一次性发放,而是会在这个时间窗口内匀速发放。 在令牌发放器就是一个水龙头,假如在下面接水的桶子满了,那么自然这个水(令牌)就流到了外面。在令牌发放过程中也一样,令牌桶的容量是有限的,如果当前已经放满了额定容量的令牌,那么新来的令牌就会被丢弃掉。 令牌获取每个访问请求到来后,必须获取到一个令牌才能执行后面的逻辑。假如令牌的数量少,而访问请求较多的情况下,一部分请求自然无法获取到令牌,那么这个时候我们可以设置一个“缓冲队列”来暂存这些多余的请求。 缓冲队列其实是一个可选的选项,并不是所有应用了令牌桶算法的程序都会实现队列。当有缓存队列存在的情况下,那些暂时没有获取到令牌的请求将被放到这个队列中排队,直到新的令牌产生后,再从队列头部拿出一个请求来匹配令牌。 当队列已满的情况下,这部分访问请求将被丢弃。在实际应用中我们还可以给这个队列加一系列的特效,比如设置队列中请求的存活时间,或者将队列改造为PriorityQueue,根据某种优先级排序,而不是先进先出。算法是死的,人是活的,先进的生产力来自于不断的创造,在技术领域尤其如此。 漏桶算法Leaky Bucket。瞧见没,又是个桶,限流算法是跟桶杠上了,那么漏桶和令牌桶有什么不同呢?我们来看图说话: 漏桶算法的前半段和令牌桶类似,但是操作的对象不同,令牌桶是将令牌放入桶里,而漏桶是将访问请求的数据包放到桶里。同样的是,如果桶满了,那么后面新来的数据包将被丢弃。 漏桶算法的后半程是有鲜明特色的,它永远只会以一个恒定的速率将数据包从桶内流出。打个比方,如果我设置了漏桶可以存放100个数据包,然后流出速度是1s一个,那么不管数据包以什么速率流入桶里,也不管桶里有多少数据包,漏桶能保证这些数据包永远以1s一个的恒定速度被处理。 漏桶 vs 令牌桶的区别根据它们各自的特点不难看出来,这两种算法都有一个“恒定”的速率和“不定”的速率。令牌桶是以恒定速率创建令牌,但是访问请求获取令牌的速率“不定”,反正有多少令牌发多少,令牌没了就干等。而漏桶是以“恒定”的速率处理请求,但是这些请求流入桶的速率是“不定”的。 从这两个特点来说,漏桶的天然特性决定了它不会发生突发流量,就算每秒1000个请求到来,那么它对后台服务输出的访问速率永远恒定。而令牌桶则不同,其特性可以“预存”一定量的令牌,因此在应对突发流量的时候可以在短时间消耗所有令牌,其突发流量处理效率会比漏桶高,但是导向后台系统的压力也会相应增多。 滑动窗口Rolling Window 上图中黑色的大框就是时间窗口,我们设定窗口时间为5秒,它会随着时间推移向后滑动。我们将窗口内的时间划分为五个小格子,每个格子代表1秒钟,同时这个格子还包含一个计数器,用来计算在当前时间内访问的请求数量。那么这个时间窗口内的总访问量就是所有格子计数器累加后的数值。 比如说,我们在第一秒内有5个用户访问,第5秒内有10个用户访问,那么在0到5秒这个时间窗口内访问量就是15。如果我们的接口设置了时间窗口内访问上限是20,那么当时间到第六秒的时候,这个时间窗口内的计数总和就变成了10,因为1秒的格子已经退出了时间窗口,因此在第六秒内可以接收的访问量就是20-10=10个。 滑动窗口其实也是一种计算器算法,它有一个显著特点,当时间窗口的跨度越长时,限流效果就越平滑。打个比方,如果当前时间窗口只有两秒,而访问请求全部集中在第一秒的时候,当时间向后滑动一秒后,当前窗口的计数量将发生较大的变化,拉长时间窗口可以降低这种情况的发生概率。

July 8, 2020 · 1 min · jiezi

分布式限流之限流方案

网关层限流在整个分布式系统中,如果有这么一个“一夫当关,万夫莫开”的角色,非网关层莫属。服务网关,作为整个分布式链路中的第一道关卡,承接了所有用户来访请求. 网关层限流的架构考量我们可以将系统流量的分布层次抽象成一个简单的漏斗模型来看 上面是一个最普通的流量模型,从上到下的路径依次是: 用户流量从网关层转发到后台服务后台服务承接流量,调用缓存获取数据缓存中无数据,则访问数据库为什么说它是一个漏斗模型,因为流量自上而下是逐层递减的,在网关层聚集了最多最密集的用户访问请求,其次是后台服务。然后经过后台服务的验证逻辑之后,刷掉了一部分错误请求,剩下的请求落在缓存上,如果缓存中没有数据才会请求漏斗最下方的数据库,因此数据库层面请求数量最小(相比较其他组件来说数据库往往是并发量能力最差的一环,阿里系的MySQL即便经过了大量改造,单机并发量也无法和Redis、Kafka之类的组件相比) 如果在上面这个漏斗模型中做流量限制,最合适的环节就是网关层,因为它是整个访问链路的源头,是所有流量途径的第一站。目前主流的网关层有以软件为代表的Nginx,还有Spring Cloud中的Gateway和Zuul这类网关层组件,也有以硬件+软件为代表的F5(F5价钱贵到你怀疑人生) 中间件限流我们有没有一个解决方案,将限流下沉到业务层来,让开发团队可以自行控制?我们来思考一下如何在分布式环境中引入服务层限流。 对于分布式环境来说,无非是需要一个类似中心节点的地方存储限流数据。打个比方,如果我希望控制接口的访问速率为每秒100个请求,那么我就需要将当前1s内已经接收到的请求的数量保存在某个地方,并且可以让集群环境中所有节点都能访问。那我们可以用什么技术来存储这个临时数据呢?这个场景天然适合我们的中间件大显神威!而且还得需要支持超高并发的中间件,谁能堪此重任? 一并中间件这下起劲儿了,纷纷表示“选我选我选我”。数据库行不行?不行,并发量不够。Message Queue行不行?好像MQ的运作模式不太适合这个场景,而且并发量也就差强人意。Kafka行不行,嗯,并发量杠杠的,是个Option。那Redis呢?OMG,憋说话就你了!理由这就给足你! Redis简直就是为服务端限流量身打造的利器。利用Redis过期时间特性,我们可以轻松设置限流的时间跨度(比如每秒10个请求,或者每10秒10个请求)。同时Redis还有一个特殊技能–脚本编程,我们可以将限流逻辑编写成一段脚本植入到Redis中,这样就将限流的重任从服务层完全剥离出来,同时Redis强大的并发量特性以及高可用集群架构也可以很好的支持庞大集群的限流访问。 限流组件除了上面介绍的几种方式以外,目前也有一些开源组件提供了类似的功能,比如Sentinel就是一个不错的选择。Sentinel是阿里出品的开源组件,并且包含在了Spring Cloud Alibaba组件库中,可以为Cloud服务在下一个“微服务架构设计与落地”的大章节中,我们将详细介绍Sentinel在分布式限流中的应用。 从架构维度考虑限流设计在真实的大型项目里,不会只使用一种限流手段,往往是几种方式互相搭配使用,让限流策略有一种层次感,达到资源的最大使用率。在这个过程中,限流策略的设计也可以参考前面提到的漏斗模型,上宽下紧,漏斗不同部位的限流方案设计要尽量关注当前组件的高可用。

July 8, 2020 · 1 min · jiezi

分布式事务-2PC-3PC

目前的数据库仅支持单库事务,并不支持跨库事务。而随着微服务架构的普及,一个大型业务系统往往由若干个子系统构成,这些子系统又拥有各自独立的数据库。往往一个业务流程需要由多个子系统共同完成,而且这些操作可能需要在一个事务中完成。在微服务系统中,这些业务场景是普遍存在的。此时,我们就需要在数据库之上通过某种手段,实现支持跨数据库的事务支持,这也就是常说的分布式事务。 两阶段提交协议 2 Phase Commit该分布式系统中,存在一个节点作为协调者(Coordinator),其他节点作为参与者(Cohorts)。且节点之间可以进行网络通信。 所有节点都采用预写式日志,且日志被写入后即被保持在可靠的存储设备上,即使节点损坏不会导致日志数据的消失。所有节点不会永久性损坏,即使损坏后仍然可以恢复。 第一阶段(投票阶段)协调者节点向所有参与者节点询问是否可以执行提交操作(vote),并开始等待各参与者节点的响应。 参与者节点执行询问发起为止的所有事务操作,并将Undo信息和Redo信息写入日志。(注意:若成功这里其实每个参与者已经执行了事务操作) 各参与者节点响应协调者节点发起的询问。如果参与者节点的事务操作实际执行成功,则它返回一个”同意”消息;如果参与者节点的事务操作实际执行失败,则它返回一个”中止”消息。 ##### 第二阶段(提交执行阶段) 当协调者节点从所有参与者节点获得的相应消息都为”同意”时 协调者节点向所有参与者节点发出”正式提交(commit)”的请求。 参与者节点正式完成操作,并释放在整个事务期间内占用的资源。 参与者节点向协调者节点发送”完成”消息。 协调者节点受到所有参与者节点反馈的”完成”消息后,完成事务。 如果任一参与者节点在第一阶段返回的响应消息为”中止”,或协调者节点在第一阶段的询问超时之前无法获取所有参与者节点的响应消息时 协调者节点向所有参与者节点发出”回滚操作(rollback)”的请求。 参与者节点利用之前写入的Undo信息执行回滚,并释放在整个事务期间内占用的资源。 参与者节点向协调者节点发送”回滚完成”消息。 协调者节点受到所有参与者节点反馈的”回滚完成”消息后,取消事务。 不管最后结果如何,第二阶段都会结束当前事务。 二阶段提交看起来确实能够提供原子性的操作,但二阶段提交还是有几个缺点 执行过程中,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。 参与者发生故障。协调者需要给每个参与者额外指定超时机制,超时后整个事务失败。(没有多少容错机制) 协调者发生故障。参与者会一直阻塞下去。需要额外的备机进行容错。(这个可以依赖后面要讲的Paxos协议实现HA) 二阶段无法解决的问题 协调者发出commit消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。 三阶段提交协议 3PC三阶段提交有两个改动点 引入超时机制。同时在协调者和参与者中都引入超时机制。 在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。这样就有CanCommit、PreCommit、DoCommit三个阶段。 ##### CanCommit 3PC的CanCommit阶段其实和2PC的准备阶段很像。协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。 事务询问 ,协调者向参与者发送CanCommit请求。询问是否可以执行事务提交操作。然后开始等待参与者的响应。 响应反馈 ,参与者接到CanCommit请求之后,正常情况下,如果其自身认为可以顺利执行事务,则返回Yes响应,并进入预备状态。否则反馈No ##### PreCommit 协调者根据参与者的反应情况来决定是否可以记性事务的PreCommit操作。根据响应情况,有以下两种可能。 假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务的预执行。 发送预提交请求 协调者向参与者发送PreCommit请求,并进入Prepared阶段。 事务预提交 参与者接收到PreCommit请求后,会执行事务操作,并将undo和redo信息记录到事务日志中。 响应反馈 如果参与者成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令。 假如有任何一个参与者向协调者发送了No响应,或者等待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断。 发送中断请求 协调者向所有参与者发送abort请求。 中断事务 参与者收到来自协调者的abort请求之后(或超时之后,仍未收到协调者的请求),执行事务的中断。 ##### DoCommit 该阶段进行真正的事务提交,也可以分为以下两种情况。 执行提交 发送提交请求 协调接收到参与者发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有参与者发送doCommit请求。 事务提交 参与者接收到doCommit请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源。 响应反馈 事务提交完之后,向协调者发送ACK响应。 ...

June 26, 2020 · 1 min · jiezi

分布式事务-TCC

全局事务(DTP模型)     全局事务基于DTP模型实现,DTP是由X/Open组织提出的一种分布式事务模型——X/Open Distributed Transaction Processing Reference Model,规定了要实现分布式事务需要三种角色。     AP:Application 应用系统     开发的业务系统,在开发的过程中,可以使用资源管理器提供的事务接口来实现分布式事务。     TM:Transaction Manager 事务管理器     分布式事务的实现由事务管理器来完成,它会提供分布式事务的操作接口供我们的业务系统调用。这些接口称为TX接口。 事务管理器还管理着所有的资源管理器,通过它们提供的XA接口来同一调度这些资源管理器,以实现分布式事务。 DTP只是一套实现分布式事务的规范,并没有定义具体如何实现分布式事务,TM可以采用2PC、3PC、Paxos等协议实现分布式事务。          RM:Resource Manager 资源管理器 能够提供数据服务的对象都可以是资源管理器,比如:数据库、消息中间件、缓存等。大部分场景下,数据库即为分布式事务中的资源管理器。 资源管理器能够提供单数据库的事务能力,它们通过XA接口,将本数据库的提交、回滚等能力提供给事务管理器调用,以帮助事务管理器实现分布式的事务管理。 XA是DTP模型定义的接口,用于向事务管理器提供该资源管理器(该数据库)的提交、回滚等能力。 DTP只是一套实现分布式事务的规范,RM具体的实现是由数据库厂商来完成的。 基于可靠消息服务的分布式事务 这种实现分布式事务的方式需要通过消息中间件来实现。假设有A和B两个系统,分别可以处理任务A和任务B。此时系统A中存在一个业务流程,需要将任务A和任务B在同一个事务中处理。 系统A处理任务A前,首先向消息中间件发送一条消息 消息中间件收到后将该条消息持久化,但并不投递。此时下游系统B仍然不知道该条消息的存在。 消息中间件持久化成功后,便向系统A返回一个确认应答; 系统A收到确认应答后,则可以开始处理任务A; 任务A处理完成后,向消息中间件发送Commit消息。该请求发送完成后,对系统A而言,该事务的处理过程就结束了,此时它可以处理别的任务。 但Commit消息可能会在传输途中丢失,从而消息中间件并不会向系统B投递这条消息,从而系统就会出现不一致性。这个问题由消息中间件的事务回查机制完成,下文会介绍。 消息中间件收到Commit指令后,便向系统B投递该消息,从而触发任务B的执行; 当任务B执行完成后,系统B向消息中间件返回一个确认应答,告诉消息中间件该消息已经成功消费,此时,这个分布式事务完成。 上述过程可以得出如下几个结论 消息中间件扮演者分布式事务协调者的角色。 系统A完成任务A后,到任务B执行完成之间,会存在一定的时间差。在这个时间差内,整个系统处于数据不一致的状态,但这短暂的不一致性是可以接受的,因为经过短暂的时间后,系统又可以保持数据一致性,满足CAP理论。 如果任务A处理失败,那么需要进入回滚流程     若系统A在处理任务A时失败,那么就会向消息中间件发送Rollback请求。和发送Commit请求一样,系统A发完之后便可以认为回滚已经完成,它便可以去做其他的事情。 消息中间件收到回滚请求后,直接将该消息丢弃,而不投递给系统B,从而不会触发系统B的任务B。 系统又处于一致性状态,因为任务A和任务B都没有执行。上述Commit和Rollback都属于理想情况,在实际系统中,Commit和Rollback指令都有可能在传输途中丢失。这种情况就需要超时询问机制。 系统A除了实现正常的业务流程外,还需提供一个事务询问的接口,供消息中间件调用。当消息中间件收到一条事务型消息后便开始计时,如果到了超时时间也没收到系统A发来的Commit或Rollback指令的话,就会主动调用系统A提供的事务询问接口询问该系统目前的状态,该接口会返回三种结果。 提交 ,则将该消息投递给系统B。 回滚 ,则直接将条消息丢弃。 处理中 ,则继续等待。 如果消息在投递过程中丢失,或消息的确认应答在返回途中丢失,那么消息中间件在等待确认应答超时之后就会重新投递,直到下游消费者返回消费成功响应为止。当然,消息中间件可以设置消息重试的次数和时间间隔,如当第一次投递失败后,每隔五分钟重试一次,一共重试3次。如果重试3次之后仍然投递失败,那么这条消息就需要人工干预。     当系统A将向消息中间件发送Commit指令后,它便去做别的事情了。如果此时消息投递失败,需要回滚的话,就需要让系统A事先提供回滚接口,这无疑增加了额外的开发成本,业务系统的复杂度也将提高。对于一个业务系统的设计目标是,在保证性能的前提下,最大限度地降低系统复杂度,从而能够降低系统的运维成本,因此在消息投递失败后为什么不回滚消息,而是不断尝试重新投递。     上游系统A向消息中间件提交Commit/Rollback消息采用的是异步方式,也就是当上游系统提交完消息后便可以去做别的事情,接下来提交、回滚就完全交给消息中间件来完成,并且完全信任消息中间件,认为它一定能正确地完成事务的提交或回滚。然而,消息中间件向下游系统投递消息的过程是同步的。也就是消息中间件将消息投递给下游系统后,它会阻塞等待,等下游系统成功处理完任务返回确认应答后才取消阻塞等待。为什么这两者在设计上不一致?     首先,上游系统和消息中间件之间采用异步通信是为了提高系统并发度。业务系统直接和用户打交道,用户体验尤为重要,因此这种异步通信方式能够极大程度地降低用户等待时间。此外,异步通信相对于同步通信而言,没有了长时间的阻塞等待,因此系统的并发性也大大增加。但异步通信可能会引起Commit/Rollback指令丢失的问题,这就由消息中间件的超时询问机制来弥补。     那么,消息中间件和下游系统之间为什么要采用同步通信呢?     异步能提升系统性能,但随之会增加系统复杂度;而同步虽然降低系统并发度,但实现成本较低。因此,在对并发度要求不是很高的情况下,或者服务器资源较为充裕的情况下,我们可以选择同步来降低系统的复杂度。  我们知道,消息中间件是一个独立于业务系统的第三方中间件,它不和任何业务系统产生直接的耦合,它也不和用户产生直接的关联,它一般部署在独立的服务器集群上,具有良好的可扩展性,所以不必太过于担心它的性能,如果处理速度无法满足我们的要求,可以增加机器来解决。而且,即使消息中间件处理速度有一定的延迟那也是可以接受的,因为前面所介绍的CAP理论就告诉我们了,我们追求的是最终一致性,而非实时一致性,因此消息中间件产生的时延导致事务短暂的不一致是可以接受的。 最大努力通知(定期校对) 最大努力通知也被称为定期校对,其实在消息中间件方案中已经包含,这种方案也需要消息中间件的参与。     上游系统在完成任务后,向消息中间件同步地发送一条消息,确保消息中间件成功持久化这条消息,然后上游系统可以去做别的事情了; ...

June 26, 2020 · 1 min · jiezi

PowerJob一款强大且开源的分布式调度与计算框架

项目名称:PowerJob 项目作者:假诗人 开源许可协议:Apache-2.0 项目地址:https://gitee.com/KFCFans/OhMyScheduler 项目简介PowerJob(原OhMyScheduler)是全新一代分布式调度与计算框架,其主要功能特性如下: 使用简单:提供前端Web界面,允许开发者可视化地完成调度任务的管理(增、删、改、查)、任务运行状态监控和运行日志查看等功能。定时策略完善:支持CRON表达式、固定频率、固定延迟和API四种定时调度策略。执行模式丰富:支持单机、广播、Map、MapReduce四种执行模式,其中Map/MapReduce处理器能使开发者寥寥数行代码便获得集群分布式计算的能力。执行器支持广泛:支持Spring Bean、内置/外置Java类、Shell、Python等处理器,应用范围广。运维便捷:支持在线日志功能,执行器产生的日志可以在前端控制台页面实时显示,降低debug成本,极大地提高开发效率。依赖精简:最小仅依赖关系型数据库(MySQL/PostgreSQL/Oracle/MS SQLServer...)高可用&高性能:调度服务器经过精心设计,一改其他调度框架基于数据库锁的策略,实现了无锁化调度。部署多个调度服务器可以同时实现高可用和性能的提升(支持无限的水平扩展)。故障转移与恢复:任务执行失败后,可根据配置的重试策略完成重试,只要执行器集群有足够的计算节点,任务就能顺利完成适用场景有定时执行需求的业务场景:如每天凌晨全量同步数据、生成业务报表等。有需要全部机器一同执行的业务场景:如使用广播执行模式清理集群日志。有需要分布式处理的业务场景:比如需要更新一大批数据,单机执行耗时非常长,可以使用Map/MapReduce处理器完成任务的分发,调动整个集群加速计算。同类产品对比 项目截图 脚本处理器的简单试用:在任务管理界面直接创建任务,将脚本内容复制进去即可。 Java 处理器的试用 创建任务:任务录入示例如下,注意:处理器信息的填写格式为 容器ID#全限定类名 目前该项目作者处于全职维护状态,所以大家如果有好的意见和建议的话,欢迎点击后面的链接前往项目主页和作者取得联系:https://gitee.com/KFCFans/OhMyScheduler

June 23, 2020 · 1 min · jiezi

分布式load-balance-04java-从零手写实现负载均衡

负载均衡系列专题01-负载均衡基础知识 02-一致性 hash 原理 03-一致性哈希算法 java 实现 04-负载均衡算法 java 实现 本节我们来看一下如何实现一负载均衡框架。 源码核心接口定义public interface ILoadBalance { /** * 选择下一个节点 * * 返回下标 * @param context 上下文 * @return 结果 * @since 0.0.1 */ IServer select(final ILoadBalanceContext context);}1. 随机策略public class LoadBalanceRandom extends AbstractLoadBalance{ public LoadBalanceRandom(List<IServer> servers) { super(servers); } @Override protected IServer doSelect(ILoadBalanceContext context) { Random random = ThreadLocalRandom.current(); int nextIndex = random.nextInt(servers.size()); return servers.get(nextIndex); }}2. 轮训public class LoadBalanceRoundRobbin extends AbstractLoadBalance { /** * 位移指针 * @since 0.0.1 */ private final AtomicLong indexHolder = new AtomicLong(); public LoadBalanceRoundRobbin(List<IServer> servers) { super(servers); } @Override protected IServer doSelect(ILoadBalanceContext context) { long index = indexHolder.getAndIncrement(); int actual = (int) (index % servers.size()); return servers.get(actual); }}3. 有权重的轮训这个需要对数据进行初始化处理,计算数组的最大公约数。 ...

June 20, 2020 · 2 min · jiezi

分布式load-balance-02consistent-hash-algorithm-一致性哈希算法原理详解

负载均衡系列专题01-负载均衡基础知识 02-一致性 hash 原理 03-一致性哈希算法 java 实现 04-负载均衡算法 java 实现 概念一致哈希是一种特殊的哈希算法。 在使用一致哈希算法后,哈希表槽位数(大小)的改变平均只需要对 K/n个关键字重新映射,其中K是关键字的数量, n是槽位数量。 然而在传统的哈希表中,添加或删除一个槽位的几乎需要对所有关键字进行重新映射。 有什么用现在想来,很多分布式中间件,在增删节点的时候都需要进行 re-balance。 借助一致性 hash,感觉可以避免这一步坑。 业务场景假设有1000w个数据项,100个存储节点,请设计一种算法合理地将他们存储在这些节点上。 强哈希考虑到单服务器不能承载,因此使用了分布式架构,最初的算法为 hash() mod n, hash()通常取用户ID,n为节点数。 此方法容易实现且能够满足运营要求。缺点是当单点发生故障时,系统无法自动恢复。同样不也不能进行动态增加节点。 原理图看一看普通 Hash 算法的原理: 核心计算如下for item in range(ITEMS): k = md5(str(item)).digest() h = unpack_from(">I", k)[0] # 通过取余的方式进行映射 n = h % NODES node_stat[n] += 1输出 Ave: 100000Max: 100695 (0.69%)Min: 99073 (0.93%)从上述结果可以发现,普通的Hash算法均匀地将这些数据项打散到了这些节点上,并且分布最少和最多的存储节点数据项数目小于1%。 之所以分布均匀,主要是依赖Hash算法(实现使用的MD5算法)能够比较随机的分布。 缺点然而,我们看看存在一个问题,由于该算法使用节点数取余的方法,强依赖node的数目。 因此,当是node数发生变化的时候,item所对应的node发生剧烈变化,而发生变化的成本就是我们需要在node数发生变化的时候,数据需要迁移,这对存储产品来说显然是不能忍的,我们观察一下增加node后,数据项移动的情况: for item in range(ITEMS): k = md5(str(item)).digest() h = unpack_from(">I", k)[0] # 原映射结果 n = h % NODES # 现映射结果 n_new = h % NEW_NODES if n_new != n: change += 1输出 ...

June 20, 2020 · 2 min · jiezi

分布式load-balance-03一致性哈希算法-java-实现

负载均衡系列专题01-负载均衡基础知识 02-一致性 hash 原理 03-一致性哈希算法 java 实现 04-负载均衡算法 java 实现 本节我们来看一下如何实现一个一致性 hash 框架。 源码普通 hash我们首先定义一下 hash 接口,以及最简单的 jdk 实现: IHashpublic interface IHash { /** * 计算 hash 值 * @param text 文本 * @return 结果 * @since 0.0.1 */ int hash(String text);}HashJdk.javapublic class HashJdk implements IHash { @Override public int hash(String text) { return text.hashCode(); }}Node 定义用来定义一个节点: 此处省略了一些方法。 public class Node { /** * 节点名称 * @since 0.0.1 */ private String name; /** * 节点 ip * @since 0.0.1 */ private String ip; public Node(String name, String ip) { this.name = name; this.ip = ip; } public Node(String ip) { this(ip, ip); } //Getter & Setter & toString() // equals && hashCode}核心实现IConsistentHashing.java一致性 hash 的接口定义。 ...

June 20, 2020 · 2 min · jiezi

分布式load-balance-01负载均衡基础知识

负载均衡系列专题01-负载均衡基础知识 02-一致性 hash 原理 03-一致性哈希算法 java 实现 04-负载均衡算法 java 实现 负载均衡负载均衡是高可用网络基础架构的关键组件,通常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性。 传统架构 在这里用户是直连到 web 服务器,如果这个服务器宕机了,那么用户自然也就没办法访问了。 另外,如果同时有很多用户试图访问服务器,超过了其能处理的极限,就会出现加载速度缓慢或根本无法连接的情况。 引入负载均衡而通过在后端引入一个负载均衡器和至少一个额外的 web 服务器,可以缓解这个故障。 通常情况下,所有的后端服务器会保证提供相同的内容,以便用户无论哪个服务器响应,都能收到一致的内容。 从图里可以看到,用户访问负载均衡器,再由负载均衡器将请求转发给后端服务器。 在这种情况下,单点故障现在转移到负载均衡器上了。 这里又可以通过引入第二个负载均衡器来缓解,但在讨论之前,我们先探讨下负载均衡器的工作方式。 负载均衡的优势(1)高性能:负载均衡技术将业务较均衡的分担到多台设备或链路上,从而提高了整个系统的性能; (2)可扩展性:负载均衡技术可以方便的增加集群中设备或链路的数量,在不降低业务质量的前提下满足不断增长的业务需求; (3)高可靠性:单个甚至多个设备或链路法神故障也不会导致业务中断,提高了整个系统的可靠性; (4)可管理性:大量的管理共组都集中在使用负载均衡技术的设备上,设备集群或链路集群只需要维护通过的配置即可; (5)透明性:对用户而言,集群等于一个或多个高可靠性、高性能的设备或链路,用户感知不到,也不关心具体的网络结构,增加或减少设备或链路数量都不会影响正常的业务。 反向代理与负载均衡反向代理是实现负载均衡的一种方法。 反向代理先谈反向代理。用户在请求时,先把请求发送给代理的服务器,然后由代理服务器根据算法去请求真实的服务器,最后返回给用户。 这种做法,其一是提高了安全性;其二是通过多台的real server分担了用户的请求,实现了负载均衡。 负载均衡再谈负载均衡。 负载均衡的出现,是通过横向的扩展,尽可能地降低单台服务器的压力。 常见WEB层面的负载均衡的方案有硬件F5、Nginx代理、LVS、各个云商的负载均衡服务(如AWS的ELB服务)等。 负载均衡后面连的一般是实际提供服务的服务器,如通过ELB服务,可以做到流量的均匀分担,从而减少单机服务器的压力。 由于增加了负载均衡这层,所以单纯地使用某个方案还是要考虑单点的问题。 负责由于负载均衡这个服务器未能承受住压力,宕机了,服务也是不可用的。 所以Nginx、LVS尽量配置多台代理,可以故障转移和故障报警,从而及时去处理代理层服务器的问题。 ELB是亚马逊提供的服务,它本身的实现底层就有数百甚至上千的机器,所以把它想象成一个代理集群就好。 以上是大致的说了下区别,具体的实现还需要结合实际的业务情况。 四层和七层负载均衡的区别?负载均衡又分为四层负载均衡和七层负载均衡。 四层负载均衡工作在OSI模型的传输层,主要工作是转发,它在接收到客户端的流量以后通过修改数据包的地址信息将流量转发到应用服务器。 七层负载均衡工作在OSI模型的应用层,因为它需要解析应用层流量,所以七层负载均衡在接到客户端的流量以后,还需要一个完整的TCP/IP协议栈。 七层负载均衡会与客户端建立一条完整的连接并将应用层的请求流量解析出来,再按照调度算法选择一个应用服务器,并与应用服务器建立另外一条连接将请求发送过去,因此七层负载均衡的主要工作就是代理。 技术原理上的区别四层所谓四层负载均衡,也就是主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。 以常见的TCP为例,负载均衡设备在接收到第一个来自客户端的 SYN 请求时,即通过上述方式选择一个最佳的服务器,并对报文中目标IP地址进行修改(改为后端服务器IP),直接转发给该服务器。 TCP的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。 在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。 七层所谓七层负载均衡,也称为“内容交换”,也就是主要通过报文中的真正有意义的应用层内容,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。 以常见的TCP为例,负载均衡设备如果要根据真正的应用层内容再选择服务器,只能先代理最终的服务器和客户端建立连接(三次握手)后,才可能接受到客户端发送的真正应用层内容的报文,然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。 负载均衡设备在这种情况下,更类似于一个代理服务器。负载均衡和前端的客户端以及后端的服务器会分别建立TCP连接。 所以从这个技术原理上来看,七层负载均衡明显的对负载均衡设备的要求更高,处理七层的能力也必然会低于四层模式的部署方式。 那么,为什么还需要七层负载均衡呢? 应用场景的需求七层应用负载的好处,是使得整个网络更智能化。 参考我们之前的另外一篇专门针对HTTP应用的优化的介绍,就可以基本上了解这种方式的优势所在。 例如访问一个网站的用户流量,可以通过七层的方式,将对图片类的请求转发到特定的图片服务器并可以使用缓存技术;将对文字类的请求可以转发到特定的文字服务器并可以使用压缩技术。 当然这只是七层应用的一个小案例,从技术原理上,这种方式可以对客户端的请求和服务器的响应进行任意意义上的修改,极大的提升了应用系统在网络层的灵活性。 很多在后台,(例如Nginx或者Apache)上部署的功能可以前移到负载均衡设备上,例如客户请求中的Header重写,服务器响应中的关键字过滤或者内容插入等功能。 另外一个常常被提到功能就是安全性。 网络中最常见的SYN Flood攻击,即黑客控制众多源客户端,使用虚假IP地址对同一目标发送SYN攻击,通常这种攻击会大量发送SYN报文,耗尽服务器上的相关资源,以达到Denial of Service(DoS)的目的。 ...

June 20, 2020 · 1 min · jiezi

分布式架构之CDN加速文件访问

1.简介CDN加速大家应该都不陌生,至少是有听说过的,其实我们应该每天都会无形中使用到它,大多数比较优秀的互联网公司都会用到它来提高网站的响应速度,比如阿里,腾讯等.CDN是Content Delivery Network的简称,即“内容分发网络”的意思,一般是指网站加速或者用户下载资源加速. 简单来说,CDN相当于一个中间代理,原来我们需要请求某个网址比如www.baidu.com,请求会直接发送至百度的服务器上,假如请求者在新疆,但百度的服务器在北京,这样的话请求和响应都会受距离影响慢一些,但有了CDN后,请求是先发至距离请求IP定位最近的CDN服务器上,该服务器上缓存了www.baidu.com页面上的一些静态文件,比如js,css.html,图片等,这样对请求的发起者来说,获取这些静态资源就比较近了,因此可以起到一定的加速效果.至于动态的资源,因为是可变的,所以无法通过缓存的方式存储在CDN服务器上,仍需要通过CDN去请求对应服务器获取资源,所以CDN加速仅限于静态资源.下图是某CDN第三方在国内部署的CDN节点. 在分布式系统中,CDN可以一定程度的减轻服务器的IO压力,提高响应速度,而且在使用CDN后用户的请求是发送到CDN服务器上的,可以避免用户直接访问源服务器,从而可以一定程度上提高系统安全性,降低被黑客攻击的可能性,类似于保护代理... 但CDN的架设成本比较高,就像快递公司的网点一样,如果需要提高服务效率和质量,需要在全国各个地区都设有网点,而且在人口稠密地区需要架设更多的网点来缓解单个网点的压力,这笔成本可以说是非常高了,所以一般CDN加速都是由专门的第三方大公司去做的,比如阿里,七牛云等,对小公司而言,自己架设成本太高,如果需要CDN加速,直接付费使用第三方提供的即可,价格合理,治理方便,一般第三方会提供详细的使用文档和优质的服务.   2.CDN 的工作原理CDN网络是在用户和服务器之间增加Cache层,主要是通过接管DNS实现,将用户的请求引导到Cache上获得源服务器的数据。步骤如下: 用户输入访问的域名,操作系统向 LocalDns 查询域名的ip地址.LocalDns向 ROOT DNS 查询域名的授权服务器(这里假设LocalDns缓存过期)ROOT DNS将域名授权dns记录回应给 LocalDnsLocalDns得到域名的授权dns记录后,继续向域名授权dns查询域名的ip地址域名授权dns 查询域名记录后(一般是CNAME),回应给 LocalDnsLocalDns 得到域名记录后,向智能调度DNS查询域名的ip地址智能调度DNS 根据一定的算法和策略(比如静态拓扑,容量等),将最适合的CDN节点ip地址回应给 LocalDnsLocalDns 将得到的域名ip地址,回应给 用户端用户得到域名ip地址后,访问站点服务器CDN节点服务器应答请求,将内容返回给客户端.(缓存服务器一方面在本地进行保存,以备以后使用,二方面把获取的数据返回给客户端,完成数据服务过程) 通过以上的分析我们可以得到,为了实现对普通用户透明(使用缓存后用户客户端无需进行任何设置)访问,需要使用DNS(域名解析)来引导用户来访问Cache服务器,以实现透明的加速服务. 由于用户访问网站的第一步就是域名解析,所以通过修改dns来引导用户访问是最简单有效的方式. CDN网络的组成要素对于普通的Internet用户,每个CDN节点就相当于一个放置在它周围的网站服务器. 通过对dns的接管,用户的请求被透明地指向离他最近的节点,节点中CDN服务器会像网站的原始服务器一样,响应用户的请求. 由于它离用户更近,因而响应时间必然更快. 从上面图中 虚线圈起来的那块,就是CDN层,这层是位于 用户端 和 站点服务器 之间. 智能调度DNS(比如f5的3DNS) 智能调度DNS是CDN服务中的关键系统.当用户访问加入CDN服务的网站时,域名解析请求将最终由 “智能调度DNS”负责处理。它通过一组预先定义好的策略,将当时最接近用户的节点地址提供给用户,使用户可以得到快速的服务。同时它需要与分布在各地的CDN节点保持通信,跟踪各节点的健康状态、容量等信息,确保将用户的请求分配到就近可用的节点上.缓存功能服务 负载均衡设备(如lvs,F5的BIG/IP) 内容Cache服务器(如squid) 共享存储(根据缓存数据量多少决定是否需要) CDN 智能调度Dns 实例分析3.1 分析img.alibaba.com域名在系统中,执行dig命令,输出如下: dig img.alibaba.com ; 部分省略  ;; QUESTION SECTION: ;img.alibaba.com. IN A  ;; ANSWER SECTION: img.alibaba.com. 600 IN CNAME img.alibaba.com.edgesuite.net. img.alibaba.com.edgesuite.net. 7191 IN CNAME img.alibaba.com.georedirector.akadns.net. img.alibaba.com.georedirector.akadns.net. 3592 IN CNAME a1366.g.akamai.net. a1366.g.akamai.net. 12 IN A 204.203.18.145 ...

June 18, 2020 · 2 min · jiezi

快讯分布式调度项目ElasticJob正式迁入Apache仓库

ElasticJob(https://github.com/elasticjob)是一个分布式调度解决方案,提供分布式任务的分片,弹性伸缩,全自动发现,基于时间驱动、数据驱动、常驻任务和临时任务的多任务类型,任务聚合和动态调配资源,故障检测、自动修复,失效转移和重试,完善的运维平台和管理工具,以及对云原生的良好支持等功能特性,可以全面满足企业对于任务管理和批量作业的全面调度处理能力。 ElasticJob自2014年底开源以来,经历了5年多的发展,以其功能的丰富性,文档的全面性,代码的高质量,框架的易用性,积累了大量的忠实用户和良好的业内口碑(5.8K star),一直也是分布式调度框架领域最受大家欢迎的项目之一。 2020年6月,经过Apache ShardingSphere社区投票,接纳ElasticJob为其子项目。目前ElasticJob的四个子项目已经正式迁入Apache仓库。 Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务。仓库地址为:https://github.com/apache/shardingsphere-elastic-job-lite Elastic-Job-Cloud采用自研Mesos Framework的解决方案,额外提供资源治理、应用分发以及进程隔离等功能。仓库地址为:https://github.com/apache/shardingsphere-elastic-job-cloud 另外两个仓库分别为官方文档和示例,地址分别为: 文档:https://github.com/apache/shardingsphere-elastic-job-doc示例:https://github.com/apache/shardingsphere-elastic-job-example后续ElasticJob会作为Apache ShardingSphere ElasticJob子项目继续发展,并融入Apache ShardingSphere解决方案,成为生态体系中的一个重要调度组件。并且可以作为全功能的分布式调度框架,独立应用于各种业务调度场景。

June 17, 2020 · 1 min · jiezi

快讯ElasticJob-30-新特性在社区开启讨论

大家好,随着 ElasticJob 成为了 Apache ShardingSphere 的子项目,社区开始规划并开放讨论 ElasticJob 3.0 的新特性。 有关新特性的想法:在基于时间的 cron 表达式触发之外,增加 ElasticJob lite 的单次作业触发;支持基于每个作业以及每个分片项为维度的两种作业依赖方式;考虑在注册中心模块使用 ZooKeeper 原生 API 代替 Apache Curator。有关架构的想法:重构 Job API,只需保留 SimpleJob,并通过 SPI 机制引入其他作业类型;重新设计 Job 领域模型,将 Job 作为顶级接口,每个分片项作为 Task;重构事件跟踪模块。 拆分事件跟踪和 elasticjob-core 模块;提供 SPI 机制扩展事件跟踪的数据存储层;考虑支持 prometheus 存储;考虑对接 Apache SkyWalking。邮件讨论地址:https://lists.apache.org/thre... 欢迎对 ElasticJob 感兴趣的同学参与讨论, ElasticJob 3.0 的新特性由你做主。

June 17, 2020 · 1 min · jiezi

志愿者招募-ShardingSphere社区技术文章-中译英

如果你对技术文章翻译感兴趣,希望加入Apache开源社区,那么请成为我们的志愿者吧! 能力要求 英语翻译技能对 ShardingSphere 有基本的了解文章列表 Start ElasticJob off with new goalHow to construct the distributed databaseApache ShardingSphere is included in CNCF LandscapeThe mixed open-source distributed transaction solutionWould you like to become an Apache committerHow automatic executor of ShardingSphere worksHow to merge the child resultsetsThe quick explanation of ShardingSphere transaction moduleWhat is the ShardingProxy如何提交你的翻译 添加你的翻译至blog的 xxx.en.md 文档注意:所有英文文章对应的xxx.cn.md的中文文章都可以在blog找到。发起PR小贴士 所有名为xxx.cn.md的中文文章可以在翻译的同一目录中找到。如果你希望找到长篇文章的翻译合作小伙伴,也可以在这里留言。对于文章中的作者简介可以提供简短的翻译,例如名字和头衔。欢迎大家积极参与,想要翻译的的同学可以在以下链接处留言文章编号和预计完成时间,我们也会在这里不定期更新需要翻译文章,大家可以积极关注我们的动态。如果有其他的想法或者反馈,也可以留言:https://github.com/apache/sha... 我们期待你的参与! 关于ShardingSphereApache ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈,它由 JDBC、Proxy 和 Sidecar(规划中)这 3 款相互独立,却又能够混合部署配合使用的产品组成。 它们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如 Java 同构、异构语言、云原生等各种多样化的应用场景。ShardingSphere 已于2020年4月16日成为 Apache 软件基金会的顶级项目。 ...

June 17, 2020 · 1 min · jiezi

面试官小伙子说说你对分布式系统原理的看法吧

1 概念1.1 模型1.2 副本1.3 衡量分布式系统的指标2 分布式系统原理2.1 数据分布方式2.2 基本副本协议2.3 Lease 机制2.4 Quorum 机制2.5 日志技术2.6 两阶段提交协议2.7 MVCC2.8 Paxos协议2.9 CAP1 概念1.1 模型节点在具体的工程项目中,一个节点往往是一个操作系统上的进程。在本文的模型中,认为节点是一个完整的、不可分的整体,如果某个程序进程实际上由若干相对独立部分构成,则在模型中可以将一个进程划分为多个节点。 异常机器宕机:机器宕机是最常见的异常之一。在大型集群中每日宕机发生的概率为千分之一左右,在实践中,一台宕机的机器恢复的时间通常认为是24 小时,一般需要人工介入重启机器。网络异常:消息丢失,两片节点之间彼此完全无法通信,即出现了“网络分化”;消息乱序,有一定的概率不是按照发送时的顺序依次到达目的节点,考虑使用序列号等机制处理网络消息的乱序问题,使得无效的、过期的网络消息不影响系统的正确性;数据错误;不可靠的TCP,TCP 协议为应用层提供了可靠的、面向连接的传输服务,但在分布式系统的协议设计中不能认为所有网络通信都基于TCP 协议则通信就是可靠的。TCP协议只能保证同一个TCP 链接内的网络消息不乱序,TCP 链接之间的网络消息顺序则无法保证。分布式三态:如果某个节点向另一个节点发起RPC(Remote procedure call)调用,即某个节点A 向另一个节点B 发送一个消息,节点B 根据收到的消息内容完成某些操作,并将操作的结果通过另一个消息返回给节点A,那么这个RPC 执行的结果有三种状态:“成功”、“失败”、“超时(未知)”,称之为分布式系统的三态。存储数据丢失:对于有状态节点来说,数据丢失意味着状态丢失,通常只能从其他节点读取、恢复存储的状态。异常处理原则:被大量工程实践所检验过的异常处理黄金原则是:任何在设计阶段考虑到的异常情况一定会在系统实际运行中发生,但在系统实际运行遇到的异常却很有可能在设计时未能考虑,所以,除非需求指标允许,在系统设计时不能放过任何异常情况。1.2 副本副本(replica/copy)指在分布式系统中为数据或服务提供的冗余。对于数据副本指在不同的节点上持久化同一份数据,当出现某一个节点的存储的数据丢失时,可以从副本上读到数据。数据副本是分布式系统解决数据丢失异常的唯一手段。另一类副本是服务副本,指数个节点提供某种相同的服务,这种服务一般并不依赖于节点的本地存储,其所需数据一般来自其他节点。 副本协议是贯穿整个分布式系统的理论核心。 副本一致性分布式系统通过副本控制协议,使得从系统外部读取系统内部各个副本的数据在一定的约束条件下相同,称之为副本一致性(consistency)。副本一致性是针对分布式系统而言的,不是针对某一个副本而言。 强一致性(strong consistency):任何时刻任何用户或节点都可以读到最近一次成功更新的副本数据。强一致性是程度最高的一致性要求,也是实践中最难以实现的一致性。单调一致性(monotonic consistency):任何时刻,任何用户一旦读到某个数据在某次更新后的值,这个用户不会再读到比这个值更旧的值。单调一致性是弱于强一致性却非常实用的一种一致性级别。因为通常来说,用户只关心从己方视角观察到的一致性,而不会关注其他用户的一致性情况。会话一致性(session consistency):任何用户在某一次会话内一旦读到某个数据在某次更新后的值,这个用户在这次会话过程中不会再读到比这个值更旧的值。会话一致性通过引入会话的概念,在单调一致性的基础上进一步放松约束,会话一致性只保证单个用户单次会话内数据的单调修改,对于不同用户间的一致性和同一用户不同会话间的一致性没有保障。实践中有许多机制正好对应会话的概念,例如php 中的session 概念。最终一致性(eventual consistency):最终一致性要求一旦更新成功,各个副本上的数据最终将达 到完全一致的状态,但达到完全一致状态所需要的时间不能保障。对于最终一致性系统而言,一个用户只要始终读取某一个副本的数据,则可以实现类似单调一致性的效果,但一旦用户更换读取的副本,则无法保障任何一致性。弱一致性(week consistency):一旦某个更新成功,用户无法在一个确定时间内读到这次更新的值,且即使在某个副本上读到了新的值,也不能保证在其他副本上可以读到新的值。弱一致性系统一般很难在实际中使用,使用弱一致性系统需要应用方做更多的工作从而使得系统可用。1.3 衡量分布式系统的指标性能:系统的吞吐能力,指系统在某一时间可以处理的数据总量,通常可以用系统每秒处理的总的数据量来衡量;系统的响应延迟,指系统完成某一功能需要使用的时间;系统的并发能力,指系统可以同时完成某一功能的能力,通常也用QPS(query per second)来衡量。上述三个性能指标往往会相互制约,追求高吞吐的系统,往往很难做到低延迟;系统平均响应时间较长时,也很难提高QPS。可用性:系统的可用性(availability)指系统在面对各种异常时可以正确提供服务的能力。系统的可用性可以用系统停服务的时间与正常服务的时间的比例来衡量,也可以用某功能的失败次数与成功次数的比例来衡量。可用性是分布式的重要指标,衡量了系统的鲁棒性,是系统容错能力的体现。可扩展性:系统的可扩展性(scalability)指分布式系统通过扩展集群机器规模提高系统性能(吞吐、延迟、并发)、存储容量、计算能力的特性。好的分布式系统总在追求“线性扩展性”,也就是使得系统的某一指标可以随着集群中的机器数量线性增长。一致性:分布式系统为了提高可用性,总是不可避免的使用副本的机制,从而引发副本一致性的问题。越是强的一致的性模型,对于用户使用来说使用起来越简单。2 分布式系统原理2.1 数据分布方式所谓分布式系统顾名思义就是利用多台计算机协同解决单台计算机所不能解决的计算、存储等问题。单机系统与分布式系统的最大的区别在于问题的规模,即计算、存储的数据量的区别。将一个单机问题使用分布式解决,首先要解决的就是如何将问题拆解为可以使用多机分布式解决,使得分布式系统中的每台机器负责原问题的一个子集。由于无论是计算还是存储,其问题输入对象都是数据,所以如何拆解分布式系统的输入数据成为分布式系统的基本问题。 哈希方式 哈希分布数据的缺点同样明显,突出表现为可扩展性不高,一旦集群规模需要扩展,则几乎所有的数据需要被迁移并重新分布。工程中,扩展哈希分布数据的系统时,往往使得集群规模成倍扩展,按照数据重新计算哈希,这样原本一台机器上的数据只需迁移一半到另一台对应的机器上即可完成扩展。 针对哈希方式扩展性差的问题,一种思路是不再简单的将哈希值与机器做除法取模映射,而是将对应关系作为元数据由专门的元数据服务器管理.同时,哈希值取模个数往往大于机器个数,这样同一台机器上需要负责多个哈希取模的余数。但需要以较复杂的机制维护大量的元数据。哈希分布数据的另一个缺点是,一旦某数据特征值的数据严重不均,容易出现“数据倾斜”(data skew)问题。 哈希分布数据的另一个缺点是,一旦某数据特征值的数据严重不均,容易出现“数据倾斜”(data skew)问题 按数据范围分布按数据范围分布是另一个常见的数据分布式,将数据按特征值的值域范围划分为不同的区间,使得集群中每台(组)服务器处理不同区间的数据。 工程中,为了数据迁移等负载均衡操作的方便,往往利用动态划分区间的技术,使得每个区间中服务的数据量尽量的一样多。当某个区间的数据量较大时,通过将区间“分裂”的方式拆分为两个区间,使得每个数据区间中的数据量都尽量维持在一个较为固定的阈值之下。 一般的,往往需要使用专门的服务器在内存中维护数据分布信息,称这种数据的分布信息为一种元信息。甚至对于大规模的集群,由于元信息的规模非常庞大,单台 计算机无法独立维护,需要使用多台机器作为元信息服务器。 按数据量分布数据量分布数据与具体的数据特征无关,而是将数据视为一个顺序增长的文件,并将这个文件按照某一较为固定的大小划分为若干数据块(chunk),不同的数据块分布到不同的服务器上。与按数据范围分布数据的方式类似的是,按数据量分布数据也需要记录数据块的具体分布情况,并将该分布信息作为元数据使用元数据服务器管理。 由于与具体的数据内容无关,按数据量分布数据的方式一般没有数据倾斜的问题,数据总是被均匀切分并分布到集群中。当集群需要重新负载均衡时,只需通过迁移数据块即可完成。集群扩容也没有太大的限制,只需将部分数据库迁移到新加入的机器上即可以完成扩容。按数据量划分数据的缺点是需要管理较为复杂的元信息,与按范围分布数据的方式类似,当集群规模较大时,元信息的数据量也变得很大,高效的管理元信息成为新的课题。 一致性哈希一致性哈希(consistent hashing)是另一个种在工程中使用较为广泛的数据分布方式。一致性哈希最初在P2P 网络中作为分布式哈希表(DHT)的常用数据分布算法。一致性哈希的基本方式是使用一个哈希函数计算数据或数据特征的哈希值,令该哈希函数的输出值域为一个封闭的环,即哈希函数输出的最大值是最小值的前序。将节点随机分布到这个环上,每个节点负责处理从自己开始顺时针至下一个节点的全部哈希值域上的数据。 ...

June 7, 2020 · 5 min · jiezi

如果要面试zookeeper把这篇文章看完就够了

Zookeeper概述zookeeper高容错数据一致性协议(CP)的分布式小文件系统,提供类似于文件系统的目录方式的数据存储。 全局数据一致性:每个server保存一份相同的数据副本,client无论连接到哪个server展示的数据都是一致的。可靠性:一旦事务成功提交,就会被保留下来。有序性:客户端发起的事务请求,在也会顺序的应用在Zookeeper中。数据更新原子性:一次数据更新要么成功要么失败,不存在中间状态。实时性:保证客户端在一个间隔时间范围内获取服务的更新消息或服务器失效信息。zookeeper单机数据模型:每一个节点都是znode(兼具文件和目录两种特点),每一个znode都具有原子操作。znode存储的数据大小有限制(默认1MB),通过绝对路径引用。znode分为3个部分: stat:状态信息,描述znode的版本和权限等信息。data:与该znode关联的数据。children:该znode下的子节点。znode节点类型临时节点:该节点的生命周期依赖于创建它的会话,一旦会话结束临时节点就会被删除。临时节点不允许拥有子节点。永久节点:只能通过客户端显示执行删除操作。临时序列化节点。永久序列化节点。znode序列化:znode的名字后面追加一个不断增加的序列号。每一个序列号对父节点来说是唯一的,可以记录每一个子节点的先后顺序。znode节点属性zookeeper的节点属性包括节点数据,状态,权限等信息。 属性说明cZxidznode创建节点的事务ID,Zookeeper中每个变化都会产生一个全局唯一的zxid。通过它可确定更新操作的先后顺序ctime创建时间mZxid修改节点的事务IDmtime最后修改时间pZxid子节点变更的事务ID,添加子节点或删除子节点就会影响子节点列表,但是修改子节点的数据内容则不影响该IDcversion子节点版本号,子节点每次修改版本号加1dataversion数据版本号,数据每次修改该版本号加1 ,多个客户端对同一个znode进行更新操作时,因为数据版本号,才能保证更新操作的先后顺序性。例:客户端A正在对znode节点做更新操作,此时如果另一个客户端B同时更新了这个znode,则A的版本号已经过期,那么A调用setData不会成功。aclversion权限版本号,权限每次修改该版本号加1dataLength该节点的数据长度numChildern该节点拥有的子节点的数量 znode ACL权限控制ACL权限控制使用 schema:id:permission来标识。示例:setAcl /test2 ip:128.0.0.1:crwda SchemaSchema枚举值说明world使用用户名设置,id为一个用户,但这个id只有一个值:anyone,代表所有人ip使用IP地址进行认证,ID对应为一个IP地址或IP段auth使用已添加认证的用户进行认证,以通过addauth digest user:pwd 来添加当前上下文中的授权用户digest使用“用户名:密码”方式认证permission权限ACL简写描述CREATEc可以创建子节点DELETEd可以删除子节点(仅下一级节点)READr可以读取节点数据及显示子节点列表WRITEw可以设置节点数据ADMINa可以设置节点访问控制列表权限权限相关命令命令使用方式描述getAclgetAcl <path>读取ACL权限setAclsetAcl <path> <acl>设置ACL权限addauthaddauth <scheme> <auth>添加认证用户zookeeper:提供了分布式发布/订阅功能,能让多个订阅者同时监听某一个主题对象,通过watche机制来实现。 zookeeper watch机制一个Watch事件是一个一次性的触发器,当被设置了Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端,以便通知它们。 父节点的创建,修改,删除都会触发Watcher事件。子节点的创建,删除会触发Watcher事件。监听器watch特性特性说明一次性Watcher是一次性的,一旦被触发就会移除,再次使用时需要重新注册。监听的客户端很多情况下,每次变动都要通知到所有的客户端,给网络和服务器造成很大压力。一次性可以减轻这种压力客户端顺序回调客户端 Watcher 回调的过程是一个串行同步的过程。轻量Watcher 通知非常简单,只会告诉客户端发生了事件,而不会说明事件的具体内容。监听器原理首先要有一个main()线程,在main线程中创建Zookeeper客户端,这时就会创建两个线程,一个负责网络连接通信(connet),一个负责监听(listener)。通过connect线程将注册的监听事件发送给Zookeeper服务端。在Zookeeper服务端的注册监听器列表中将注册的监听事件添加到列表中。Zookeeper监听到有数据或路径变化,就会将这个消息发送给listener线程。 listener线程内部调用了process()方法来触发Watcher。zookeeper会话管理客户端会不时地向所连接的ZkServer发送ping消息,ZkServer接收到ping消息,或者任何其它消息的时候,都会将客户端的session_id,session_timeout记录在一个map中。Leader ZkServer会周期性地向所有的follower发送心跳消息,follower接收到ping消息后,会将记录session信息的map作为返回消息,返回给leader,同时清空follower本地的map。 Leader使用这些信息重新计算客户端的超时时间。一旦在session timout的时间到,leader即没有从其它follower上收集到客户端的session信息,也没有直接接收到该客户端的任何请求,那么该客户端的session就会被关闭。zookeeper数据模型zk维护的数据主要有:客户端的会话(session)状态及数据节(dataNode)信息。zk在内存中构造了个DataTree的数据结构,维护着path到dataNode的映射以及dataNode间的树状层级关系。为了提高读取性能,集群中每个服务节点都是将数据全量存储在内存中。所以,zk最适于读多写少且轻量级数据的应用场景。3.数据仅存储在内存是很不安全的,zk采用事务日志文件及快照文件的方案来落盘数据,保障数据在不丢失的情况下能快速恢复。 Zookeeper集群集群角色Leader:集群工作的核心,事务请求的唯一调度和处理者,保证事务处理的顺序性。对于有写操作的请求,需统一转发给Leader处理。Leader需决定编号执行操作。Follower:处理客户端非事务请求,转发事务请求转发给Leader,参与Leader选举。Observer观察者:进行非事务请求的独立处理,对于事务请求,则转发给Leader服务器进行处理.不参与投票。事务事务:ZooKeeper中,能改变ZooKeeper服务器状态的操作称为事务操作。一般包括数据节点创建与删除、数据内容更新和客户端会话创建与失效等操作。对应每一个事务请求,ZooKeeper 都会为其分配一个全局唯一的事务ID,用 ZXID 表示,通常是一个64位的数字。每一个ZXID对应一次更新操作,从这些ZXID中可以间接地识别出ZooKeeper处理这些事务操作请求的全局顺序。事务日志:所有事务操作都是需要记录到日志文件中的,可通过 dataLogDir配置文件目录,文件是以写入的第一条事务zxid为后缀,方便后续的定位查找。zk会采取“磁盘空间预分配”的策略,来避免磁盘Seek频率,提升zk服务器对事务请求的影响能力。默认设置下,每次事务日志写入操作都会实时刷入磁盘,也可以设置成非实时(写到内存文件流,定时批量写入磁盘),但那样断电时会带来丢失数据的风险。事务日志记录的次数达到一定数量后,就会将内存数据库序列化一次,使其持久化保存到磁盘上,序列化后的文件称为"快照文件"。有了事务日志和快照,就可以让任意节点恢复到任意时间点 数据快照:数据快照是zk数据存储中另一个非常核心的运行机制。数据快照用来记录zk服务器上某一时刻的全量内存数据内容,并将其写入到指定的磁盘文件中,可通过dataDir配置文件目录。可配置参数snapCount,设置两次快照之间的事务操作个数,zk节点记录完事务日志时,会统计判断是否需要做数据快照(距离上次快照,事务操作次数等于[snapCount/2~snapCount] 中的某个值时,会触发快照生成操作,随机值是为了避免所有节点同时生成快照,导致集群影响缓慢)。过半原则1. 过半:所谓“过半”是指大于集群机器数量的一半,即大于或等于(n/2+1),此处的“集群机器数量”不包括observer角色节点。leader广播一个事务消息后,当收到半数以上的ack信息时,就认为集群中所有节点都收到了消息,然后leader就不需要再等待剩余节点的ack,直接广播commit消息,提交事务。半数选举导致zookeeper通常由2n+1台server组成。 zookeeper的两阶段提交:zookeeper中,客户端会随机连接到 zookeeper 集群中的一个节点,如果是读请求,就直接从当前节点中读取数据。如果是写请求,那么请求会被转发给 leader 提交事务,然后 leader 会广播事务,只要有超过半数节点写入成功,那么写请求就会被提交。 Leader将写请求转化为一个Proposal(提议),将其分发给集群中的所有Follower节点。Leader等待所有的Follower节点的反馈,一旦超过半数Follower进行了正确的反馈,那么Leader就会再次向所有的Follower节点发送Commit消息,要求各个Follower节点对前面的一个Proposal节点进行提交。leader节点将最新数据同步给Observer节点。返回给客户端执行的结果。ZAB协议ZooKeeper 能够保证数据一致性主要依赖于 ZAB 协议的消息广播,崩溃恢复和数据同步三个过程。 消息广播一个事务请求进来之后,Leader节点会将写请求包装成提议(Proposal)事务,并添加一个全局唯一的 64 位递增事务 ID,Zxid。Leader 节点向集群中其他节点广播Proposal事务,Leader 节点和 Follower 节点是解耦的,通信都会经过一个 FIFO 的消息队列,Leader 会为每一个 Follower 节点分配一个单独的 FIFO 队列,然后把 Proposal 发送到队列中。Follower 节点收到对应的Proposal之后会把它持久到磁盘上,当完全写入之后,发一个ACK给Leader。当Leader节点收到超过半数Follower节点的ACK之后会提交本地机器上的事务,同时开始广播commit,Follower节点收到 commit 之后,完成各自的事务提交。消息广播类似一个分布式事务的两阶段提交模式。在这种模式下,无法处理因Leader在发起事务请求后节点宕机带来的数据不一致问题。因此ZAB协议引入了崩溃恢复机制。 ...

June 7, 2020 · 1 min · jiezi

首次公开京东数科强一致高性能分布式事务中间件-JDTX

在分布式数据库、云原生数据库、NewSQL 等名词在数据库领域层出不穷的当今,变革——在这个相对稳定的领域已愈加不可避免。相比于完全革新,渐进式增强的方案在拥有厚重沉淀的行业则更受青睐。 同所有分布式领域的解决方案相同,分而治之的透明化数据分片方案,是新一代数据库解决海量数据的核心理念。水平拆分使得分布式事务的重要性,较之垂直拆分的业务系统进一步提升。另外,弹性扩(缩)容、HTAP 等概念也是新一代数据库的关注重点。京东数科开源的 Apache ShardingSphere 在数据分片方面已逐渐成熟,在此场景之上开发的分布式事务中间件 JDTX 与之共同组成了分布式数据库的内核拼图。 JDTX 是由京东数科的数据研发团队倾力打造的分布式事务中间件。本次分享是 JDTX 首次公开出现在大众视野面前,分享内容涵盖 JDTX 的核心设计理念及相关的技术实现难点,希望能为打造分布式事务解决方案的团队提供一些思路。 背景数据库事务需要满足 ACID(原子性、一致性、隔离性、持久性)4 个特性。 在单一数据节点中,事务仅限于对单一数据库资源的访问控制,称之为本地事务。几乎所有的成熟的关系型数据库都提供了对本地事务的原生支持。但是在基于微服务的分布式应用环境下,越来越多的应用场景要求对多个服务的访问及其相对应的多个数据库资源能纳入到同一个事务当中,分布式事务应运而生。 关系型数据库虽然对本地事务提供了完美的 ACID 原生支持。但在分布式的场景下,它却成为系统性能的桎梏。如何让数据库在分布式场景下满足 ACID 的特性或找寻相应的替代方案,是分布式事务的重点工作。 本地事务在不开启任何分布式事务管理器的前提下,让每个数据节点各自管理自己的事务。它们之间没有协调以及通信的能力,也并不互相知晓其他数据节点事务的成功与否。本地事务在性能方面无任何损耗,但在强一致性以及最终一致性方面则力不从心。 两阶段提交XA 协议最早的分布式事务模型是由 X/Open 国际联盟提出的 X/Open Distributed Transaction Processing(DTP)模型,简称 XA 协议。 基于 XA 协议实现的分布式事务对业务侵入很小。它最大的优势就是对使用方透明,用户可以像使用本地事务一样使用基于 XA 协议的分布式事务。XA 协议能够严格保障事务 ACID 特性。 严格保障事务 ACID 特性是一把双刃剑。事务执行在过程中需要将所需资源全部锁定,它更加适用于执行时间确定的短事务。对于长事务来说,整个事务进行期间对数据的独占,将导致对热点数据依赖的业务系统并发性能衰退明显。因此,在高并发的性能至上场景中,基于 XA 协议两阶段提交类型的分布式事务并不是最佳选择。 柔性事务如果将实现了 ACID 的事务要素的事务称为刚性事务的话,那么基于 BASE 事务要素的事务则称为柔性事务。BASE 是基本可用、柔性状态和最终一致性这 3 个要素的缩写。 在 ACID 事务中对一致性和隔离性的要求很高,在事务执行过程中,必须将所有的资源占用。柔性事务的理念则是通过业务逻辑将互斥锁操作从资源层面上移至业务层面。通过放宽对强一致性和隔离性的要求,只要求当整个事务最终结束的时候,数据是一致的。而在事务执行期间,任何读取操作得到的数据都有可能被改变。这种弱一致性的设计可以用来换取系统吞吐量的提升。Saga 和 TCC 都是典型的柔性事务实现方案。 结论基于 ACID 的两阶段事务和基于 BASE 的最终一致性事务都不是银弹,可通过下表详细对比它们之间的区别。 ...

June 3, 2020 · 3 min · jiezi

刚柔并济的开源分布式事务解决方案

作者张亮,京东数科数据研发负责人,Apache ShardingSphere发起人 & PPMC 热爱开源,目前主导开源项目ShardingSphere(原名Sharding-JDBC)和Elastic-Job。擅长以java为主分布式架构以及以Kubernetes和Mesos为主的云平台方向,推崇优雅代码,对如何写出具有展现力的代码有较多研究。 目前主要精力投入在将ShardingSphere打造为业界一流的金融级数据解决方案之上。ShardingSphere已经进入Apache孵化器,是京东集团首个进入Apache基金会的开源项目,也是Apache基金会首个分布式数据库中间件。 姜宁,华为开源能力中心技术专家,Apache ServiceComb项目负责人。前红帽软件首席软件工程师,在企业级开源中间件开发方面有十余年经验,有丰富的Java开发和使用经验,函数式编程爱好者。从2006年开始一直从事Apache开源中间件项目的开发工作,先后参与Apache CXF,Apache Camel,以及Apache ServiceMix的开发。对微服务架构,WebServices,Enterprise Integration Pattern,SOA, OSGi 均有比较深入的研究。 博客地址:https://willemjiang.github.io/ 冯征,红帽软件工程师。2009年加入红帽软件公司,主要从事事务管理器方面的工作,做为核心开发人员参与了Narayan和Blacktie项目,在与多个应用服务器(Wildfly, Karaf, Tomcat)和框架(Common DBCP, Spring Boot)的事务处理集成方面有过贡献。从2017年开始参与了Apache ServiceComb项目,目前是PMC成员之一。对于分布式事务处理以及微服务环境中的事务处理,有过深入的研究。 导读相比于数据分片方案的逐渐成熟,集性能、透明化、自动化、强一致、并能适用于各种应用场景于一体的分布式事务解决方案则显得凤毛麟角。基于两(三)阶段提交的分布式事务的性能瓶颈以及柔性事务的业务改造问题,使得分布式事务至今依然是令架构师们头疼的问题。 Apache ShardingSphere(Incubating)不失时机的在2019年初,提供了一个刚柔并济的一体化分布式事务解决方案。如果您的应用系统正在受到这方面的困扰,不妨倒上一杯咖啡,花十分钟阅读此文,说不定会有些收获呢? 背景数据库事务需要满足ACID(原子性、一致性、隔离性、持久性)4个特性。 原子性(Atomicity)指事务作为整体来执行,要么全部执行,要么全不执行。一致性(Consistency)指事务应确保数据从一个一致的状态转变为另一个一致的状态。隔离性(Isolation)指多个事务并发执行时,一个事务的执行不应影响其他事务的执行。持久性(Durability)指已提交的事务修改数据会被持久保存。在单一数据节点中,事务仅限于对单一数据库资源的访问控制,称之为本地事务。几乎所有的成熟的关系型数据库都提供了对本地事务的原生支持。 但是在基于微服务的分布式应用环境下,越来越多的应用场景要求对多个服务的访问及其相对应的多个数据库资源能纳入到同一个事务当中,分布式事务应运而生。 关系型数据库虽然对本地事务提供了完美的ACID原生支持。 但在分布式的场景下,它却成为系统性能的桎梏。如何让数据库在分布式场景下满足ACID的特性或找寻相应的替代方案,是分布式事务的重点工作。 本地事务在不开启任何分布式事务管理器的前提下,让每个数据节点各自管理自己的事务。 它们之间没有协调以及通信的能力,也并不互相知晓其他数据节点事务的成功与否。 本地事务在性能方面无任何损耗,但在强一致性以及最终一致性方面则力不从心。 两阶段提交XA协议最早的分布式事务模型是由X/Open国际联盟提出的X/Open Distributed Transaction Processing(DTP)模型,简称XA协议。 基于XA协议实现的分布式事务对业务侵入很小。 它最大的优势就是对使用方透明,用户可以像使用本地事务一样使用基于XA协议的分布式事务。 XA协议能够严格保障事务ACID特性。 严格保障事务ACID特性是一把双刃剑。 事务执行在过程中需要将所需资源全部锁定,它更加适用于执行时间确定的短事务。 对于长事务来说,整个事务进行期间对数据的独占,将导致对热点数据依赖的业务系统并发性能衰退明显。 因此,在高并发的性能至上场景中,基于XA协议两阶段提交类型的分布式事务并不是最佳选择。 柔性事务如果将实现了ACID的事务要素的事务称为刚性事务的话,那么基于BASE事务要素的事务则称为柔性事务。 BASE是基本可用、柔性状态和最终一致性这3个要素的缩写。 基本可用(Basically Available)保证分布式事务参与方不一定同时在线。柔性状态(Soft state)则允许系统状态更新有一定的延时,这个延时对客户来说不一定能够察觉。最终一致性(Eventually consistent)通常是通过消息传递的方式保证系统的最终一致性。在ACID事务中对一致性和隔离性的要求很高,在事务执行过程中,必须将所有的资源占用。 柔性事务的理念则是通过业务逻辑将互斥锁操作从资源层面上移至业务层面。通过放宽对强一致性和隔离性的要求,只要求当整个事务最终结束的时候,数据是一致的。而在事务执行期间,任何读取操作得到的数据都有可能被改变。这种弱一致性的设计可以用来换取系统吞吐量的提升。 Saga是典型的柔性事务管理器。Sagas这个概念来源于三十多年前的一篇数据库论文[http://www.cs.cornell.edu/and...] ,一个Saga事务是一个有多个短时事务组成的长时的事务。 在分布式事务场景下,我们把一个Saga分布式事务看做是一个由多个本地事务组成的事务,每个本地事务都有一个与之对应的补偿事务。在Saga事务的执行过程中,如果某一步执行出现异常,Saga事务会被终止,同时会调用对应的补偿事务完成相关的恢复操作,这样保证Saga相关的本地事务要么都是执行成功,要么通过补偿恢复成为事务执行之前的状态。 TCC(Try-Cancel/Confirm实现)是另一种柔性事务的协调实现。TCC借助两阶段提交协议提供了一种比较完美的恢复方式。在TCC方式下,cancel补偿显然是在第二阶段需要执行业务逻辑来取消第一阶段产生的后果。Try是在第一阶段执行相关的业务操作,完成相关业务资源的占用,例如预先分配票务资源,或者检查并刷新用户账户信用额度。 在取消阶段释放相关的业务资源,例如释放预先分配的票务资源或者恢复之前占用的用户信用额度。 那我们为什么还要加入确认操作呢?这需要从业务资源的使用生命周期来入手。在try过程中,我们只是占用的业务资源,相关的执行操作只是出于待定状态,只有在确认操作执行完毕之后,业务资源才能真正被确认。 基于ACID的强一致性事务和基于BASE的最终一致性事务都不是银弹,只有在最适合的场景中才能发挥它们的最大长处。可通过下表详细对比它们之间的区别,以帮助开发者进行技术选型。 挑战由于应用的场景不同,需要开发者能够合理的在性能与功能之间权衡各种分布式事务。 两阶段提交与柔性事务的API和功能并不完全相同,在它们之间并不能做到自由的透明切换。在开发决策阶段,就不得不在两阶段提交的事务和柔性事务之间抉择,使得设计和开发成本被大幅增加。 基于XA的两阶段提交事务使用相对简单,但是无法很好的应对互联网的高并发或复杂系统的长事务场景;柔性事务则需要开发者对应用进行改造,接入成本非常高,并且需要开发者自行实现资源占用和反向补偿。 ShardingSphere的分布式事务整合现有的成熟事务方案,为本地事务、两阶段提交和柔性事务提供统一的分布式事务接口,并弥补当前方案的不足,提供一站式的分布式事务解决方案是Apache ShardingSphere(Incubating)分布式事务模块的主要设计目标。该模块的名称是sharding-transaction。可以用刚柔并济、自动化和透明化这3个关键词来概括sharding-transaction模块的设计理念和功能呈现。 1.刚柔并济 ...

June 3, 2020 · 1 min · jiezi

技术分享-ZooKeeper-快速部署-DBLE-集群环境

作者:叶晓莉本文需读者掌握 ZooKeeper 和 DBLE 基本原理。想要学习 DBLE 相关知识的小伙伴可以查看文章末尾的 DBLE 公开课。ZooKeeper - 分布式协调技术 / DBLE - 分布式数据库中间件,使用二者搭建集群,能够为 MySQL 集群提供稳定的分布式协调环境,进一步实现服务高可用。说明:ZooKeeper(以下简称 ZK) 可以单例管理 DBLE 集群,此文我们使用 ZK 的集群模式(至少3 台)管理 DBLE 集群,接下来介绍具体步骤: 环境架构目的部署依赖安装 DBLE (3台)部署 ZooKeeper 集群部署 DBLE 集群简单测试其他环境架构 环境版本信息:系统 | Linux :CentOS Linux release 7.5.1804 (Core)中间件 | DBLE: 2.19.05.0数据库 | MySQL :5.7.13协调器 | ZooKeeper: 3.4.12 目的利用 ZK 集群实现 DBLE 集群中各节点的状态和元数据的一致性,当集群中有节点故障时,可使用其他节点继续提供服务。通过实验,验证此架构的可行性。 部署依赖(重要)安装 JDK 版本 1.8 或以上,确保 JAVA_HOME 配置正确启动 MySQL 实例,创建好用户,并对该用户授权远程登陆权限安装 DBLE (3台)下载安装包wget https://github.com/actiontech/dble/releases/download/2.19.05.0%2Ftag/actiontech-dble-2.19.05.0.tar.gz解压安装包tar zxvf actiontech-dble-2.19.05.0.tar.gz配置 DBLE 后端节点,修改 dble/conf/ 目录下 schema.xml 文件,配置 writeHost, readHost 为自己的 MySQL 实例,如下:<writeHost host="hostM1" url="ip1:3306" user="your_user" password="your_psw"> <readHost host="hostS1" url="ip2:3306" user="your_user" password="your_psw"/></writeHost>部署 ZooKeeper 集群下载并解压安装包,官网链接:http://archive.apache.org/dis... ...

June 2, 2020 · 2 min · jiezi

Spark-Relational-Cache实现亚秒级响应的交互式分析

本场视频链接:https://developer.aliyun.com/live/1548?spm=a2c6h.12873581.0.0.71671566Xloy3Z&groupCode=apachespark 本场PPT资料:https://www.slidestalk.com/AliSpark/SparkRelationalCache2019_57927 本次分享主要分为以下四个方面: 项目介绍技术分析如何使用性能分析一、项目介绍项目背景阿里云EMR是一个开源大数据解决方案,目前EMR上面已经集成了很多开源组件,并且组件数量也在不断的增加中。EMR下层可以访问各种各样的存储,比如对象存储OSS、集群内部自建的HDFS以及流式数据等。用户可以利用EMR处理海量数据和进行快速分析,也能够支持用户在上面做机器学习以及数据清洗等工作。EMR希望能够支撑非常大的业务数据量,同时也希望能够在数据量不断增长的时候,能够通过集群扩容实现快速数据分析。 云上Adhoc数据分析痛点在云上做Adhoc数据分析的时候,很难实现随着数据量的增长使得查询的延迟不会大幅度增加。虽然目前各种引擎不断出现,并且某些引擎在一些场景下运行很快,但是数据量变大之后,查询响应速度难免有所下降,因此希望在比较统一的平台之上获得较好的性能。与此同时,阿里云也希望能够提供云原生的解决方案。Spark是目前工业界使用较多的计算引擎,应用非常广泛,但是在处理Adhoc上还是存在很多不足之处,因此阿里云在Spark上做了大量优化,帮助用户满足Adhoc查询的需求。因此就会涉及到缓存方案,虽然Spark中很早就有了缓存机制,但想要满足云上Adhoc场景却存在很多不足之处,因此阿里云会在Spark上做大量优化,帮助用户优化Adhoc查询速度。但是如果把数据放到内存中,将所有数据全部用作缓存可能也不足够,因此就催生出了Spark Relational Cache。 Spark Relational Cache用户的SQL请求过来之后,到了Spark上面,会需要比较长的时间在数据来源上进行处理,这里下层的存储包括集群的HDFS以及远端的JindoFS和阿里云OSS等。当有了Spark Relational Cache之后,查询过来之后会查询是否能够用到存储在Relational Cache中缓存的数据,如果不能用到则会转发到原生路径上,如果能用到则会用非常快的速度从缓存里面将数据读取出来并将结果返回给用户。因为Relational Cache构建在高效存储之上,通过用户的DDL将数据变成Relational Cache。 Spark Relational Cache特点Spark Relational Cache希望能够达到秒级响应或者亚秒级响应,能够在提交SQL之后很快地看到结果。并且也支持很大的数据量,将其存储在持久化的存储上面,同时通过一些匹配手段,增加了匹配的场景。此外,下层存储也使用了高效的存储格式,比如离线分析都会使用的列式存储,并且对于列式存储进行了大量优化。此外,Relational Cache也是用户透明的特性,用户上来进行查询不需要知道几个表之间的关系,这些都是已经有过缓存的,不需要根据已有的缓存重写Query,可以直接判断是否有可以使用的Relational Cache,对于一个厂商而言只需要几个管理员进行维护即可。Spark Relational Cache支持自动更新,用户不需要担心因为插入了新的数据就使得Cache过时导致查询到错误的数据,这里面为用户提供了一些设置的规则,帮助用户去进行更新。此外,Spark Relational Cache还在研发方面,比如智能推荐方面进行了大量探索,比如根据用户SQL的历史可以推荐用户基于怎样的关系去建立Relational Cache。 二、技术分析阿里云EMR具有很多核心技术,如数据预计算、查询自动匹配以及数据预组织。 数据预计算数据在很多情况下都有一个模型,雪花模型是传统数据库中非常常见的模型,阿里云EMR添加了Primary Key/Foreign Key的支持,允许用户通过Primary Key/Foreign Key明确表之间的关系,提高匹配成功率。在数据预计算方面,充分利用EMR Spark加强的计算能力。此外,还通过Data Cube数据立方来支持多维数据分析。 执行计划重写这部分首先通过数据预计算生成预计算的结果,并将结果存储在外部存储上,比如OSS、HDFS以及其他第三方存储中,对于Spark DataSource等数据格式都支持,对于DataLake等热门的存储格式后续也会添加支持。在传统数据库中有类似的优化方案,比如物化视图方式,而在Spark中使用这样的方式就不合适了,将逻辑匹配放在了Catalyst逻辑优化器内部来重写逻辑执行计划,判断Query能否通过Relational Cache实现查询,并基于Relational Cache实现进一步的Join或者组合。将简化后的逻辑计划转化成为物理计划在物理引擎上执行。依托EMR Spark其他的优化方向可以实现非常快速的执行结果,并且通过开关控制执行计划的重写。 自动查询匹配这里有一个简单的例子,将三个表简单地Join在一起,经过过滤条件获得最终的结果。当Query过来之后先判断Spark Relational Cache是否能够符合需求,进而实现对于预先计算好的结果进行过滤,进而得到最终想要的结果。 数据预组织如果将数十T的数据存在存储里面,那么从这个关系中获取最终的结果还需要不少的时间,因为需要启动不少的Task节点,而这些Task的调度也需要不少的开销,通过文件索引的方式将时间开销压缩到秒级水平,可以在执行时过滤所需要读取的文件总量,这样大大减少了任务的数量,这样执行的速度就会快很多。因为需要让全局索引变得更加有效,因此最好让数据是排过序的,如果对于结构化数据进行排序就会知道只是对于排列在第一位的Key有一个非常好的优化效果,对于排列在后面的Key比较困难,因此引入了ZOrder排序,使得列举出来的每个列都具有同等的效果。同时将数据存储在分区表里,使用GroupID作为分区列。 三、如何使用DDL对于简单的Query,可以指定自动更新的开关,并起一个名字方便后续管理。还可以规定数据Layout的形式,并最终通过SQL语句来描述关系,后续提供给用户WebUI一样的东西,方便用户管理Relational Cache。 数据更新Relational Cache的数据更新主要有两种策略,一种是On Commit,比如当依赖的数据发生更新的时候,可以将所有需要添加的数据都追加写进去。还有一种默认的On Demand形式,用户通过Refresh命令手动触发更新,可以在创建的时候指定,也可以在创建之后手工调整。Relational Cache增量的更新是基于分区实现的,后续会考虑集成一些更加智能的存储格式,来支持行级别的更新。 四、性能分析Cube构建阿里巴巴的EMR Spark对于1T数据的构建时间只需要1小时。 查询性能在查询性能方面,SSB平均查询耗时,无Cache时查询 时间按Scale成比例增加,Cache Cube后始终保持在亚秒级响应。 ...

November 5, 2019 · 1 min · jiezi

提效降本蚂蚁金服如何用融合计算改造在线机器学习

去年春节期间支付宝推出的集五福的活动可谓风靡一时,每张福卡背面都有刮刮卡,里面有来自蚂蚁金服、阿里巴巴以及合作伙伴的上百种权益。集五福的活动集中在春节前的几天,具有很强的时效性。所以如何实现权益和投放人群的自动匹配,解决系统的冷启动问题,优化转化率和提升用户体验,就成了一个在线学习的优化问题。 之前我们搭建一个这样的系统需要的模块非常繁杂。我们需要日志收集、数据聚合、样本的拼接和采样等流处理任务,需要对接模型训练、模型验证等机器学习模块,需要有把模型实时加载的模型服务,还需要其他的配套设施等等。众多模块的衔接极大地增加了系统的复杂性。 由于涉及的系统比较多,我们之前的系统遇到了比较多的问题。比如大促时为了保证高优链路的稳定性,上游某些数据处理的链路就会被降级了,但下游同学并不知情。另外一个很常见问题的是流批逻辑不一致,需要离线特征来训练基准模型,同时在线计算的特征来对模型进行实时更新。这两个模块一个在离线一个在线,曾经出现过处理逻辑的细微差别对业务效果造成了很大的影响。 总结下来,我们曾经遇到的坑可以归结为三类: SLA:整个链路的SLA会受到每个模块的SLA的影响,并随着模块的增多而放大,稳定性成为制约业务发展的重要因素。系统效率:模块之间的衔接多数是通过数据的落盘来进行,模块间的调度通过系统调度来实现,造成不必要的I/O、计算和网络开销。开发和运维的成本:各个模块风格迥异,开发模式、计算框架、甚至代码风格都不一致,开发和运维对接时需要花很多时间去熟悉系统,降低业务开放的效率。 一个理想的系统应该提供什么样的能力呢?可以从“稳快简”三个方面来讲:首先从数据来讲它需要保证数据和计算一致性,实现整个链路端到端的SLA,数据一致性和链路的稳定是保障业务稳定的基础。第二是我们需要去优化系统效率,我们希望把这十几个系统的衔接转换成系统内部的衔接,希望把这些作业调度转换成任务的调度,通过这样转化我们希望把计算与计算之间协同调度,从而提高系统效率和降低网络带宽使用的目的。一个融合的系统也可以对开发和运维提供非常大的便利,以前需要对接十几个系统,现在只要对接一个系统就可以了。以前我们在应急的时候需要回溯好几个业务来发现问题,现在融合在一起的系统调试也会更加容易。 在线机器学习最外层需要透出数据处理、模型训练、模型服务三个能力。这三个能力反映到对计算引擎框架上的需求是敏捷的调用机制、比较灵活的资源管控,以及比较完善的容错机制。上层的系统往往是通过不同编程语言来实现的,因此还需要有多语言接口。通过对底层需求的考量以及现在各框架的特点,最后我们选择了Ray为融合计算的底座。 Ray是由伯克利大学RiseLab实验室发起,蚂蚁金服共同参与的一个开源分布式计算框架,它提出的初衷在于让分布式系统的开发和应用能够更加简单。Ray作为计算框架可以帮我们实现上面“稳快简”三个目标。Ray作为计算框架具有敏捷的调度机制,用它可以一秒钟进行上百万次任务调度,它也可以根据计算对资源使用的需求实现异构调度。 在目前比较流行的分布式框架,都有三个比较基础的分布式原语,分布式任务、对象和服务。而我们常用的面向过程的编程语言中,也刚好有三个基本概念,函数、变量和类。这三个编程语基本概念刚好可以和分布式框架的原语对应起来。在Ray系统中,可以通过简单的改动,实现他们之间的转换。 左边是一个简单的例子,在这个函数前面需要加入一个“@remote”修饰符,就可以把一个函数转换成为分布式任务。任务通过“.remote”调用执行,返回值是一个变量,又可以参与到其他计算中。 右边是另一个例子,通过加“@remote”修饰符的方式可以把一个类转变成服务。类中的方法可以通过“.remote”调用变成一个分布式任务,和函数的使用非常相似。通过这种方式可以实现从单机程序到分布式任务的转变,把本地的任务调度到远程的机器上进行执行。 Ray上应该做怎么样的调度,衡量指标就是系统的效率问题,系统的效率很多时候取决于计算和数据的组织方式,比如说我们要计算Add(a,b),首先这个函数在本地会被自动注册并且提供给本地调度器。之后通过全剧调度器和第二个节点的本地调度器一起协同工作,把A备份到第二个节点执行Add这个操作。它还可以根据A和B的数据大小来进行进一步的调度和控制优化,A和B可以是简单数据类型,也可以是比较复杂的变量或者矩阵。 Ray上面提供多语言API接口。由于历史原因,在蚂蚁金服内部流式计算使用最多的语言是Java,而机器学习建模比较普遍使用的语言是Python。我先希望重用Java语言实现的流处理算子,同时保留Python进行机器学习建模的便捷性。Ray上面提供这样的多元化支持就非常方便我们做这个事情,用户在上层开发的时候可以可以方便地使用Java和Python分别进行流处理和机器学习模型的开发。 对于在线机器学习来说,它最核心需要解决的问题是要打通流计算和模型训练,那我们需要使用一个介质,这个介质能够比较方便的将两者衔接在一起。之前我们介绍Ray的几个特点,如提供多语言的接口、灵活的调动机制,这是因为这两个特点在Ray上可以比较方便做这个事情,Ray可以起到衔接的作用。数据处理的最后一个节点是流计算的输出,worker节点消费数据,是模型训练的输入。Ray就可以通过调度机制把这两个计算调度在一个节点上,实现数据共享从而实现两个模式的打通。通过这种方式不仅可以兼容流计算和机器学习,也可以将其他模式进行衔接。 计算中DAG概念最开始是为了解决多阶段分布式计算的效率而提出的,主要思想是通过调度减少计算时的IO。但是以前的计算DAG,在任务执行的时候它就已经确定了,但我们在机器学习的任务里面,很多时候我们会需要设计新的模型,或者对模型的超参进行调试,我们希望看到这些模型能被加载到链路上,看到业务效果的同时又不想线上已经有的模型的训练和服务被中断。在Ray系统内部,计算的过程中可以动态的生成另外一个节点,我们可以利用这个特性来增点和变,从而动态的对DAG进行局部修正。 在线系统和离线系统之间比较大的区别,在于如果一个离线系统里的任务挂了,一般来说可以通过重启机器的方式来解决,但对在线系统来说,出于时效性的考虑,我们不能简单的通过重启机群回溯数据的方式来解决。因此就需要有比较完善的容错机制。我们在模型训练的时候可以利用Ray的Actor来拉起模型训练的worker和server节点。如果worker或者server节点处于不健康状态,我们就可以利用Actor的容错特性通过血缘关系来对数据和计算进行恢复,从而实现容错的训练。 我们比较追求链路的时效性,模型能够尽快的拟合实时数据里。但是追求时效性的同时也要保证整个链路的稳定性,在敏捷和敏感之间达到平衡。我们从三个方面,系统稳定性、模型稳定性、机制稳定性来保障整个链路的稳定性。 系统稳定性,里面包括数据实时性和强一致性保障。模型稳定性,我们希望设计的模型能够拟合实时数据流,但同时要防止在线学习链路在各种不确定性因素下,如数据噪音,造成的效果退化。因此我们需要考虑在线特征和离线特征的组合,在模型设计上需要考虑到深层模型和浅层模型对数据的敏感性和噪音的容忍度。机制稳定性,赛马机制、快速回滚策略。除了之前用Ray来实现融合以及它带来的好处,我们也做了非常多的模块建设,TF融合、稳定性保障、样本回流、延迟样本修正、数据共享、流批一体、端到端强一致、模型增量导出。我们把这个平台上线了支付宝的几个场景,从下面的几个数字可以一探效果: 99.9%的全链路SLA业务指标有2%到40%的提升几十分钟模型延迟到4、5分钟,并且可以根据业务的需求进一步降低机器使用降低了60%我们从去年8月份开始建设,今年2月份开始上线第一个场景,在支付线财富线也都取得了不错的效果,接下来我们会推广到蚂蚁金服的其他业务线上。 基于融合计算机器学习,它是融合计算和机器学习这两种模式的有机组合,实现优化资源共享。我们通过这两方面的探索初步验证了融合计算的框架,融合计算是旨在数据共享来进行计算模式的兼容,融合的本质是开放,开放的基础是实现数据的互通,只要我们能够方便的实现各模式之间的数据互通,并且能够保障它们数字的实时性和端到端的一致性,就可以实现复杂场景里面需要多种模式进行组合的计算。模块的衔接就像搭乐高积木一样,基本的模块可能只有几种,但是搭建出复杂且多变的系统。 阿里云双11领亿元补贴,拼手气抽iPhone 11 Pro、卫衣等好礼,点此参与:http://t.cn/Ai1hLLJT 本文作者:缪克卢汉 阅读原文 本文为云栖社区原创内容,未经允许不得转载。

November 4, 2019 · 1 min · jiezi

MIT6824Lab2A

Lab2ALab2A的地址:https://pdos.csail.mit.edu/6.824/labs/lab-raft.html Lab2A需要我们做Leader Election部分。根据论文, 我们在Lab2A需要完成的内容是: 初始选举Candidate发布RequestVote rpcLeader发布AppendEntry rpc, 包括心跳server的状态转换(Follower, Candidate, Leader)基本上就是照着paper figure 2去做。 Lab2A的Hint(真多): 为raft.go添加需要的状态.定义log entry的结构.填写RequestVoteArgs和RequestVOteReply结构.修改Make()去创建后台goroutine, 必要时这个goroutine会发送RequestVoteRPC.实现RequestVote()RPC handler.定义AppendEntriesRPC结构和handler.处理election timeout和只vote一次.tester要求heartbeat发送速率不能超过10个/s,5s内选出新leader, 即使因为split vote导致多轮选举.所以要选择恰当的时间参数.因为tester的限制, 所以不能按照论文中的election timeout设置为150ms~300ms, 必须更大.但不能太大, 否则没办法达到5s内选出leader.切记, 在Go中, 大写字母开头的函数和结构(方法和成员)才能被外部访问!测试lab 2A有两个测试:TestInitialElection()和TestReElection(). 前者较为简单, 只需要完成初始选举并且各节点就term达成一致就可以通过. 构思经过不断重构, 最后的程序结构如下: MainBody(), 负责监听来自rf.Controller的信号并转换状态.Timer(), 计时器.Voter(), 负责发送RequestVote RPC和计算选举结果.APHandler(), 负责发送心跳,并且统计结果.四个通过channel来通信(自定义整型信号).先前的设计是MainBody() 监听来自若干个channel的信号,后来了解到channel一发多收, 信号只能被一个gorouine接受, 可能会有出乎意料的后果. 随后修改为MainBody主循环只监听rf.Controller, 然后向其他channel中发送信号(MPSC). BugsTestReElection(), 时不时fail, 预算笔者给TestReElection()添加一些输出, 将其分为多个阶段, 方便debug: 选出leader1# 1 ------------------------------ leader1 下线 选出新leader# 2 ------------------------------ leader1 上线, 变为follower# 3 ------------------------------ leader2 和 (leader2 + 1 ) % 3 下线 等待2s, 没有新leader产生# 4 ------------------------------ (leader2 + 1 ) % 3 产生 选出新leader# 5 ------------------------------ leader2 上线# 6 ------------------------------但是测试会是不是失败, 都是在第3-4阶段时失败。原因是:此时系统中应该不存在leader, 但是某节点仍声称是leader. ...

November 3, 2019 · 1 min · jiezi

Redis-Streams与Spark的完美结合

来源:Redislabs作者:Roshan Kumar翻译:Kevin  (公众号:中间件小哥) 最近,我有幸在 Spark +AI 峰会上发表了题目为“Redis + Structured Streaming:扩展您的持续应用的完美组合”的演讲。 我对这个主题的兴趣是由 Apache Spark 和 Redis 在过去几个月中引入的新功能引起的。根据我之前使用 Apache Spark 的经验,我很欣赏它在运行批处理时的优雅,并且它在 2.0 版本中引入 Structured Streaming 是在这个方向上的进一步发展。 与此同时,Redis 最近宣布了用于管理流数据的新数据结构,称为“Streams”。Redis Streams 提供了生产者和消费者之间的异步通信功能以及持久性、回顾性查询功能和类似于 Apache Kafka 的横向扩展选项。从本质上讲,Redis 通过Streams 提供了一个轻便、快速、易于管理的流数据库,使数据工程师们受益良多。 此外,开发 Spark-Redis 库是为了使 Redis 可以作为弹性分布式数据集(RDD)使用。因为现在有了 Structured Streaming 和 Redis Streams,我们决定扩展 Spark-Redis 库将 Redis Streams 集成为 Apache Spark Structured Streaming 的数据源。 在上个月的演讲中,我演示了如何在 Redis Streams 中收集用户活动数据并将其下载到 Apache Spark 进行实时数据分析。我开发了一个小型的适合移动设备的 Node.js 应用程序,在这个程序中人们可以点击投票给他们最喜欢的狗来进行有趣的比赛。 这是一场艰苦的战斗,有几个观众甚至是黑客很有创意地攻击了我的应用程序。他们使用“页面检查”选项更改了 HTML 按钮名称试图弄乱应用的显示。但最终他们失败了,因为 Redis Streams,Apache Spark,Spark-Redis 库和我的代码都足够的强大,可以有效地应对这些攻击。 ...

October 17, 2019 · 1 min · jiezi

程序员转型架构师推荐你读这几本书

从CRUD的程序员,到系统的架构师,进阶推荐读这几本书。架构师书单分为两部分,第一部分是关于系统架构的方法论,包括领域驱动设计,微服务,整洁架构,第二部分介绍各大互联网大公司是如何做系统架构落地实践。 程序员书单会做成一个系列,会推荐面试,职业规划,软技能等不同主题的书单,同时我会在博客和公众号「架构进化论」中,对书单中推荐的好书做解读,欢迎持续关注。 一、方法论《领域驱动设计》 这本书可以帮助我们理解用代码呈现真实世界的重要性,并且告诉我们如何更好地进行建模。 简而言之,这本书提供了深入的架构洞察力,并帮助你在不断变化的环境中创建强大的系统,最重要的是,Eric Evans用开发人员可以理解的语言来描述,非常难得。 书中给出了领域驱动设计的系统化方法,并将人们普遍接受的一些实践综合到一起,融入了作者的见解和经验,展现了一些可扩展的设计新实践、已验证过的技术以及便于应对复杂领域的软件项目开发的基本原则。 《架构整洁之道》 来自传奇人物Robert C. Martin的实用软件架构解决方案,作者还有另外一本非常经典的书《代码整洁之道》。 干净的架构对于每一个软件架构师、系统分析师、系统设计师和软件管理人员来说都是必不可少的,想要成为软件架构师,这本书一定是必不可少的。 《微服务设计》 这是一本了解现代分布式软件设计和体系结构的好书,特别是微服务,如Uber,Facebook,NetFlix等的实践。 本书全面介绍了微服务的建模、集成、测试、部署和监控,通过一个虚构的公司讲解了如何建立微服务架构。主要内容包括认识微服务在保证系统设计与组织目标统一上的重要性,学会把服务集成到已有系统中,采用递增手段拆分单块大型应用,通过持续集成部署微服务等。 作者和译者都来自ThoughtWorks,值得信赖,除了系统化地论述了微服务的方方面面以外,书中推荐的技术博客、工具软件等对增强感性认识都很有帮助。对关于COTS的集成,作者提出的在自己可控的平台进行定制化的核心思想尤其值得牢记。 《架构即未来:现代企业可扩展的Web架构、流程和组织》 作者还有另外一本《架构真经》,一起推荐。本书汇聚了作者从eBay、VISA、Salesforce.com到Apple超过30年的丰富经验,全面阐释了经过验证的信息技术扩展方法,对所需要掌握的产品和服务的平滑扩展做了详尽的论述。 任何一个持续成长的公司最终都需要解决系统、组织和流程的扩展性问题,作者详尽地介绍了影响扩展性的各个方面,包括架构、过程、组织和技术。阅读本书,可以学习到以最大化敏捷性和扩展性来优化组织机构的新策略,以及对云计算(IaaS/PaaS)、NoSQL、DevOps和业务指标等的新见解。利用其中的工具和建议,可以系统化地清除扩展性道路上的障碍,更好的开展技术和业务。 二、架构落地实践《淘宝技术这十年》 生动形象的介绍了淘宝从小到大的技术发展历程,是企业架构发展的一个缩影,对思考技术发展有较好的帮助。 《淘宝技术这十年》从工程师的角度讲述淘宝这个超大规模互联网系统的成长历程,及其所有主动和被动的技术变革的前因后果。书中有幕后故事、产品经验、架构演进、技术启蒙,也有大牛成长、业内八卦、失败案例、励志故事。《淘宝技术这十年》文风流畅,有技术人员特有的幽默感;内容积极正面,有现场感,全部是作者亲身经历。 作者子柳,创办“淘宝技术大学”,培养内外部工程师众多,人称“校长“,微博上也有他很多关于互联网的思考。 《分布式服务框架:原理与实践》 这本书对分布式服务框架做了拆解,依托工作实践,从分布式服务框架的架构设计原理到实践经验总结,涵盖了服务化架构演进、订阅发布、路由策略、集群容错和服务治理等多个专题,全方位剖析服务框架的设计原则和原理,结合大量实践案例与读者分享作者对分布式服务框架设计和运维的体会。同时,对基于Docker部署微服务以及基于微服务架构开发、部署和运维业务系统进行了详细介绍。 作者具有丰富的分布式服务框架、平台中间件的架构设计和实践经验,主导设计的华为分布式服务框架已经在全球数十个国家成功商用。 《大型网站技术架构:核心原理与案例分析》 一本国内不错的关于软件架构实践的书,销量和评价都挺好。这本书通过梳理大型网站技术发展历程,剖析大型网站技术架构模式,深入讲述大型互联网架构设计的核心原理,并通过一组典型网站技术架构设计案例,呈现了一幅包括技术选型、架构设计、性能优化、Web 安全、系统发布、运维监控等在内的大型网站开发全景视图。 《大型网站系统与Java中间件实践》 阿里系技术图书,对分布式系统的演进做了较好的介绍,围绕大型网站和支撑大型网站架构的 Java 中间件的实践展开介绍。本书从分布式系统的知识切入,让读者对分布式系统有基本的了解;然后介绍大型网站随着数据量、访问量增长而发生的架构变迁;接着讲述构建 Java 中间件的相关知识;最后介绍支撑大型网站架构的 Java 中间件系统的设计和实践。 通过本书可以了解大型网站架构变迁过程中的较为通用的问题和解法,并了解构建支撑大型网站的 Java 中间件的实践经验。 《企业IT架构转型之道:阿里巴巴中台战略思想与架构实战》 看这本书,帮助你了解阿里的中台设计,也就是阿里巴巴的共享服务理念以及企业级互联网架构建设的思路。 本书从阿里巴巴启动中台战略说起,详细阐述了共享服务理念给企业业务发展带来的业务价值。接着会分享阿里巴巴在建设共享服务体系时如何进行技术框架的选择,哪些重要的技术平台支撑起了共享服务体系,这也是迄今为止对阿里巴巴集团中间件体系对外最全面系统的介绍。除了技术层面之外,本书还分享了阿里巴巴内部的一些经验和实践,如组织的架构和体制如何更好地支持共享服务体系的持续发展。 《尽在双11:阿里巴巴技术演进与超越》 这本书是阿里巴巴集团双11技术团队出品,集合了各个事业部对双十一的复盘,全面阐述双11八年以来在技术和商业上演进和创新历程的书籍。内容涵盖在双11背景下阿里技术架构八年来的演进,如何确保稳定性这条双 11 生命线的安全和可靠,技术和商业交织发展的历程,无线和互动的持续创新与突破,以及对商家的赋能和生态的促进与繁荣。 推荐做业务架构的工程师阅读,特别是双十一全链路压测,稳定性保障的篇幅。 本文作者:邴越 阅读原文 本文为云栖社区原创内容,未经允许不得转载。

October 17, 2019 · 1 min · jiezi