

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Refragmentar um fluxo
<a name="kinesis-using-sdk-java-resharding"></a>

**Importante**  
Você pode refragmentar seu stream usando a [UpdateShardCount](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_UpdateShardCount.html)API. Caso contrário, é possível continuar executando divisões e mesclagens, como explicado aqui.

O Amazon Kinesis Data Streams oferece suporte à *refragmentação*, o que permite ajustar o número de fragmentos no fluxo para se adaptar a alterações na taxa de dados no fluxo. A refragmentação é considerada uma operação avançada. Se esta é a primeira experiência com o Kinesis Data Streams, volte a este tópico depois de se familiarizar com todos os outros aspectos do serviço.

Há dois tipos de operações de refragmentação: divisão de fragmento e mesclagem de fragmento. Na divisão de fragmento, um único fragmento é dividido em dois. Na mesclagem de fragmento, dois fragmentos são combinados em um. A refragmentação sempre ocorre em *pares*, ou seja, não é possível dividir em mais de dois fragmentos em uma única operação, e não é possível mesclar mais de dois fragmentos em uma única operação. O fragmento (ou o par de fragmentos) que é objeto da operação de refragmentação é chamado de fragmento *pai*. O fragmento (ou o par de fragmentos) resultante da operação de refragmentação é chamado de fragmento *filho*. 

A divisão aumenta o número de fragmentos no fluxo e, portanto, aumenta a capacidade de dados do fluxo. Como a cobrança é feita por fragmento, a divisão aumenta o custo do fluxo. Comparativamente, a mesclagem reduz o número de fragmentos no fluxo e, portanto, diminui a capacidade de dados e o custo do fluxo. 

A refragmentação costuma ser executada por um aplicativo administrativo, que é diferente dos aplicativos de produtor (put) e dos aplicativos de consumidor (get). Esse aplicativo administrativo monitora o desempenho geral do stream com base nas métricas fornecidas pela Amazon CloudWatch ou com base nas métricas coletadas dos produtores e consumidores. O aplicativo administrativo também precisa de um conjunto mais amplo de permissões do IAM do que os consumidores ou produtores, porque os consumidores e produtores geralmente não precisam acessar o APIs usado para refragmentação. Para obter mais informações sobre as permissões do IAM para o Kinesis Data Streams, consulte [Controlar o acesso aos recursos do Amazon Kinesis Data Streams usando o IAM](controlling-access.md). 

