我正面临一个问题。我正在测试3个消费者和1个制作人。从生产者生产的按键操作开始,消费者无法接收生产者发送的所有数据。这可能是什么原因?
在以下屏幕截图中,制作人发送了a
,b
,c
和d
,但只收到了d
。
右下角是制作人,其他3位是听取同一流的消费者。如我们所见,左下角只有一位消费者收到d
,而其他数据已丢失。
我正在测试的代码:
制片:
var stdin = process.openStdin();
function insert( input ) {
var params = {
Data: input,
PartitionKey: 'users',
StreamName: 'test-stream1'
};
kinesis.putRecord( params, function ( err, data ) {
if ( err ) console.log( err, err.stack ); // an error occurred
else console.log( data ); // successful response
} );
}
stdin.addListener( "data", function ( d ) {
// PRODUCING THE KEY STROKES
// TYPED BY USER INPUT
insert( d.toString().trim() );
} );
消费者:
function getRecord() {
kinesis.describeStream( {
StreamName: 'test-stream1'
}, function ( err, streamData ) {
if ( err ) {
console.log( err, err.stack ); // an error occurred
} else {
// console.log( streamData ); // successful response
streamData.StreamDescription.Shards.forEach( shard => {
kinesis.getShardIterator( {
ShardId: shard.ShardId,
ShardIteratorType: 'LATEST',
StreamName: 'test-stream1'
}, function ( err, shardIteratordata ) {
if ( err ) {
// console.log( err, err.stack ); // an error occurred
} else {
//console.log(shardIteratordata); // successful response
kinesis.getRecords( {
ShardIterator: shardIteratordata.ShardIterator
}, function ( err, recordsData ) {
if ( err ) {
// console.log( err, err.stack ); // an error occurred
} else {
// console.log( JSON.stringify( recordsData ) ); // successful response
recordsData.Records.forEach( record => {
console.log( record.Data.toString(), shard.ShardId );
} );
}
} );
}
} );
} );
}
} );
}
setInterval( getRecord, 1000 * 1 );
我使用了迭代器类型LATEST
,以便每个消费者从生产者那里获取最新数据。
答案 0 :(得分:1)
If I am not mistaken you are always reading after the most recent records. This is configured via the ShardIteratorType: 'Latest'
.
According to the documentation it says
LATEST - Start reading just after the most recent record in the shard, so that you always read the most recent data in the shard.
This should only be used to get the very first iterator and afterwards you need to get the next iterator starting at the exact same position where you ended with the last one.
Therefore you can use the NextShardIterator
of the GetIterator
request if present to followup on the comping records. See doc.
Currently you are discarding the iterator after each interval and starting at the very end again.
I took your code and moved the setInterval
to only repeat the getRecords
request with the next iterator
function getRecord() {
kinesis.describeStream({ StreamName: 'test-stream1'}, function ( err, streamData ) {
if ( err ) {
console.log( err, err.stack ); // an error occurred
} else {
// console.log( streamData ); // successful response
streamData.StreamDescription.Shards.forEach( shard => {
kinesis.getShardIterator({
ShardId: shard.ShardId,
ShardIteratorType: 'LATEST',
StreamName: 'test-stream1'
}, function ( err, shardIteratordata ) {
if ( err ) {
console.log( err, err.stack ); // an error occurred
} else {
var shardIterator = shardIteratordata.ShardIterator;
setInterval(function() {
kinesis.getRecords({ ShardIterator: shardIterator }, function ( err, recordsData ) {
if ( err ) {
console.log( err, err.stack ); // an error occurred
} else {
// console.log( JSON.stringify( recordsData ) ); // successful response
recordsData.Records.forEach(record => {
console.log( record.Data.toString(), shard.ShardId );
});
shardIterator = iterator = recordsData.NextShardIterator;
}
});
}, 1000 * 1 );
}
});
});
}
});
}