Java 使用大量连接时出现运动错误

Java 使用大量连接时出现运动错误,java,exception,amazon-web-services,jmeter,amazon-kinesis,Java,Exception,Amazon Web Services,Jmeter,Amazon Kinesis,我使用Kinesis存储从安装在EC2服务器上的Jmeter发送的记录。 问题是,当我启动7200个线程并在我的Kinesis流上使用1个共享线程时,一切都正常。如果启动9000个线程,则会收到此错误 Rate exceeded for shard shardId-000000000001 in stream Jmeter under account 769870455028. (Service: AmazonKinesis; Status Code: 400; Error Code: Prov

我使用Kinesis存储从安装在EC2服务器上的Jmeter发送的记录。 问题是,当我启动7200个线程并在我的Kinesis流上使用1个共享线程时,一切都正常。如果启动9000个线程,则会收到此错误

Rate exceeded for shard shardId-000000000001 in stream Jmeter under account 769870455028. (Service: AmazonKinesis; Status Code: 400; Error Code: ProvisionedThroughputExceededException; Request ID: 98f687d9-ffbe-11e4-a897-357ee8c24764)
所以我增加了碎片的数量,将其设置为2和3,但它不起作用。 所以我认为问题不在于碎片编号,而是我的java代码,或者我不知道还有什么。 这是我的代码:

  public MyKinesisClient( String streamName, int partitionKey, String accessKey, String secretKey, String endpoint, String serviceName, String regionId ) {
        this.streamName=streamName;
        this.partitionKey=partitionKey;
        AWSCredentials credentials = null;
        credentials = new BasicAWSCredentials(accessKey, secretKey);
        kinesisClient = new AmazonKinesisClient(credentials);
        kinesisClient.setEndpoint(endpoint,serviceName,regionId);
    }

    /**
     * Metodo utilizzato per l'invio di un json a Kinesis
     * @param json: com.amazonaws.util.json.JSONObject da inviare a Kinesis
     * @throws UnsupportedEncodingException
     * @throws JSONException
     */
    public void sendJson(JSONObject json) throws UnsupportedEncodingException, JSONException {
        try{
        PutRecordRequest putRecordRequest = new PutRecordRequest();
        putRecordRequest.setStreamName(streamName);
        putRecordRequest.setData(ByteBuffer.wrap(json.toString().getBytes("utf-8")));
        //putRecordRequest.setData(ByteBuffer.wrap(String.format("testData-%d", createTime).getBytes()));
        putRecordRequest.setPartitionKey(String.format("partitionKey-%d", partitionKey));
        kinesisClient.putRecord(putRecordRequest);
        }catch(Exception e){
            System.out.println(e.getMessage());
        }

    }

有一条使用更多碎片的指令?提前谢谢

我使用两个分区键解决了这个问题。根据亚马逊的定义:

分区键用于隔离记录并将其路由到流的不同碎片。在向Amazon Kinesis流添加数据时,数据生成器指定了分区键。例如,假设您有一个包含两个碎片(碎片1和碎片2)的流。您可以将数据生成器配置为使用两个分区键(键A和键B),以便将具有键A的所有记录添加到碎片1,并将具有键B的所有记录添加到碎片2

很明显,我必须为每个碎片使用一个分区键 但这足够重要:

由于这种散列机制,所有数据记录都具有相同的 分区键映射到流中的相同分片。然而,如果 分区键的数量超过了碎片的数量,有些碎片 必须包含具有不同分区键的记录。从 从设计角度来看,为了确保所有碎片都得到充分利用, 碎片的数量(由 CreateStreamRequest)应大大少于 唯一的分区键,以及流向单个分区的数据量 分区密钥应大大小于 碎片

@卢卡 如果您使用6个线程组和6个碎片,您将收到速率超过异常。因为每个碎片每秒有5个getRecord请求的限制。
请参阅

那么您是否已将您的配置为使用shard 1,直到它已满,然后切换到shard 2以进行新连接?或者只是循环他们,因为你知道你将在2分限制下?您需要指定要使用的碎片,这似乎违反直觉。这似乎会在扩展时在shard1中留下额外的资源,而不是在添加更多的shard时接受更多的连接。我将两个shard一起使用,我只将线程拆分为2个shard。我不知道是否存在一种用一个分区键使用更多碎片的方法。当然,使用我的解决方案,每个shardy都会浪费资源。您还可以在每次调用中随机化分区\ u键,以提供更均匀的分配,这就更有意义了!。一个碎片的一个关键似乎是在浪费资源。我是随机化的triyng。文档在这一点上有点混乱。我不明白为什么如果我使用一个线程组和一个碎片都可以正常工作,如果我使用6个线程组和6个碎片,我收到的速率超过了异常