《Python3.6官方文档》– 六月翻译邀请

原文链接       邀请者:小村长

 

概述

本篇是 Python官方文档的的翻译邀请函。只从AlphaGo成功挑战世界围棋冠军之后,在软件工程界掀起了一股人工智能热。而Python凭借着大量丰富的机器学习库迎来了人生的第二春,从此Python与机器学习人工智能接下了不解之缘。并发编程网在此也借助广大的技术爱好者们,希望给大家带来更高质量的Python技术文档。本次翻译希望大家积极参加为技术推广做一份小小的贡献,在此村长向所有参入开源热衷于技术推广的有志之士表示深深的谢意,在端午节来临之际,提前祝愿大家磕家欢乐,幸福健康一万年。

 

如何领取

通过评论领取想要翻译的文章,每次领取一章或一节(根据内容长短),翻译完后再领取其他章节。领取完成之后,译文最好在一个星期内翻译完成,如果不能完成翻译,也欢迎你邀请其他同学和你一起完成翻译。请谨慎领取,很多文章领取了没有翻译,导致文章很长时间没人翻译。

如何提交

翻译完成之后请登录到并发网提交成待审核状态,会有专门的编辑校对后进行发布。如果多篇文章翻译被评为A级会升级您为译者,并加入译者沟通微信群。如果在本站翻译超过十篇文章,将有礼品赠送,比如签名版的《Java并发编程的艺术》或者荣誉译者奖杯等。如果你喜欢使用markdown编写文章,可以将markdown生成后的HTML复制到网站上进行提交,mac下推荐使用MacDown软件。

 

以下为每章的翻译章节

 

 

 

 

解读Raft(四 成员变更)

将成员变更纳入到算法中是Raft易于应用到实践中的关键,相对于Paxos,它给出了明确的变更过程(实践的基础,任何现实的系统中都会遇到因为硬件故障等原因引起的节点变更的操作)。

显然,我们可以通过shutdown集群,然后变更配置后重启集群的方式达到成员变更的目的。但是这种操作会损失系统的可用性,同时会带来操作失误引起的风险。支持自动化配置,即配置可以在集群运行期间进行动态的变更(不影响可用性)显示是一个非常重要的特性。

Raft成员变更机制

在成员变更时,因为无法做到在同一个时刻使所有的节点从旧配置转换到新配置,那么直接从就配置向新配置切换就可能存在一个节点同时满足新旧配置的“超过半数”原则。

如下图,原集群由Server1、Server2、Server3,现在对集群做变更,增加Server4、Server5。如果采用直接从旧配置到新配置的切换,那么有一段时间存在两个不想交的“超过半数的集群”。

上图,中在中间位置Server1可以通过自身和Server2的选票成为Leader(满足旧配置下收到大多数选票的原则);Server3可以通过自身和Server4、Server5的选票成为Leader(满足新配置线,即集群有5个节点的情况下的收到大多数选票的原则);此时整个集群可能在同一任期中出现了两个Leader,这和协议是违背的。

为了保证安全性,Raft采用了一种两阶段的方式。

第一阶段称为joint consensus,当joint consensus被提交后切换到新的配置下。

joint consensus状态下:

  • 日志被提交给新老配置下所有的节点
  • 新旧配置中所有机器都可能称为Leader
  • 达成一致(选举和提交)要在两种配置上获得超过半数的支持

具体的切换过程如下:

  • Leader收到C-old到C-new的配置变更请求时,创建C-old-new的日志并开始复制给其他节点(和普通日志复制没有区别)
  • Follower以最新的配置做决定(收到C-old-new后就以C-old-new来决定),Leader需要以已经提交的配置来做决定(即只有C-old-new复制到大多数节点后Leader才以这个配置做决定);这个时候处于一个共同决定的过程
  • 之后提交C-new到所有节点,一旦C-new被提交,旧的配置就无所谓了

从上图可以看出,不存在一个阶段C-old和C-new可以同时根据自己的配置做出决定,所以不会出现本文开头描述的情况。

Review成员变更

如果当前的Leader不在C-new的配置中会怎么样(即当前的Leader是一个要被下线的节点)?

在C-old-new的状态下,Leader依旧可用;在C-new被commit之后Leader实际已经从集群中脱离,此时可以对Leader节点进行下线操作,而新集群则会在C-new的配置下重新选举出一个Leader。

