kafka-crab-js 1.9.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +287 -43
- package/dist/index.cjs +109 -83
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +4 -1
- package/dist/index.js +107 -83
- package/dist/index.js.map +3 -3
- package/dist/kafka-client.d.ts +12 -5
- package/dist/streams/base-kafka-stream-readable.d.ts +58 -0
- package/dist/streams/kafka-batch-stream-readable.d.ts +31 -0
- package/dist/streams/kafka-stream-readable.d.ts +12 -0
- package/js-binding.cjs +46 -46
- package/js-binding.d.ts +10 -9
- package/js-binding.js +46 -46
- package/package.json +11 -9
- package/dist/kafka-stream-readable.d.ts +0 -76
package/README.md
CHANGED
|
@@ -10,32 +10,97 @@ A lightweight, flexible, and reliable Kafka client for JavaScript/TypeScript. It
|
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
## What's New in Version
|
|
13
|
+
## What's New in Version 2.0.0
|
|
14
|
+
|
|
15
|
+
### BREAKING CHANGES ⚠️
|
|
16
|
+
|
|
17
|
+
This major version includes important breaking changes that improve API consistency and memory management:
|
|
18
|
+
|
|
19
|
+
1. **Consumer Configuration API Changes**:
|
|
20
|
+
- **REMOVED**: `createTopic` field from `ConsumerConfiguration`
|
|
21
|
+
- **Migration**: Use `createTopic` field in `TopicPartitionConfig` instead when subscribing to topics
|
|
22
|
+
- **Before**: `new KafkaClient().createConsumer({ groupId: 'test', createTopic: true })`
|
|
23
|
+
- **After**: `consumer.subscribe([{ topic: 'my-topic', createTopic: true }])`
|
|
24
|
+
|
|
25
|
+
2. **Stream Lifecycle Management**:
|
|
26
|
+
- Stream consumers now properly implement Node.js stream lifecycle methods (`_destroy()`, `_final()`)
|
|
27
|
+
- **Memory leak prevention**: Streams now automatically disconnect Kafka consumers during destruction
|
|
28
|
+
- Better resource cleanup ensures no hanging connections or memory leaks
|
|
29
|
+
- Error handling during stream destruction is improved with proper error propagation
|
|
30
|
+
|
|
31
|
+
3. **Stream Error Handling**:
|
|
32
|
+
- Stream errors now use `destroy(error)` instead of `emit('error')` for proper stream termination
|
|
33
|
+
- This ensures streams are properly closed when errors occur, preventing resource leaks
|
|
34
|
+
- Error propagation follows Node.js stream standards more closely
|
|
35
|
+
|
|
36
|
+
4. **Rust Configuration Simplification**:
|
|
37
|
+
- Removed `MAX_BATCH_TIMEOUT` constant - now uses only `DEFAULT_BATCH_TIMEOUT` (1000ms)
|
|
38
|
+
- Simplified timeout validation logic in Rust layer
|
|
39
|
+
- Invalid timeout values (< 1ms) now log warnings and use default timeout
|
|
40
|
+
|
|
41
|
+
5. **Code Quality Improvements**:
|
|
42
|
+
- Fixed linting violations: short variable names and `any` type usage
|
|
43
|
+
- Better TypeScript typing throughout the codebase
|
|
44
|
+
- Removed redundant validation functions for cleaner code
|
|
45
|
+
|
|
46
|
+
### Migration Guide
|
|
47
|
+
|
|
48
|
+
- **No API changes required** - all public interfaces remain the same
|
|
49
|
+
- **Stream memory management** - streams now automatically clean up resources
|
|
50
|
+
- **Error handling** - streams will properly terminate on errors (existing error handling code still works)
|
|
51
|
+
- **Performance** - simplified timeout logic may provide marginal performance improvements
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## What's New in Version 2.0.0
|
|
14
56
|
|
|
15
57
|
### Major Updates:
|
|
16
|
-
|
|
58
|
+
|
|
59
|
+
1. **Performance Benchmark Suite**:
|
|
60
|
+
- Added comprehensive benchmark suite comparing performance against `kafkajs`, `node-rdkafka`, and `@platformatic/rdkafka`
|
|
61
|
+
- Benchmark scripts with automated setup and data generation
|
|
62
|
+
- Performance testing for both serial and batch processing modes
|
|
63
|
+
- Supports configurable iterations and message sizes for realistic testing scenarios
|
|
64
|
+
|
|
65
|
+
2. **Enhanced Stream Consumer Configuration**:
|
|
66
|
+
- Stream consumer constructor now accepts optional `ReadableOptions` parameter
|
|
67
|
+
- Default `objectMode: true` for better stream processing ergonomics
|
|
68
|
+
- Improved batch processing configuration with proper defaults
|
|
69
|
+
|
|
70
|
+
3. **Flexible Configuration System**:
|
|
71
|
+
- **BREAKING**: Configuration properties now accept `Record<string, any>` instead of `Record<string, string>`
|
|
72
|
+
- Enhanced type flexibility for complex configuration values (numbers, booleans, objects)
|
|
73
|
+
- Better support for advanced librdkafka configuration options
|
|
74
|
+
|
|
75
|
+
4. **Enhanced Topic Management**:
|
|
76
|
+
- Added `createTopic`, `numPartitions`, and `replicas` options to `TopicPartitionConfig`
|
|
77
|
+
- Improved topic creation control during consumer subscription
|
|
78
|
+
- Better handling of partition assignment and topic setup
|
|
79
|
+
|
|
80
|
+
5. **Build System Improvements**:
|
|
81
|
+
- Updated TypeScript configuration with modular `tsconfig.base.json`
|
|
82
|
+
- Added `typecheck` script for standalone type checking
|
|
83
|
+
- Enhanced build pipeline with better declaration file generation
|
|
84
|
+
- Updated to pnpm@10.15.1 for improved dependency management
|
|
85
|
+
|
|
86
|
+
6. **Development Tools Enhancement**:
|
|
87
|
+
- Enhanced oxlint configuration with benchmark-specific rules
|
|
88
|
+
- Added support for benchmark directory linting and formatting
|
|
89
|
+
- Improved development workflow with better error handling rules
|
|
90
|
+
|
|
91
|
+
### Previous Version (1.9.0) Updates:
|
|
92
|
+
7. **Consumer Topic Creation Control**:
|
|
17
93
|
- Added fine-grained control over consumer topic creation behavior
|
|
18
94
|
- Enhanced consistency in topic management and cleanup processes
|
|
19
95
|
- Improved handling of topic creation inconsistencies during consumer operations
|
|
20
96
|
|
|
21
|
-
|
|
97
|
+
8. **Enhanced Manual Commit Testing**:
|
|
22
98
|
- Consolidated manual commit tests for better reliability and coverage
|
|
23
99
|
- Added comprehensive integration tests with PostRebalance event handling
|
|
24
100
|
- Tests now verify offset persistence across consumer restarts and batch processing
|
|
25
|
-
- Improved timing and synchronization in integration test scenarios
|
|
26
|
-
|
|
27
|
-
3. **Optional Producer Configuration**:
|
|
28
|
-
- Producer configuration is now optional with sensible defaults
|
|
29
|
-
- Enhanced commit logging for better debugging and monitoring
|
|
30
|
-
- Improved flexibility in producer setup and configuration
|
|
31
|
-
|
|
32
|
-
4. **Build System Improvements**:
|
|
33
|
-
- Added Cargo.lock tracking for reproducible builds across environments
|
|
34
|
-
- Enhanced dependency management and version consistency
|
|
35
|
-
- Updated TypeScript bindings and CommonJS exports
|
|
36
101
|
|
|
37
102
|
### Previous Version (1.8.0) Breaking Changes:
|
|
38
|
-
|
|
103
|
+
9. **Async Consumer Commit**:
|
|
39
104
|
- **BREAKING**: The `consumer.commit()` method is now async and must be awaited
|
|
40
105
|
- **Before**: `consumer.commit(topic, partition, offset, 'Sync')`
|
|
41
106
|
- **After**: `await consumer.commit(topic, partition, offset, 'Sync')`
|
|
@@ -51,9 +116,11 @@ A lightweight, flexible, and reliable Kafka client for JavaScript/TypeScript. It
|
|
|
51
116
|
- 🎯 Type-safe interfaces (TypeScript support)
|
|
52
117
|
- ⚡ Async/await support
|
|
53
118
|
- 🛠️ Configurable consumer and producer options
|
|
54
|
-
- 📊 Stream processing support
|
|
119
|
+
- 📊 Stream processing support with configurable stream options
|
|
55
120
|
- 📦 Message batching capabilities
|
|
56
121
|
- 🔍 Comprehensive error handling
|
|
122
|
+
- 📈 Performance benchmarking suite
|
|
123
|
+
- 🔧 Flexible configuration system supporting complex data types
|
|
57
124
|
|
|
58
125
|
## Table of Contents
|
|
59
126
|
|
|
@@ -63,9 +130,10 @@ A lightweight, flexible, and reliable Kafka client for JavaScript/TypeScript. It
|
|
|
63
130
|
4. [Producer Examples](#producer-examples)
|
|
64
131
|
5. [Stream Processing](#stream-processing)
|
|
65
132
|
6. [Configuration](#configuration)
|
|
66
|
-
7. [
|
|
67
|
-
8. [
|
|
68
|
-
9. [
|
|
133
|
+
7. [Performance Benchmarks](#performance-benchmarks)
|
|
134
|
+
8. [Best Practices](#best-practices)
|
|
135
|
+
9. [Contributing](#contributing)
|
|
136
|
+
10. [License](#license)
|
|
69
137
|
|
|
70
138
|
## Installation
|
|
71
139
|
|
|
@@ -91,12 +159,21 @@ async function run() {
|
|
|
91
159
|
brokerAddressFamily: 'v4',
|
|
92
160
|
});
|
|
93
161
|
|
|
94
|
-
// Create consumer
|
|
162
|
+
// Create consumer with topic creation control
|
|
95
163
|
const consumer = kafkaClient.createConsumer({
|
|
96
164
|
groupId: 'foo-group',
|
|
165
|
+
configuration: {
|
|
166
|
+
'auto.offset.reset': 'earliest',
|
|
167
|
+
'enable.auto.commit': false, // Use manual commit for better control
|
|
168
|
+
}
|
|
97
169
|
});
|
|
98
170
|
|
|
99
|
-
|
|
171
|
+
// Subscribe with topic creation options
|
|
172
|
+
await consumer.subscribe([{
|
|
173
|
+
topic: 'foo',
|
|
174
|
+
createTopic: true,
|
|
175
|
+
numPartitions: 3
|
|
176
|
+
}]);
|
|
100
177
|
|
|
101
178
|
const message = await consumer.recv();
|
|
102
179
|
const { payload, partition, offset, topic } = message;
|
|
@@ -111,7 +188,6 @@ async function run() {
|
|
|
111
188
|
await consumer.commit(topic, partition, offset + 1, 'Sync');
|
|
112
189
|
|
|
113
190
|
consumer.unsubscribe();
|
|
114
|
-
|
|
115
191
|
}
|
|
116
192
|
|
|
117
193
|
await run();
|
|
@@ -129,7 +205,14 @@ const kafkaClient = new KafkaClient({
|
|
|
129
205
|
brokerAddressFamily: 'v4',
|
|
130
206
|
});
|
|
131
207
|
|
|
132
|
-
|
|
208
|
+
// Producer configuration is now optional with sensible defaults
|
|
209
|
+
const producer = kafkaClient.createProducer({
|
|
210
|
+
configuration: {
|
|
211
|
+
'message.timeout.ms': 5000, // Now supports number values
|
|
212
|
+
'batch.size': 16384,
|
|
213
|
+
'compression.type': 'snappy'
|
|
214
|
+
}
|
|
215
|
+
});
|
|
133
216
|
|
|
134
217
|
const message = {
|
|
135
218
|
id: 1,
|
|
@@ -150,12 +233,11 @@ if (errors.length > 0) {
|
|
|
150
233
|
} else {
|
|
151
234
|
console.log('Message sent. Offset:', result);
|
|
152
235
|
}
|
|
153
|
-
|
|
154
236
|
```
|
|
155
237
|
|
|
156
238
|
## Stream Processing
|
|
157
239
|
|
|
158
|
-
### Stream Consumer Example
|
|
240
|
+
### Enhanced Stream Consumer Example
|
|
159
241
|
|
|
160
242
|
```javascript
|
|
161
243
|
import { KafkaClient } from 'kafka-crab-js';
|
|
@@ -167,24 +249,38 @@ const kafkaClient = new KafkaClient({
|
|
|
167
249
|
brokerAddressFamily: 'v4',
|
|
168
250
|
});
|
|
169
251
|
|
|
252
|
+
// Stream consumer with custom ReadableOptions (v1.10.0+)
|
|
170
253
|
const kafkaStream = kafkaClient.createStreamConsumer({
|
|
171
|
-
groupId: `my-
|
|
254
|
+
groupId: `my-group-id`,
|
|
172
255
|
enableAutoCommit: true,
|
|
256
|
+
}, {
|
|
257
|
+
objectMode: true, // Default in v1.10.0+
|
|
258
|
+
highWaterMark: 1024,
|
|
259
|
+
encoding: null
|
|
173
260
|
});
|
|
174
261
|
|
|
175
|
-
await kafkaStream.subscribe([
|
|
262
|
+
await kafkaStream.subscribe([
|
|
263
|
+
{ topic: 'foo', createTopic: true },
|
|
264
|
+
{ topic: 'bar', createTopic: true }
|
|
265
|
+
]);
|
|
176
266
|
|
|
177
267
|
kafkaStream.on('data', (message) => {
|
|
178
|
-
console.log('>>> Message received:', {
|
|
268
|
+
console.log('>>> Message received:', {
|
|
269
|
+
payload: message.payload.toString(),
|
|
270
|
+
offset: message.offset,
|
|
271
|
+
partition: message.partition,
|
|
272
|
+
topic: message.topic
|
|
273
|
+
});
|
|
274
|
+
|
|
179
275
|
if (message.offset > 10) {
|
|
180
276
|
kafkaStream.destroy();
|
|
181
277
|
}
|
|
182
|
-
})
|
|
278
|
+
});
|
|
183
279
|
|
|
184
280
|
kafkaStream.on('close', () => {
|
|
185
281
|
kafkaStream.unsubscribe();
|
|
186
|
-
console.log('Stream ended')
|
|
187
|
-
})
|
|
282
|
+
console.log('Stream ended');
|
|
283
|
+
});
|
|
188
284
|
```
|
|
189
285
|
|
|
190
286
|
## Producer Examples
|
|
@@ -197,7 +293,16 @@ const kafkaClient = new KafkaClient({
|
|
|
197
293
|
clientId: 'my-client-id',
|
|
198
294
|
brokerAddressFamily: 'v4',
|
|
199
295
|
});
|
|
200
|
-
|
|
296
|
+
|
|
297
|
+
// Enhanced producer with flexible configuration
|
|
298
|
+
const producer = kafkaClient.createProducer({
|
|
299
|
+
configuration: {
|
|
300
|
+
'batch.size': 50000, // Number value supported
|
|
301
|
+
'linger.ms': 10, // Number value supported
|
|
302
|
+
'compression.type': 'lz4',
|
|
303
|
+
'enable.idempotence': true // Boolean value supported
|
|
304
|
+
}
|
|
305
|
+
});
|
|
201
306
|
|
|
202
307
|
const messages = Array.from({ length: 100 }, (_, i) => ({
|
|
203
308
|
payload: Buffer.from(JSON.stringify({
|
|
@@ -223,11 +328,17 @@ try {
|
|
|
223
328
|
|
|
224
329
|
```javascript
|
|
225
330
|
async function produceWithMetadata() {
|
|
226
|
-
const producer =
|
|
331
|
+
const producer = kafkaClient.createProducer({
|
|
332
|
+
configuration: {
|
|
333
|
+
'acks': 'all',
|
|
334
|
+
'retries': 5,
|
|
335
|
+
'max.in.flight.requests.per.connection': 1
|
|
336
|
+
}
|
|
337
|
+
});
|
|
227
338
|
|
|
228
339
|
try {
|
|
229
340
|
await producer.send({
|
|
230
|
-
topic,
|
|
341
|
+
topic: 'user-events',
|
|
231
342
|
messages: [{
|
|
232
343
|
key: 'user-123',
|
|
233
344
|
payload: Buffer.from(JSON.stringify({
|
|
@@ -258,6 +369,8 @@ const kafkaClient = new KafkaClient({
|
|
|
258
369
|
brokerAddressFamily: 'v4',
|
|
259
370
|
configuration: {
|
|
260
371
|
'auto.offset.reset': 'earliest',
|
|
372
|
+
'session.timeout.ms': 30000,
|
|
373
|
+
'heartbeat.interval.ms': 10000
|
|
261
374
|
},
|
|
262
375
|
})
|
|
263
376
|
|
|
@@ -268,10 +381,14 @@ async function createConsumer() {
|
|
|
268
381
|
const kafkaStream = kafkaClient.createStreamConsumer({
|
|
269
382
|
groupId: 'reconnect-test',
|
|
270
383
|
enableAutoCommit: true,
|
|
384
|
+
}, {
|
|
385
|
+
highWaterMark: 100,
|
|
386
|
+
objectMode: true
|
|
271
387
|
})
|
|
388
|
+
|
|
272
389
|
await kafkaStream.subscribe([
|
|
273
|
-
{ topic: 'foo' },
|
|
274
|
-
{ topic: 'bar' },
|
|
390
|
+
{ topic: 'foo', createTopic: true },
|
|
391
|
+
{ topic: 'bar', createTopic: true },
|
|
275
392
|
])
|
|
276
393
|
return kafkaStream
|
|
277
394
|
}
|
|
@@ -343,7 +460,7 @@ await startConsumer()
|
|
|
343
460
|
|
|
344
461
|
### Examples
|
|
345
462
|
|
|
346
|
-
You can find some examples on the [example](https://github.com/
|
|
463
|
+
You can find some examples on the [example](https://github.com/flash-tecnologia/kafka-crab-js/tree/main/example) folder of this project.
|
|
347
464
|
|
|
348
465
|
## Configuration
|
|
349
466
|
|
|
@@ -356,13 +473,101 @@ You can find some examples on the [example](https://github.com/mthssdrbrg/kafka-
|
|
|
356
473
|
| `brokers` | `string` || List of brokers to connect to |
|
|
357
474
|
| `clientId` | `string` || Client id to use for the connection |
|
|
358
475
|
| `securityProtocol` | `SecurityProtocol` || Security protocol to use (PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL) |
|
|
359
|
-
| `logLevel` | `string` | `info` |
|
|
476
|
+
| `logLevel` | `string` | `info` | Log level for the client |
|
|
360
477
|
| `brokerAddressFamily` | `string` | `"v4"` | Address family to use for the connection (v4, v6) |
|
|
361
|
-
| `configuration` | `
|
|
478
|
+
| `configuration` | `Record<string, any>` | `{}` | Additional configuration options for the client. **v1.10.0+**: Now supports any value type (string, number, boolean, object) |
|
|
479
|
+
|
|
480
|
+
### ConsumerConfiguration
|
|
481
|
+
|
|
482
|
+
| Property | Type | Default | Description |
|
|
483
|
+
| --- | --- | --- | --- |
|
|
484
|
+
| `groupId` | `string` || Consumer group ID |
|
|
485
|
+
| `enableAutoCommit` | `boolean` | `true` | Enable automatic offset commits |
|
|
486
|
+
| `configuration` | `Record<string, any>` | `{}` | Additional consumer configuration options |
|
|
487
|
+
| `fetchMetadataTimeout` | `number` | `60000` | Timeout for fetching metadata (ms) |
|
|
488
|
+
| `maxBatchMessages` | `number` | `1000` | Maximum messages in a batch operation |
|
|
489
|
+
|
|
490
|
+
### ProducerConfiguration
|
|
491
|
+
|
|
492
|
+
| Property | Type | Default | Description |
|
|
493
|
+
| --- | --- | --- | --- |
|
|
494
|
+
| `queueTimeout` | `number` | `5000` | Queue timeout in milliseconds |
|
|
495
|
+
| `autoFlush` | `boolean` | `true` | Enable automatic message flushing |
|
|
496
|
+
| `configuration` | `Record<string, any>` | `{}` | Additional producer configuration options |
|
|
497
|
+
|
|
498
|
+
### TopicPartitionConfig
|
|
499
|
+
|
|
500
|
+
| Property | Type | Default | Description |
|
|
501
|
+
| --- | --- | --- | --- |
|
|
502
|
+
| `topic` | `string` || Topic name |
|
|
503
|
+
| `allOffsets` | `OffsetModel` || Offset configuration for all partitions |
|
|
504
|
+
| `partitionOffset` | `Array<PartitionOffset>` || Per-partition offset configuration |
|
|
505
|
+
| `createTopic` | `boolean` | `false` | **v2.0.x+**: Create topic if it doesn't exist |
|
|
506
|
+
| `numPartitions` | `number` | `1` | **v2.0.x+**: Number of partitions when creating topic |
|
|
507
|
+
| `replicas` | `number` | `1` | **v2.0.x+**: Number of replicas when creating topic |
|
|
362
508
|
|
|
363
509
|
You can see the available options here: [librdkafka](https://docs.confluent.io/platform/current/clients/librdkafka/html/md_CONFIGURATION.html).
|
|
364
510
|
|
|
511
|
+
## Performance Benchmarks
|
|
512
|
+
|
|
513
|
+
### Running Benchmarks
|
|
514
|
+
|
|
515
|
+
kafka-crab-js v1.10.0+ includes a comprehensive benchmark suite to compare performance against other popular Kafka clients:
|
|
516
|
+
|
|
517
|
+
```bash
|
|
518
|
+
# Set up benchmark environment (requires Kafka running locally)
|
|
519
|
+
pnpm add -D tsx # For running TypeScript files directly
|
|
520
|
+
npx tsx benchmark/utils/setup.ts
|
|
521
|
+
|
|
522
|
+
# Run consumer performance benchmarks
|
|
523
|
+
node benchmark/consumer.ts
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### Benchmark Results
|
|
527
|
+
|
|
528
|
+
*Benchmarks run on macOS with Apple M1 chip processing 50,000 messages*
|
|
529
|
+
|
|
530
|
+
```
|
|
531
|
+
╔════════════════════════╤═════════╤══════════════════╤═══════════╤══════════════════════════╗
|
|
532
|
+
║ Slower tests │ Samples │ Result │ Tolerance │ Difference with previous ║
|
|
533
|
+
╟────────────────────────┼─────────┼──────────────────┼───────────┼──────────────────────────╢
|
|
534
|
+
║ kafkajs │ 50000 │ 2316.67 op/sec │ ± 1.12 % │ ║
|
|
535
|
+
║ kafka-crab-js (serial) │ 50000 │ 38414.57 op/sec │ ± 2.97 % │ + 1558.18 % ║
|
|
536
|
+
║ node-rdkafka (stream) │ 50000 │ 43681.44 op/sec │ ± 13.98 % │ + 13.71 % ║
|
|
537
|
+
║ node-rdkafka (evented) │ 53841 │ 74137.97 op/sec │ ± 69.30 % │ + 69.72 % ║
|
|
538
|
+
╟────────────────────────┼─────────┼──────────────────┼───────────┼──────────────────────────╢
|
|
539
|
+
║ Fastest test │ Samples │ Result │ Tolerance │ Difference with previous ║
|
|
540
|
+
╟────────────────────────┼─────────┼──────────────────┼───────────┼──────────────────────────╢
|
|
541
|
+
║ kafka-crab-js (batch) │ 50000 │ 153533.53 op/sec │ ± 15.98 % │ + 107.09 % ║
|
|
542
|
+
╚════════════════════════╧═════════╧══════════════════╧═══════════╧══════════════════════════╝
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
The benchmark suite compares:
|
|
546
|
+
- **kafka-crab-js (serial)**: Single message processing - **38,415 ops/sec**
|
|
547
|
+
- **kafka-crab-js (batch)**: Batch message processing - **153,534 ops/sec** (fastest)
|
|
548
|
+
- **node-rdkafka (evented)**: Event-based processing - **74,138 ops/sec**
|
|
549
|
+
- **node-rdkafka (stream)**: Stream-based processing - **43,681 ops/sec**
|
|
550
|
+
- **kafkajs**: Official KafkaJS client - **2,317 ops/sec**
|
|
551
|
+
|
|
552
|
+
Performance characteristics:
|
|
553
|
+
- **17x faster than kafkajs** in serial mode, **66x faster in batch mode**
|
|
554
|
+
- **High throughput**: Batch processing provides 4x performance improvement over serial mode
|
|
555
|
+
- **Low latency**: Optimized for both single and batch message processing
|
|
556
|
+
- **Memory efficient**: Lock-free data structures minimize memory overhead
|
|
557
|
+
- **Concurrent processing**: Zero-contention concurrent operations
|
|
558
|
+
|
|
559
|
+
### Benchmark Configuration
|
|
365
560
|
|
|
561
|
+
You can customize benchmark parameters in `benchmark/utils/definitions.ts`:
|
|
562
|
+
|
|
563
|
+
```typescript
|
|
564
|
+
export const topic = 'benchmarks'
|
|
565
|
+
export const brokers = ['localhost:9092', 'localhost:9093', 'localhost:9094']
|
|
566
|
+
|
|
567
|
+
// Benchmark parameters can be adjusted in consumer.ts:
|
|
568
|
+
const iterations = 10_000 // Number of messages to process
|
|
569
|
+
const maxBytes = 200 // Maximum message size
|
|
570
|
+
```
|
|
366
571
|
|
|
367
572
|
## Best Practices
|
|
368
573
|
|
|
@@ -373,21 +578,60 @@ You can see the available options here: [librdkafka](https://docs.confluent.io/p
|
|
|
373
578
|
|
|
374
579
|
### Performance
|
|
375
580
|
- Use batch operations for high-throughput scenarios
|
|
376
|
-
- Configure appropriate batch sizes and compression
|
|
581
|
+
- Configure appropriate batch sizes and compression settings
|
|
377
582
|
- Monitor and tune consumer group performance
|
|
583
|
+
- Leverage the benchmark suite to optimize your specific use case
|
|
584
|
+
|
|
585
|
+
### Configuration (v1.10.0+)
|
|
586
|
+
- Use the flexible configuration system with proper data types:
|
|
587
|
+
```javascript
|
|
588
|
+
const config = {
|
|
589
|
+
'batch.size': 16384, // number
|
|
590
|
+
'compression.type': 'snappy', // string
|
|
591
|
+
'enable.idempotence': true, // boolean
|
|
592
|
+
'retries': 5 // number
|
|
593
|
+
}
|
|
594
|
+
```
|
|
378
595
|
|
|
379
596
|
### Message Processing
|
|
380
597
|
- Validate message formats before processing
|
|
381
598
|
- Implement proper serialization/deserialization
|
|
382
599
|
- Handle message ordering when required
|
|
600
|
+
- Use topic creation options for better topic management
|
|
601
|
+
|
|
602
|
+
### Stream Processing (v1.10.0+)
|
|
603
|
+
- Configure appropriate `ReadableOptions` for your use case
|
|
604
|
+
- Use `objectMode: true` for structured message processing
|
|
605
|
+
- Set appropriate `highWaterMark` based on memory constraints
|
|
383
606
|
|
|
384
607
|
## Contributing
|
|
385
608
|
|
|
386
609
|
1. Fork the repository
|
|
387
610
|
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
388
|
-
3.
|
|
389
|
-
4.
|
|
390
|
-
5.
|
|
611
|
+
3. Run the benchmark suite to ensure performance isn't degraded
|
|
612
|
+
4. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
613
|
+
5. Push to the branch (`git push origin feature/amazing-feature`)
|
|
614
|
+
6. Open a Pull Request
|
|
615
|
+
|
|
616
|
+
### Development Commands
|
|
617
|
+
|
|
618
|
+
```bash
|
|
619
|
+
# Build the project
|
|
620
|
+
pnpm build
|
|
621
|
+
|
|
622
|
+
# Run type checking
|
|
623
|
+
pnpm typecheck
|
|
624
|
+
|
|
625
|
+
# Run linting
|
|
626
|
+
pnpm lint
|
|
627
|
+
|
|
628
|
+
# Format code
|
|
629
|
+
pnpm fmt
|
|
630
|
+
|
|
631
|
+
# Run benchmarks
|
|
632
|
+
npx tsx benchmark/utils/setup.ts
|
|
633
|
+
npx tsx benchmark/consumer.ts
|
|
634
|
+
```
|
|
391
635
|
|
|
392
636
|
## License
|
|
393
637
|
|