Para obter mais informações sobre refragmentação, consulte [How do I change the number of open shards in Kinesis Data Streams?](https://aws.amazon.com/premiumsupport/knowledge-center/kinesis-data-streams-open-shards/)

**Topics**
+ [Decidir uma estratégia para refragmentar](kinesis-using-sdk-java-resharding-strategies.md)
+ [Dividir um fragmento](kinesis-using-sdk-java-resharding-split.md)
+ [Mesclar dois fragmentos](kinesis-using-sdk-java-resharding-merge.md)
+ [Concluir a ação de refragmentação](kinesis-using-sdk-java-after-resharding.md)

# Decidir uma estratégia para refragmentar
<a name="kinesis-using-sdk-java-resharding-strategies"></a>

A finalidade da refragmentação no Amazon Kinesis Data Streams é permitir que o fluxo se adapte a alterações na taxa do fluxo de dados. Fragmentos são divididos para aumentar a capacidade (e o custo) do fluxo. Fragmentos são mesclados para reduzir o custo (e a capacidade) do fluxo.

 Uma abordagem de refragmentação pode ser dividir cada fragmento do fluxo, o que dobraria sua capacidade. No entanto, isso pode fornecer mais capacidade adicional do que o realmente necessário e, portanto, gerar um custo desnecessário. 

Também é possível usar métricas para identificar os fragmentos *quentes* ou *frios*, ou seja, os fragmentos que estão recebendo muito mais ou muito menos dados do que o esperado. Em seguida, é possível seletivamente dividir os fragmentos quentes para aumentar a capacidade das chaves de hash que almejam esses fragmentos. Comparativamente, pode-se mesclar os fragmentos frios para dar uma melhor serventia à capacidade não usada.

Você pode obter alguns dados de desempenho do seu stream a partir das CloudWatch métricas da Amazon que o Kinesis Data Streams publica. No entanto, também é possível coletar algumas métricas dos seus fluxos. Uma abordagem é registrar em log os valores de chave de hash gerados pelas chaves de partição dos seus registros de dados. Lembre-se de que a chave de partição é especificada no momento em que o registro é adicoinado ao fluxo. 

```
putRecordRequest.setPartitionKey( String.format( "myPartitionKey" ) );
```

O Kinesis Data [MD5](http://en.wikipedia.org/wiki/MD5)Streams usa para calcular a chave de hash a partir da chave de partição. Como você especifica a chave de partição para o registro, você pode MD5 usá-la para calcular o valor da chave de hash desse registro e registrá-lo. 

Você também pode registrar os IDs fragmentos aos quais seus registros de dados estão atribuídos. O ID do fragmento é obtido usando-se o método `getShardId` do objeto `putRecordResults` retornado pelo método `putRecords` e o objeto `putRecordResult` retornado pelo método `putRecord`.

```
String shardId = putRecordResult.getShardId();
```

Com os valores do fragmento IDs e da chave de hash, você pode determinar quais fragmentos e chaves de hash estão recebendo mais ou menos tráfego. Em seguida, é possível usar a refragmentação para fornecer mais ou menos capacidade, conforme apropriado para essas chaves.

# Dividir um fragmento
<a name="kinesis-using-sdk-java-resharding-split"></a>

Para dividir um fragmento no Amazon Kinesis Data Streams, é necessário especificar como os valores de chave de hash dos fragmentos pai devem ser redistribuídos para os fragmentos filho. Ao adicionar um registro de dados a um fluxo, ele é atribuído a um fragmento com base em um valor de chave de hash. O valor da chave de hash é o [MD5](http://en.wikipedia.org/wiki/MD5)hash da chave de partição que você especifica para o registro de dados no momento em que adiciona o registro de dados ao fluxo. Os registros de dados que têm a mesma chave de partição também têm o mesmo valor de chave de hash.

Os valores possíveis de chave de hash de um determinado fragmento constituem um conjunto de números inteiros contíguos, não negativos e ordenados. Esse intervalo de possíveis valores de chave de hash é determinado pelo seguinte: 

```
shard.getHashKeyRange().getStartingHashKey();
shard.getHashKeyRange().getEndingHashKey();
```

Ao dividir o fragmento, um valor é especificado neste intervalo. Esse valor de chave de hash e todos os valores de chave de hash maiores são distribuídos para um dos fragmentos filhos. Todos os valores de chave de hash menores são distribuídos para os outros fragmentos filhos. 

O seguinte código demonstra uma operação de divisão de fragmento que redistribui as chaves de hash uniformemente entre cada um dos fragmentos filhos, basicamente, dividindo o fragmento pai no meio. Essa é apenas uma das maneiras possíveis de dividir o fragmento pai. É possível, por exemplo, dividir o fragmento de maneira que o terço inferior das chaves do pai vá para um fragmento filho e os dois terços superiores das chaves vão para o outro fragmento filho. No entanto, para muitos aplicativos, dividir os fragmentos no meio é uma abordagem eficiente. 

O código pressupõe que `myStreamName` contém o nome do seu fluxo e a variável de objeto `shard` contém o fragmento a dividir. Comece instanciando um novo objeto `splitShardRequest` e definindo o nome do fluxo e o ID do fragmento.

```
SplitShardRequest splitShardRequest = new SplitShardRequest();
splitShardRequest.setStreamName(myStreamName);
splitShardRequest.setShardToSplit(shard.getShardId());
```

Determine o valor da chave de hash que é meio caminho entre o maior valor e o menor valor no fragmento. Trata-se do valor de chave de hash inicial para o fragmento filho que conterá a metade superior das chaves de hash do fragmento pai. Especifique esse valor no método `setNewStartingHashKey`. Basta especificar esse valor. O Kinesis Data Streams distribui automaticamente as chaves de hash abaixo desse valor para os outros fragmentos filho criados pela divisão. A última etapa é chamar o método `splitShard` no cliente do Kinesis Data Streams.

```
BigInteger startingHashKey = new BigInteger(shard.getHashKeyRange().getStartingHashKey());
BigInteger endingHashKey   = new BigInteger(shard.getHashKeyRange().getEndingHashKey());
String newStartingHashKey  = startingHashKey.add(endingHashKey).divide(new BigInteger("2")).toString();

splitShardRequest.setNewStartingHashKey(newStartingHashKey);
client.splitShard(splitShardRequest);
```

A primeira etapa após este procedimento é mostrada em [Aguardar um fluxo ficar ativo novamente](kinesis-using-sdk-java-after-resharding.md#kinesis-using-sdk-java-resharding-wait-until-active). 

# Mesclar dois fragmentos
<a name="kinesis-using-sdk-java-resharding-merge"></a>

 Uma operação de mesclagem de fragmentos usa dois fragmentos especificados e combina-os em um único fragmento. Após a mesclagem, o único fragmento filho recebe dados para todos os valores de chave de hash cobertos pelos dois fragmentos pais. 

**Adjacência de fragmento**  
Para mesclar dois fragmentos, eles precisam estar *adjacentes*. Dois fragmentos são considerados adjacentes quando a união dos intervalos de chave de hash dos dois fragmentos forma um conjunto contíguo sem lacunas. Por exemplo, suponha que haja dois fragmentos, um com o intervalo de chaves de hash 276...381 e o outro com o intervalo de chaves de hash 382...454. É possível mesclar esses dois fragmentos em um só, que teria um intervalo de chaves de hash 276...454. 

Para usar outro exemplo, suponha que haja dois fragmentos, um com um intervalo de chaves de hash 276...381 e o outro com um intervalo de chaves de hash 455...560. Não seria possível mesclar esses dois fragmentos porque haveria um ou mais fragmentos entre eles que estariam no intervalo 382...454. 

O conjunto de todos os `OPEN` fragmentos em um fluxo, como um grupo, sempre abrange toda a faixa de valores da chave de hash. MD5 Para obter mais informações sobre esses estados de fragmento (como `CLOSED`), consulte [Considerar o roteamento de dados, a persistência de dados e o estado do fragmento após uma refragmentação](kinesis-using-sdk-java-after-resharding.md#kinesis-using-sdk-java-resharding-data-routing). 

Para identificar os fragmentos candidatos para mesclagem, deve-se filtrar todos os fragmentos que estão no estado `CLOSED`. Os fragmentos `OPEN` (ou seja, não `CLOSED`) têm um número de sequência final `null`. É possível testar o número sequencial de término de um fragmento usando: 

```
if( null == shard.getSequenceNumberRange().getEndingSequenceNumber() ) 
{
  // Shard is OPEN, so it is a possible candidate to be merged.
}
```

Após filtrar os fragmentos fechados, classifique os fragmentos restantes pelo valor de chave de hash mais alto aceito por cada fragmento. É possível recuperar esse valor usando: 

```
shard.getHashKeyRange().getEndingHashKey();
```

 Se dois fragmentos são adjacentes nessa lista filtrada e classificada, eles podem ser mesclados. 

**Código da operação de mesclagem**  
 O código a seguir mescla dois fragmentos. O código pressupõe que `myStreamName` contém o nome do seu fluxo e as variáveis de objeto `shard1` e `shard2` contém os dois fragmentos adjacentes a mesclar.

Para a operação de mesclagem, comece instanciando um novo objeto `mergeShardsRequest`. Especifique o nome do fluxo com o método `setStreamName`. Em seguida, especifique os dois fragmentos a mesclar usando os métodos `setShardToMerge` e `setAdjacentShardToMerge`. Por fim, chame o método `mergeShards` no cliente do Kinesis Data Streams para executar a operação.

```
MergeShardsRequest mergeShardsRequest = new MergeShardsRequest();
mergeShardsRequest.setStreamName(myStreamName);
mergeShardsRequest.setShardToMerge(shard1.getShardId());
mergeShardsRequest.setAdjacentShardToMerge(shard2.getShardId());
client.mergeShards(mergeShardsRequest);
```

A primeira etapa após este procedimento é mostrada em [Aguardar um fluxo ficar ativo novamente](kinesis-using-sdk-java-after-resharding.md#kinesis-using-sdk-java-resharding-wait-until-active).

# Concluir a ação de refragmentação
<a name="kinesis-using-sdk-java-after-resharding"></a>

Após qualquer tipo de procedimento de refragmentação no Amazon Kinesis Data Streams e antes de retomar o processamento normal de registros, é necessário realizar outros procedimentos e fazer algumas considerações. As seções a seguir descrevem esses itens.

**Topics**
+ [Aguardar um fluxo ficar ativo novamente](#kinesis-using-sdk-java-resharding-wait-until-active)
+ [Considerar o roteamento de dados, a persistência de dados e o estado do fragmento após uma refragmentação](#kinesis-using-sdk-java-resharding-data-routing)

## Aguardar um fluxo ficar ativo novamente
<a name="kinesis-using-sdk-java-resharding-wait-until-active"></a>

Depois de chamar uma operação de refragmentação, `splitShard` ou `mergeShards`, deve-se esperar o fluxo ficar ativo novamente. O código a ser usado é o mesmo de quando espera-se que um fluxo se torne ativo após a [criação de um fluxo](kinesis-using-sdk-java-create-stream.md). Esse código é o seguinte:

```
DescribeStreamRequest describeStreamRequest = new DescribeStreamRequest();
describeStreamRequest.setStreamName( myStreamName );

long startTime = System.currentTimeMillis();
long endTime = startTime + ( 10 * 60 * 1000 );
while ( System.currentTimeMillis() < endTime ) 
{
  try {
    Thread.sleep(20 * 1000);
  } 
  catch ( Exception e ) {}
  
  try {
    DescribeStreamResult describeStreamResponse = client.describeStream( describeStreamRequest );
    String streamStatus = describeStreamResponse.getStreamDescription().getStreamStatus();
    if ( streamStatus.equals( "ACTIVE" ) ) {
      break;
    }
   //
    // sleep for one second
    //
    try {
      Thread.sleep( 1000 );
    }
    catch ( Exception e ) {}
  }
  catch ( ResourceNotFoundException e ) {}
}
if ( System.currentTimeMillis() >= endTime ) 
{
  throw new RuntimeException( "Stream " + myStreamName + " never went active" );
}
```

## Considerar o roteamento de dados, a persistência de dados e o estado do fragmento após uma refragmentação
<a name="kinesis-using-sdk-java-resharding-data-routing"></a>

O Kinesis Data Streams é um serviço de fluxo de dados em tempo real. Seus aplicativos devem pressupor que os dados fluem continuamente pelos fragmentos do fluxo. Ao refragmentar, os registros de dados que estavam fluindo para os fragmentos pais são re-roteados para fluírem para os fragmentos filhos com base nos valores de chave de hash para as quais são mapeadas as chaves de partição de registro de dados. No entanto, os registros de dados que estavam nos fragmentos pais antes da refragmentação permanecem nesses fragmentos. Os fragmentos principais não desaparecem quando a refragmentação ocorre. Eles persistem com os dados que continham antes da refragmentação. Os registros de dados nos fragmentos pai podem ser acessados usando as operações [`getShardIterator` e `getRecords`](developing-consumers-with-sdk.md#kinesis-using-sdk-java-get-data) na API do Kinesis Data Streams ou por meio da Kinesis Client Library.

**nota**  
Os registros de dados podem ser acessados a partir do momento em que são adicionados ao fluxo até o período de retenção atual. Isso é verdadeiro independentemente de quaisquer alterações aos fragmentos no fluxo durante esse período. Para obter mais informações sobre o período de retenção de um stream, consulte [Alterar o período de retenção de dados](kinesis-extended-retention.md).

No processo de refragmentação, um fragmento pai passa de um estado `OPEN` para um estado `CLOSED` para um estado `EXPIRED`. 
+  **OPEN**: antes de uma operação de refragmentação, um fragmento pai está no estado `OPEN`, o que significa que os registros de dados podem ser adicionados ao fragmento e recuperados do fragmento.
+  **CLOSED**: após uma operação de refragmentação, o fragmento pai passa para um estado `CLOSED`. Isso significa que os registros de dados não são mais adicionados ao fragmento. Os registros de dados que foram adicionados a esse fragmento agora são adicionados a um fragmento filho. No entanto, os registros de dados ainda podem ser recuperados do fragmento por tempo limitado. 
+  **EXPIRED**: após a expiração do período de retenção do fluxo, todos os registros de dados no fragmento pai expiraram e não estão mais acessíveis. Neste momento, o próprio fragmento muda para um estado `EXPIRED`. As chamadas a `getStreamDescription().getShards` para enumerar os fragmentos no fluxo não incluem os fragmentos `EXPIRED` na lista de fragmentos retornados. Para obter mais informações sobre o período de retenção de um stream, consulte [Alterar o período de retenção de dados](kinesis-extended-retention.md).

Depois da refragmentação, com o fluxo novamente em um estado `ACTIVE`, é possível iniciar imediatamente a leitura de dados dos fragmentos filhos. No entanto, os fragmentos principais que permanecem após a refragmentação ainda podem conter dados que ainda não foram lidos e foram adicionados ao fluxo antes da refragmentação. Ao ler dados de fragmentos filhos antes ler todos os dados dos fragmentos pais, pode-se ler dados de uma determinada chave de hash fora da ordem determinada pelos números sequenciais dos registros de dados. Portanto, pressupondo que a ordem dos dados é importante, é necessário, após uma refragmentação, sempre continuar lendo dados dos fragmentos pais até esgotá-los. Só depois deve-se começar a ler dados dos fragmentos filhos. Quando `getRecordsResult.getNextShardIterator` retorna `null`, indica que todos os dados no fragmento pai foram lidos. 