如果在配置分发过程中Leader Crash了会怎么样?

这个问题要分为多种情况:1. C-new已经分发到超过半数节点、2. C-new还没分发到超过半数的节点

情况1:C-new已经分发到超过半数节点

集群开始重新选举,此时在C-new的规则下,旧节点(不存在新配置中的节点)不会赢得选举(因为他们要在C-old-new的情况下决定,但是拿不到C-new的选票),只有拿到C-new的节点可能成为Leader并继续下发C-new配置,流程恢复。

情况2:C-new还没分发到超过半数的节点

这种情况下,C-old-new和C-new的节点都可以成为Leader,但是无所谓,因为无论谁成为Leader,都能根据当前的配置继续完成后续流程(如果是C-new那么相当与完成了最终的配置,不在C-new的节点会因为没有心跳数据而失效)

旧节点下线造成的问题:旧节点收不到心跳触发选举,发送请求给C-old-new中的节点,是否会影响集群正常运行

Raft的处理方式:当节点确信有Leader存在时,不会进行投票(在Leader超时之前收到新的投票请求时不会提升term和投票)。且开始选举之前等待一个选举超时时间,这样在新Leader正常工作的情况下,不会受到旧节点的影响。

旧节点在发起选举前需要等待一段时间,那么这段时间新Leader可以发送心跳,这样就减少了影响。 对正常流程的影响不大。(Leader失效后要等一段时间,没有及时触发,然而本身这里就有一个判断失效的时间,好像影响不大;比如原先超时时间是10s,那么如果设置成5s,原策略下10s超时就是10s后开始选举,新策略下5s超时就是超时后再等5s再开始选举,影响就是超时时间变短)

新的服务器没有任何数据,加入进来进来怎么保证系统的可用性(这个时候新日志没办法Commit就没办法响应给客户端)?

新加入的节点需要时间复制数据,在这个过程完成之前,Raft采用以下机制来保证可用性: 新加入节点没有投票权(Leader复制日志给他们,但是不将他们考虑在机器数量里面——即在判断是否超过半数时不把这些节点考虑在内),直到这些节点的日志追上其他节点。

 

欢迎关注公众号交流:

使用数据库悲观锁实现不可重入的分布式锁

一、前言

在同一个jvm进程中时,可以使用JUC提供的一些锁来解决多个线程竞争同一个共享资源时候的线程安全问题,但是当多个不同机器上的不同jvm进程共同竞争同一个共享资源时候,juc包的锁就无能无力了,这时候就需要分布式锁了。常见的有使用zk的最小版本,redis的set函数,数据库锁来实现,本节我们谈谈使用数据库悲观锁机制来实现一个分布式锁。 Read more

解读Raft(三 安全性)

前言

之前的两篇文章更多的是在描述Raft算法的正常流程,没有过多的去讨论异常场景。

而实际在分布式系统中,我们更多的都是在应对网络不可用、机器故障等异常场景,所以本篇来讨论一下Raft协议的安全性,即在异常场景下是否会导致数据丢失、数据不一致等情况。

Read more

解读Raft(二 选举和日志复制)

Leader election

Raft采用心跳机制来触发Leader选举。Leader周期性的发送心跳(如果有正常的RPC的请求情况下可以不发心跳)包保持自己Leader的角色(避免集群中其他节点认为没有Leader而开始选举)。

Follower在收到Leader或者Candidate的RPC请求的情况下一直保持Follower状态。而当一段时间内(election timeout)没有收到请求则认为没有Leader节点而出发选举流程。

Read more

使用zookeeper序列节点实现不可重入分布式锁

一、前言

在同一个jvm进程中时,可以使用JUC提供的一些锁来解决多个线程竞争同一个共享资源时候的线程安全问题,但是当多个不同机器上的不同jvm进程共同竞争同一个共享资源时候,juc包的锁就无能无力了,这时候就需要分布式锁了。常见的有使用zk的最小版本,redis的set函数,数据库锁来实现,本节我们谈谈使用zookeeper的序列节点机制来实现一个分布式锁。 Read more

解读Raft协议(一 算法基础)

什么是RAFT

分布式系统除了提升整个体统的性能外还有一个重要特征就是提高系统的可靠性。

提供可靠性可以理解为系统中一台或多台的机器故障不会使系统不可用(或者丢失数据)。

保证系统可靠性的关键就是多副本(即数据需要有备份),一旦有多副本,那么久面临多副本之间的一致性问题。

一致性算法正是用于解决分布式环境下多副本之间数据一致性的问题的。

Read more

使用Redis单实例实现分布式锁

一、前言

在同一个jvm进程中时,可以使用JUC提供的一些锁来解决多个线程竞争同一个共享资源时候的线程安全问题,但是当多个不同机器上的不同jvm进程共同竞争同一个共享资源时候,juc包的锁就无能无力了,这时候就需要分布式锁了。常见的有使用zk的最小版本,redis的set函数,数据库锁来实现,本节我们谈谈Redis单实例情况下使用set函数来实现分布式锁。 Read more

司空见惯的包

作者:刘文敏

本文所说的包不是LV,也不是Chanel,而是Java语言中的包package,是Java程序员从写“Hello World”开始就接触的概念,Java引入包机制是为了更好的组织类,防止命名冲突,进行访问控制,提供搜索和定位类。

程序员对包的使用可以说是烂熟于心,但是笔者近日在自动构建后代码合规检查过程中发现了一个有趣的现象,某个Ant项目在自动构建时顺利通过,而代码合规检查的报告中则有许多类报声明的包”com.test“与期望的包”com.Test“不匹配这类错误,查看报错的源文件及文件目录,笔者发现源文件中写的是类似package com.test,而文件目录则为com\Test,笔者对Ant能编译通过深感好奇与困惑,立马写一个测试程序进行试验。

Read more

《软件架构模式》-第四章 微服务框架模式(下)

原文链接 译者:克里斯托刘

《软件架构模式》-第四章 微服务框架模式(下)

避免依赖和编排

设计微服务架构的一个主要难度是为服务组件选择正确的粗细粒度。如果服务组件设计的太粗糙,就彰显不了这种架构模式带来的好处(如部署、可扩展性、可测试性和松耦合)。但是,服务组件设计的过于细化,对服务组件编排要求更高,将你的微服务系统演变成面向服务的重量级体系结构,通常会带来缺点如复杂性、误导性、高开销,这些都是能在基于SOA的应用程序中找到的。

Read more

计算机科学中抽象的好处与问题—伪共享实例分析

David John Wheeler有一句名言“计算机科学中的任何问题都可以通过加上一层间接层来解决”一层不够就再加一层。后半句是我加的 (* ̄︶ ̄) ,虽然有点玩笑的意思,但是也的确能说明一些问题。计算机科学的确是靠着一层又一层的抽象与封装解决了巨量的问题。

Read more

使用包定长FixedLengthFrameDecoder解决半包粘包

四、使用包定长FixedLengthFrameDecoder解决半包粘包

Read more

高性能网络通信框架Netty-Netty客户端底层与Java NIO对应关系

5.1 Netty客户端底层与Java NIO对应关系

在讲解Netty客户端程序时候我们提到指定NioSocketChannel用于创建客户端NIO套接字通道的实例,下面我们来看NioSocketChannel是如何创建一个Java NIO里面的SocketChannel的。

Read more

初探Kafka Streams

Kafka在0.10版本推出了Stream API,提供了对存储在Kafka内的数据进行流式处理和分析的能力。

本文将从流式计算出发,之后介绍Kafka Streams的特点,最后探究Kafka Streams的架构。

Read more

如何在MQ中实现支持任意延迟的消息?

什么是定时消息和延迟消息?

  • 定时消息:Producer 将消息发送到 MQ 服务端,但并不期望这条消息立马投递,而是推迟到在当前时间点之后的某一个时间投递到 Consumer 进行消费,该消息即定时消息。
  • 延迟消息:Producer 将消息发送到 MQ 服务端,但并不期望这条消息立马投递,而是延迟一定时间后才投递到 Consumer 进行消费,该消息即延时消息。

定时消息与延迟消息在代码配置上存在一些差异,但是最终达到的效果相同:消息在发送到 MQ 服务端后并不会立马投递,而是根据消息中的属性延迟固定时间后才投递给消费者。

Read more

return top