@ohos-ports/confluentinc-kafka-javascript 1.10.0-beta.1

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.
Files changed (628) hide show
  1. package/CHANGELOG.md +457 -0
  2. package/LICENSE.kafkajs +31 -0
  3. package/LICENSE.node-rdkafka +25 -0
  4. package/LICENSE.txt +20 -0
  5. package/README.md +133 -0
  6. package/binding.gyp +184 -0
  7. package/build/Release/confluent-kafka-javascript.node +0 -0
  8. package/build/deps/librdkafka++.so.1 +0 -0
  9. package/build/deps/librdkafka.Makefile +6 -0
  10. package/build/deps/librdkafka.so.1 +0 -0
  11. package/build/deps/librdkafka.target.mk +55 -0
  12. package/deps/librdkafka/.clang-format +136 -0
  13. package/deps/librdkafka/.clang-format-cpp +103 -0
  14. package/deps/librdkafka/.dir-locals.el +10 -0
  15. package/deps/librdkafka/.formatignore +35 -0
  16. package/deps/librdkafka/.gdbmacros +19 -0
  17. package/deps/librdkafka/CHANGELOG.md +2477 -0
  18. package/deps/librdkafka/CMakeLists.txt +291 -0
  19. package/deps/librdkafka/CODE_OF_CONDUCT.md +46 -0
  20. package/deps/librdkafka/CONFIGURATION.md +212 -0
  21. package/deps/librdkafka/CONTRIBUTING.md +431 -0
  22. package/deps/librdkafka/Doxyfile +2375 -0
  23. package/deps/librdkafka/INTRODUCTION.md +2752 -0
  24. package/deps/librdkafka/LICENSE +26 -0
  25. package/deps/librdkafka/LICENSE.cjson +22 -0
  26. package/deps/librdkafka/LICENSE.crc32c +28 -0
  27. package/deps/librdkafka/LICENSE.fnv1a +18 -0
  28. package/deps/librdkafka/LICENSE.hdrhistogram +27 -0
  29. package/deps/librdkafka/LICENSE.lz4 +26 -0
  30. package/deps/librdkafka/LICENSE.murmur2 +25 -0
  31. package/deps/librdkafka/LICENSE.nanopb +22 -0
  32. package/deps/librdkafka/LICENSE.opentelemetry +203 -0
  33. package/deps/librdkafka/LICENSE.pycrc +23 -0
  34. package/deps/librdkafka/LICENSE.queue +31 -0
  35. package/deps/librdkafka/LICENSE.regexp +5 -0
  36. package/deps/librdkafka/LICENSE.snappy +36 -0
  37. package/deps/librdkafka/LICENSE.tinycthread +26 -0
  38. package/deps/librdkafka/LICENSE.wingetopt +49 -0
  39. package/deps/librdkafka/LICENSES.txt +625 -0
  40. package/deps/librdkafka/Makefile +125 -0
  41. package/deps/librdkafka/README.md +201 -0
  42. package/deps/librdkafka/README.win32 +26 -0
  43. package/deps/librdkafka/STATISTICS.md +624 -0
  44. package/deps/librdkafka/configure +214 -0
  45. package/deps/librdkafka/configure.self +341 -0
  46. package/deps/librdkafka/dev-conf.sh +123 -0
  47. package/deps/librdkafka/lds-gen.py +73 -0
  48. package/deps/librdkafka/mainpage.doxy +40 -0
  49. package/deps/librdkafka/mklove/Makefile.base +329 -0
  50. package/deps/librdkafka/mklove/modules/configure.atomics +144 -0
  51. package/deps/librdkafka/mklove/modules/configure.base +2484 -0
  52. package/deps/librdkafka/mklove/modules/configure.builtin +70 -0
  53. package/deps/librdkafka/mklove/modules/configure.cc +186 -0
  54. package/deps/librdkafka/mklove/modules/configure.cxx +8 -0
  55. package/deps/librdkafka/mklove/modules/configure.fileversion +65 -0
  56. package/deps/librdkafka/mklove/modules/configure.gitversion +29 -0
  57. package/deps/librdkafka/mklove/modules/configure.good_cflags +18 -0
  58. package/deps/librdkafka/mklove/modules/configure.host +132 -0
  59. package/deps/librdkafka/mklove/modules/configure.lib +49 -0
  60. package/deps/librdkafka/mklove/modules/configure.libcurl +99 -0
  61. package/deps/librdkafka/mklove/modules/configure.libsasl2 +36 -0
  62. package/deps/librdkafka/mklove/modules/configure.libssl +147 -0
  63. package/deps/librdkafka/mklove/modules/configure.libzstd +58 -0
  64. package/deps/librdkafka/mklove/modules/configure.parseversion +95 -0
  65. package/deps/librdkafka/mklove/modules/configure.pic +16 -0
  66. package/deps/librdkafka/mklove/modules/configure.socket +20 -0
  67. package/deps/librdkafka/mklove/modules/configure.zlib +61 -0
  68. package/deps/librdkafka/mklove/modules/patches/README.md +8 -0
  69. package/deps/librdkafka/mklove/modules/patches/libcurl.0000-no-runtime-linking-check.patch +11 -0
  70. package/deps/librdkafka/mklove/modules/patches/libssl.0000-osx-rand-include-fix-OpenSSL-PR16409.patch +56 -0
  71. package/deps/librdkafka/service.yml +182 -0
  72. package/deps/librdkafka/src/CMakeLists.txt +379 -0
  73. package/deps/librdkafka/src/Makefile +105 -0
  74. package/deps/librdkafka/src/README.lz4.md +30 -0
  75. package/deps/librdkafka/src/cJSON.c +3191 -0
  76. package/deps/librdkafka/src/cJSON.h +306 -0
  77. package/deps/librdkafka/src/crc32c.c +430 -0
  78. package/deps/librdkafka/src/crc32c.h +38 -0
  79. package/deps/librdkafka/src/generate_proto.sh +66 -0
  80. package/deps/librdkafka/src/librdkafka_cgrp_synch.png +0 -0
  81. package/deps/librdkafka/src/lz4.c +2727 -0
  82. package/deps/librdkafka/src/lz4.h +842 -0
  83. package/deps/librdkafka/src/lz4frame.c +2078 -0
  84. package/deps/librdkafka/src/lz4frame.h +692 -0
  85. package/deps/librdkafka/src/lz4frame_static.h +47 -0
  86. package/deps/librdkafka/src/lz4hc.c +1631 -0
  87. package/deps/librdkafka/src/lz4hc.h +413 -0
  88. package/deps/librdkafka/src/nanopb/pb.h +917 -0
  89. package/deps/librdkafka/src/nanopb/pb_common.c +388 -0
  90. package/deps/librdkafka/src/nanopb/pb_common.h +49 -0
  91. package/deps/librdkafka/src/nanopb/pb_decode.c +1727 -0
  92. package/deps/librdkafka/src/nanopb/pb_decode.h +193 -0
  93. package/deps/librdkafka/src/nanopb/pb_encode.c +1000 -0
  94. package/deps/librdkafka/src/nanopb/pb_encode.h +185 -0
  95. package/deps/librdkafka/src/opentelemetry/common.pb.c +32 -0
  96. package/deps/librdkafka/src/opentelemetry/common.pb.h +170 -0
  97. package/deps/librdkafka/src/opentelemetry/metrics.options +2 -0
  98. package/deps/librdkafka/src/opentelemetry/metrics.pb.c +67 -0
  99. package/deps/librdkafka/src/opentelemetry/metrics.pb.h +966 -0
  100. package/deps/librdkafka/src/opentelemetry/resource.pb.c +12 -0
  101. package/deps/librdkafka/src/opentelemetry/resource.pb.h +58 -0
  102. package/deps/librdkafka/src/queue.h +850 -0
  103. package/deps/librdkafka/src/rd.h +592 -0
  104. package/deps/librdkafka/src/rdaddr.c +255 -0
  105. package/deps/librdkafka/src/rdaddr.h +202 -0
  106. package/deps/librdkafka/src/rdatomic.h +262 -0
  107. package/deps/librdkafka/src/rdavg.h +260 -0
  108. package/deps/librdkafka/src/rdavl.c +210 -0
  109. package/deps/librdkafka/src/rdavl.h +250 -0
  110. package/deps/librdkafka/src/rdbase64.c +200 -0
  111. package/deps/librdkafka/src/rdbase64.h +43 -0
  112. package/deps/librdkafka/src/rdbuf.c +1884 -0
  113. package/deps/librdkafka/src/rdbuf.h +375 -0
  114. package/deps/librdkafka/src/rdcrc32.c +114 -0
  115. package/deps/librdkafka/src/rdcrc32.h +170 -0
  116. package/deps/librdkafka/src/rddl.c +179 -0
  117. package/deps/librdkafka/src/rddl.h +43 -0
  118. package/deps/librdkafka/src/rdendian.h +175 -0
  119. package/deps/librdkafka/src/rdfloat.h +67 -0
  120. package/deps/librdkafka/src/rdfnv1a.c +113 -0
  121. package/deps/librdkafka/src/rdfnv1a.h +35 -0
  122. package/deps/librdkafka/src/rdgz.c +120 -0
  123. package/deps/librdkafka/src/rdgz.h +46 -0
  124. package/deps/librdkafka/src/rdhdrhistogram.c +721 -0
  125. package/deps/librdkafka/src/rdhdrhistogram.h +87 -0
  126. package/deps/librdkafka/src/rdhttp.c +831 -0
  127. package/deps/librdkafka/src/rdhttp.h +101 -0
  128. package/deps/librdkafka/src/rdinterval.h +177 -0
  129. package/deps/librdkafka/src/rdkafka.c +7287 -0
  130. package/deps/librdkafka/src/rdkafka.h +11795 -0
  131. package/deps/librdkafka/src/rdkafka_admin.c +10165 -0
  132. package/deps/librdkafka/src/rdkafka_admin.h +658 -0
  133. package/deps/librdkafka/src/rdkafka_assignment.c +1282 -0
  134. package/deps/librdkafka/src/rdkafka_assignment.h +73 -0
  135. package/deps/librdkafka/src/rdkafka_assignor.c +1800 -0
  136. package/deps/librdkafka/src/rdkafka_assignor.h +402 -0
  137. package/deps/librdkafka/src/rdkafka_aux.c +409 -0
  138. package/deps/librdkafka/src/rdkafka_aux.h +174 -0
  139. package/deps/librdkafka/src/rdkafka_background.c +222 -0
  140. package/deps/librdkafka/src/rdkafka_broker.c +6736 -0
  141. package/deps/librdkafka/src/rdkafka_broker.h +851 -0
  142. package/deps/librdkafka/src/rdkafka_buf.c +543 -0
  143. package/deps/librdkafka/src/rdkafka_buf.h +1525 -0
  144. package/deps/librdkafka/src/rdkafka_cert.c +576 -0
  145. package/deps/librdkafka/src/rdkafka_cert.h +62 -0
  146. package/deps/librdkafka/src/rdkafka_cgrp.c +8310 -0
  147. package/deps/librdkafka/src/rdkafka_cgrp.h +589 -0
  148. package/deps/librdkafka/src/rdkafka_conf.c +5177 -0
  149. package/deps/librdkafka/src/rdkafka_conf.h +746 -0
  150. package/deps/librdkafka/src/rdkafka_confval.h +97 -0
  151. package/deps/librdkafka/src/rdkafka_coord.c +623 -0
  152. package/deps/librdkafka/src/rdkafka_coord.h +132 -0
  153. package/deps/librdkafka/src/rdkafka_error.c +228 -0
  154. package/deps/librdkafka/src/rdkafka_error.h +80 -0
  155. package/deps/librdkafka/src/rdkafka_event.c +502 -0
  156. package/deps/librdkafka/src/rdkafka_event.h +126 -0
  157. package/deps/librdkafka/src/rdkafka_feature.c +898 -0
  158. package/deps/librdkafka/src/rdkafka_feature.h +104 -0
  159. package/deps/librdkafka/src/rdkafka_fetcher.c +3820 -0
  160. package/deps/librdkafka/src/rdkafka_fetcher.h +62 -0
  161. package/deps/librdkafka/src/rdkafka_header.c +220 -0
  162. package/deps/librdkafka/src/rdkafka_header.h +76 -0
  163. package/deps/librdkafka/src/rdkafka_idempotence.c +807 -0
  164. package/deps/librdkafka/src/rdkafka_idempotence.h +144 -0
  165. package/deps/librdkafka/src/rdkafka_int.h +1505 -0
  166. package/deps/librdkafka/src/rdkafka_interceptor.c +842 -0
  167. package/deps/librdkafka/src/rdkafka_interceptor.h +104 -0
  168. package/deps/librdkafka/src/rdkafka_lz4.c +450 -0
  169. package/deps/librdkafka/src/rdkafka_lz4.h +49 -0
  170. package/deps/librdkafka/src/rdkafka_metadata.c +2347 -0
  171. package/deps/librdkafka/src/rdkafka_metadata.h +350 -0
  172. package/deps/librdkafka/src/rdkafka_metadata_cache.c +1183 -0
  173. package/deps/librdkafka/src/rdkafka_mock.c +4514 -0
  174. package/deps/librdkafka/src/rdkafka_mock.h +867 -0
  175. package/deps/librdkafka/src/rdkafka_mock_cgrp.c +1877 -0
  176. package/deps/librdkafka/src/rdkafka_mock_handlers.c +5255 -0
  177. package/deps/librdkafka/src/rdkafka_mock_int.h +1005 -0
  178. package/deps/librdkafka/src/rdkafka_mock_sharegrp.c +1207 -0
  179. package/deps/librdkafka/src/rdkafka_msg.c +2619 -0
  180. package/deps/librdkafka/src/rdkafka_msg.h +629 -0
  181. package/deps/librdkafka/src/rdkafka_msgbatch.h +62 -0
  182. package/deps/librdkafka/src/rdkafka_msgset.h +105 -0
  183. package/deps/librdkafka/src/rdkafka_msgset_reader.c +2099 -0
  184. package/deps/librdkafka/src/rdkafka_msgset_writer.c +1474 -0
  185. package/deps/librdkafka/src/rdkafka_offset.c +1565 -0
  186. package/deps/librdkafka/src/rdkafka_offset.h +150 -0
  187. package/deps/librdkafka/src/rdkafka_op.c +1219 -0
  188. package/deps/librdkafka/src/rdkafka_op.h +1065 -0
  189. package/deps/librdkafka/src/rdkafka_partition.c +5109 -0
  190. package/deps/librdkafka/src/rdkafka_partition.h +1215 -0
  191. package/deps/librdkafka/src/rdkafka_pattern.c +228 -0
  192. package/deps/librdkafka/src/rdkafka_pattern.h +70 -0
  193. package/deps/librdkafka/src/rdkafka_plugin.c +213 -0
  194. package/deps/librdkafka/src/rdkafka_plugin.h +41 -0
  195. package/deps/librdkafka/src/rdkafka_proto.h +739 -0
  196. package/deps/librdkafka/src/rdkafka_protocol.h +131 -0
  197. package/deps/librdkafka/src/rdkafka_queue.c +1351 -0
  198. package/deps/librdkafka/src/rdkafka_queue.h +1235 -0
  199. package/deps/librdkafka/src/rdkafka_range_assignor.c +1748 -0
  200. package/deps/librdkafka/src/rdkafka_request.c +7298 -0
  201. package/deps/librdkafka/src/rdkafka_request.h +761 -0
  202. package/deps/librdkafka/src/rdkafka_roundrobin_assignor.c +123 -0
  203. package/deps/librdkafka/src/rdkafka_sasl.c +589 -0
  204. package/deps/librdkafka/src/rdkafka_sasl.h +63 -0
  205. package/deps/librdkafka/src/rdkafka_sasl_cyrus.c +722 -0
  206. package/deps/librdkafka/src/rdkafka_sasl_int.h +89 -0
  207. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.c +1833 -0
  208. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer.h +52 -0
  209. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.c +1827 -0
  210. package/deps/librdkafka/src/rdkafka_sasl_oauthbearer_oidc.h +52 -0
  211. package/deps/librdkafka/src/rdkafka_sasl_plain.c +142 -0
  212. package/deps/librdkafka/src/rdkafka_sasl_scram.c +858 -0
  213. package/deps/librdkafka/src/rdkafka_sasl_win32.c +550 -0
  214. package/deps/librdkafka/src/rdkafka_share_acknowledgement.c +1445 -0
  215. package/deps/librdkafka/src/rdkafka_share_acknowledgement.h +373 -0
  216. package/deps/librdkafka/src/rdkafka_ssl.c +2235 -0
  217. package/deps/librdkafka/src/rdkafka_ssl.h +86 -0
  218. package/deps/librdkafka/src/rdkafka_sticky_assignor.c +4785 -0
  219. package/deps/librdkafka/src/rdkafka_subscription.c +411 -0
  220. package/deps/librdkafka/src/rdkafka_telemetry.c +761 -0
  221. package/deps/librdkafka/src/rdkafka_telemetry.h +52 -0
  222. package/deps/librdkafka/src/rdkafka_telemetry_decode.c +1307 -0
  223. package/deps/librdkafka/src/rdkafka_telemetry_decode.h +59 -0
  224. package/deps/librdkafka/src/rdkafka_telemetry_encode.c +1309 -0
  225. package/deps/librdkafka/src/rdkafka_telemetry_encode.h +459 -0
  226. package/deps/librdkafka/src/rdkafka_timer.c +407 -0
  227. package/deps/librdkafka/src/rdkafka_timer.h +117 -0
  228. package/deps/librdkafka/src/rdkafka_topic.c +2382 -0
  229. package/deps/librdkafka/src/rdkafka_topic.h +369 -0
  230. package/deps/librdkafka/src/rdkafka_transport.c +1309 -0
  231. package/deps/librdkafka/src/rdkafka_transport.h +99 -0
  232. package/deps/librdkafka/src/rdkafka_transport_int.h +100 -0
  233. package/deps/librdkafka/src/rdkafka_txnmgr.c +3256 -0
  234. package/deps/librdkafka/src/rdkafka_txnmgr.h +171 -0
  235. package/deps/librdkafka/src/rdkafka_zstd.c +226 -0
  236. package/deps/librdkafka/src/rdkafka_zstd.h +57 -0
  237. package/deps/librdkafka/src/rdlist.c +593 -0
  238. package/deps/librdkafka/src/rdlist.h +444 -0
  239. package/deps/librdkafka/src/rdlog.c +89 -0
  240. package/deps/librdkafka/src/rdlog.h +41 -0
  241. package/deps/librdkafka/src/rdmap.c +508 -0
  242. package/deps/librdkafka/src/rdmap.h +492 -0
  243. package/deps/librdkafka/src/rdmurmur2.c +167 -0
  244. package/deps/librdkafka/src/rdmurmur2.h +35 -0
  245. package/deps/librdkafka/src/rdports.c +61 -0
  246. package/deps/librdkafka/src/rdports.h +38 -0
  247. package/deps/librdkafka/src/rdposix.h +250 -0
  248. package/deps/librdkafka/src/rdrand.c +151 -0
  249. package/deps/librdkafka/src/rdrand.h +72 -0
  250. package/deps/librdkafka/src/rdregex.c +156 -0
  251. package/deps/librdkafka/src/rdregex.h +43 -0
  252. package/deps/librdkafka/src/rdsignal.h +57 -0
  253. package/deps/librdkafka/src/rdstring.c +645 -0
  254. package/deps/librdkafka/src/rdstring.h +98 -0
  255. package/deps/librdkafka/src/rdsysqueue.h +404 -0
  256. package/deps/librdkafka/src/rdtime.h +356 -0
  257. package/deps/librdkafka/src/rdtypes.h +86 -0
  258. package/deps/librdkafka/src/rdunittest.c +564 -0
  259. package/deps/librdkafka/src/rdunittest.h +232 -0
  260. package/deps/librdkafka/src/rdunittest_acknowledge.c +1177 -0
  261. package/deps/librdkafka/src/rdunittest_fetcher.c +1211 -0
  262. package/deps/librdkafka/src/rdunittest_msgset_errors.c +1521 -0
  263. package/deps/librdkafka/src/rdvarint.c +134 -0
  264. package/deps/librdkafka/src/rdvarint.h +165 -0
  265. package/deps/librdkafka/src/rdwin32.h +382 -0
  266. package/deps/librdkafka/src/rdxxhash.c +1030 -0
  267. package/deps/librdkafka/src/rdxxhash.h +328 -0
  268. package/deps/librdkafka/src/regexp.c +1352 -0
  269. package/deps/librdkafka/src/regexp.h +41 -0
  270. package/deps/librdkafka/src/snappy.c +1866 -0
  271. package/deps/librdkafka/src/snappy.h +62 -0
  272. package/deps/librdkafka/src/snappy_compat.h +138 -0
  273. package/deps/librdkafka/src/statistics_schema.json +444 -0
  274. package/deps/librdkafka/src/tinycthread.c +932 -0
  275. package/deps/librdkafka/src/tinycthread.h +503 -0
  276. package/deps/librdkafka/src/tinycthread_extra.c +210 -0
  277. package/deps/librdkafka/src/tinycthread_extra.h +218 -0
  278. package/deps/librdkafka/src/win32_config.h +58 -0
  279. package/deps/librdkafka/src-cpp/CMakeLists.txt +90 -0
  280. package/deps/librdkafka/src-cpp/ConfImpl.cpp +84 -0
  281. package/deps/librdkafka/src-cpp/ConsumerImpl.cpp +244 -0
  282. package/deps/librdkafka/src-cpp/HandleImpl.cpp +436 -0
  283. package/deps/librdkafka/src-cpp/HeadersImpl.cpp +48 -0
  284. package/deps/librdkafka/src-cpp/KafkaConsumerImpl.cpp +296 -0
  285. package/deps/librdkafka/src-cpp/Makefile +55 -0
  286. package/deps/librdkafka/src-cpp/MessageImpl.cpp +38 -0
  287. package/deps/librdkafka/src-cpp/MetadataImpl.cpp +170 -0
  288. package/deps/librdkafka/src-cpp/ProducerImpl.cpp +197 -0
  289. package/deps/librdkafka/src-cpp/QueueImpl.cpp +70 -0
  290. package/deps/librdkafka/src-cpp/README.md +16 -0
  291. package/deps/librdkafka/src-cpp/RdKafka.cpp +59 -0
  292. package/deps/librdkafka/src-cpp/TopicImpl.cpp +124 -0
  293. package/deps/librdkafka/src-cpp/TopicPartitionImpl.cpp +57 -0
  294. package/deps/librdkafka/src-cpp/rdkafkacpp.h +3797 -0
  295. package/deps/librdkafka/src-cpp/rdkafkacpp_int.h +1641 -0
  296. package/deps/librdkafka/tests/0000-unittests.c +72 -0
  297. package/deps/librdkafka/tests/0001-multiobj.c +102 -0
  298. package/deps/librdkafka/tests/0002-unkpart.c +244 -0
  299. package/deps/librdkafka/tests/0003-msgmaxsize.c +173 -0
  300. package/deps/librdkafka/tests/0004-conf.c +934 -0
  301. package/deps/librdkafka/tests/0005-order.c +133 -0
  302. package/deps/librdkafka/tests/0006-symbols.c +163 -0
  303. package/deps/librdkafka/tests/0007-autotopic.c +136 -0
  304. package/deps/librdkafka/tests/0008-reqacks.c +179 -0
  305. package/deps/librdkafka/tests/0009-mock_cluster.c +272 -0
  306. package/deps/librdkafka/tests/0011-produce_batch.c +753 -0
  307. package/deps/librdkafka/tests/0012-produce_consume.c +537 -0
  308. package/deps/librdkafka/tests/0013-null-msgs.c +473 -0
  309. package/deps/librdkafka/tests/0014-reconsume-191.c +512 -0
  310. package/deps/librdkafka/tests/0015-offset_seeks.c +172 -0
  311. package/deps/librdkafka/tests/0016-client_swname.c +181 -0
  312. package/deps/librdkafka/tests/0017-compression.c +140 -0
  313. package/deps/librdkafka/tests/0018-cgrp_term.c +444 -0
  314. package/deps/librdkafka/tests/0019-list_groups.c +289 -0
  315. package/deps/librdkafka/tests/0020-destroy_hang.c +162 -0
  316. package/deps/librdkafka/tests/0021-rkt_destroy.c +72 -0
  317. package/deps/librdkafka/tests/0022-consume_batch.c +331 -0
  318. package/deps/librdkafka/tests/0025-timers.c +147 -0
  319. package/deps/librdkafka/tests/0026-consume_pause.c +547 -0
  320. package/deps/librdkafka/tests/0028-long_topicnames.c +79 -0
  321. package/deps/librdkafka/tests/0029-assign_offset.c +202 -0
  322. package/deps/librdkafka/tests/0030-offset_commit.c +589 -0
  323. package/deps/librdkafka/tests/0031-get_offsets.c +235 -0
  324. package/deps/librdkafka/tests/0033-regex_subscribe.c +536 -0
  325. package/deps/librdkafka/tests/0034-offset_reset.c +398 -0
  326. package/deps/librdkafka/tests/0035-api_version.c +73 -0
  327. package/deps/librdkafka/tests/0036-partial_fetch.c +87 -0
  328. package/deps/librdkafka/tests/0037-destroy_hang_local.c +85 -0
  329. package/deps/librdkafka/tests/0038-performance.c +121 -0
  330. package/deps/librdkafka/tests/0039-event.c +284 -0
  331. package/deps/librdkafka/tests/0040-io_event.c +257 -0
  332. package/deps/librdkafka/tests/0041-fetch_max_bytes.c +97 -0
  333. package/deps/librdkafka/tests/0042-many_topics.c +252 -0
  334. package/deps/librdkafka/tests/0043-no_connection.c +77 -0
  335. package/deps/librdkafka/tests/0044-partition_cnt.c +94 -0
  336. package/deps/librdkafka/tests/0045-subscribe_update.c +1010 -0
  337. package/deps/librdkafka/tests/0046-rkt_cache.c +65 -0
  338. package/deps/librdkafka/tests/0047-partial_buf_tmout.c +98 -0
  339. package/deps/librdkafka/tests/0048-partitioner.c +283 -0
  340. package/deps/librdkafka/tests/0049-consume_conn_close.c +162 -0
  341. package/deps/librdkafka/tests/0050-subscribe_adds.c +145 -0
  342. package/deps/librdkafka/tests/0051-assign_adds.c +126 -0
  343. package/deps/librdkafka/tests/0052-msg_timestamps.c +238 -0
  344. package/deps/librdkafka/tests/0053-stats_cb.cpp +527 -0
  345. package/deps/librdkafka/tests/0054-offset_time.cpp +236 -0
  346. package/deps/librdkafka/tests/0055-producer_latency.c +539 -0
  347. package/deps/librdkafka/tests/0056-balanced_group_mt.c +315 -0
  348. package/deps/librdkafka/tests/0057-invalid_topic.cpp +112 -0
  349. package/deps/librdkafka/tests/0058-log.cpp +123 -0
  350. package/deps/librdkafka/tests/0059-bsearch.cpp +241 -0
  351. package/deps/librdkafka/tests/0060-op_prio.cpp +163 -0
  352. package/deps/librdkafka/tests/0061-consumer_lag.cpp +295 -0
  353. package/deps/librdkafka/tests/0062-stats_event.c +126 -0
  354. package/deps/librdkafka/tests/0063-clusterid.cpp +180 -0
  355. package/deps/librdkafka/tests/0064-interceptors.c +529 -0
  356. package/deps/librdkafka/tests/0065-yield.cpp +140 -0
  357. package/deps/librdkafka/tests/0066-plugins.cpp +143 -0
  358. package/deps/librdkafka/tests/0067-empty_topic.cpp +151 -0
  359. package/deps/librdkafka/tests/0068-produce_timeout.c +136 -0
  360. package/deps/librdkafka/tests/0069-consumer_add_parts.c +119 -0
  361. package/deps/librdkafka/tests/0070-null_empty.cpp +197 -0
  362. package/deps/librdkafka/tests/0072-headers_ut.c +448 -0
  363. package/deps/librdkafka/tests/0073-headers.c +381 -0
  364. package/deps/librdkafka/tests/0074-producev.c +87 -0
  365. package/deps/librdkafka/tests/0075-retry.c +290 -0
  366. package/deps/librdkafka/tests/0076-produce_retry.c +452 -0
  367. package/deps/librdkafka/tests/0077-compaction.c +366 -0
  368. package/deps/librdkafka/tests/0078-c_from_cpp.cpp +96 -0
  369. package/deps/librdkafka/tests/0079-fork.c +93 -0
  370. package/deps/librdkafka/tests/0080-admin_ut.c +3095 -0
  371. package/deps/librdkafka/tests/0081-admin.c +5633 -0
  372. package/deps/librdkafka/tests/0082-fetch_max_bytes.cpp +137 -0
  373. package/deps/librdkafka/tests/0083-cb_event.c +233 -0
  374. package/deps/librdkafka/tests/0084-destroy_flags.c +208 -0
  375. package/deps/librdkafka/tests/0085-headers.cpp +392 -0
  376. package/deps/librdkafka/tests/0086-purge.c +368 -0
  377. package/deps/librdkafka/tests/0088-produce_metadata_timeout.c +162 -0
  378. package/deps/librdkafka/tests/0089-max_poll_interval.c +511 -0
  379. package/deps/librdkafka/tests/0090-idempotence.c +171 -0
  380. package/deps/librdkafka/tests/0091-max_poll_interval_timeout.c +295 -0
  381. package/deps/librdkafka/tests/0092-mixed_msgver.c +103 -0
  382. package/deps/librdkafka/tests/0093-holb.c +200 -0
  383. package/deps/librdkafka/tests/0094-idempotence_msg_timeout.c +231 -0
  384. package/deps/librdkafka/tests/0095-all_brokers_down.cpp +122 -0
  385. package/deps/librdkafka/tests/0097-ssl_verify.cpp +674 -0
  386. package/deps/librdkafka/tests/0098-consumer-txn.cpp +1218 -0
  387. package/deps/librdkafka/tests/0099-commit_metadata.c +194 -0
  388. package/deps/librdkafka/tests/0100-thread_interceptors.cpp +195 -0
  389. package/deps/librdkafka/tests/0101-fetch-from-follower.cpp +446 -0
  390. package/deps/librdkafka/tests/0102-static_group_rebalance.c +836 -0
  391. package/deps/librdkafka/tests/0103-transactions.c +1383 -0
  392. package/deps/librdkafka/tests/0104-fetch_from_follower_mock.c +625 -0
  393. package/deps/librdkafka/tests/0105-transactions_mock.c +3930 -0
  394. package/deps/librdkafka/tests/0106-cgrp_sess_timeout.c +318 -0
  395. package/deps/librdkafka/tests/0107-topic_recreate.c +259 -0
  396. package/deps/librdkafka/tests/0109-auto_create_topics.cpp +278 -0
  397. package/deps/librdkafka/tests/0110-batch_size.cpp +182 -0
  398. package/deps/librdkafka/tests/0111-delay_create_topics.cpp +127 -0
  399. package/deps/librdkafka/tests/0112-assign_unknown_part.c +87 -0
  400. package/deps/librdkafka/tests/0113-cooperative_rebalance.cpp +3473 -0
  401. package/deps/librdkafka/tests/0114-sticky_partitioning.cpp +176 -0
  402. package/deps/librdkafka/tests/0115-producer_auth.cpp +182 -0
  403. package/deps/librdkafka/tests/0116-kafkaconsumer_close.cpp +216 -0
  404. package/deps/librdkafka/tests/0117-mock_errors.c +331 -0
  405. package/deps/librdkafka/tests/0118-commit_rebalance.c +154 -0
  406. package/deps/librdkafka/tests/0119-consumer_auth.cpp +167 -0
  407. package/deps/librdkafka/tests/0120-asymmetric_subscription.c +185 -0
  408. package/deps/librdkafka/tests/0121-clusterid.c +115 -0
  409. package/deps/librdkafka/tests/0122-buffer_cleaning_after_rebalance.c +227 -0
  410. package/deps/librdkafka/tests/0123-connections_max_idle.c +98 -0
  411. package/deps/librdkafka/tests/0124-openssl_invalid_engine.c +69 -0
  412. package/deps/librdkafka/tests/0125-immediate_flush.c +144 -0
  413. package/deps/librdkafka/tests/0126-oauthbearer_oidc.c +1164 -0
  414. package/deps/librdkafka/tests/0127-fetch_queue_backoff.cpp +165 -0
  415. package/deps/librdkafka/tests/0128-sasl_callback_queue.cpp +217 -0
  416. package/deps/librdkafka/tests/0129-fetch_aborted_msgs.c +79 -0
  417. package/deps/librdkafka/tests/0130-store_offsets.c +178 -0
  418. package/deps/librdkafka/tests/0131-connect_timeout.c +81 -0
  419. package/deps/librdkafka/tests/0132-strategy_ordering.c +179 -0
  420. package/deps/librdkafka/tests/0133-ssl_keys.c +150 -0
  421. package/deps/librdkafka/tests/0134-ssl_provider.c +92 -0
  422. package/deps/librdkafka/tests/0135-sasl_credentials.cpp +279 -0
  423. package/deps/librdkafka/tests/0136-resolve_cb.c +181 -0
  424. package/deps/librdkafka/tests/0137-barrier_batch_consume.c +752 -0
  425. package/deps/librdkafka/tests/0138-admin_mock.c +281 -0
  426. package/deps/librdkafka/tests/0139-offset_validation_mock.c +950 -0
  427. package/deps/librdkafka/tests/0140-commit_metadata.cpp +108 -0
  428. package/deps/librdkafka/tests/0142-reauthentication.c +931 -0
  429. package/deps/librdkafka/tests/0143-exponential_backoff_mock.c +552 -0
  430. package/deps/librdkafka/tests/0144-idempotence_mock.c +373 -0
  431. package/deps/librdkafka/tests/0145-pause_resume_mock.c +119 -0
  432. package/deps/librdkafka/tests/0146-metadata_mock.c +505 -0
  433. package/deps/librdkafka/tests/0147-consumer_group_consumer_mock.c +1210 -0
  434. package/deps/librdkafka/tests/0148-offset_fetch_commit_error_mock.c +569 -0
  435. package/deps/librdkafka/tests/0149-broker-same-host-port.c +140 -0
  436. package/deps/librdkafka/tests/0150-telemetry_mock.c +651 -0
  437. package/deps/librdkafka/tests/0151-purge-brokers.c +566 -0
  438. package/deps/librdkafka/tests/0152-rebootstrap.c +59 -0
  439. package/deps/librdkafka/tests/0153-memberid.c +128 -0
  440. package/deps/librdkafka/tests/0155-share_group_heartbeat_mock.c +2695 -0
  441. package/deps/librdkafka/tests/0156-share_consumer_fetch_mock.c +1551 -0
  442. package/deps/librdkafka/tests/0157-share_consumer_ack_mock.c +1788 -0
  443. package/deps/librdkafka/tests/0158-share_consumer_transactions_mock.c +467 -0
  444. package/deps/librdkafka/tests/0170-share_consumer_subscription.c +2192 -0
  445. package/deps/librdkafka/tests/0171-share_consumer_consume.c +2150 -0
  446. package/deps/librdkafka/tests/0172-share_consumer_acknowledge.c +1919 -0
  447. package/deps/librdkafka/tests/0173-share_consumer_commit_async.c +2735 -0
  448. package/deps/librdkafka/tests/0174-share_consumer_concurrency.c +1434 -0
  449. package/deps/librdkafka/tests/0175-share_consumer_groups.c +574 -0
  450. package/deps/librdkafka/tests/0176-share_consumer_commit_sync.c +2986 -0
  451. package/deps/librdkafka/tests/0177-share_consumer_transactions.c +1815 -0
  452. package/deps/librdkafka/tests/0178-share_consumer_close.c +2102 -0
  453. package/deps/librdkafka/tests/0179-share_consumer_destroy.c +2482 -0
  454. package/deps/librdkafka/tests/0180-share_consumer_config.c +1677 -0
  455. package/deps/librdkafka/tests/0181-share_consumer_topic_delete.c +354 -0
  456. package/deps/librdkafka/tests/0182-share_consumer_error_handling_mock.c +3358 -0
  457. package/deps/librdkafka/tests/0183-share_consumer_leader_change_mock.c +1234 -0
  458. package/deps/librdkafka/tests/0184-share_consumer_topic_recreate.c +1356 -0
  459. package/deps/librdkafka/tests/0185-share_consumer_max_poll_interval.c +557 -0
  460. package/deps/librdkafka/tests/0186-share_consumer_fatal_error.c +360 -0
  461. package/deps/librdkafka/tests/0190-share_consumer_telemetry.c +387 -0
  462. package/deps/librdkafka/tests/1000-unktopic.c +164 -0
  463. package/deps/librdkafka/tests/8000-idle.cpp +60 -0
  464. package/deps/librdkafka/tests/8001-fetch_from_follower_mock_manual.c +113 -0
  465. package/deps/librdkafka/tests/CMakeLists.txt +193 -0
  466. package/deps/librdkafka/tests/LibrdkafkaTestApp.py +291 -0
  467. package/deps/librdkafka/tests/Makefile +182 -0
  468. package/deps/librdkafka/tests/README.md +514 -0
  469. package/deps/librdkafka/tests/autotest.sh +33 -0
  470. package/deps/librdkafka/tests/backtrace.gdb +30 -0
  471. package/deps/librdkafka/tests/broker_version_tests.py +315 -0
  472. package/deps/librdkafka/tests/buildbox.sh +17 -0
  473. package/deps/librdkafka/tests/cleanup-checker-tests.sh +20 -0
  474. package/deps/librdkafka/tests/cluster_testing.py +203 -0
  475. package/deps/librdkafka/tests/delete-test-topics.sh +56 -0
  476. package/deps/librdkafka/tests/fixtures/oauthbearer/jwt_assertion_template.json +10 -0
  477. package/deps/librdkafka/tests/fixtures/ssl/Makefile +8 -0
  478. package/deps/librdkafka/tests/fixtures/ssl/README.md +13 -0
  479. package/deps/librdkafka/tests/fixtures/ssl/client.keystore.intermediate.p12 +0 -0
  480. package/deps/librdkafka/tests/fixtures/ssl/client.keystore.p12 +0 -0
  481. package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.intermediate.pem +72 -0
  482. package/deps/librdkafka/tests/fixtures/ssl/client2.certificate.pem +50 -0
  483. package/deps/librdkafka/tests/fixtures/ssl/client2.intermediate.key +46 -0
  484. package/deps/librdkafka/tests/fixtures/ssl/client2.key +46 -0
  485. package/deps/librdkafka/tests/fixtures/ssl/create_keys.sh +168 -0
  486. package/deps/librdkafka/tests/fuzzers/Makefile +12 -0
  487. package/deps/librdkafka/tests/fuzzers/README.md +31 -0
  488. package/deps/librdkafka/tests/fuzzers/fuzz_regex.c +74 -0
  489. package/deps/librdkafka/tests/fuzzers/helpers.h +90 -0
  490. package/deps/librdkafka/tests/gen-ssl-certs.sh +165 -0
  491. package/deps/librdkafka/tests/interactive_broker_version.py +170 -0
  492. package/deps/librdkafka/tests/interceptor_test/CMakeLists.txt +16 -0
  493. package/deps/librdkafka/tests/interceptor_test/Makefile +22 -0
  494. package/deps/librdkafka/tests/interceptor_test/interceptor_test.c +314 -0
  495. package/deps/librdkafka/tests/interceptor_test/interceptor_test.h +54 -0
  496. package/deps/librdkafka/tests/java/IncrementalRebalanceCli.java +97 -0
  497. package/deps/librdkafka/tests/java/Makefile +13 -0
  498. package/deps/librdkafka/tests/java/Murmur2Cli.java +46 -0
  499. package/deps/librdkafka/tests/java/README.md +14 -0
  500. package/deps/librdkafka/tests/java/TransactionProducerCli.java +162 -0
  501. package/deps/librdkafka/tests/java/run-class.sh +11 -0
  502. package/deps/librdkafka/tests/librdkafka.suppressions +483 -0
  503. package/deps/librdkafka/tests/lz4_manual_test.sh +59 -0
  504. package/deps/librdkafka/tests/multi-broker-version-test.sh +50 -0
  505. package/deps/librdkafka/tests/parse-refcnt.sh +43 -0
  506. package/deps/librdkafka/tests/performance_plot.py +115 -0
  507. package/deps/librdkafka/tests/plugin_test/Makefile +19 -0
  508. package/deps/librdkafka/tests/plugin_test/plugin_test.c +58 -0
  509. package/deps/librdkafka/tests/requirements.txt +2 -0
  510. package/deps/librdkafka/tests/run-all-tests.sh +81 -0
  511. package/deps/librdkafka/tests/run-consumer-tests.sh +16 -0
  512. package/deps/librdkafka/tests/run-producer-tests.sh +16 -0
  513. package/deps/librdkafka/tests/run-test-batches.py +157 -0
  514. package/deps/librdkafka/tests/run-test.sh +141 -0
  515. package/deps/librdkafka/tests/rusage.c +249 -0
  516. package/deps/librdkafka/tests/sasl_test.py +289 -0
  517. package/deps/librdkafka/tests/scenarios/README.md +6 -0
  518. package/deps/librdkafka/tests/scenarios/ak23.json +6 -0
  519. package/deps/librdkafka/tests/scenarios/default.json +5 -0
  520. package/deps/librdkafka/tests/scenarios/noautocreate.json +5 -0
  521. package/deps/librdkafka/tests/share_telemetry_verify/share-otel-collector-config.yaml +28 -0
  522. package/deps/librdkafka/tests/sockem.c +801 -0
  523. package/deps/librdkafka/tests/sockem.h +85 -0
  524. package/deps/librdkafka/tests/sockem_ctrl.c +145 -0
  525. package/deps/librdkafka/tests/sockem_ctrl.h +61 -0
  526. package/deps/librdkafka/tests/test.c +8376 -0
  527. package/deps/librdkafka/tests/test.conf.example +27 -0
  528. package/deps/librdkafka/tests/test.h +1150 -0
  529. package/deps/librdkafka/tests/testcpp.cpp +131 -0
  530. package/deps/librdkafka/tests/testcpp.h +388 -0
  531. package/deps/librdkafka/tests/testshared.h +416 -0
  532. package/deps/librdkafka/tests/tools/README.md +4 -0
  533. package/deps/librdkafka/tests/tools/stats/README.md +21 -0
  534. package/deps/librdkafka/tests/tools/stats/filter.jq +42 -0
  535. package/deps/librdkafka/tests/tools/stats/graph.py +150 -0
  536. package/deps/librdkafka/tests/tools/stats/requirements.txt +3 -0
  537. package/deps/librdkafka/tests/tools/stats/to_csv.py +124 -0
  538. package/deps/librdkafka/tests/trivup/trivup-0.15.0.tar.gz +0 -0
  539. package/deps/librdkafka/tests/until-fail.sh +87 -0
  540. package/deps/librdkafka/tests/xxxx-assign_partition.c +122 -0
  541. package/deps/librdkafka/tests/xxxx-metadata.cpp +159 -0
  542. package/deps/librdkafka/vcpkg.json +23 -0
  543. package/deps/librdkafka/win32/README.md +5 -0
  544. package/deps/librdkafka/win32/build-package.bat +3 -0
  545. package/deps/librdkafka/win32/build.bat +19 -0
  546. package/deps/librdkafka/win32/common.vcxproj +84 -0
  547. package/deps/librdkafka/win32/interceptor_test/interceptor_test.vcxproj +87 -0
  548. package/deps/librdkafka/win32/librdkafka.autopkg.template +54 -0
  549. package/deps/librdkafka/win32/librdkafka.master.testing.targets +13 -0
  550. package/deps/librdkafka/win32/librdkafka.sln +226 -0
  551. package/deps/librdkafka/win32/librdkafka.vcxproj +282 -0
  552. package/deps/librdkafka/win32/librdkafkacpp/librdkafkacpp.vcxproj +104 -0
  553. package/deps/librdkafka/win32/msbuild.ps1 +58 -0
  554. package/deps/librdkafka/win32/openssl_engine_example/openssl_engine_example.vcxproj +132 -0
  555. package/deps/librdkafka/win32/package-zip.ps1 +46 -0
  556. package/deps/librdkafka/win32/packages/repositories.config +4 -0
  557. package/deps/librdkafka/win32/push-package.bat +4 -0
  558. package/deps/librdkafka/win32/rdkafka_complex_consumer_example_cpp/rdkafka_complex_consumer_example_cpp.vcxproj +67 -0
  559. package/deps/librdkafka/win32/rdkafka_example/rdkafka_example.vcxproj +97 -0
  560. package/deps/librdkafka/win32/rdkafka_performance/rdkafka_performance.vcxproj +97 -0
  561. package/deps/librdkafka/win32/setup-msys2.ps1 +47 -0
  562. package/deps/librdkafka/win32/setup-vcpkg.ps1 +34 -0
  563. package/deps/librdkafka/win32/tests/test.conf.example +25 -0
  564. package/deps/librdkafka/win32/tests/tests.vcxproj +278 -0
  565. package/deps/librdkafka/win32/win_ssl_cert_store/win_ssl_cert_store.vcxproj +132 -0
  566. package/deps/librdkafka/win32/wingetopt.c +564 -0
  567. package/deps/librdkafka/win32/wingetopt.h +101 -0
  568. package/deps/librdkafka/win32/wintime.h +33 -0
  569. package/deps/librdkafka.gyp +83 -0
  570. package/deps/windows-install.py +80 -0
  571. package/index.d.ts +3 -0
  572. package/lib/admin.js +732 -0
  573. package/lib/client.js +679 -0
  574. package/lib/error.js +501 -0
  575. package/lib/index.js +8 -0
  576. package/lib/kafka-consumer-stream.js +399 -0
  577. package/lib/kafka-consumer.js +798 -0
  578. package/lib/kafkajs/_admin.js +1052 -0
  579. package/lib/kafkajs/_common.js +887 -0
  580. package/lib/kafkajs/_consumer.js +2156 -0
  581. package/lib/kafkajs/_consumer_cache.js +310 -0
  582. package/lib/kafkajs/_error.js +298 -0
  583. package/lib/kafkajs/_kafka.js +125 -0
  584. package/lib/kafkajs/_linked-list.js +220 -0
  585. package/lib/kafkajs/_producer.js +863 -0
  586. package/lib/kafkajs/index.js +5 -0
  587. package/lib/producer/high-level-producer.js +400 -0
  588. package/lib/producer-stream.js +337 -0
  589. package/lib/producer.js +405 -0
  590. package/lib/rdkafka.js +44 -0
  591. package/lib/tools/ref-counter.js +53 -0
  592. package/lib/topic-partition.js +91 -0
  593. package/lib/topic.js +43 -0
  594. package/lib/util.js +55 -0
  595. package/librdkafka.js +12 -0
  596. package/package.json +85 -0
  597. package/shim/source_location +54 -0
  598. package/src/admin.cc +1597 -0
  599. package/src/admin.h +112 -0
  600. package/src/binding.cc +76 -0
  601. package/src/binding.h +25 -0
  602. package/src/callbacks.cc +676 -0
  603. package/src/callbacks.h +302 -0
  604. package/src/common.cc +1628 -0
  605. package/src/common.h +192 -0
  606. package/src/config.cc +219 -0
  607. package/src/config.h +61 -0
  608. package/src/connection.cc +703 -0
  609. package/src/connection.h +117 -0
  610. package/src/errors.cc +119 -0
  611. package/src/errors.h +60 -0
  612. package/src/kafka-consumer.cc +1539 -0
  613. package/src/kafka-consumer.h +147 -0
  614. package/src/producer.cc +917 -0
  615. package/src/producer.h +124 -0
  616. package/src/topic.cc +173 -0
  617. package/src/topic.h +54 -0
  618. package/src/workers.cc +1714 -0
  619. package/src/workers.h +690 -0
  620. package/types/config.d.ts +1269 -0
  621. package/types/errors.d.ts +373 -0
  622. package/types/kafkajs.d.ts +568 -0
  623. package/types/rdkafka.d.ts +571 -0
  624. package/util/configure.js +32 -0
  625. package/util/generate-docs.sh +18 -0
  626. package/util/get-env.js +6 -0
  627. package/util/test-compile.js +11 -0
  628. package/util/test-producer-delivery.js +100 -0
@@ -0,0 +1,2752 @@
1
+ <a name="introduction-to-librdkafka---the-apache-kafka-cc-client-library"></a>
2
+ # Introduction to librdkafka - the Apache Kafka C/C++ client library
3
+
4
+
5
+ librdkafka is a high performance C implementation of the Apache
6
+ Kafka client, providing a reliable and performant client for production use.
7
+ librdkafka also provides a native C++ interface.
8
+
9
+ <!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->
10
+ **Table of Contents**
11
+
12
+ - [Introduction to librdkafka - the Apache Kafka C/C++ client library](#introduction-to-librdkafka---the-apache-kafka-cc-client-library)
13
+ - [Performance](#performance)
14
+ - [High throughput](#high-throughput)
15
+ - [Low latency](#low-latency)
16
+ - [Latency measurement](#latency-measurement)
17
+ - [Compression](#compression)
18
+ - [Message reliability](#message-reliability)
19
+ - [Producer message delivery success](#producer-message-delivery-success)
20
+ - [Producer message delivery failure](#producer-message-delivery-failure)
21
+ - [Error: Timed out in transmission queue](#error-timed-out-in-transmission-queue)
22
+ - [Error: Timed out in flight to/from broker](#error-timed-out-in-flight-tofrom-broker)
23
+ - [Error: Temporary broker-side error](#error-temporary-broker-side-error)
24
+ - [Error: Temporary errors due to stale metadata](#error-temporary-errors-due-to-stale-metadata)
25
+ - [Error: Local time out](#error-local-time-out)
26
+ - [Error: Permanent errors](#error-permanent-errors)
27
+ - [Producer retries](#producer-retries)
28
+ - [Reordering](#reordering)
29
+ - [Idempotent Producer](#idempotent-producer)
30
+ - [Guarantees](#guarantees)
31
+ - [Ordering and message sequence numbers](#ordering-and-message-sequence-numbers)
32
+ - [Partitioner considerations](#partitioner-considerations)
33
+ - [Message timeout considerations](#message-timeout-considerations)
34
+ - [Leader change](#leader-change)
35
+ - [Error handling](#error-handling)
36
+ - <a href="#rd-kafka-resp-err-out-of-order-sequence-number">RD_KAFKA_RESP_ERR_OUT_OF_ORDER_SEQUENCE_NUMBER</a>
37
+ - <a href="#rd-kafka-resp-err-duplicate-sequence-number">RD_KAFKA_RESP_ERR_DUPLICATE_SEQUENCE_NUMBER</a>
38
+ - <a href="#rd-kafka-resp-err-unknown-producer-id">RD_KAFKA_RESP_ERR_UNKNOWN_PRODUCER_ID</a>
39
+ - [Standard errors](#standard-errors)
40
+ - [Message persistence status](#message-persistence-status)
41
+ - [Transactional Producer](#transactional-producer)
42
+ - [Error handling](#error-handling-1)
43
+ - [Old producer fencing](#old-producer-fencing)
44
+ - [Configuration considerations](#configuration-considerations)
45
+ - [Exactly Once Semantics (EOS) and transactions](#exactly-once-semantics-eos-and-transactions)
46
+ - [Usage](#usage)
47
+ - [Documentation](#documentation)
48
+ - [Initialization](#initialization)
49
+ - [Configuration](#configuration)
50
+ - [Example](#example)
51
+ - [Termination](#termination)
52
+ - [High-level KafkaConsumer](#high-level-kafkaconsumer)
53
+ - [Producer](#producer)
54
+ - [Admin API client](#admin-api-client)
55
+ - [Speeding up termination](#speeding-up-termination)
56
+ - [Threads and callbacks](#threads-and-callbacks)
57
+ - [Brokers](#brokers)
58
+ - [SSL](#ssl)
59
+ - [OAUTHBEARER with support for OIDC](#oauthbearer-with-support-for-oidc)
60
+ - [JWT bearer grant type (KIP-1139)](#jwt-bearer-grant-type-kip-1139)
61
+ - [Metadata based authentication](#metadata-based-authentication)
62
+ - [Azure IMDS](#azure-imds)
63
+ - [Sparse connections](#sparse-connections)
64
+ - [Random broker selection](#random-broker-selection)
65
+ - [Persistent broker connections](#persistent-broker-connections)
66
+ - [Connection close](#connection-close)
67
+ - [Fetch From Follower](#fetch-from-follower)
68
+ - [Logging](#logging)
69
+ - [Debug contexts](#debug-contexts)
70
+ - [Feature discovery](#feature-discovery)
71
+ - [Producer API](#producer-api)
72
+ - [Simple Consumer API (legacy)](#simple-consumer-api-legacy)
73
+ - [Offset management](#offset-management)
74
+ - [Auto offset commit](#auto-offset-commit)
75
+ - [At-least-once processing](#at-least-once-processing)
76
+ - [Auto offset reset](#auto-offset-reset)
77
+ - [Consumer groups](#consumer-groups)
78
+ - [Static consumer groups](#static-consumer-groups)
79
+ - [Next Generation Consumer Group Protocol (KIP-848)](#next-generation-consumer-group-protocol-kip-848)
80
+ - [Overview](#overview)
81
+ - [Available Features](#available-features)
82
+ - [Contract Changes](#contract-changes)
83
+ - [Client Configuration changes](#client-configuration-changes)
84
+ - [Rebalance Callback Changes](#rebalance-callback-changes)
85
+ - [Regex Subscription Changes](#regex-subscription-changes)
86
+ - [Static Group Membership](#static-group-membership)
87
+ - [Session Timeout \& Fetching](#session-timeout--fetching)
88
+ - [Closing / Auto-Commit](#closing--auto-commit)
89
+ - [Error Handling Changes](#error-handling-changes)
90
+ - [Summary of Key Differences (Classic vs Next-Gen)](#summary-of-key-differences-classic-vs-next-gen)
91
+ - [Minimal Example Config](#minimal-example-config)
92
+ - [Classic Protocol](#classic-protocol)
93
+ - [Next-Gen Protocol / KIP-848](#next-gen-protocol--kip-848)
94
+ - [Rebalance Callback Migration](#rebalance-callback-migration)
95
+ - [Range Assignor (Classic)](#range-assignor-classic)
96
+ - [Incremental Assignor (Including Range in Consumer / KIP-848, Any Protocol)](#incremental-assignor-including-range-in-consumer--kip-848-any-protocol)
97
+ - [Upgrade and Downgrade](#upgrade-and-downgrade)
98
+ - [Migration Checklist (Next-Gen Protocol / KIP-848)](#migration-checklist-next-gen-protocol--kip-848)
99
+ - [Note on Batch consume APIs](#note-on-batch-consume-apis)
100
+ - [Share consumers (Queues for Kafka)](#share-consumers-queues-for-kafka)
101
+ - [Topics](#topics)
102
+ - [Unknown or unauthorized topics](#unknown-or-unauthorized-topics)
103
+ - [Topic metadata propagation for newly created topics](#topic-metadata-propagation-for-newly-created-topics)
104
+ - [Topic auto creation](#topic-auto-creation)
105
+ - [Metadata](#metadata)
106
+ - [\< 0.9.3](#lt093)
107
+ - [\> 0.9.3](#gt093-1)
108
+ - [Query reasons](#query-reasons)
109
+ - [Caching strategy](#caching-strategy)
110
+ - [Fatal errors](#fatal-errors)
111
+ - [Fatal producer errors](#fatal-producer-errors)
112
+ - [Fatal consumer errors](#fatal-consumer-errors)
113
+ - [Compatibility](#compatibility)
114
+ - [Broker version compatibility](#broker-version-compatibility)
115
+ - [Broker version \>= 0.10.0.0 (or trunk)](#broker-version--01000-or-trunk)
116
+ - [Broker versions 0.9.0.x](#broker-versions-090x)
117
+ - [Broker versions 0.8.x.y](#broker-versions-08xy)
118
+ - [Detailed description](#detailed-description)
119
+ - [Supported KIPs](#supported-kips)
120
+ - [Supported protocol versions](#supported-protocol-versions)
121
+ - [Recommendations for language binding developers](#recommendations-for-language-binding-developers)
122
+ - [Expose the configuration interface pass-thru](#expose-the-configuration-interface-pass-thru)
123
+ - [Error constants](#error-constants)
124
+ - [Reporting client software name and version to broker](#reporting-client-software-name-and-version-to-broker)
125
+ - [Documentation reuse](#documentation-reuse)
126
+ - [Community support](#community-support)
127
+
128
+ <!-- markdown-toc end -->
129
+
130
+
131
+ <a name="performance"></a>
132
+ ## Performance
133
+
134
+ librdkafka is a multi-threaded library designed for use on modern hardware and
135
+ it attempts to keep memory copying to a minimum. The payload of produced or
136
+ consumed messages may pass through without any copying
137
+ (if so desired by the application) putting no limit on message sizes.
138
+
139
+ librdkafka allows you to decide if high throughput is the name of the game,
140
+ or if a low latency service is required, or a balance between the two, all
141
+ through the configuration property interface.
142
+
143
+ The single most important configuration properties for performance tuning is
144
+ `linger.ms` - how long to wait for `batch.num.messages` or `batch.size` to
145
+ fill up in the local per-partition queue before sending the batch of messages
146
+ to the broker.
147
+
148
+ In low throughput scenarios, a lower value improves latency.
149
+ As throughput increases, the cost of each broker request becomes significant
150
+ impacting both maximum throughput and latency. For higher throughput
151
+ applications, latency will typically be lower using a higher `linger.ms` due
152
+ to larger batches resulting in a lesser number of requests, yielding decreased
153
+ per-message load on the broker. A good general purpose setting is 5ms.
154
+ For applications seeking maximum throughput, the recommended value is >= 50ms.
155
+
156
+
157
+ <a name="high-throughput"></a>
158
+ ### High throughput
159
+
160
+ The key to high throughput is message batching - waiting for a certain amount
161
+ of messages to accumulate in the local queue before sending them off in
162
+ one large message set or batch to the peer. This amortizes the messaging
163
+ overhead and eliminates the adverse effect of the round trip time (rtt).
164
+
165
+ `linger.ms` (also called `queue.buffering.max.ms`) allows librdkafka to
166
+ wait up to the specified amount of time to accumulate up to
167
+ `batch.num.messages` or `batch.size` in a single batch (MessageSet) before
168
+ sending to the broker. The larger the batch the higher the throughput.
169
+ Enabling `msg` debugging (set `debug` property to `msg`) will emit log
170
+ messages for the accumulation process which lets you see what batch sizes
171
+ are being produced.
172
+
173
+ Example using `linger.ms=1`:
174
+
175
+ ```
176
+ ... test [0]: MessageSet with 1514 message(s) delivered
177
+ ... test [3]: MessageSet with 1690 message(s) delivered
178
+ ... test [0]: MessageSet with 1720 message(s) delivered
179
+ ... test [3]: MessageSet with 2 message(s) delivered
180
+ ... test [3]: MessageSet with 4 message(s) delivered
181
+ ... test [0]: MessageSet with 4 message(s) delivered
182
+ ... test [3]: MessageSet with 11 message(s) delivered
183
+ ```
184
+
185
+ Example using `linger.ms=1000`:
186
+ ```
187
+ ... test [0]: MessageSet with 10000 message(s) delivered
188
+ ... test [0]: MessageSet with 10000 message(s) delivered
189
+ ... test [0]: MessageSet with 4667 message(s) delivered
190
+ ... test [3]: MessageSet with 10000 message(s) delivered
191
+ ... test [3]: MessageSet with 10000 message(s) delivered
192
+ ... test [3]: MessageSet with 4476 message(s) delivered
193
+
194
+ ```
195
+
196
+
197
+ The default setting of `linger.ms=5` is not suitable for
198
+ high throughput, it is recommended to set this value to >50ms, with
199
+ throughput leveling out somewhere around 100-1000ms depending on
200
+ message produce pattern and sizes.
201
+
202
+ These setting are set globally (`rd_kafka_conf_t`) but applies on a
203
+ per topic+partition basis.
204
+
205
+
206
+ <a name="low-latency"></a>
207
+ ### Low latency
208
+
209
+ When low latency messaging is required the `linger.ms` should be
210
+ tuned to the maximum permitted producer-side latency.
211
+ Setting `linger.ms` to 0 or 0.1 will make sure messages are sent as
212
+ soon as possible.
213
+ Lower buffering time leads to smaller batches and larger per-message overheads,
214
+ increasing network, memory and CPU usage for producers, brokers and consumers.
215
+
216
+ See [How to decrease message latency](https://github.com/confluentinc/librdkafka/wiki/How-to-decrease-message-latency) for more info.
217
+
218
+
219
+ <a name="latency-measurement"></a>
220
+ #### Latency measurement
221
+
222
+ End-to-end latency is preferably measured by synchronizing clocks on producers
223
+ and consumers and using the message timestamp on the consumer to calculate
224
+ the full latency. Make sure the topic's `log.message.timestamp.type` is set to
225
+ the default `CreateTime` (Kafka topic configuration, not librdkafka topic).
226
+
227
+ Latencies are typically incurred by the producer, network and broker, the
228
+ consumer effect on end-to-end latency is minimal.
229
+
230
+ To break down the end-to-end latencies and find where latencies are adding up
231
+ there are a number of metrics available through librdkafka statistics
232
+ on the producer:
233
+
234
+ * `brokers[].int_latency` is the time, per message, between produce()
235
+ and the message being written to a MessageSet and ProduceRequest.
236
+ High `int_latency` indicates CPU core contention: check CPU load and,
237
+ involuntary context switches (`/proc/<..>/status`).
238
+ Consider using a machine/instance with more CPU cores.
239
+ This metric is only relevant on the producer.
240
+
241
+ * `brokers[].outbuf_latency` is the time, per protocol request
242
+ (such as ProduceRequest), between the request being enqueued (which happens
243
+ right after int_latency) and the time the request is written to the
244
+ TCP socket connected to the broker.
245
+ High `outbuf_latency` indicates CPU core contention or network congestion:
246
+ check CPU load and socket SendQ (`netstat -anp | grep :9092`).
247
+
248
+ * `brokers[].rtt` is the time, per protocol request, between the request being
249
+ written to the TCP socket and the time the response is received from
250
+ the broker.
251
+ High `rtt` indicates broker load or network congestion:
252
+ check broker metrics, local socket SendQ, network performance, etc.
253
+
254
+ * `brokers[].throttle` is the time, per throttled protocol request, the
255
+ broker throttled/delayed handling of a request due to usage quotas.
256
+ The throttle time will also be reflected in `rtt`.
257
+
258
+ * `topics[].batchsize` is the size of individual Producer MessageSet batches.
259
+ See below.
260
+
261
+ * `topics[].batchcnt` is the number of messages in individual Producer
262
+ MessageSet batches. Due to Kafka protocol overhead a batch with few messages
263
+ will have a higher relative processing and size overhead than a batch
264
+ with many messages.
265
+ Use the `linger.ms` client configuration property to set the maximum
266
+ amount of time allowed for accumulating a single batch, the larger the
267
+ value the larger the batches will grow, thus increasing efficiency.
268
+ When producing messages at a high rate it is recommended to increase
269
+ linger.ms, which will improve throughput and in some cases also latency.
270
+
271
+
272
+ See [STATISTICS.md](STATISTICS.md) for the full definition of metrics.
273
+ A JSON schema for the statistics is available in
274
+ [statistics-schema.json](src/statistics-schema.json).
275
+
276
+
277
+ <a name="compression"></a>
278
+ ### Compression
279
+
280
+ Producer message compression is enabled through the `compression.codec`
281
+ configuration property.
282
+
283
+ Compression is performed on the batch of messages in the local queue, the
284
+ larger the batch the higher likelyhood of a higher compression ratio.
285
+ The local batch queue size is controlled through the `batch.num.messages`,
286
+ `batch.size`, and `linger.ms` configuration properties as described in the
287
+ **High throughput** chapter above.
288
+
289
+
290
+
291
+ <a name="message-reliability"></a>
292
+ ## Message reliability
293
+
294
+ Message reliability is an important factor of librdkafka - an application
295
+ can rely fully on librdkafka to deliver a message according to the specified
296
+ configuration (`request.required.acks` and `message.send.max.retries`, etc).
297
+
298
+ If the topic configuration property `request.required.acks` is set to wait
299
+ for message commit acknowledgements from brokers (any value but 0, see
300
+ [`CONFIGURATION.md`](CONFIGURATION.md)
301
+ for specifics) then librdkafka will hold on to the message until
302
+ all expected acks have been received, gracefully handling the following events:
303
+
304
+ * Broker connection failure
305
+ * Topic leader change
306
+ * Produce errors signaled by the broker
307
+ * Network problems
308
+
309
+ We recommend `request.required.acks` to be set to `all` to make sure
310
+ produced messages are acknowledged by all in-sync replica brokers.
311
+
312
+ This is handled automatically by librdkafka and the application does not need
313
+ to take any action at any of the above events.
314
+ The message will be resent up to `message.send.max.retries` times before
315
+ reporting a failure back to the application.
316
+
317
+ The delivery report callback is used by librdkafka to signal the status of
318
+ a message back to the application, it will be called once for each message
319
+ to report the status of message delivery:
320
+
321
+ * If `error_code` is non-zero the message delivery failed and the error_code
322
+ indicates the nature of the failure (`rd_kafka_resp_err_t` enum).
323
+ * If `error_code` is zero the message has been successfully delivered.
324
+
325
+ See Producer API chapter for more details on delivery report callback usage.
326
+
327
+ The delivery report callback is optional but highly recommended.
328
+
329
+
330
+ <a name="producer-message-delivery-success"></a>
331
+ ### Producer message delivery success
332
+
333
+ When a ProduceRequest is successfully handled by the broker and a
334
+ ProduceResponse is received (also called the ack) without an error code
335
+ the messages from the ProduceRequest are enqueued on the delivery report
336
+ queue (if a delivery report callback has been set) and will be passed to
337
+ the application on the next invocation rd_kafka_poll().
338
+
339
+
340
+ <a name="producer-message-delivery-failure"></a>
341
+ ### Producer message delivery failure
342
+
343
+ The following sub-chapters explains how different produce errors
344
+ are handled.
345
+
346
+ If the error is retryable and there are remaining retry attempts for
347
+ the given message(s), an automatic retry will be scheduled by librdkafka,
348
+ these retries are not visible to the application.
349
+
350
+ Only permanent errors and temporary errors that have reached their maximum
351
+ retry count will generate a delivery report event to the application with an
352
+ error code set.
353
+
354
+ The application should typically not attempt to retry producing the message
355
+ on failure, but instead configure librdkafka to perform these retries
356
+ using the `retries`, `retry.backoff.ms` and `retry.backoff.max.ms`
357
+ configuration properties.
358
+
359
+
360
+ <a name="error-timed-out-in-transmission-queue"></a>
361
+ #### Error: Timed out in transmission queue
362
+
363
+ Internal error ERR__TIMED_OUT_QUEUE.
364
+
365
+ The connectivity to the broker may be stalled due to networking contention,
366
+ local or remote system issues, etc, and the request has not yet been sent.
367
+
368
+ The producer can be certain that the message has not been sent to the broker.
369
+
370
+ This is a retryable error, but is not counted as a retry attempt
371
+ since the message was never actually transmitted.
372
+
373
+ A retry by librdkafka at this point will not cause duplicate messages.
374
+
375
+
376
+ <a name="error-timed-out-in-flight-tofrom-broker"></a>
377
+ #### Error: Timed out in flight to/from broker
378
+
379
+ Internal error ERR__TIMED_OUT, ERR__TRANSPORT.
380
+
381
+ Same reasons as for `Timed out in transmission queue` above, with the
382
+ difference that the message may have been sent to the broker and might
383
+ be stalling waiting for broker replicas to ack the message, or the response
384
+ could be stalled due to networking issues.
385
+ At this point the producer can't know if the message reached the broker,
386
+ nor if the broker wrote the message to disk and replicas.
387
+
388
+ This is a retryable error.
389
+
390
+ A retry by librdkafka at this point may cause duplicate messages.
391
+
392
+
393
+ <a name="error-temporary-broker-side-error"></a>
394
+ #### Error: Temporary broker-side error
395
+
396
+ Broker errors ERR_REQUEST_TIMED_OUT, ERR_NOT_ENOUGH_REPLICAS,
397
+ ERR_NOT_ENOUGH_REPLICAS_AFTER_APPEND.
398
+
399
+ These errors are considered temporary and librdkafka is will retry them
400
+ if permitted by configuration.
401
+
402
+
403
+ <a name="error-temporary-errors-due-to-stale-metadata"></a>
404
+ #### Error: Temporary errors due to stale metadata
405
+
406
+ Broker errors ERR_LEADER_NOT_AVAILABLE, ERR_NOT_LEADER_FOR_PARTITION.
407
+
408
+ These errors are considered temporary and a retry is warranted, a metadata
409
+ request is automatically sent to find a new leader for the partition.
410
+
411
+ A retry by librdkafka at this point will not cause duplicate messages.
412
+
413
+
414
+ <a name="error-local-time-out"></a>
415
+ #### Error: Local time out
416
+
417
+ Internal error ERR__MSG_TIMED_OUT.
418
+
419
+ The message could not be successfully transmitted before `message.timeout.ms`
420
+ expired, typically due to no leader being available or no broker connection.
421
+ The message may have been retried due to other errors but
422
+ those error messages are abstracted by the ERR__MSG_TIMED_OUT error code.
423
+
424
+ Since the `message.timeout.ms` has passed there will be no more retries
425
+ by librdkafka.
426
+
427
+
428
+ <a name="error-permanent-errors"></a>
429
+ #### Error: Permanent errors
430
+
431
+ Any other error is considered a permanent error and the message
432
+ will fail immediately, generating a delivery report event with the
433
+ distinctive error code.
434
+
435
+ The full list of permanent errors depend on the broker version and
436
+ will likely grow in the future.
437
+
438
+ Typical permanent broker errors are:
439
+ * ERR_CORRUPT_MESSAGE
440
+ * ERR_MSG_SIZE_TOO_LARGE - adjust client's or broker's `message.max.bytes`.
441
+ * ERR_UNKNOWN_TOPIC_OR_PART - topic or partition does not exist,
442
+ automatic topic creation is disabled on the
443
+ broker or the application is specifying a
444
+ partition that does not exist.
445
+ * ERR_RECORD_LIST_TOO_LARGE
446
+ * ERR_INVALID_REQUIRED_ACKS
447
+ * ERR_TOPIC_AUTHORIZATION_FAILED
448
+ * ERR_UNSUPPORTED_FOR_MESSAGE_FORMAT
449
+ * ERR_CLUSTER_AUTHORIZATION_FAILED
450
+
451
+
452
+ <a name="producer-retries"></a>
453
+ ### Producer retries
454
+
455
+ The ProduceRequest itself is not retried, instead the messages
456
+ are put back on the internal partition queue by an insert sort
457
+ that maintains their original position (the message order is defined
458
+ at the time a message is initially appended to a partition queue, i.e., after
459
+ partitioning).
460
+ A backoff time (`retry.backoff.ms`) is set on the retried messages which
461
+ effectively blocks retry attempts until the backoff time has expired.
462
+
463
+
464
+ <a name="reordering"></a>
465
+ ### Reordering
466
+
467
+ As for all retries, if `max.in.flight` > 1 and `retries` > 0, retried messages
468
+ may be produced out of order, since a sub-sequent message in a sub-sequent
469
+ ProduceRequest may already be in-flight (and accepted by the broker)
470
+ by the time the retry for the failing message is sent.
471
+
472
+ Using the Idempotent Producer prevents reordering even with `max.in.flight` > 1,
473
+ see [Idempotent Producer](#idempotent-producer) below for more information.
474
+
475
+
476
+ <a name="idempotent-producer"></a>
477
+ ### Idempotent Producer
478
+
479
+ librdkafka supports the idempotent producer which provides strict ordering and
480
+ and exactly-once producer guarantees.
481
+ The idempotent producer is enabled by setting the `enable.idempotence`
482
+ configuration property to `true`, this will automatically adjust a number of
483
+ other configuration properties to adhere to the idempotency requirements,
484
+ see the documentation of `enable.idempotence` in [CONFIGURATION.md](CONFIGURATION.md) for
485
+ more information.
486
+ Producer instantiation will fail if the user supplied an incompatible value
487
+ for any of the automatically adjusted properties, e.g., it is an error to
488
+ explicitly set `acks=1` when `enable.idempotence=true` is set.
489
+
490
+
491
+ <a name="guarantees"></a>
492
+ #### Guarantees
493
+
494
+ There are three types of guarantees that the idempotent producer can satisfy:
495
+
496
+ * Exactly-once - a message is only written to the log once.
497
+ Does NOT cover the exactly-once consumer case.
498
+ * Ordering - a series of messages are written to the log in the
499
+ order they were produced.
500
+ * Gap-less - **EXPERIMENTAL** a series of messages are written once and
501
+ in order without risk of skipping messages. The sequence
502
+ of messages may be cut short and fail before all
503
+ messages are written, but may not fail individual
504
+ messages in the series.
505
+ This guarantee is disabled by default, but may be enabled
506
+ by setting `enable.gapless.guarantee` if individual message
507
+ failure is a concern.
508
+ Messages that fail due to exceeded timeout (`message.timeout.ms`),
509
+ are permitted by the gap-less guarantee and may cause
510
+ gaps in the message series without raising a fatal error.
511
+ See **Message timeout considerations** below for more info.
512
+ **WARNING**: This is an experimental property subject to
513
+ change or removal.
514
+
515
+ All three guarantees are in effect when idempotence is enabled, only
516
+ gap-less may be disabled individually.
517
+
518
+
519
+ <a name="ordering-and-message-sequence-numbers"></a>
520
+ #### Ordering and message sequence numbers
521
+
522
+ librdkafka maintains the original produce() ordering per-partition for all
523
+ messages produced, using an internal per-partition 64-bit counter
524
+ called the msgid which starts at 1. This msgid allows messages to be
525
+ re-inserted in the partition message queue in the original order in the
526
+ case of retries.
527
+
528
+ The Idempotent Producer functionality in the Kafka protocol also has
529
+ a per-message sequence number, which is a signed 32-bit wrapping counter that is
530
+ reset each time the Producer's ID (PID) or Epoch changes.
531
+
532
+ The librdkafka msgid is used, along with a base msgid value stored
533
+ at the time the PID/Epoch was bumped, to calculate the Kafka protocol's
534
+ message sequence number.
535
+
536
+ With Idempotent Producer enabled there is no risk of reordering despite
537
+ `max.in.flight` > 1 (capped at 5).
538
+
539
+ **Note**: "MsgId" in log messages refer to the librdkafka msgid, while "seq"
540
+ refers to the protocol message sequence, "baseseq" is the seq of
541
+ the first message in a batch.
542
+ MsgId starts at 1, while message seqs start at 0.
543
+
544
+
545
+ The producer statistics also maintain two metrics for tracking the next
546
+ expected response sequence:
547
+
548
+ * `next_ack_seq` - the next sequence to expect an acknowledgement for, which
549
+ is the last successfully produced MessageSet's last
550
+ sequence + 1.
551
+ * `next_err_seq` - the next sequence to expect an error for, which is typically
552
+ the same as `next_ack_seq` until an error occurs, in which
553
+ case the `next_ack_seq` can't be incremented (since no
554
+ messages were acked on error). `next_err_seq` is used to
555
+ properly handle sub-sequent errors due to a failing
556
+ first request.
557
+
558
+ **Note**: Both are exposed in partition statistics.
559
+
560
+
561
+
562
+ <a name="partitioner-considerations"></a>
563
+ #### Partitioner considerations
564
+
565
+ Strict ordering is guaranteed on a **per partition** basis.
566
+
567
+ An application utilizing the idempotent producer should not mix
568
+ producing to explicit partitions with partitioner-based partitions
569
+ since messages produced for the latter are queued separately until
570
+ a topic's partition count is known, which would insert these messages
571
+ after the partition-explicit messages regardless of produce order.
572
+
573
+
574
+ <a name="message-timeout-considerations"></a>
575
+ #### Message timeout considerations
576
+
577
+ If messages time out (due to `message.timeout.ms`) while in the producer queue
578
+ there will be gaps in the series of produced messages.
579
+
580
+ E.g., Messages 1,2,3,4,5 are produced by the application.
581
+ While messages 2,3,4 are transmitted to the broker the connection to
582
+ the broker goes down.
583
+ While the broker is down the message timeout expires for message 2 and 3.
584
+ As the connection comes back up messages 4, 5 are transmitted to the
585
+ broker, resulting in a final written message sequence of 1, 4, 5.
586
+
587
+ The producer gracefully handles this case by draining the in-flight requests
588
+ for a given partition when one or more of its queued (not transmitted)
589
+ messages are timed out. When all requests are drained the Epoch is bumped and
590
+ the base sequence number is reset to the first message in the queue, effectively
591
+ skipping the timed out messages as if they had never existed from the
592
+ broker's point of view.
593
+ The message status for timed out queued messages will be
594
+ `RD_KAFKA_MSG_STATUS_NOT_PERSISTED`.
595
+
596
+ If messages time out while in-flight to the broker (also due to
597
+ `message.timeout.ms`), the protocol request will fail, the broker
598
+ connection will be closed by the client, and the timed out messages will be
599
+ removed from the producer queue. In this case the in-flight messages may be
600
+ written to the topic log by the broker, even though
601
+ a delivery report with error `ERR__MSG_TIMED_OUT` will be raised, since
602
+ the producer timed out the request before getting an acknowledgement back
603
+ from the broker.
604
+ The message status for timed out in-flight messages will be
605
+ `RD_KAFKA_MSG_STATUS_POSSIBLY_PERSISTED`, indicating that the producer
606
+ does not know if the messages were written and acked by the broker,
607
+ or dropped in-flight.
608
+
609
+ An application may inspect the message status by calling
610
+ `rd_kafka_message_status()` on the message in the delivery report callback,
611
+ to see if the message was (possibly) persisted (written to the topic log) by
612
+ the broker or not.
613
+
614
+ Despite the graceful handling of timeouts, we recommend to use a
615
+ large `message.timeout.ms` to minimize the risk of timeouts.
616
+
617
+ **Warning**: `enable.gapless.guarantee` does not apply to timed-out messages.
618
+
619
+ **Note**: `delivery.timeout.ms` is an alias for `message.timeout.ms`.
620
+
621
+
622
+ <a name="leader-change"></a>
623
+ #### Leader change
624
+
625
+ There are corner cases where an Idempotent Producer has outstanding
626
+ ProduceRequests in-flight to the previous leader while a new leader is elected.
627
+
628
+ A leader change is typically triggered by the original leader
629
+ failing or terminating, which has the risk of also failing (some of) the
630
+ in-flight ProduceRequests to that broker. To recover the producer to a
631
+ consistent state it will not send any ProduceRequests for these partitions to
632
+ the new leader broker until all responses for any outstanding ProduceRequests
633
+ to the previous partition leader has been received, or these requests have
634
+ timed out.
635
+ This drain may take up to `min(socket.timeout.ms, message.timeout.ms)`.
636
+ If the connection to the previous broker goes down the outstanding requests
637
+ are failed immediately.
638
+
639
+
640
+ <a name="error-handling"></a>
641
+ #### Error handling
642
+
643
+ Background:
644
+ The error handling for the Idempotent Producer, as initially proposed
645
+ in the [EOS design document](https://docs.google.com/document/d/11Jqy_GjUGtdXJK94XGsEIK7CP1SnQGdp2eF0wSw9ra8),
646
+ missed some corner cases which are now being addressed in [KIP-360](https://cwiki.apache.org/confluence/display/KAFKA/KIP-360%3A+Improve+handling+of+unknown+producer).
647
+ There were some intermediate fixes and workarounds prior to KIP-360 that proved
648
+ to be incomplete and made the error handling in the client overly complex.
649
+ With the benefit of hindsight the librdkafka implementation will attempt
650
+ to provide correctness from the lessons learned in the Java client and
651
+ provide stricter and less complex error handling.
652
+
653
+ The follow sections describe librdkafka's handling of the
654
+ Idempotent Producer specific errors that may be returned by the broker.
655
+
656
+ <a name="rd-kafka-resp-err-out-of-order-sequence-number"></a>
657
+ ##### RD_KAFKA_RESP_ERR_OUT_OF_ORDER_SEQUENCE_NUMBER
658
+
659
+ This error is returned by the broker when the sequence number in the
660
+ ProduceRequest is larger than the expected next sequence
661
+ for the given PID+Epoch+Partition (last BaseSeq + msgcount + 1).
662
+ Note: sequence 0 is always accepted.
663
+
664
+ If the failed request is the head-of-line (next expected sequence to be acked)
665
+ it indicates desynchronization between the client and broker:
666
+ the client thinks the sequence number is correct but the broker disagrees.
667
+ There is no way for the client to recover from this scenario without
668
+ risking message loss or duplication, and it is not safe for the
669
+ application to manually retry messages.
670
+ A fatal error (`RD_KAFKA_RESP_ERR_OUT_OF_ORDER_SEQUENCE_NUMBER`) is raised.
671
+
672
+ When the request is not head-of-line the previous request failed
673
+ (for any reason), which means the messages in the current request
674
+ can be retried after waiting for all outstanding requests for this
675
+ partition to drain and then reset the Producer ID and start over.
676
+
677
+
678
+ **Java Producer behaviour**:
679
+ Fail the batch, reset the pid, and then continue producing
680
+ (and retrying sub-sequent) messages. This will lead to gaps
681
+ in the message series.
682
+
683
+
684
+ <a name="rd-kafka-resp-err-duplicate-sequence-number"></a>
685
+ ##### RD_KAFKA_RESP_ERR_DUPLICATE_SEQUENCE_NUMBER
686
+
687
+ Returned by broker when the request's base sequence number is
688
+ less than the expected sequence number (which is the last written
689
+ sequence + msgcount).
690
+ Note: sequence 0 is always accepted.
691
+
692
+ This error is typically benign and occurs upon retrying a previously successful
693
+ send that was not acknowledged.
694
+
695
+ The messages will be considered successfully produced but will have neither
696
+ timestamp or offset set.
697
+
698
+
699
+ **Java Producer behaviour:**
700
+ Treats the message as successfully delivered.
701
+
702
+ <a name="rd-kafka-resp-err-unknown-producer-id"></a>
703
+ ##### RD_KAFKA_RESP_ERR_UNKNOWN_PRODUCER_ID
704
+
705
+ Returned by broker when the PID+Epoch is unknown, which may occur when
706
+ the PID's state has expired (due to topic retention, DeleteRecords,
707
+ or compaction).
708
+
709
+ The Java producer added quite a bit of error handling for this case,
710
+ extending the ProduceRequest protocol to return the logStartOffset
711
+ to give the producer a chance to differentiate between an actual
712
+ UNKNOWN_PRODUCER_ID or topic retention having deleted the last
713
+ message for this producer (effectively voiding the Producer ID cache).
714
+ This workaround proved to be error prone (see explanation in KIP-360)
715
+ when the partition leader changed.
716
+
717
+ KIP-360 suggests removing this error checking in favour of failing fast,
718
+ librdkafka follows suite.
719
+
720
+
721
+ If the response is for the first ProduceRequest in-flight
722
+ and there are no messages waiting to be retried nor any ProduceRequests
723
+ unaccounted for, then the error is ignored and the epoch is incremented,
724
+ this is likely to happen for an idle producer who's last written
725
+ message has been deleted from the log, and thus its PID state.
726
+ Otherwise the producer raises a fatal error
727
+ (RD_KAFKA_RESP_ERR_UNKNOWN_PRODUCER_ID) since the delivery guarantees can't
728
+ be satisfied.
729
+
730
+
731
+ **Java Producer behaviour:**
732
+ Retries the send in some cases (but KIP-360 will change this).
733
+ Not a fatal error in any case.
734
+
735
+
736
+ <a name="standard-errors"></a>
737
+ ##### Standard errors
738
+
739
+ All the standard Produce errors are handled in the usual way,
740
+ permanent errors will fail the messages in the batch, while
741
+ temporary errors will be retried (if retry count permits).
742
+
743
+ If a permanent error is returned for a batch in a series of in-flight batches,
744
+ the sub-sequent batches will fail with
745
+ RD_KAFKA_RESP_ERR_OUT_OF_ORDER_SEQUENCE_NUMBER since the sequence number of the
746
+ failed batched was never written to the topic log and next expected sequence
747
+ thus not incremented on the broker.
748
+
749
+ A fatal error (RD_KAFKA_RESP_ERR__GAPLESS_GUARANTEE) is raised to satisfy
750
+ the gap-less guarantee (if `enable.gapless.guarantee` is set) by failing all
751
+ queued messages.
752
+
753
+
754
+ <a name="message-persistence-status"></a>
755
+ ##### Message persistence status
756
+
757
+ To help the application decide what to do in these error cases, a new
758
+ per-message API is introduced, `rd_kafka_message_status()`,
759
+ which returns one of the following values:
760
+
761
+ * `RD_KAFKA_MSG_STATUS_NOT_PERSISTED` - the message has never
762
+ been transmitted to the broker, or failed with an error indicating
763
+ it was not written to the log.
764
+ Application retry will risk ordering, but not duplication.
765
+ * `RD_KAFKA_MSG_STATUS_POSSIBLY_PERSISTED` - the message was transmitted
766
+ to the broker, but no acknowledgement was received.
767
+ Application retry will risk ordering and duplication.
768
+ * `RD_KAFKA_MSG_STATUS_PERSISTED` - the message was written to the log by
769
+ the broker and fully acknowledged.
770
+ No reason for application to retry.
771
+
772
+ This method should be called by the application on delivery report error.
773
+
774
+
775
+ <a name="transactional-producer"></a>
776
+ ### Transactional Producer
777
+
778
+
779
+ <a name="error-handling-1"></a>
780
+ #### Error handling
781
+
782
+ Using the transactional producer simplifies error handling compared to the
783
+ standard or idempotent producer, a transactional application will only need
784
+ to care about these different types of errors:
785
+
786
+ * Retriable errors - the operation failed due to temporary problems,
787
+ such as network timeouts, the operation may be safely retried.
788
+ Use `rd_kafka_error_is_retriable()` to distinguish this case.
789
+ * Abortable errors - if any of the transactional APIs return a non-fatal
790
+ error code the current transaction has failed and the application
791
+ must call `rd_kafka_abort_transaction()`, rewind its input to the
792
+ point before the current transaction started, and attempt a new transaction
793
+ by calling `rd_kafka_begin_transaction()`, etc.
794
+ Use `rd_kafka_error_txn_requires_abort()` to distinguish this case.
795
+ * Fatal errors - the application must cease operations and destroy the
796
+ producer instance.
797
+ Use `rd_kafka_error_is_fatal()` to distinguish this case.
798
+ * For all other errors returned from the transactional API: the current
799
+ recommendation is to treat any error that has neither retriable, abortable,
800
+ or fatal set, as a fatal error.
801
+
802
+ While the application should log the actual fatal or abortable errors, there
803
+ is no need for the application to handle the underlying errors specifically.
804
+
805
+
806
+
807
+ <a name="old-producer-fencing"></a>
808
+ #### Old producer fencing
809
+
810
+ If a new transactional producer instance is started with the same
811
+ `transactional.id`, any previous still running producer
812
+ instance will be fenced off at the next produce, commit or abort attempt, by
813
+ raising a fatal error with the error code set to
814
+ `RD_KAFKA_RESP_ERR__FENCED`.
815
+
816
+
817
+ <a name="configuration-considerations"></a>
818
+ #### Configuration considerations
819
+
820
+ To make sure messages time out (in case of connectivity problems, etc) within
821
+ the transaction, the `message.timeout.ms` configuration property must be
822
+ set lower than the `transaction.timeout.ms`, this is enforced when
823
+ creating the producer instance.
824
+ If `message.timeout.ms` is not explicitly configured it will be adjusted
825
+ automatically.
826
+
827
+
828
+
829
+
830
+ <a name="exactly-once-semantics-eos-and-transactions"></a>
831
+ ### Exactly Once Semantics (EOS) and transactions
832
+
833
+ librdkafka supports Exactly One Semantics (EOS) as defined in [KIP-98](https://cwiki.apache.org/confluence/display/KAFKA/KIP-98+-+Exactly+Once+Delivery+and+Transactional+Messaging).
834
+ For more on the use of transactions, see [Transactions in Apache Kafka](https://www.confluent.io/blog/transactions-apache-kafka/).
835
+
836
+ See [examples/transactions.c](examples/transactions.c) for an example
837
+ transactional EOS application.
838
+
839
+ **Warning**
840
+ If the broker version is older than Apache Kafka 2.5.0 then one transactional
841
+ producer instance per consumed input partition is required.
842
+ For 2.5.0 and later a single producer instance may be used regardless of
843
+ the number of input partitions.
844
+ See KIP-447 for more information.
845
+
846
+
847
+ <a name="usage"></a>
848
+ ## Usage
849
+
850
+ <a name="documentation"></a>
851
+ ### Documentation
852
+
853
+ The librdkafka API is documented in the [`rdkafka.h`](src/rdkafka.h)
854
+ header file, the configuration properties are documented in
855
+ [`CONFIGURATION.md`](CONFIGURATION.md)
856
+
857
+ <a name="initialization"></a>
858
+ ### Initialization
859
+
860
+ The application needs to instantiate a top-level object `rd_kafka_t` which is
861
+ the base container, providing global configuration and shared state.
862
+ It is created by calling `rd_kafka_new()`.
863
+
864
+ It also needs to instantiate one or more topics (`rd_kafka_topic_t`) to be used
865
+ for producing to or consuming from. The topic object holds topic-specific
866
+ configuration and will be internally populated with a mapping of all available
867
+ partitions and their leader brokers.
868
+ It is created by calling `rd_kafka_topic_new()`.
869
+
870
+ Both `rd_kafka_t` and `rd_kafka_topic_t` comes with a configuration API which
871
+ is optional.
872
+ Not using the API will cause librdkafka to use its default values which are
873
+ documented in [`CONFIGURATION.md`](CONFIGURATION.md).
874
+
875
+ **Note**: An application may create multiple `rd_kafka_t` objects and
876
+ they share no state.
877
+
878
+ **Note**: An `rd_kafka_topic_t` object may only be used with the `rd_kafka_t`
879
+ object it was created from.
880
+
881
+
882
+
883
+ <a name="configuration"></a>
884
+ ### Configuration
885
+
886
+ To ease integration with the official Apache Kafka software and lower
887
+ the learning curve, librdkafka implements identical configuration
888
+ properties as found in the official clients of Apache Kafka.
889
+
890
+ Configuration is applied prior to object creation using the
891
+ `rd_kafka_conf_set()` and `rd_kafka_topic_conf_set()` APIs.
892
+
893
+ **Note**: The `rd_kafka.._conf_t` objects are not reusable after they have been
894
+ passed to `rd_kafka.._new()`.
895
+ The application does not need to free any config resources after a
896
+ `rd_kafka.._new()` call.
897
+
898
+ <a name="example"></a>
899
+ #### Example
900
+
901
+ ```c
902
+ rd_kafka_conf_t *conf;
903
+ rd_kafka_conf_res_t res;
904
+ rd_kafka_t *rk;
905
+ char errstr[512];
906
+
907
+ conf = rd_kafka_conf_new();
908
+
909
+ res = rd_kafka_conf_set(conf, "compression.codec", "snappy",
910
+ errstr, sizeof(errstr));
911
+ if (res != RD_KAFKA_CONF_OK)
912
+ fail("%s\n", errstr);
913
+
914
+ res = rd_kafka_conf_set(conf, "batch.num.messages", "100",
915
+ errstr, sizeof(errstr));
916
+ if (res != RD_KAFKA_CONF_OK)
917
+ fail("%s\n", errstr);
918
+
919
+ rk = rd_kafka_new(RD_KAFKA_PRODUCER, conf, errstr, sizeof(errstr));
920
+ if (!rk) {
921
+ rd_kafka_conf_destroy(rk);
922
+ fail("Failed to create producer: %s\n", errstr);
923
+ }
924
+
925
+ /* Note: librdkafka takes ownership of the conf object on success */
926
+ ```
927
+
928
+ Configuration properties may be set in any order (except for interceptors) and
929
+ may be overwritten before being passed to `rd_kafka_new()`.
930
+ `rd_kafka_new()` will verify that the passed configuration is consistent
931
+ and will fail and return an error if incompatible configuration properties
932
+ are detected. It will also emit log warnings for deprecated and problematic
933
+ configuration properties.
934
+
935
+
936
+ <a name="termination"></a>
937
+ ### Termination
938
+
939
+ librdkafka is asynchronous in its nature and performs most operation in its
940
+ background threads.
941
+
942
+ Calling the librdkafka handle destructor tells the librdkafka background
943
+ threads to finalize their work, close network connections, clean up, etc, and
944
+ may thus take some time. The destructor (`rd_kafka_destroy()`) will block
945
+ until all background threads have terminated.
946
+
947
+ If the destructor blocks indefinitely it typically means there is an outstanding
948
+ object reference, such as a message or topic object, that was not destroyed
949
+ prior to destroying the client handle.
950
+
951
+ All objects except for the handle (C: `rd_kafka_t`,
952
+ C++: `Consumer,KafkaConsumer,Producer`), such as topic objects, messages,
953
+ `topic_partition_t`, `TopicPartition`, events, etc, **MUST** be
954
+ destroyed/deleted prior to destroying or closing the handle.
955
+
956
+ For C, make sure the following objects are destroyed prior to calling
957
+ `rd_kafka_consumer_close()` and `rd_kafka_destroy()`:
958
+ * `rd_kafka_message_t`
959
+ * `rd_kafka_topic_t`
960
+ * `rd_kafka_topic_partition_t`
961
+ * `rd_kafka_topic_partition_list_t`
962
+ * `rd_kafka_event_t`
963
+ * `rd_kafka_queue_t`
964
+
965
+ For C++ make sure the following objects are deleted prior to
966
+ calling `KafkaConsumer::close()` and delete on the Consumer, KafkaConsumer or
967
+ Producer handle:
968
+ * `Message`
969
+ * `Topic`
970
+ * `TopicPartition`
971
+ * `Event`
972
+ * `Queue`
973
+
974
+
975
+ <a name="high-level-kafkaconsumer"></a>
976
+ #### High-level KafkaConsumer
977
+
978
+ Proper termination sequence for the high-level KafkaConsumer is:
979
+ ```c
980
+ /* 1) Leave the consumer group, commit final offsets, etc. */
981
+ rd_kafka_consumer_close(rk);
982
+
983
+ /* 2) Destroy handle object */
984
+ rd_kafka_destroy(rk);
985
+ ```
986
+
987
+ **NOTE**: There is no need to unsubscribe prior to calling `rd_kafka_consumer_close()`.
988
+
989
+ **NOTE**: Any topic objects created must be destroyed prior to rd_kafka_destroy()
990
+
991
+ Effects of not doing the above, for:
992
+ 1. Final offsets are not committed and the consumer will not actively leave
993
+ the group, it will be kicked out of the group after the `session.timeout.ms`
994
+ expires. It is okay to omit the `rd_kafka_consumer_close()` call in case
995
+ the application does not want to wait for the blocking close call.
996
+ 2. librdkafka will continue to operate on the handle. Actual memory leaks.
997
+
998
+
999
+ <a name="producer"></a>
1000
+ #### Producer
1001
+
1002
+ The proper termination sequence for Producers is:
1003
+
1004
+ ```c
1005
+ /* 1) Make sure all outstanding requests are transmitted and handled. */
1006
+ rd_kafka_flush(rk, 60*1000); /* One minute timeout */
1007
+
1008
+ /* 2) Destroy the topic and handle objects */
1009
+ rd_kafka_topic_destroy(rkt); /* Repeat for all topic objects held */
1010
+ rd_kafka_destroy(rk);
1011
+ ```
1012
+
1013
+ Effects of not doing the above, for:
1014
+ 1. Messages in-queue or in-flight will be dropped.
1015
+ 2. librdkafka will continue to operate on the handle. Actual memory leaks.
1016
+
1017
+
1018
+ <a name="admin-api-client"></a>
1019
+ #### Admin API client
1020
+
1021
+ Unlike the Java Admin client, the Admin APIs in librdkafka are available
1022
+ on any type of client instance and can be used in combination with the
1023
+ client type's main functionality, e.g., it is perfectly fine to call
1024
+ `CreateTopics()` in your running producer, or `DeleteRecords()` in your
1025
+ consumer.
1026
+
1027
+ If you need a client instance to only perform Admin API operations the
1028
+ recommendation is to create a producer instance since it requires less
1029
+ configuration (no `group.id`) than the consumer and is generally more cost
1030
+ efficient.
1031
+ We do recommend that you set `allow.auto.create.topics=false` to avoid
1032
+ topic metadata lookups to unexpectedly have the broker create topics.
1033
+
1034
+
1035
+
1036
+ <a name="speeding-up-termination"></a>
1037
+ #### Speeding up termination
1038
+ To speed up the termination of librdkafka an application can set a
1039
+ termination signal that will be used internally by librdkafka to quickly
1040
+ cancel any outstanding I/O waits.
1041
+ Make sure you block this signal in your application.
1042
+
1043
+ ```c
1044
+ char tmp[16];
1045
+ snprintf(tmp, sizeof(tmp), "%i", SIGIO); /* Or whatever signal you decide */
1046
+ rd_kafka_conf_set(rk_conf, "internal.termination.signal", tmp, errstr, sizeof(errstr));
1047
+ ```
1048
+
1049
+
1050
+ <a name="threads-and-callbacks"></a>
1051
+ ### Threads and callbacks
1052
+
1053
+ librdkafka uses multiple threads internally to fully utilize modern hardware.
1054
+ The API is completely thread-safe and the calling application may call any
1055
+ of the API functions from any of its own threads at any time.
1056
+
1057
+ A poll-based API is used to provide signaling back to the application,
1058
+ the application should call rd_kafka_poll() at regular intervals.
1059
+ The poll API will call the following configured callbacks (optional):
1060
+
1061
+ * `dr_msg_cb` - Message delivery report callback - signals that a message has
1062
+ been delivered or failed delivery, allowing the application to take action
1063
+ and to release any application resources used in the message.
1064
+ * `error_cb` - Error callback - signals an error. These errors are usually of
1065
+ an informational nature, i.e., failure to connect to a broker, and the
1066
+ application usually does not need to take any action.
1067
+ The type of error is passed as a rd_kafka_resp_err_t enum value,
1068
+ including both remote broker errors as well as local failures.
1069
+ An application typically does not have to perform any action when
1070
+ an error is raised through the error callback, the client will
1071
+ automatically try to recover from all errors, given that the
1072
+ client and cluster is correctly configured.
1073
+ In some specific cases a fatal error may occur which will render
1074
+ the client more or less inoperable for further use:
1075
+ if the error code in the error callback is set to
1076
+ `RD_KAFKA_RESP_ERR__FATAL` the application should retrieve the
1077
+ underlying fatal error and reason using the `rd_kafka_fatal_error()` call,
1078
+ and then begin terminating the instance.
1079
+ The Event API's EVENT_ERROR has a `rd_kafka_event_error_is_fatal()`
1080
+ function, and the C++ EventCb has a `fatal()` method, to help the
1081
+ application determine if an error is fatal or not.
1082
+ * `stats_cb` - Statistics callback - triggered if `statistics.interval.ms`
1083
+ is configured to a non-zero value, emitting metrics and internal state
1084
+ in JSON format, see [STATISTICS.md].
1085
+ * `throttle_cb` - Throttle callback - triggered whenever a broker has
1086
+ throttled (delayed) a request.
1087
+
1088
+ These callbacks will also be triggered by `rd_kafka_flush()`,
1089
+ `rd_kafka_consumer_poll()`, and any other functions that serve queues.
1090
+
1091
+
1092
+ Optional callbacks not triggered by poll, these may be called spontaneously
1093
+ from any thread at any time:
1094
+
1095
+ * `log_cb` - Logging callback - allows the application to output log messages
1096
+ generated by librdkafka.
1097
+ * `partitioner_cb` - Partitioner callback - application provided message partitioner.
1098
+ The partitioner may be called in any thread at any time, it may be
1099
+ called multiple times for the same key.
1100
+ Partitioner function contraints:
1101
+ - MUST NOT call any rd_kafka_*() functions
1102
+ - MUST NOT block or execute for prolonged periods of time.
1103
+ - MUST return a value between 0 and partition_cnt-1, or the
1104
+ special RD_KAFKA_PARTITION_UA value if partitioning
1105
+ could not be performed.
1106
+
1107
+
1108
+
1109
+ <a name="brokers"></a>
1110
+ ### Brokers
1111
+
1112
+ On initialization, librdkafka only needs a partial list of
1113
+ brokers (at least one), called the bootstrap brokers.
1114
+ The client will connect to the bootstrap brokers specified by the
1115
+ `bootstrap.servers` configuration property and query cluster Metadata
1116
+ information which contains the full list of brokers, topic, partitions and their
1117
+ leaders in the Kafka cluster.
1118
+
1119
+ Broker names are specified as `host[:port]` where the port is optional
1120
+ (default 9092) and the host is either a resolvable hostname or an IPv4 or IPv6
1121
+ address.
1122
+ If host resolves to multiple addresses librdkafka will round-robin the
1123
+ addresses for each connection attempt.
1124
+ A DNS record containing all broker address can thus be used to provide a
1125
+ reliable bootstrap broker.
1126
+
1127
+
1128
+ <a name="ssl"></a>
1129
+ #### SSL
1130
+
1131
+ If the client is to connect to a broker's SSL endpoints/listeners the client
1132
+ needs to be configured with `security.protocol=SSL` for just SSL transport or
1133
+ `security.protocol=SASL_SSL` for SASL authentication and SSL transport.
1134
+ The client will try to verify the broker's certificate by checking the
1135
+ CA root certificates, if the broker's certificate can't be verified
1136
+ the connection is closed (and retried). This is to protect the client
1137
+ from connecting to rogue brokers.
1138
+
1139
+ The CA root certificate defaults are system specific:
1140
+ * On Linux, Mac OSX, and other Unix-like system the OpenSSL default
1141
+ CA path will be used, also called the OPENSSLDIR, which is typically
1142
+ `/etc/ssl/certs` (on Linux, typcially in the `ca-certificates` package) and
1143
+ `/usr/local/etc/openssl` on Mac OSX (Homebrew).
1144
+ * On Windows the Root certificate store is used, unless
1145
+ `ssl.ca.certificate.stores` is configured in which case certificates are
1146
+ read from the specified stores.
1147
+ * If OpenSSL is linked statically, librdkafka will set the default CA
1148
+ location to the first of a series of probed paths (see below).
1149
+
1150
+ If the system-provided default CA root certificates are not sufficient to
1151
+ verify the broker's certificate, such as when a self-signed certificate
1152
+ or a local CA authority is used, the CA certificate must be specified
1153
+ explicitly so that the client can find it.
1154
+ This can be done either by providing a PEM file (e.g., `cacert.pem`)
1155
+ as the `ssl.ca.location` configuration property, or by passing an in-memory
1156
+ PEM, X.509/DER or PKCS#12 certificate to `rd_kafka_conf_set_ssl_cert()`.
1157
+
1158
+ It is also possible to disable broker certificate verification completely
1159
+ by setting `enable.ssl.certificate.verification=false`, but this is not
1160
+ recommended since it allows for rogue brokers and man-in-the-middle attacks,
1161
+ and should only be used for testing and troubleshooting purposes.
1162
+
1163
+ CA location probe paths (see [rdkafka_ssl.c](src/rdkafka_ssl.c) for full list)
1164
+ used when OpenSSL is statically linked:
1165
+
1166
+ "/etc/pki/tls/certs/ca-bundle.crt",
1167
+ "/etc/ssl/certs/ca-bundle.crt",
1168
+ "/etc/pki/tls/certs/ca-bundle.trust.crt",
1169
+ "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
1170
+ "/etc/ssl/ca-bundle.pem",
1171
+ "/etc/pki/tls/cacert.pem",
1172
+ "/etc/ssl/cert.pem",
1173
+ "/etc/ssl/cacert.pem",
1174
+ "/etc/certs/ca-certificates.crt",
1175
+ "/etc/ssl/certs/ca-certificates.crt",
1176
+ "/etc/ssl/certs",
1177
+ "/usr/local/etc/ssl/cert.pem",
1178
+ "/usr/local/etc/ssl/cacert.pem",
1179
+ "/usr/local/etc/ssl/certs/cert.pem",
1180
+ "/usr/local/etc/ssl/certs/cacert.pem",
1181
+ etc..
1182
+
1183
+
1184
+ On **Windows** the Root certificate store is read by default, but any number
1185
+ of certificate stores can be read by setting the `ssl.ca.certificate.stores`
1186
+ configuration property to a comma-separated list of certificate store names.
1187
+ The predefined system store names are:
1188
+
1189
+ * `MY` - User certificates
1190
+ * `Root` - System CA certificates (default)
1191
+ * `CA` - Intermediate CA certificates
1192
+ * `Trust` - Trusted publishers
1193
+
1194
+ For example, to read both intermediate and root CAs, set
1195
+ `ssl.ca.certificate.stores=CA,Root`.
1196
+
1197
+
1198
+ <a name="oauthbearer-with-support-for-oidc"></a>
1199
+ #### OAUTHBEARER with support for OIDC
1200
+
1201
+ OAUTHBEARER with OIDC provides a method for the client to authenticate to the
1202
+ Kafka cluster by requesting an authentication token from an issuing server
1203
+ and passing the retrieved token to brokers during connection setup.
1204
+
1205
+ To use this authentication method the client needs to be configured as follows:
1206
+
1207
+ * `security.protocol` - set to `SASL_SSL` or `SASL_PLAINTEXT`.
1208
+ * `sasl.mechanism` - set to `OAUTHBEARER`.
1209
+ * `sasl.oauthbearer.method` - set to `OIDC`.
1210
+ * `sasl.oauthbearer.token.endpoint.url` - OAUTH issuer token
1211
+ endpoint HTTP(S) URI used to retrieve the token.
1212
+ * `sasl.oauthbearer.client.id` - public identifier for the application.
1213
+ It must be unique across all clients that the authorization server handles.
1214
+ * `sasl.oauthbearer.client.secret` - secret known only to the
1215
+ application and the authorization server.
1216
+ This should be a sufficiently random string that is not guessable.
1217
+ * `sasl.oauthbearer.scope` - clients use this to specify the scope of the
1218
+ access request to the broker.
1219
+ * `sasl.oauthbearer.extensions` - (optional) additional information to be
1220
+ provided to the broker. A comma-separated list of key=value pairs.
1221
+ For example:
1222
+ `supportFeatureX=true,organizationId=sales-emea`
1223
+ * `https.ca.location` - (optional) to customize the CA certificates
1224
+ location.
1225
+
1226
+ * `https.ca.pem` - (optional) to provide the CA certificates as a PEM string.
1227
+
1228
+ <a name="jwt-bearer-grant-type-kip-1139">
1229
+ ##### JWT bearer grant type (KIP-1139)
1230
+
1231
+ This KIP adds support for the `client_credentials, urn:ietf:params:oauth:grant-type:jwt-bearer`
1232
+ grant type, with a series of properties to be used for creating a JWT assertion
1233
+ sent to the token endpoint. The authenticated principal corresponds to the
1234
+ `sub` claim returned by token endpoint, `sasl.oauthbearer.client.id` and
1235
+ `sasl.oauthbearer.client.secret` aren't used. Required JWT claims must be set
1236
+ either through the template or with the `claim` properties.
1237
+
1238
+ * `sasl.oauthbearer.grant.type` - changes the default grant type, set it to
1239
+ `urn:ietf:params:oauth:grant-type:jwt-bearer`.
1240
+ * `sasl.oauthbearer.assertion.algorithm` - JWT algorithm defaults to `RS256`.
1241
+ * `sasl.oauthbearer.assertion.private.key.file` - a private key file for signing
1242
+ the token.
1243
+ * `sasl.oauthbearer.assertion.private.key.passphrase` - (optional) passphrase for the key if encrypted.
1244
+ * `sasl.oauthbearer.assertion.private.key.pem` - alternatively to the key file
1245
+ it's possible to pass the private key as a string.
1246
+ * `sasl.oauthbearer.assertion.file` - (optional) assertion file: with this property all other
1247
+ assertion related fields are ignored and the assertion is read from this file
1248
+ that should be periodically updated.
1249
+ * `sasl.oauthbearer.assertion.jwt.template.file` - (optional) template file: a template containing
1250
+ a default `header` and `payload` that can be overwritten by the `claim` properties.
1251
+ * `sasl.oauthbearer.assertion.claim.aud`,
1252
+ `sasl.oauthbearer.assertion.claim.exp.seconds`,
1253
+ `sasl.oauthbearer.assertion.claim.iss`,
1254
+ `sasl.oauthbearer.assertion.claim.jti.include`,
1255
+ `sasl.oauthbearer.assertion.claim.sub` - (optional) the `claim` properties:
1256
+ it's possible to dynamically customize the JWT claims with these or to
1257
+ skip the template file and use only these properties.
1258
+
1259
+ <a name="metadata-based-authentication"></a>
1260
+ ##### Metadata based authentication
1261
+
1262
+ Some cloud providers added the ability to authenticate clients based on
1263
+ OAUTHBEARER/OIDC tokens returned from endpoints that can only be called from
1264
+ a given instance. Such endpoints are served on a specific IP address (169.254.169.254)
1265
+ that is a link-local metadata endpoint.
1266
+
1267
+
1268
+ While there is no standard for that still, librdkafka has support for
1269
+ some metadata based OAUTHBEARER authentication types.
1270
+
1271
+
1272
+ Currently these authentication types are supported:
1273
+
1274
+ <a name="azure-imds">
1275
+ ###### Azure IMDS
1276
+
1277
+ To use this method you set:
1278
+
1279
+ * `sasl.oauthbearer.metadata.authentication.type=azure_imds` this makes it so
1280
+ that ` sasl.oauthbearer.client.id` and `sasl.oauthbearer.client.secret`
1281
+ aren't required.
1282
+ * `sasl.oauthbearer.config` is a general purpose configuration property
1283
+ In this case it accepts comma-separated `key=value` pairs.
1284
+ The `query` key is required in case `sasl.oauthbearer.token.endpoint.url` isn't
1285
+ specified and its value is the GET query string to append
1286
+ to the token endpoint URL. Such query string contains params required by
1287
+ Azure IMDS such as `client_id` (the UAMI), `resource` for determining the
1288
+ target audience and `api-version` for the API version to be used by the endpoint
1289
+ * `sasl.oauthbearer.token.endpoint.url` (optional) is set automatically.
1290
+ when choosing `sasl.oauthbearer.metadata.authentication.type=azure_imds` but can
1291
+ be customized.
1292
+
1293
+
1294
+ _Example:_ `sasl.oauthbearer.metadata.authentication.type=azure_imds` and
1295
+ `sasl.oauthbearer.config=params=api-version=2025-04-07&resource=api://<App registration client id>&client_id=<UAMI client id>`
1296
+
1297
+
1298
+ <a name="sparse-connections"></a>
1299
+ #### Sparse connections
1300
+
1301
+ The client will only connect to brokers it needs to communicate with, and
1302
+ only when necessary.
1303
+
1304
+ Examples of needed broker connections are:
1305
+
1306
+ * leaders for partitions being consumed from
1307
+ * leaders for partitions being produced to
1308
+ * consumer group coordinator broker
1309
+ * cluster controller for Admin API operations
1310
+
1311
+
1312
+ <a name="random-broker-selection"></a>
1313
+ ##### Random broker selection
1314
+
1315
+ When there is no broker connection and a connection to any broker
1316
+ is needed, such as on startup to retrieve metadata, the client randomly selects
1317
+ a broker from its list of brokers, which includes both the configured bootstrap
1318
+ brokers (including brokers manually added with `rd_kafka_brokers_add()`), as
1319
+ well as the brokers discovered from cluster metadata.
1320
+ Brokers with no prior connection attempt are tried first.
1321
+
1322
+ If there is already an available broker connection to any broker it is used,
1323
+ rather than connecting to a new one.
1324
+
1325
+ The random broker selection and connection scheduling is triggered when:
1326
+ * bootstrap servers are configured (`rd_kafka_new()`)
1327
+ * brokers are manually added (`rd_kafka_brokers_add()`).
1328
+ * a consumer group coordinator needs to be found.
1329
+ * acquiring a ProducerID for the Idempotent Producer.
1330
+ * cluster or topic metadata is being refreshed.
1331
+
1332
+ A single connection attempt will be performed, and the broker will
1333
+ return to an idle INIT state on failure to connect.
1334
+
1335
+ The random broker selection is rate-limited to:
1336
+ 10 < `reconnect.backoff.ms`/2 < 1000 milliseconds.
1337
+
1338
+ **Note**: The broker connection will be maintained until it is closed
1339
+ by the broker (idle connection reaper).
1340
+
1341
+ <a name="persistent-broker-connections"></a>
1342
+ ##### Persistent broker connections
1343
+
1344
+ While the random broker selection is useful for one-off queries, there
1345
+ is need for the client to maintain persistent connections to certain brokers:
1346
+ * Consumer: the group coordinator.
1347
+ * Consumer: partition leader for topics being fetched from.
1348
+ * Producer: partition leader for topics being produced to.
1349
+
1350
+ These dependencies are discovered and maintained automatically, marking
1351
+ matching brokers as persistent, which will make the client maintain connections
1352
+ to these brokers at all times, reconnecting as necessary.
1353
+
1354
+
1355
+ <a name="connection-close"></a>
1356
+ #### Connection close
1357
+
1358
+ A broker connection may be closed by the broker, intermediary network gear,
1359
+ due to network errors, timeouts, etc.
1360
+ When a broker connection is closed, librdkafka will back off the next reconnect
1361
+ attempt (to the given broker) for `reconnect.backoff.ms` -25% to +50% jitter,
1362
+ this value is increased exponentially for each connect attempt until
1363
+ `reconnect.backoff.max.ms` is reached, at which time the value is reset
1364
+ to `reconnect.backoff.ms`.
1365
+
1366
+ The broker will disconnect clients that have not sent any protocol requests
1367
+ within `connections.max.idle.ms` (broker configuration propertion, defaults
1368
+ to 10 minutes), but there is no fool proof way for the client to know that it
1369
+ was a deliberate close by the broker and not an error. To avoid logging these
1370
+ deliberate idle disconnects as errors the client employs some logic to try to
1371
+ classify a disconnect as an idle disconnect if no requests have been sent in
1372
+ the last `socket.timeout.ms` or there are no outstanding, or
1373
+ queued, requests waiting to be sent. In this case the standard "Disconnect"
1374
+ error log is silenced (will only be seen with debug enabled).
1375
+
1376
+ Otherwise, if a connection is closed while there are requests in-flight
1377
+ the logging level will be LOG_WARNING (4), else LOG_INFO (6).
1378
+
1379
+ `log.connection.close=false` may be used to silence all disconnect logs,
1380
+ but it is recommended to instead rely on the above heuristics.
1381
+
1382
+
1383
+ <a name="fetch-from-follower"></a>
1384
+ #### Fetch From Follower
1385
+
1386
+ librdkafka supports consuming messages from follower replicas
1387
+ ([KIP-392](https://cwiki.apache.org/confluence/display/KAFKA/KIP-392%3A+Allow+consumers+to+fetch+from+closest+replica)).
1388
+ This is enabled by setting the `client.rack` configuration property which
1389
+ corresponds to `broker.rack` on the broker. The actual assignment of
1390
+ consumers to replicas is determined by the configured `replica.selector.class`
1391
+ on the broker.
1392
+
1393
+
1394
+ <a name="logging"></a>
1395
+ ### Logging
1396
+
1397
+ <a name="debug-contexts"></a>
1398
+ #### Debug contexts
1399
+
1400
+ Extensive debugging of librdkafka can be enabled by setting the
1401
+ `debug` configuration property to a CSV string of debug contexts:
1402
+
1403
+ | Debug context | Type | Description |
1404
+ | ------------- | -------- | ------------------------------------------------------------------------------------------- |
1405
+ | generic | * | General client instance level debugging. Includes initialization and termination debugging. |
1406
+ | broker | * | Broker and connection state debugging. |
1407
+ | topic | * | Topic and partition state debugging. Includes leader changes. |
1408
+ | metadata | * | Cluster and topic metadata retrieval debugging. |
1409
+ | feature | * | Kafka protocol feature support as negotiated with the broker. |
1410
+ | queue | producer | Message queue debugging. |
1411
+ | msg | * | Message debugging. Includes information about batching, compression, sizes, etc. |
1412
+ | protocol | * | Kafka protocol request/response debugging. Includes latency (rtt) printouts. |
1413
+ | cgrp | consumer | Low-level consumer group state debugging. |
1414
+ | security | * | Security and authentication debugging. |
1415
+ | fetch | consumer | Consumer message fetch debugging. Includes decision when and why messages are fetched. |
1416
+ | interceptor | * | Interceptor interface debugging. |
1417
+ | plugin | * | Plugin loading debugging. |
1418
+ | consumer | consumer | High-level consumer debugging. |
1419
+ | admin | admin | Admin API debugging. |
1420
+ | eos | producer | Idempotent Producer debugging. |
1421
+ | mock | * | Mock cluster functionality debugging. |
1422
+ | assignor | consumer | Detailed consumer group partition assignor debugging. |
1423
+ | conf | * | Display set configuration properties on startup. |
1424
+ | all | * | All of the above. |
1425
+
1426
+
1427
+ Suggested debugging settings for troubleshooting:
1428
+
1429
+ | Problem space | Type | Debug setting |
1430
+ | -------------------------------------------- | -------- | -------------------------------------------------------------------- |
1431
+ | Producer not delivering messages to broker | producer | `broker,topic,msg` |
1432
+ | Consumer not fetching messages | consumer | Start with `consumer`, or use `cgrp,fetch` for detailed information. |
1433
+ | Consumer starts reading at unexpected offset | consumer | `consumer` or `cgrp,fetch` |
1434
+ | Authentication or connectivity issues | * | `broker,auth` |
1435
+ | Protocol handling or latency | * | `broker,protocol` |
1436
+ | Topic leader and state | * | `topic,metadata` |
1437
+
1438
+
1439
+
1440
+
1441
+ <a name="feature-discovery"></a>
1442
+ ### Feature discovery
1443
+
1444
+ Apache Kafka broker version 0.10.0 added support for the ApiVersionRequest API
1445
+ which allows a client to query a broker for its range of supported API versions.
1446
+
1447
+ librdkafka supports this functionality and will query each broker on connect
1448
+ for this information (if `api.version.request=true`) and use it to enable or disable
1449
+ various protocol features, such as MessageVersion 1 (timestamps), KafkaConsumer, etc.
1450
+
1451
+ If the broker fails to respond to the ApiVersionRequest librdkafka will
1452
+ assume the broker is too old to support the API and fall back to an older
1453
+ broker version's API. These fallback versions are hardcoded in librdkafka
1454
+ and is controlled by the `broker.version.fallback` configuration property.
1455
+
1456
+
1457
+
1458
+ <a name="producer-api"></a>
1459
+ ### Producer API
1460
+
1461
+ After setting up the `rd_kafka_t` object with type `RD_KAFKA_PRODUCER` and one
1462
+ or more `rd_kafka_topic_t` objects librdkafka is ready for accepting messages
1463
+ to be produced and sent to brokers.
1464
+
1465
+ The `rd_kafka_produce()` function takes the following arguments:
1466
+
1467
+ * `rkt` - the topic to produce to, previously created with
1468
+ `rd_kafka_topic_new()`
1469
+ * `partition` - partition to produce to. If this is set to
1470
+ `RD_KAFKA_PARTITION_UA` (UnAssigned) then the configured partitioner
1471
+ function will be used to select a target partition.
1472
+ * `msgflags` - 0, or one of:
1473
+ * `RD_KAFKA_MSG_F_COPY` - librdkafka will immediately make a copy of
1474
+ the payload. Use this when the payload is in non-persistent
1475
+ memory, such as the stack.
1476
+ * `RD_KAFKA_MSG_F_FREE` - let librdkafka free the payload using
1477
+ `free(3)` when it is done with it.
1478
+
1479
+ These two flags are mutually exclusive and neither need to be set in
1480
+ which case the payload is neither copied nor freed by librdkafka.
1481
+
1482
+ If `RD_KAFKA_MSG_F_COPY` flag is not set no data copying will be
1483
+ performed and librdkafka will hold on the payload pointer until
1484
+ the message has been delivered or fails.
1485
+ The delivery report callback will be called when librdkafka is done
1486
+ with the message to let the application regain ownership of the
1487
+ payload memory.
1488
+ The application must not free the payload in the delivery report
1489
+ callback if `RD_KAFKA_MSG_F_FREE is set`.
1490
+ * `payload`,`len` - the message payload
1491
+ * `key`,`keylen` - an optional message key which can be used for partitioning.
1492
+ It will be passed to the topic partitioner callback, if any, and
1493
+ will be attached to the message when sending to the broker.
1494
+ * `msg_opaque` - an optional application-provided per-message opaque pointer
1495
+ that will be provided in the message delivery callback to let
1496
+ the application reference a specific message.
1497
+
1498
+
1499
+ `rd_kafka_produce()` is a non-blocking API, it will enqueue the message
1500
+ on an internal queue and return immediately.
1501
+ If the new message would cause the internal queue to exceed
1502
+ `queue.buffering.max.messages` or `queue.buffering.max.kbytes`
1503
+ configuration properties, `rd_kafka_produce()` returns -1 and sets errno
1504
+ to `ENOBUFS` and last_error to `RD_KAFKA_RESP_ERR__QUEUE_FULL`, thus
1505
+ providing a backpressure mechanism.
1506
+
1507
+
1508
+ `rd_kafka_producev()` provides an alternative produce API that does not
1509
+ require a topic `rkt` object and also provides support for extended
1510
+ message fields, such as timestamp and headers.
1511
+
1512
+
1513
+ **Note**: See `examples/rdkafka_performance.c` for a producer implementation.
1514
+
1515
+
1516
+ <a name="simple-consumer-api-legacy"></a>
1517
+ ### Simple Consumer API (legacy)
1518
+
1519
+ NOTE: For the high-level KafkaConsumer interface see rd_kafka_subscribe (rdkafka.h) or KafkaConsumer (rdkafkacpp.h)
1520
+
1521
+ The consumer API is a bit more stateful than the producer API.
1522
+ After creating `rd_kafka_t` with type `RD_KAFKA_CONSUMER` and
1523
+ `rd_kafka_topic_t` instances the application must also start the consumer
1524
+ for a given partition by calling `rd_kafka_consume_start()`.
1525
+
1526
+ `rd_kafka_consume_start()` arguments:
1527
+
1528
+ * `rkt` - the topic to start consuming from, previously created with
1529
+ `rd_kafka_topic_new()`.
1530
+ * `partition` - partition to consume from.
1531
+ * `offset` - message offset to start consuming from. This may either be an
1532
+ absolute message offset or one of the three special offsets:
1533
+ `RD_KAFKA_OFFSET_BEGINNING` to start consuming from the beginning
1534
+ of the partition's queue (oldest message), or
1535
+ `RD_KAFKA_OFFSET_END` to start consuming at the next message to be
1536
+ produced to the partition, or
1537
+ `RD_KAFKA_OFFSET_STORED` to use the offset store.
1538
+
1539
+ After a topic+partition consumer has been started librdkafka will attempt
1540
+ to keep `queued.min.messages` messages in the local queue by repeatedly
1541
+ fetching batches of messages from the broker. librdkafka will fetch all
1542
+ consumed partitions for which that broker is a leader, through a single
1543
+ request.
1544
+
1545
+ This local message queue is then served to the application through three
1546
+ different consume APIs:
1547
+
1548
+ * `rd_kafka_consume()` - consumes a single message
1549
+ * `rd_kafka_consume_batch()` - consumes one or more messages
1550
+ * `rd_kafka_consume_callback()` - consumes all messages in the local
1551
+ queue and calls a callback function for each one.
1552
+
1553
+ These three APIs are listed above the ascending order of performance,
1554
+ `rd_kafka_consume()` being the slowest and `rd_kafka_consume_callback()` being
1555
+ the fastest. The different consume variants are provided to cater for different
1556
+ application needs.
1557
+
1558
+ A consumed message, as provided or returned by each of the consume functions,
1559
+ is represented by the `rd_kafka_message_t` type.
1560
+
1561
+ `rd_kafka_message_t` members:
1562
+
1563
+ * `err` - Error signaling back to the application. If this field is non-zero
1564
+ the `payload` field should be considered an error message and
1565
+ `err` is an error code (`rd_kafka_resp_err_t`).
1566
+ If `err` is zero then the message is a proper fetched message
1567
+ and `payload` et.al contains message payload data.
1568
+ * `rkt`,`partition` - Topic and partition for this message or error.
1569
+ * `payload`,`len` - Message payload data or error message (err!=0).
1570
+ * `key`,`key_len` - Optional message key as specified by the producer
1571
+ * `offset` - Message offset
1572
+
1573
+ Both the `payload` and `key` memory, as well as the message as a whole, is
1574
+ owned by librdkafka and must not be used after an `rd_kafka_message_destroy()`
1575
+ call. librdkafka will share the same messageset receive buffer memory for all
1576
+ message payloads of that messageset to avoid excessive copying which means
1577
+ that if the application decides to hang on to a single `rd_kafka_message_t`
1578
+ it will hinder the backing memory to be released for all other messages
1579
+ from the same messageset.
1580
+
1581
+ When the application is done consuming messages from a topic+partition it
1582
+ should call `rd_kafka_consume_stop()` to stop the consumer. This will also
1583
+ purge any messages currently in the local queue.
1584
+
1585
+
1586
+ **Note**: See `examples/rdkafka_performance.c` for a consumer implementation.
1587
+
1588
+
1589
+ <a name="offset-management"></a>
1590
+ #### Offset management
1591
+
1592
+ Broker based offset management is available for broker version >= 0.9.0
1593
+ in conjunction with using the high-level KafkaConsumer interface (see
1594
+ rdkafka.h or rdkafkacpp.h)
1595
+
1596
+ Offset management is also available through a deprecated local offset file,
1597
+ where the offset is periodically written to a local file for each
1598
+ topic+partition according to the following topic configuration properties:
1599
+
1600
+ * `enable.auto.commit`
1601
+ * `auto.commit.interval.ms`
1602
+ * `offset.store.path`
1603
+ * `offset.store.sync.interval.ms`
1604
+
1605
+ The legacy `auto.commit.enable` topic configuration property is only to be used
1606
+ with the legacy low-level consumer.
1607
+ Use `enable.auto.commit` with the modern KafkaConsumer.
1608
+
1609
+
1610
+ <a name="auto-offset-commit"></a>
1611
+ ##### Auto offset commit
1612
+
1613
+ The consumer will automatically commit offsets every `auto.commit.interval.ms`
1614
+ when `enable.auto.commit` is enabled (default).
1615
+
1616
+ Offsets to be committed are kept in a local in-memory offset store,
1617
+ this offset store is updated by `consumer_poll()` (et.al) to
1618
+ store the offset of the last message passed to the application
1619
+ (per topic+partition).
1620
+
1621
+ <a name="at-least-once-processing"></a>
1622
+ ##### At-least-once processing
1623
+ Since auto commits are performed in a background thread this may result in
1624
+ the offset for the latest message being committed before the application has
1625
+ finished processing the message. If the application was to crash or exit
1626
+ prior to finishing processing, and the offset had been auto committed,
1627
+ the next incarnation of the consumer application would start at the next
1628
+ message, effectively missing the message that was processed when the
1629
+ application crashed.
1630
+ To avoid this scenario the application can disable the automatic
1631
+ offset **store** by setting `enable.auto.offset.store` to false
1632
+ and manually **storing** offsets after processing by calling
1633
+ `rd_kafka_offsets_store()`.
1634
+ This gives an application fine-grained control on when a message
1635
+ is eligible for committing without having to perform the commit itself.
1636
+ `enable.auto.commit` should be set to true when using manual offset storing.
1637
+ The latest stored offset will be automatically committed every
1638
+ `auto.commit.interval.ms`.
1639
+
1640
+ **Note**: Only greater offsets are committed, e.g., if the latest committed
1641
+ offset was 10 and the application performs an offsets_store()
1642
+ with offset 9, that offset will not be committed.
1643
+
1644
+
1645
+ <a name="auto-offset-reset"></a>
1646
+ ##### Auto offset reset
1647
+
1648
+ The consumer will by default try to acquire the last committed offsets for
1649
+ each topic+partition it is assigned using its configured `group.id`.
1650
+ If there is no committed offset available, or the consumer is unable to
1651
+ fetch the committed offsets, the policy of `auto.offset.reset` will kick in.
1652
+ This configuration property may be set to one the following values:
1653
+
1654
+ * `earliest` - start consuming the earliest message of the partition.
1655
+ * `latest` - start consuming the next message to be produced to the partition.
1656
+ * `error` - don't start consuming but isntead raise a consumer error
1657
+ with error-code `RD_KAFKA_RESP_ERR__AUTO_OFFSET_RESET` for
1658
+ the topic+partition. This allows the application to decide what
1659
+ to do in case there is no committed start offset.
1660
+
1661
+
1662
+ <a name="consumer-groups"></a>
1663
+ ### Consumer groups
1664
+
1665
+ Broker based consumer groups (requires Apache Kafka broker >=0.9) are supported,
1666
+ see KafkaConsumer in rdkafka.h or rdkafkacpp.h
1667
+
1668
+ The following diagram visualizes the high-level balanced consumer group state
1669
+ flow and synchronization between the application, librdkafka consumer,
1670
+ group coordinator, and partition leader(s).
1671
+
1672
+ ![Consumer group state diagram](src/librdkafka_cgrp_synch.png)
1673
+
1674
+
1675
+ <a name="static-consumer-groups"></a>
1676
+ #### Static consumer groups
1677
+
1678
+ By default Kafka consumers are rebalanced each time a new consumer joins
1679
+ the group or an existing member leaves. This is what is known as a dynamic
1680
+ membership. Apache Kafka >= 2.3.0 introduces static membership.
1681
+ Unlike dynamic membership, static members can leave and rejoin a group
1682
+ within the `session.timeout.ms` without triggering a rebalance, retaining
1683
+ their existing partitions assignment.
1684
+
1685
+ To enable static group membership configure each consumer instance
1686
+ in the group with a unique `group.instance.id`.
1687
+
1688
+ Consumers with `group.instance.id` set will not send a leave group request on
1689
+ close - session timeout, change of subscription, or a new group member joining
1690
+ the group, are the only mechanisms that will trigger a group rebalance for
1691
+ static consumer groups.
1692
+
1693
+ If a new consumer joins the group with same `group.instance.id` as an
1694
+ existing consumer, the existing consumer will be fenced and raise a fatal error.
1695
+ The fatal error is propagated as a consumer error with error code
1696
+ `RD_KAFKA_RESP_ERR__FATAL`, use `rd_kafka_fatal_error()` to retrieve
1697
+ the original fatal error code and reason.
1698
+
1699
+ To read more about static group membership, see [KIP-345](https://cwiki.apache.org/confluence/display/KAFKA/KIP-345%3A+Introduce+static+membership+protocol+to+reduce+consumer+rebalances).
1700
+
1701
+ <a name="next-generation-consumer-group-protocol-kip-848"></a>
1702
+ ### Next Generation Consumer Group Protocol ([KIP-848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848%3A+The+Next+Generation+of+the+Consumer+Rebalance+Protocol))
1703
+
1704
+ Starting with **librdkafka v2.12.0** (GA release), the next generation consumer group rebalance protocol defined in **[KIP-848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848%3A+The+Next+Generation+of+the+Consumer+Rebalance+Protocol)** is **production-ready**.
1705
+
1706
+ **Note:** The new consumer group protocol defined in [KIP-848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848%3A+The+Next+Generation+of+the+Consumer+Rebalance+Protocol) is not enabled by default. There are few contract change associated with the new protocol and might cause breaking changes. `group.protocol` configuration property dictates whether to use the new `consumer` protocol or older `classic` protocol. It defaults to `classic` if not provided.
1707
+
1708
+ <a name="overview"></a>
1709
+ #### Overview
1710
+ - **What changed:**
1711
+ The **Group Leader role** (consumer member) is removed. Assignments are calculated by the **Group Coordinator (broker)** and distributed via **heartbeats**.
1712
+
1713
+ - **Requirements:**
1714
+ - Broker version: **v4.0.0+**
1715
+ - librdkafka version: **v2.12.0+**: GA (production-ready)
1716
+
1717
+ - **Enablement (client-side):**
1718
+ - `group.protocol=consumer`
1719
+ - `group.remote.assignor=<assignor>` (optional; broker-controlled if `NULL`; default broker assignor is **`uniform`**)
1720
+
1721
+ <a name="available-features"></a>
1722
+ #### Available Features
1723
+
1724
+ All [KIP-848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848%3A+The+Next+Generation+of+the+Consumer+Rebalance+Protocol) features are supported including:
1725
+
1726
+ - Subscription to one or more topics, including **regular expression (regex) subscriptions**
1727
+ - Rebalance callbacks (**incremental only**)
1728
+ - Static group membership
1729
+ - Configurable remote assignor
1730
+ - Enforced max poll interval
1731
+ - Upgrade from `classic` protocol or downgrade from `consumer` protocol
1732
+ - AdminClient changes as per KIP
1733
+
1734
+ <a name="contract-changes"></a>
1735
+ #### Contract Changes
1736
+
1737
+ <a name="client-configuration-changes"></a>
1738
+ ##### Client Configuration changes
1739
+
1740
+ | Classic Protocol (Deprecated Configs in KIP-848) | KIP-848 / Next-Gen Replacement |
1741
+ | ------------------------------------------------ | ----------------------------------------------------- |
1742
+ | `partition.assignment.strategy` | `group.remote.assignor` |
1743
+ | `session.timeout.ms` | Broker config: `group.consumer.session.timeout.ms` |
1744
+ | `heartbeat.interval.ms` | Broker config: `group.consumer.heartbeat.interval.ms` |
1745
+ | `group.protocol.type` | Not used in the new protocol |
1746
+
1747
+ **Note:** The properties listed under “Classic Protocol (Deprecated Configs in KIP-848)” are **no longer used** when using the KIP-848 consumer protocol.
1748
+
1749
+ <a name="regex-subscription-changes"></a>
1750
+ ##### Regex Subscription Changes
1751
+
1752
+ Regex matching in the `consumer` protocol is performed on the broker side, using the **Google RE2/J** regex engine.
1753
+ This differs from the `classic` protocol—where librdkafka and derived clients performed regex evaluation locally using the **libc regex** engine.
1754
+
1755
+ As part of adopting the `consumer` protocol, librdkafka (and derived clients) now rely on the broker’s RE2/J engine for regex-based subscriptions, effectively replacing the previous `libc`-based matching behavior.
1756
+
1757
+ **A known case which would fail with the new protocol**: we have topics `topic-1` and `topic-2`. If we subscribe with `^topic` or `^topic*` in the `classic` protocol, it's assigned partitions from both topics but no partitions is assigned with the `consumer` protocol. That's because the broker side regex implementation as well as the Java classic protocol one requires that regexes match the complete topic, while `libc` one only finds the pattern into the topic, that could also be present as a prefix. To obtain the same result with this example you'd use `^topic.*` instead.
1758
+
1759
+ <a name="rebalance-callback-changes"></a>
1760
+ ##### Rebalance Callback Changes
1761
+
1762
+ - Protocol is **fully incremental**.
1763
+ - **Inside the rebalance callback**, you **must use**:
1764
+ - `rd_kafka_incremental_assign(rk, partitions)` to assign partitions
1765
+ - `rd_kafka_incremental_unassign(rk, partitions)` to revoke partitions
1766
+ - **Do not** use `rd_kafka_assign()` or other assignment APIs in KIP-848.
1767
+ - **Important:** The `partitions` parameter passed to `rd_kafka_incremental_assign` or `rd_kafka_incremental_unassign` contains only an **incremental list of partitions**—those being added or revoked—rather than the full partition list returned by `rd_kafka_assign(rk, partitions)` in the **range assignor of the classic protocol**, which was the default.
1768
+ - All assignors are **sticky**, including `range` (which wasn’t sticky before).
1769
+
1770
+ <a name="static-group-membership"></a>
1771
+ ##### Static Group Membership
1772
+
1773
+ - Duplicate `group.instance.id` handling:
1774
+ - **Newly joining member** is fenced with **UNRELEASED_INSTANCE_ID (fatal)**.
1775
+ - (Classic protocol fenced the **existing** member instead.)
1776
+ - Implications:
1777
+ - Ensure only **one active instance per `group.instance.id`**.
1778
+ - Consumers must shut down cleanly to avoid blocking replacements until session timeout expires.
1779
+
1780
+ <a name="session-timeout--fetching"></a>
1781
+ ##### Session Timeout & Fetching
1782
+
1783
+ - **Session timeout is broker-controlled**:
1784
+ - If the Coordinator is unreachable, a consumer **continues fetching messages** but cannot commit offsets.
1785
+ - Consumer is fenced once a heartbeat response is received from the Coordinator.
1786
+ - In the classic protocol, the client stopped fetching when session timeout expired.
1787
+
1788
+ <a name="closing--auto-commit"></a>
1789
+ ##### Closing / Auto-Commit
1790
+
1791
+ - On `close()` or unsubscribe with auto-commit enabled:
1792
+ - Member retries committing offsets until a timeout expires.
1793
+ - Currently uses the **default remote session timeout**.
1794
+ - Future **KIP-1092** will allow custom commit timeouts.
1795
+
1796
+ <a name="error-handling-changes"></a>
1797
+ ##### Error Handling Changes
1798
+
1799
+ - `UNKNOWN_TOPIC_OR_PART` (**subscription case**):
1800
+ - No longer returned if a topic is missing in the **local cache** when subscribing; the subscription proceeds.
1801
+ - `TOPIC_AUTHORIZATION_FAILED`:
1802
+ - Reported once per heartbeat or subscription change, even if only one topic is unauthorized.
1803
+
1804
+ <a name="summary-of-key-differences-classic-vs-next-gen"></a>
1805
+ ##### Summary of Key Differences (Classic vs Next-Gen)
1806
+
1807
+ - **Assignment:** Classic protocol calculated by **Group Leader (consumer)**; KIP-848 calculated by **Group Coordinator (broker)**
1808
+ - **Assignors:** Classic range assignor was **not sticky**; KIP-848 assignors are **sticky**, including range
1809
+ - **Deprecated configs:** Classic client configs are replaced by `group.remote.assignor` and broker-controlled session/heartbeat configs
1810
+ - **Static membership fencing:** KIP-848 fences **new member** on duplicate `group.instance.id`
1811
+ - **Session timeout:** Classic enforced on client; KIP-848 enforced on broker
1812
+ - **Auto-commit on close:** Classic stops at client session timeout; KIP-848 retries until remote timeout
1813
+ - **Unknown topics:** KIP-848 does not return error on subscription if topic missing
1814
+ - **Upgrade/Downgrade:** KIP-848 supports upgrade/downgrade from/to `classic` and `consumer` protocols
1815
+
1816
+ <a name="minimal-example-config"></a>
1817
+ #### Minimal Example Config
1818
+
1819
+ <a name="classic-protocol"></a>
1820
+ ##### Classic Protocol
1821
+ ```properties
1822
+ # Optional; default is 'classic'
1823
+ group.protocol=classic
1824
+
1825
+ partition.assignment.strategy=<range,roundrobin,sticky>
1826
+ session.timeout.ms=45000
1827
+ heartbeat.interval.ms=15000
1828
+ ```
1829
+
1830
+ <a name="next-gen-protocol--kip-848"></a>
1831
+ ##### Next-Gen Protocol / KIP-848
1832
+ ```properties
1833
+ group.protocol=consumer
1834
+
1835
+ # Optional: select a remote assignor
1836
+ # Valid options currently: 'uniform' or 'range'
1837
+ # group.remote.assignor=<uniform,range>
1838
+ # If unset(NULL), broker chooses the assignor (default: 'uniform')
1839
+
1840
+ # Session & heartbeat now controlled by broker:
1841
+ # group.consumer.session.timeout.ms
1842
+ # group.consumer.heartbeat.interval.ms
1843
+ ```
1844
+
1845
+ <a name="rebalance-callback-migration"></a>
1846
+ #### Rebalance Callback Migration
1847
+
1848
+ <a name="range-assignor-classic"></a>
1849
+ ##### Range Assignor (Classic)
1850
+ ```c
1851
+ /* Rebalance callback for range assignor (classic) */
1852
+ static void rebalance_cb (rd_kafka_t *rk,
1853
+ rd_kafka_resp_err_t err,
1854
+ rd_kafka_topic_partition_list_t *partitions,
1855
+ void *opaque) {
1856
+ switch (err) {
1857
+ case RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS:
1858
+ rd_kafka_assign(rk, partitions); /* full partition list */
1859
+ break;
1860
+
1861
+ case RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS:
1862
+ rd_kafka_assign(rk, NULL); /* revoke all partitions */
1863
+ break;
1864
+
1865
+ default:
1866
+ fprintf(stderr, "Rebalance error: %s\n", rd_kafka_err2str(err));
1867
+ break;
1868
+ }
1869
+ }
1870
+ ```
1871
+
1872
+ <a name="incremental-assignor-including-range-in-consumer--kip-848-any-protocol"></a>
1873
+ ##### Incremental Assignor (Including Range in Consumer / KIP-848, Any Protocol)
1874
+
1875
+ ```c
1876
+ /* Rebalance callback for incremental assignor */
1877
+ static void rebalance_cb (rd_kafka_t *rk,
1878
+ rd_kafka_resp_err_t err,
1879
+ rd_kafka_topic_partition_list_t *partitions,
1880
+ void *opaque) {
1881
+ switch (err) {
1882
+ case RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS:
1883
+ rd_kafka_incremental_assign(rk, partitions); /* incremental partitions only */
1884
+ break;
1885
+
1886
+ case RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS:
1887
+ rd_kafka_incremental_unassign(rk, partitions);
1888
+ break;
1889
+
1890
+ default:
1891
+ fprintf(stderr, "Rebalance error: %s\n", rd_kafka_err2str(err));
1892
+ break;
1893
+ }
1894
+ }
1895
+ ```
1896
+ **Note:**
1897
+ - The `partitions` list contains **only partitions being added or revoked**, not the full partition list as in the classic `rd_kafka_assign()`.
1898
+
1899
+ <a name="upgrade-and-downgrade"></a>
1900
+ #### Upgrade and Downgrade
1901
+
1902
+ - A group made up entirely of `classic` consumers runs under the classic protocol.
1903
+ - The group is **upgraded to the consumer protocol** as soon as at least one `consumer` protocol member joins.
1904
+ - The group is **downgraded back to the classic protocol** if the last `consumer` protocol member leaves while `classic` members remain.
1905
+ - Both **rolling upgrade** (classic → consumer) and **rolling downgrade** (consumer → classic) are supported.
1906
+
1907
+
1908
+ <a name="migration-checklist-next-gen-protocol--kip-848"></a>
1909
+ #### Migration Checklist (Next-Gen Protocol / [KIP-848](https://cwiki.apache.org/confluence/display/KAFKA/KIP-848%3A+The+Next+Generation+of+the+Consumer+Rebalance+Protocol))
1910
+
1911
+ 1. Upgrade to **librdkafka ≥ v2.12.0** (GA release)
1912
+ 2. Run against **Kafka brokers ≥ v4.0.0**
1913
+ 3. Set `group.protocol=consumer`
1914
+ 4. Optionally set `group.remote.assignor`; leave `NULL` for broker-controlled (default: `uniform`), valid options: `uniform` or `range`
1915
+ 5. Replace deprecated configs with new ones
1916
+ 6. Update rebalance callbacks to **incremental APIs only**
1917
+ 7. Review static membership handling (`group.instance.id`)
1918
+ 8. Ensure proper shutdown to avoid fencing issues
1919
+ 9. Adjust error handling for unknown topics and authorization failures
1920
+
1921
+
1922
+ <a name="note-on-batch-consume-apis"></a>
1923
+ ### Note on Batch consume APIs
1924
+
1925
+ Using multiple instances of `rd_kafka_consume_batch()` and/or `rd_kafka_consume_batch_queue()`
1926
+ APIs concurrently is not thread safe and will result in undefined behaviour. We strongly recommend a
1927
+ single instance of these APIs to be used at a given time. This usecase is not supported and will not
1928
+ be supported in future as well. There are different ways to achieve similar result:
1929
+
1930
+ * Create multiple consumers reading from different partitions. In this way, different partitions
1931
+ are read by different consumers and each consumer can run its own batch call.
1932
+ * Create multiple consumers in same consumer group. In this way, partitions are assigned to
1933
+ different consumers and each consumer can run its own batch call.
1934
+ * Create single consumer and read data from single batch call and process this data in parallel.
1935
+
1936
+ Even after this if you feel the need to use multiple instances of these APIs for the same consumer
1937
+ concurrently, then don't use any of the **seek**, **pause**, **resume** or **rebalancing** operation
1938
+ in conjunction with these API calls. For **rebalancing** operation to work in sequencial manner, please
1939
+ set `rebalance_cb` configuration property (refer [examples/rdkafka_complex_consumer_example.c](examples/rdkafka_complex_consumer_example.c)
1940
+ for the help with the usage) for the consumer.
1941
+
1942
+
1943
+ <a name="share-consumers-queues-for-kafka"></a>
1944
+ ### Share consumers (Queues for Kafka)
1945
+
1946
+ > **Preview feature.** The share consumer is provided as a preview. Its public
1947
+ > interfaces (the `rd_kafka_share_*` APIs in [rdkafka.h](src/rdkafka.h)) may
1948
+ > change in a future release and it is not recommended for production use.
1949
+ > See [Current limitations](#share-consumer-current-limitations) below.
1950
+
1951
+ Share groups ([KIP-932](https://cwiki.apache.org/confluence/display/KAFKA/KIP-932%3A+Queues+for+Kafka))
1952
+ bring queue-like semantics to Kafka. Where a consumer group assigns
1953
+ each partition to exactly one member at a time, a *share group* lets multiple
1954
+ members consume from the **same** partitions cooperatively. The unit of
1955
+ progress is the individual record rather than the committed offset: each
1956
+ delivered record is *acquired* by a member under a time-limited acquisition
1957
+ lock, processed, and then *acknowledged*. The lock duration is a broker/group
1958
+ setting (`group.share.record.lock.duration.ms`, 30 seconds by default) and is
1959
+ not configured on this client. A record that is not acknowledged before its
1960
+ lock expires, or that is explicitly released, becomes available again and may
1961
+ be redelivered — possibly to a different member. A record thus moves through the
1962
+ states *available* → *acquired* → *acknowledged*; a rejected record, or one that
1963
+ exceeds the broker's delivery-count limit, becomes *archived* and is no longer
1964
+ delivered. This makes it possible to scale the number of consumers beyond the
1965
+ number of partitions and to distribute work like a traditional queue.
1966
+
1967
+ For a conceptual overview of share groups and Queues for Kafka, see the
1968
+ [Confluent share consumer documentation](https://docs.confluent.io/platform/current/clients/share-consumers.html).
1969
+
1970
+ A share consumer is a distinct handle type, `rd_kafka_share_t`, created with
1971
+ `rd_kafka_share_consumer_new()` (not `rd_kafka_new()`). The full API reference
1972
+ lives in the *Share consumer (Queues for Kafka)* section of
1973
+ [rdkafka.h](src/rdkafka.h). The share consumer is currently available through
1974
+ the **C API only**; there is no C++ (`rdkafkacpp.h`) wrapper yet.
1975
+
1976
+ #### Broker requirement
1977
+
1978
+ A share consumer requires a broker with **share groups enabled**. Share groups
1979
+ are available since **Apache Kafka 4.2.0**. Partition assignment is entirely
1980
+ broker-driven (via the share group heartbeat); there is no client-side
1981
+ rebalance callback or `assign()` step.
1982
+
1983
+ #### Lifecycle
1984
+
1985
+ ```
1986
+ rd_kafka_share_consumer_new() # create handle from an rd_kafka_conf_t
1987
+ rd_kafka_share_subscribe() # subscribe to a set of topics
1988
+ loop:
1989
+ rd_kafka_share_poll() # fetch a batch of messages
1990
+ ... process / acknowledge ...
1991
+ rd_kafka_share_commit_*() # (optional) flush acknowledgements
1992
+ rd_kafka_share_consumer_close() # send pending acks, leave the group
1993
+ rd_kafka_share_destroy() # free the handle
1994
+ ```
1995
+
1996
+ #### Configuration
1997
+
1998
+ Configure the handle through the normal `rd_kafka_conf_t` interface before
1999
+ creating it. `group.id` is required. `share.acknowledgement.mode` is optional
2000
+ and defaults to `implicit` (see below). It is the only share-specific client
2001
+ property: other share-group settings (acquisition-lock duration, delivery-count
2002
+ limit, session/heartbeat timeouts, isolation level, acquire mode and offset
2003
+ reset) are broker/group settings and are not exposed by this client.
2004
+
2005
+ Several regular-consumer properties do not apply to share consumers and are
2006
+ rejected or ignored — for example `partition.assignment.strategy`,
2007
+ `enable.auto.commit`, `auto.offset.reset` semantics, `isolation.level`,
2008
+ `enable.partition.eof`, `group.instance.id`, `group.remote.assignor`, and the
2009
+ per-partition fetch-queue tuning (`queued.min.messages`,
2010
+ `queued.max.messages.kbytes`, `fetch.message.max.bytes`, etc.). A few network
2011
+ defaults also differ for share consumers (for example `receive.message.max.bytes`,
2012
+ `connections.max.idle.ms`, `reconnect.backoff.ms`). See
2013
+ [CONFIGURATION.md](CONFIGURATION.md), where these properties are annotated, for
2014
+ the authoritative list and the share-consumer default values.
2015
+
2016
+ #### Polling and message batches
2017
+
2018
+ `rd_kafka_share_poll()` returns a **batch** of messages in a single call
2019
+ (unlike the regular single-message poll), as an opaque `rd_kafka_messages_t`
2020
+ handle. Iterate it with `rd_kafka_messages_count()` and
2021
+ `rd_kafka_messages_get()`, and release it with `rd_kafka_messages_destroy()`
2022
+ (which is NULL-safe). `max.poll.records` (default 500) bounds the batch size.
2023
+
2024
+ Record-level errors are surfaced as individual messages with a non-zero
2025
+ `rd_kafka_message_t.err` field (the topic, partition and offset remain valid),
2026
+ so the application should check each message's `err` before treating it as
2027
+ data.
2028
+
2029
+ #### Acknowledgement
2030
+
2031
+ Every acquired record is acknowledged with one of three types:
2032
+
2033
+ * **ACCEPT** (`RD_KAFKA_SHARE_ACKNOWLEDGE_TYPE_ACCEPT`) — processed
2034
+ successfully.
2035
+ * **RELEASE** (`RD_KAFKA_SHARE_ACKNOWLEDGE_TYPE_RELEASE`) — not processed; make
2036
+ the record available again for redelivery.
2037
+ * **REJECT** (`RD_KAFKA_SHARE_ACKNOWLEDGE_TYPE_REJECT`) — do not deliver the
2038
+ record again.
2039
+
2040
+ **Note**: RENEW (acquisition-lock renewal) is not yet available; see
2041
+ [Current limitations](#share-consumer-current-limitations).
2042
+
2043
+ The number of times a record has already been delivered is available via
2044
+ `rd_kafka_message_delivery_count()`, which is useful to detect and reject a
2045
+ "poison" record after a threshold. The broker also enforces its own maximum
2046
+ delivery count (`group.share.delivery.count.limit`, default 5); once a record
2047
+ exceeds it the broker archives the record and stops redelivering it.
2048
+
2049
+ There are two acknowledgement modes, selected by `share.acknowledgement.mode`:
2050
+
2051
+ * **implicit** (default) — the application does not call the acknowledge APIs.
2052
+ All records returned by a poll are automatically accepted (ACCEPT) on the
2053
+ next `rd_kafka_share_poll()` / `rd_kafka_share_commit_sync()` /
2054
+ `rd_kafka_share_commit_async()`.
2055
+ * **explicit** — the application must acknowledge every record returned by a
2056
+ poll (with `rd_kafka_share_acknowledge()`,
2057
+ `rd_kafka_share_acknowledge_type()` or `rd_kafka_share_acknowledge_offset()`)
2058
+ before the next poll. If any record from the previous batch is still
2059
+ unacknowledged, `rd_kafka_share_poll()` returns
2060
+ `RD_KAFKA_RESP_ERR__STATE`. Records you have acknowledged but not yet
2061
+ committed are also committed when the consumer is closed (unless it is
2062
+ destroyed with `RD_KAFKA_DESTROY_F_NO_CONSUMER_CLOSE`).
2063
+
2064
+ Acknowledgements are sent to the broker as part of the next poll, or flushed
2065
+ explicitly with `rd_kafka_share_commit_async()` (fire-and-forget) or
2066
+ `rd_kafka_share_commit_sync()` (blocks for broker replies, reporting
2067
+ per-partition results). The acknowledgement-commit callback registered with
2068
+ `rd_kafka_share_set_acknowledgement_commit_cb()` is invoked with the outcome
2069
+ for each partition.
2070
+
2071
+ #### Example: explicit acknowledgement
2072
+
2073
+ The example below shows the full share-consumer lifecycle in explicit mode
2074
+ (configure, create, subscribe, poll, acknowledge, commit, close, destroy) and
2075
+ focuses on the per-record acknowledgement logic. It uses the real librdkafka
2076
+ APIs but is not a complete program: call-level error handling (the
2077
+ `rd_kafka_error_t` returned by `rd_kafka_share_poll()`, the acknowledge calls
2078
+ and the commit calls, and the return value of `rd_kafka_conf_set()`) is omitted
2079
+ for brevity.
2080
+
2081
+ ```c
2082
+ char errstr[512];
2083
+
2084
+ rd_kafka_conf_t *conf = rd_kafka_conf_new();
2085
+ rd_kafka_conf_set(conf, "bootstrap.servers", "localhost:9092",
2086
+ errstr, sizeof(errstr));
2087
+ rd_kafka_conf_set(conf, "group.id", "my-share-group", errstr, sizeof(errstr));
2088
+ rd_kafka_conf_set(conf, "share.acknowledgement.mode", "explicit",
2089
+ errstr, sizeof(errstr));
2090
+
2091
+ rd_kafka_share_t *rkshare =
2092
+ rd_kafka_share_consumer_new(conf, errstr, sizeof(errstr));
2093
+
2094
+ rd_kafka_share_subscribe(rkshare, topics);
2095
+
2096
+ while (run) {
2097
+ rd_kafka_messages_t *batch = NULL;
2098
+
2099
+ rd_kafka_share_poll(rkshare, timeout_ms, &batch);
2100
+
2101
+ size_t cnt = rd_kafka_messages_count(batch);
2102
+ for (size_t i = 0; i < cnt; i++) {
2103
+ rd_kafka_message_t *rkm = rd_kafka_messages_get(batch, i);
2104
+
2105
+ if (rkm->err) {
2106
+ /* Records carrying a record-level error (rkm->err set)
2107
+ * have already been acknowledged internally by
2108
+ * librdkafka: RELEASEd for decompression failures,
2109
+ * REJECTed for corrupt/unsupported batches. The
2110
+ * application can re-acknowledge them here if required
2111
+ * (e.g. to override the internal decision); otherwise
2112
+ * it only acknowledges the records it received. */
2113
+ continue;
2114
+ }
2115
+
2116
+ switch (process(rkm)) {
2117
+ case PROCESS_OK:
2118
+ /* Processed successfully. */
2119
+ rd_kafka_share_acknowledge_type(
2120
+ rkshare, rkm, RD_KAFKA_SHARE_ACKNOWLEDGE_TYPE_ACCEPT);
2121
+ break;
2122
+ case PROCESS_TEMPORARY_FAILURE:
2123
+ /* Release for redelivery (possibly to another member). */
2124
+ rd_kafka_share_acknowledge_type(
2125
+ rkshare, rkm,
2126
+ RD_KAFKA_SHARE_ACKNOWLEDGE_TYPE_RELEASE);
2127
+ break;
2128
+ case PROCESS_PERMANENT_FAILURE:
2129
+ /* Reject a "poison" record so it is not redelivered. */
2130
+ rd_kafka_share_acknowledge_type(
2131
+ rkshare, rkm, RD_KAFKA_SHARE_ACKNOWLEDGE_TYPE_REJECT);
2132
+ break;
2133
+ }
2134
+ }
2135
+ rd_kafka_messages_destroy(batch);
2136
+
2137
+ /* Flush the acknowledgements; the next poll would also send them.
2138
+ * Use rd_kafka_share_commit_sync(rkshare, timeout_ms, &partitions)
2139
+ * to block and inspect the per-partition result. */
2140
+ rd_kafka_share_commit_async(rkshare);
2141
+ }
2142
+
2143
+ rd_kafka_share_consumer_close(rkshare);
2144
+ rd_kafka_share_destroy(rkshare);
2145
+ ```
2146
+
2147
+ Complete runnable programs are in the examples directory:
2148
+ [share_consumer.c](examples/share_consumer.c),
2149
+ [share_consumer_commit_sync.c](examples/share_consumer_commit_sync.c) and
2150
+ [share_consumer_commit_async.c](examples/share_consumer_commit_async.c).
2151
+
2152
+ #### Thread safety
2153
+
2154
+ The share consumer handle is **not thread-safe by design**: a single
2155
+ `rd_kafka_share_t` handle must not be used concurrently from multiple threads.
2156
+ This follows the share consumer design in
2157
+ [KIP-932](https://cwiki.apache.org/confluence/display/KAFKA/KIP-932%3A+Queues+for+Kafka),
2158
+ where the share consumer — like the regular consumer — is single-threaded and
2159
+ the application owns the threading model (typically one handle per thread, or
2160
+ serialised access to a handle). Concurrent use is detected on a best-effort
2161
+ basis and rejected with `RD_KAFKA_RESP_ERR__CONFLICT`. There is no wakeup
2162
+ mechanism in this preview, so a blocking poll/commit ends only when its timeout
2163
+ expires.
2164
+
2165
+ <a name="share-consumer-current-limitations"></a>
2166
+ #### Current limitations (preview)
2167
+
2168
+ The preview differs from the Apache Kafka Java share consumer in a number of
2169
+ ways. The most important for application authors:
2170
+
2171
+ * **Record limit is a soft bound.** `max.poll.records` (default 500) does not
2172
+ strictly bound the number of records returned per poll (the strict-limit and
2173
+ acquire-mode work of KIP-1206 is not implemented).
2174
+ * **Acknowledgement types are limited to ACCEPT / RELEASE / REJECT.** There is
2175
+ no acquisition-lock renewal (KIP-1222), so a long-running handler cannot
2176
+ extend a record's lock and the record may be redelivered.
2177
+ * **No wakeup API.** A blocking poll/commit can only be ended by its timeout.
2178
+ * **`close()` has no timeout argument.** `rd_kafka_share_consumer_close()`
2179
+ takes no timeout argument; close is bounded internally to roughly
2180
+ `socket.timeout.ms`.
2181
+ * **No deserialization in the C core**, hence no automatic RELEASE on a
2182
+ deserialization failure.
2183
+ * **No share-group admin operations** (describe/list/alter/delete share
2184
+ groups and offsets) and **no share-consumer client-metrics APIs**.
2185
+ * **No auto topic creation.** Share topics are resolved by topic id;
2186
+ `allow.auto.create.topics` has no effect.
2187
+ * **Failed acknowledgements are not retried** automatically; the error is
2188
+ reported through the acknowledgement-commit callback or the
2189
+ `rd_kafka_share_commit_sync()` per-partition results.
2190
+ * **Some error codes differ** because librdkafka generates certain failures
2191
+ locally without a broker round-trip (for example
2192
+ `RD_KAFKA_RESP_ERR_NOT_LEADER_OR_FOLLOWER`, `RD_KAFKA_RESP_ERR__TRANSPORT`,
2193
+ `RD_KAFKA_RESP_ERR_INVALID_SHARE_SESSION_EPOCH`). Applications that branch on
2194
+ error codes should account for this.
2195
+ * **Single-broker fetch per poll.** Each poll fetches from one broker
2196
+ (round-robin over the assigned partitions); other brokers' partitions are
2197
+ served on subsequent polls. This is a throughput/latency detail, not a
2198
+ correctness one — all brokers are served across successive polls.
2199
+
2200
+
2201
+ <a name="topics"></a>
2202
+ ### Topics
2203
+
2204
+ <a name="unknown-or-unauthorized-topics"></a>
2205
+ #### Unknown or unauthorized topics
2206
+
2207
+ If a consumer application subscribes to non-existent or unauthorized topics
2208
+ a consumer error will be propagated for each unavailable topic with the
2209
+ error code set to either `RD_KAFKA_RESP_ERR_UNKNOWN_TOPIC_OR_PART` or a
2210
+ broker-specific error code, such as
2211
+ `RD_KAFKA_RESP_ERR_TOPIC_AUTHORIZATION_FAILED`.
2212
+
2213
+ As the topic metadata is refreshed every `topic.metadata.refresh.interval.ms`
2214
+ the unavailable topics are re-checked for availability, but the same error
2215
+ will not be raised again for the same topic.
2216
+
2217
+ If a consumer has Describe (ACL) permissions for a topic but not Read it will
2218
+ be able to join a consumer group and start consuming the topic, but the Fetch
2219
+ requests to retrieve messages from the broker will fail with
2220
+ `RD_KAFKA_RESP_ERR_TOPIC_AUTHORIZATION_FAILED`.
2221
+ This error will be raised to the application once per partition and
2222
+ assign()/seek() and the fetcher will back off the next fetch 10 times longer than
2223
+ the `fetch.error.backoff.ms` (but at least 1 second).
2224
+ It is recommended that the application takes appropriate action when this
2225
+ occurs, for instance adjusting its subscription or assignment to exclude the
2226
+ unauthorized topic.
2227
+
2228
+
2229
+ <a name="topic-metadata-propagation-for-newly-created-topics"></a>
2230
+ #### Topic metadata propagation for newly created topics
2231
+
2232
+ Due to the asynchronous nature of topic creation in Apache Kafka it may
2233
+ take some time for a newly created topic to be known by all brokers in the
2234
+ cluster.
2235
+ If a client tries to use a topic after topic creation but before the topic
2236
+ has been fully propagated in the cluster it will seem as if the topic does not
2237
+ exist which would raise `RD_KAFKA_RESP_ERR__UNKNOWN_TOPIC` (et.al)
2238
+ errors to the application.
2239
+ To avoid these temporary errors being raised, the client will not flag
2240
+ a topic as non-existent until a propagation time has elapsed, this propagation
2241
+ defaults to 30 seconds and can be configured with
2242
+ `topic.metadata.propagation.max.ms`.
2243
+ The per-topic max propagation time starts ticking as soon as the topic is
2244
+ referenced (e.g., by produce()).
2245
+
2246
+ If messages are produced to unknown topics during the propagation time, the
2247
+ messages will be queued for later delivery to the broker when the topic
2248
+ metadata has propagated.
2249
+ Should the topic propagation time expire without the topic being seen the
2250
+ produced messages will fail with `RD_KAFKA_RESP_ERR__UNKNOWN_TOPIC`.
2251
+
2252
+ **Note**: The propagation time will not take affect if a topic is known to
2253
+ the client and then deleted, in this case the topic will immediately
2254
+ be marked as non-existent and remain non-existent until a topic
2255
+ metadata refresh sees the topic again (after the topic has been
2256
+ re-created).
2257
+
2258
+ **Note**: `RD_KAFKA_RESP_ERR__UNKNOWN_TOPIC*` during a `subscribe()` call occurs **only with the classic protocol**. With the next-gen `consumer` protocol (KIP-848), subscription proceeds even if the topic is not yet in the local cache (e.g., it may be created later).
2259
+
2260
+
2261
+ <a name="topic-auto-creation"></a>
2262
+ #### Topic auto creation
2263
+
2264
+ Topic auto creation is supported by librdkafka, if a non-existent topic is
2265
+ referenced by the client (by produce to, or consuming from, the topic, etc)
2266
+ the broker will automatically create the topic (with default partition counts
2267
+ and replication factor) if the broker configuration property
2268
+ `auto.create.topics.enable=true` is set.
2269
+
2270
+ *Note*: A topic that is undergoing automatic creation may be reported as
2271
+ unavailable, with e.g., `RD_KAFKA_RESP_ERR_UNKNOWN_TOPIC_OR_PART`, during the
2272
+ time the topic is being created and partition leaders are elected.
2273
+
2274
+ While topic auto creation may be useful for producer applications, it is not
2275
+ particularily valuable for consumer applications since even if the topic
2276
+ to consume is auto created there is nothing writing messages to the topic.
2277
+ To avoid consumers automatically creating topics the
2278
+ `allow.auto.create.topics` consumer configuration property is set to
2279
+ `false` by default, preventing the consumer to trigger automatic topic
2280
+ creation on the broker. This requires broker version v0.11.0.0 or later.
2281
+ The `allow.auto.create.topics` property may be set to `true` to allow
2282
+ auto topic creation, which also requires `auto.create.topics.enable=true` to
2283
+ be configured on the broker.
2284
+
2285
+
2286
+
2287
+ <a name="metadata"></a>
2288
+ ### Metadata
2289
+
2290
+ <a name="lt093"></a>
2291
+ #### < 0.9.3
2292
+ Previous to the 0.9.3 release librdkafka's metadata handling
2293
+ was chatty and excessive, which usually isn't a problem in small
2294
+ to medium-sized clusters, but in large clusters with a large amount
2295
+ of librdkafka clients the metadata requests could hog broker CPU and bandwidth.
2296
+
2297
+ <a name="gt093-1"></a>
2298
+ #### > 0.9.3
2299
+
2300
+ The remaining Metadata sections describe the current behaviour.
2301
+
2302
+ **Note:** "Known topics" in the following section means topics for
2303
+ locally created `rd_kafka_topic_t` objects.
2304
+
2305
+
2306
+ <a name="query-reasons"></a>
2307
+ #### Query reasons
2308
+
2309
+ There are four reasons to query metadata:
2310
+
2311
+ * brokers - update/populate cluster broker list, so the client can
2312
+ find and connect to any new brokers added.
2313
+
2314
+ * specific topic - find leader or partition count for specific topic
2315
+
2316
+ * known topics - same, but for all locally known topics.
2317
+
2318
+ * all topics - get topic names for consumer group wildcard subscription
2319
+ matching
2320
+
2321
+ The above list is sorted so that the sub-sequent entries contain the
2322
+ information above, e.g., 'known topics' contains enough information to
2323
+ also satisfy 'specific topic' and 'brokers'.
2324
+
2325
+
2326
+ <a name="caching-strategy"></a>
2327
+ #### Caching strategy
2328
+
2329
+ The prevalent cache timeout is `metadata.max.age.ms`, any cached entry
2330
+ will remain authoritative for this long or until a relevant broker error
2331
+ is returned.
2332
+
2333
+
2334
+ * brokers - eternally cached, the broker list is additative.
2335
+
2336
+ * topics - cached for `metadata.max.age.ms`
2337
+
2338
+
2339
+
2340
+ <a name="fatal-errors"></a>
2341
+ ### Fatal errors
2342
+
2343
+ If an unrecoverable error occurs, a fatal error is triggered in one
2344
+ or more of the follow ways depending on what APIs the application is utilizing:
2345
+
2346
+ * C: the `error_cb` is triggered with error code `RD_KAFKA_RESP_ERR__FATAL`,
2347
+ the application should call `rd_kafka_fatal_error()` to retrieve the
2348
+ underlying fatal error code and error string.
2349
+ * C: an `RD_KAFKA_EVENT_ERROR` event is triggered and
2350
+ `rd_kafka_event_error_is_fatal()` returns true: the fatal error code
2351
+ and string are available through `rd_kafka_event_error()`, and `.._string()`.
2352
+ * C and C++: any API call may return `RD_KAFKA_RESP_ERR__FATAL`, use
2353
+ `rd_kafka_fatal_error()` to retrieve the underlying fatal error code
2354
+ and error string.
2355
+ * C++: an `EVENT_ERROR` event is triggered and `event.fatal()` returns true:
2356
+ the fatal error code and string are available through `event.err()` and
2357
+ `event.str()`.
2358
+
2359
+
2360
+ An application may call `rd_kafka_fatal_error()` at any time to check if
2361
+ a fatal error has been raised.
2362
+
2363
+
2364
+ <a name="fatal-producer-errors"></a>
2365
+ #### Fatal producer errors
2366
+
2367
+ The idempotent producer guarantees of ordering and no duplicates also
2368
+ requires a way for the client to fail gracefully when these guarantees
2369
+ can't be satisfied.
2370
+
2371
+ If a fatal error has been raised, sub-sequent use of the following API calls
2372
+ will fail:
2373
+
2374
+ * `rd_kafka_produce()`
2375
+ * `rd_kafka_producev()`
2376
+ * `rd_kafka_produce_batch()`
2377
+
2378
+ The underlying fatal error code will be returned, depending on the error
2379
+ reporting scheme for each of those APIs.
2380
+
2381
+
2382
+ When a fatal error has occurred the application should call `rd_kafka_flush()`
2383
+ to wait for all outstanding and queued messages to drain before terminating
2384
+ the application.
2385
+ `rd_kafka_purge(RD_KAFKA_PURGE_F_QUEUE)` is automatically called by the client
2386
+ when a producer fatal error has occurred, messages in-flight are not purged
2387
+ automatically to allow waiting for the proper acknowledgement from the broker.
2388
+ The purged messages in queue will fail with error code set to
2389
+ `RD_KAFKA_RESP_ERR__PURGE_QUEUE`.
2390
+
2391
+
2392
+ <a name="fatal-consumer-errors"></a>
2393
+ #### Fatal consumer errors
2394
+
2395
+ A consumer configured for static group membership (`group.instance.id`) may
2396
+ raise a fatal error if a new consumer instance is started with the same
2397
+ instance id, causing the existing consumer to be fenced by the new consumer.
2398
+
2399
+ This fatal error is propagated on the fenced existing consumer in multiple ways:
2400
+ * `error_cb` (if configured) is triggered.
2401
+ * `rd_kafka_consumer_poll()` (et.al) will return a message object
2402
+ with the `err` field set to `RD_KAFKA_ERR__FATAL`.
2403
+ * any sub-sequent calls to state-changing consumer calls will
2404
+ return `RD_KAFKA_ERR___FATAL`.
2405
+ This includes `rd_kafka_subscribe()`, `rd_kafka_assign()`,
2406
+ `rd_kafka_consumer_close()`, `rd_kafka_commit*()`, etc.
2407
+
2408
+ The consumer will automatically stop consuming when a fatal error has occurred
2409
+ and no further subscription, assignment, consumption or offset committing
2410
+ will be possible. At this point the application should simply destroy the
2411
+ consumer instance and terminate the application since it has been replaced
2412
+ by a newer instance.
2413
+
2414
+
2415
+ <a name="compatibility"></a>
2416
+ ## Compatibility
2417
+
2418
+ <a name="broker-version-compatibility"></a>
2419
+ ### Broker version compatibility
2420
+
2421
+ librdkafka supports all released Apache Kafka broker versions since 0.8.0.0.0,
2422
+ but not all features may be available on all broker versions since some
2423
+ features rely on newer broker functionality.
2424
+
2425
+ **Current defaults:**
2426
+ * `api.version.request=true`
2427
+ * `broker.version.fallback=0.10.0`
2428
+ * `api.version.fallback.ms=0` (never revert to `broker.version.fallback`)
2429
+
2430
+ Depending on what broker version you are using, please configure your
2431
+ librdkafka based client as follows:
2432
+
2433
+ <a name="broker-version--01000-or-trunk"></a>
2434
+ #### Broker version >= 0.10.0.0 (or trunk)
2435
+
2436
+ For librdkafka >= v1.0.0 there is no need to set any api.version-related
2437
+ configuration parameters, the defaults are tailored for broker version 0.10.0.0
2438
+ or later.
2439
+
2440
+ For librdkafka < v1.0.0, please specify:
2441
+ ```
2442
+ api.version.request=true
2443
+ api.version.fallback.ms=0
2444
+ ```
2445
+
2446
+
2447
+ <a name="broker-versions-090x"></a>
2448
+ #### Broker versions 0.9.0.x
2449
+
2450
+ ```
2451
+ api.version.request=false
2452
+ broker.version.fallback=0.9.0.x (the exact 0.9.0.. version you are using)
2453
+ ```
2454
+
2455
+ <a name="broker-versions-08xy"></a>
2456
+ #### Broker versions 0.8.x.y
2457
+
2458
+ ```
2459
+ api.version.request=false
2460
+ broker.version.fallback=0.8.x.y (your exact 0.8... broker version)
2461
+ ```
2462
+
2463
+ <a name="detailed-description"></a>
2464
+ #### Detailed description
2465
+
2466
+ Apache Kafka version 0.10.0.0 added support for
2467
+ [KIP-35](https://cwiki.apache.org/confluence/display/KAFKA/KIP-35+-+Retrieving+protocol+version) -
2468
+ querying the broker for supported API request types and versions -
2469
+ allowing the client to figure out what features it can use.
2470
+ But for older broker versions there is no way for the client to reliably know
2471
+ what protocol features the broker supports.
2472
+
2473
+ To alleviate this situation librdkafka has three configuration properties:
2474
+ * `api.version.request=true|false` - enables the API version request,
2475
+ this requires a >= 0.10.0.0 broker and will cause a disconnect on
2476
+ brokers 0.8.x - this disconnect is recognized by librdkafka and on the next
2477
+ connection attempt (which is immediate) it will disable the API version
2478
+ request and use `broker.version.fallback` as a basis of available features.
2479
+ **NOTE**: Due to a bug in broker version 0.9.0.0 & 0.9.0.1 the broker will
2480
+ not close the connection when receiving the API version request, instead
2481
+ the request will time out in librdkafka after 10 seconds and it will fall
2482
+ back to `broker.version.fallback` on the next immediate connection attempt.
2483
+ * `broker.version.fallback=X.Y.Z.N` - if the API version request fails
2484
+ (if `api.version.request=true`) or API version requests are disabled
2485
+ (`api.version.request=false`) then this tells librdkafka what version the
2486
+ broker is running and adapts its feature set accordingly.
2487
+ * `api.version.fallback.ms=MS` - In the case where `api.version.request=true`
2488
+ and the API version request fails, this property dictates for how long
2489
+ librdkafka will use `broker.version.fallback` instead of
2490
+ `api.version.request=true`. After `MS` has passed the API version request
2491
+ will be sent on any new connections made for the broker in question.
2492
+ This allows upgrading the Kafka broker to a new version with extended
2493
+ feature set without needing to restart or reconfigure the client
2494
+ (given that `api.version.request=true`).
2495
+
2496
+ *Note: These properties applies per broker.*
2497
+
2498
+ The API version query was disabled by default (`api.version.request=false`) in
2499
+ librdkafka up to and including v0.9.5 due to the afforementioned bug in
2500
+ broker version 0.9.0.0 & 0.9.0.1, but was changed to `true` in
2501
+ librdkafka v0.11.0.
2502
+
2503
+
2504
+ <a name="supported-kips"></a>
2505
+ ### Supported KIPs
2506
+
2507
+ The [Apache Kafka Implementation Proposals (KIPs)](https://cwiki.apache.org/confluence/display/KAFKA/Kafka+Improvement+Proposals) supported by librdkafka.
2508
+
2509
+
2510
+ | KIP | Kafka release | Status |
2511
+ | ------------------------------------------------------------------------ | --------------------------- | --------------------------------------------------------------------------------------------- |
2512
+ | KIP-1 - Stop accepting request.required.acks > 1 | 0.9.0.0 | Not enforced on client (due to backwards compat with brokers <0.8.3) |
2513
+ | KIP-4 - Metadata protocol changes | 0.9.0.0, 0.10.0.0, 0.10.1.0 | Supported |
2514
+ | KIP-8 - Producer flush() | 0.9.0.0 | Supported |
2515
+ | KIP-12 - SASL Kerberos | 0.9.0.0 | Supported (uses SSPI/logged-on-user on Windows, full KRB5 keytabs on Unix) |
2516
+ | KIP-13 - Protocol request throttling (enforced on broker) | 0.9.0.0 | Supported |
2517
+ | KIP-15 - Producer close with timeout | 0.9.0.0 | Supported (through flush() + destroy()) |
2518
+ | KIP-19 - Request timeouts | 0.9.0.0 | Supported |
2519
+ | KIP-22 - Producer pluggable partitioner | 0.9.0.0 | Supported (not supported by Go, .NET and Python) |
2520
+ | KIP-31 - Relative offsets in messagesets | 0.10.0.0 | Supported |
2521
+ | KIP-35 - ApiVersionRequest | 0.10.0.0 | Supported |
2522
+ | KIP-40 - ListGroups and DescribeGroups | 0.9.0.0 | Supported |
2523
+ | KIP-41 - max.poll.records | 0.10.0.0 | Supported through batch consumption interface (not supported by .NET and Go) |
2524
+ | KIP-42 - Producer and Consumer interceptors | 0.10.0.0 | Supported (not supported by Go, .NET and Python) |
2525
+ | KIP-43 - SASL PLAIN and handshake | 0.10.0.0 | Supported |
2526
+ | KIP-48 - Delegation tokens | 1.1.0 | Not supported |
2527
+ | KIP-54 - Sticky partition assignment strategy | 0.11.0.0 | Supported but not available, use KIP-429 instead. |
2528
+ | KIP-57 - Interoperable LZ4 framing | 0.10.0.0 | Supported |
2529
+ | KIP-62 - max.poll.interval and background heartbeats | 0.10.1.0 | Supported |
2530
+ | KIP-70 - Proper client rebalance event on unsubscribe/subscribe | 0.10.1.0 | Supported |
2531
+ | KIP-74 - max.partition.fetch.bytes | 0.10.1.0 | Supported |
2532
+ | KIP-78 - Retrieve Cluster Id | 0.10.1.0 | Supported (not supported by .NET) |
2533
+ | KIP-79 - OffsetsForTimes | 0.10.1.0 | Supported |
2534
+ | KIP-81 - Consumer pre-fetch buffer size | 2.4.0 (WIP) | Supported |
2535
+ | KIP-82 - Record Headers | 0.11.0.0 | Supported |
2536
+ | KIP-84 - SASL SCRAM | 0.10.2.0 | Supported |
2537
+ | KIP-85 - SASL config properties | 0.10.2.0 | Supported |
2538
+ | KIP-86 - Configurable SASL callbacks | 2.0.0 | Not supported |
2539
+ | KIP-88 - AdminAPI: ListGroupOffsets | 0.10.2.0 | Supported |
2540
+ | KIP-91 - Intuitive timeouts in Producer | 2.1.0 | Supported |
2541
+ | KIP-92 - Per-partition lag metrics in Consumer | 0.10.2.0 | Supported |
2542
+ | KIP-97 - Backwards compatibility with older brokers | 0.10.2.0 | Supported |
2543
+ | KIP-98 - EOS | 0.11.0.0 | Supported |
2544
+ | KIP-102 - Close with timeout in consumer | 0.10.2.0 | Not supported |
2545
+ | KIP-107 - AdminAPI: DeleteRecordsBefore | 0.11.0.0 | Supported |
2546
+ | KIP-110 - ZStd compression | 2.1.0 | Supported |
2547
+ | KIP-117 - AdminClient | 0.11.0.0 | Supported |
2548
+ | KIP-124 - Request rate quotas | 0.11.0.0 | Partially supported (depending on protocol request) |
2549
+ | KIP-126 - Producer ensure proper batch size after compression | 0.11.0.0 | Supported |
2550
+ | KIP-133 - AdminAPI: DescribeConfigs and AlterConfigs | 0.11.0.0 | Supported |
2551
+ | KIP-140 - AdminAPI: ACLs | 0.11.0.0 | Supported |
2552
+ | KIP-144 - Broker reconnect backoff | 0.11.0.0 | Supported |
2553
+ | KIP-152 - Improved SASL auth error messages | 1.0.0 | Supported |
2554
+ | KIP-192 - Cleaner idempotence semantics | 1.0.0 | Not supported (superceeded by KIP-360) |
2555
+ | KIP-195 - AdminAPI: CreatePartitions | 1.0.0 | Supported |
2556
+ | KIP-204 - AdminAPI: DeleteRecords | 1.1.0 | Supported |
2557
+ | KIP-219 - Client-side throttling | 2.0.0 | Not supported |
2558
+ | KIP-222 - AdminAPI: Consumer group operations | 2.0.0 | Supported |
2559
+ | KIP-223 - Consumer partition lead metric | 2.0.0 | Not supported |
2560
+ | KIP-226 - AdminAPI: Dynamic broker config | 1.1.0 | Supported |
2561
+ | KIP-227 - Consumer Incremental Fetch | 1.1.0 | Not supported |
2562
+ | KIP-229 - AdminAPI: DeleteGroups | 1.1.0 | Supported |
2563
+ | KIP-235 - DNS alias for secure connections | 2.1.0 | Supported |
2564
+ | KIP-249 - AdminAPI: Deletegation Tokens | 2.0.0 | Not supported |
2565
+ | KIP-255 - SASL OAUTHBEARER | 2.0.0 | Supported |
2566
+ | KIP-266 - Fix indefinite consumer timeouts | 2.0.0 | Supported (bound by session.timeout.ms and max.poll.interval.ms) |
2567
+ | KIP-289 - Consumer group.id default to NULL | 2.2.0 | Supported |
2568
+ | KIP-294 - SSL endpoint verification | 2.0.0 | Supported |
2569
+ | KIP-302 - Use all addresses for resolved broker hostname | 2.1.0 | Supported |
2570
+ | KIP-320 - Consumer: handle log truncation | 2.1.0, 2.2.0 | Supported |
2571
+ | KIP-322 - DeleteTopics disabled error code | 2.1.0 | Supported |
2572
+ | KIP-339 - AdminAPI: incrementalAlterConfigs | 2.3.0 | Supported |
2573
+ | KIP-341 - Update Sticky partition assignment data | 2.3.0 | Not supported (superceeded by KIP-429) |
2574
+ | KIP-342 - Custom SASL OAUTHBEARER extensions | 2.1.0 | Supported |
2575
+ | KIP-345 - Consumer: Static membership | 2.4.0 | Supported |
2576
+ | KIP-357 - AdminAPI: list ACLs per principal | 2.1.0 | Not supported |
2577
+ | KIP-359 - Producer: use EpochLeaderId | 2.4.0 | Not supported |
2578
+ | KIP-360 - Improve handling of unknown Idempotent Producer | 2.5.0 | Supported |
2579
+ | KIP-361 - Consumer: add config to disable auto topic creation | 2.3.0 | Supported |
2580
+ | KIP-368 - SASL periodic reauth | 2.2.0 | Supported |
2581
+ | KIP-369 - Always roundRobin partitioner | 2.4.0 | Not supported |
2582
+ | KIP-389 - Consumer group max size | 2.2.0 | Supported (error is propagated to application, but the consumer does not raise a fatal error) |
2583
+ | KIP-392 - Allow consumers to fetch from closest replica | 2.4.0 | Supported |
2584
+ | KIP-394 - Consumer: require member.id in JoinGroupRequest | 2.2.0 | Supported |
2585
+ | KIP-396 - AdminAPI: commit/list offsets | 2.4.0 | Supported |
2586
+ | KIP-412 - AdminAPI: adjust log levels | 2.4.0 | Not supported |
2587
+ | KIP-421 - Variables in client config files | 2.3.0 | Not applicable (librdkafka, et.al, does not provide a config file interface, and shouldn't) |
2588
+ | KIP-429 - Consumer: incremental rebalance protocol | 2.4.0 | Supported |
2589
+ | KIP-430 - AdminAPI: return authorized operations in Describe.. responses | 2.3.0 | Supported |
2590
+ | KIP-436 - Start time in stats | 2.3.0 | Supported |
2591
+ | KIP-447 - Producer scalability for EOS | 2.5.0 | Supported |
2592
+ | KIP-455 - AdminAPI: Replica assignment | 2.4.0 (WIP) | Not supported |
2593
+ | KIP-460 - AdminAPI: electLeaders | 2.6.0 | Supported |
2594
+ | KIP-464 - AdminAPI: defaults for createTopics | 2.4.0 | Supported |
2595
+ | KIP-467 - Per-message (sort of) error codes in ProduceResponse | 2.4.0 | Supported |
2596
+ | KIP-480 - Sticky partitioner | 2.4.0 | Supported |
2597
+ | KIP-482 - Optional fields in Kafka protocol | 2.4.0 | Partially supported (ApiVersionRequest) |
2598
+ | KIP-496 - AdminAPI: delete offsets | 2.4.0 | Supported |
2599
+ | KIP-511 - Collect Client's Name and Version | 2.4.0 | Supported |
2600
+ | KIP-514 - Bounded flush() | 2.4.0 | Supported |
2601
+ | KIP-516 - Topic Identifiers | 2.8.0 (WIP) | Partially Supported |
2602
+ | KIP-517 - Consumer poll() metrics | 2.4.0 | Not supported |
2603
+ | KIP-518 - Allow listing consumer groups per state | 2.6.0 | Supported |
2604
+ | KIP-519 - Make SSL engine configurable | 2.6.0 | Supported |
2605
+ | KIP-525 - Return topic metadata and configs in CreateTopics response | 2.4.0 | Not supported |
2606
+ | KIP-526 - Reduce Producer Metadata Lookups for Large Number of Topics | 2.5.0 | Not supported |
2607
+ | KIP-533 - Add default API timeout to AdminClient | 2.5.0 | Not supported |
2608
+ | KIP-546 - Add Client Quota APIs to AdminClient | 2.6.0 | Not supported |
2609
+ | KIP-554 - Add Broker-side SCRAM Config API | 2.7.0 | Supported |
2610
+ | KIP-559 - Make the Kafka Protocol Friendlier with L7 Proxies | 2.5.0 | Not supported |
2611
+ | KIP-568 - Explicit rebalance triggering on the Consumer | 2.6.0 | Not supported |
2612
+ | KIP-659 - Add metadata to DescribeConfigsResponse | 2.6.0 | Not supported |
2613
+ | KIP-580 - Exponential backoff for Kafka clients | 3.7.0 | Supported |
2614
+ | KIP-584 - Versioning scheme for features | WIP | Not supported |
2615
+ | KIP-588 - Allow producers to recover gracefully from txn timeouts | 2.8.0 (WIP) | Not supported |
2616
+ | KIP-601 - Configurable socket connection timeout | 2.7.0 | Supported |
2617
+ | KIP-602 - Use all resolved addresses by default | 2.6.0 | Supported |
2618
+ | KIP-651 - Support PEM format for SSL certs and keys | 2.7.0 | Supported |
2619
+ | KIP-654 - Aborted txns with non-flushed msgs should not be fatal | 2.7.0 | Supported |
2620
+ | KIP-714 - Client metrics and observability | 3.7.0 | Supported |
2621
+ | KIP-735 - Increase default consumer session timeout | 3.0.0 | Supported |
2622
+ | KIP-768 - SASL/OAUTHBEARER OIDC support | 3.0 | Supported |
2623
+ | KIP-881 - Rack-aware Partition Assignment for Kafka Consumers | 3.5.0 | Supported |
2624
+ | KIP-848 - The Next Generation of the Consumer Rebalance Protocol | 4.0.0 | Supported |
2625
+ | KIP-899 - Allow producer and consumer clients to rebootstrap | 3.8.0 | Supported |
2626
+ | KIP-951 - Leader discovery optimisations for the client | 3.7.0 | Supported |
2627
+ | KIP-1082 - Require Client-Generated IDs over the ConsumerGroupHeartbeat | 4.0.0 | Supported |
2628
+ | KIP-1102 - Enable clients to rebootstrap based on timeout or error code | 4.0.0 | Supported |
2629
+ | KIP-1139 - Add support for OAuth jwt-bearer grant type | 4.1.0 (WIP) | Supported |
2630
+ | KIP-932 - Queues for Kafka (share groups / share consumer) | 4.2.0 | Preview (C API; see the [Share consumers](#share-consumers-queues-for-kafka) usage section and the Share consumer (Queues for Kafka) section in [rdkafka.h](src/rdkafka.h)) |
2631
+
2632
+
2633
+
2634
+
2635
+ <a name="supported-protocol-versions"></a>
2636
+ ### Supported protocol versions
2637
+
2638
+ "Kafka max" is the maximum ApiVersion supported in Apache Kafka 4.0.0, while
2639
+ "librdkafka max" is the maximum ApiVersion supported in the latest
2640
+ release of librdkafka.
2641
+
2642
+
2643
+ | ApiKey | Request name | Kafka max | librdkafka max |
2644
+ | ------ | ---------------------------- | --------- | -------------- |
2645
+ | 0 | Produce | 12 | 10 |
2646
+ | 1 | Fetch | 17 | 16 |
2647
+ | 2 | ListOffsets | 10 | 7 |
2648
+ | 3 | Metadata | 13 | 13 |
2649
+ | 8 | OffsetCommit | 9 | 9 |
2650
+ | 9 | OffsetFetch | 9 | 9 |
2651
+ | 10 | FindCoordinator | 6 | 2 |
2652
+ | 11 | JoinGroup | 9 | 5 |
2653
+ | 12 | Heartbeat | 4 | 3 |
2654
+ | 13 | LeaveGroup | 5 | 1 |
2655
+ | 14 | SyncGroup | 5 | 3 |
2656
+ | 15 | DescribeGroups | 6 | 5 |
2657
+ | 16 | ListGroups | 5 | 4 |
2658
+ | 17 | SaslHandshake | 1 | 1 |
2659
+ | 18 | ApiVersions | 4 | 3 |
2660
+ | 19 | CreateTopics | 7 | 4 |
2661
+ | 20 | DeleteTopics | 6 | 4 |
2662
+ | 21 | DeleteRecords | 2 | 2 |
2663
+ | 22 | InitProducerId | 5 | 4 |
2664
+ | 23 | OffsetForLeaderEpoch | 4 | 2 |
2665
+ | 24 | AddPartitionsToTxn | 5 | 0 |
2666
+ | 25 | AddOffsetsToTxn | 4 | 0 |
2667
+ | 26 | EndTxn | 5 | 1 |
2668
+ | 28 | TxnOffsetCommit | 5 | 3 |
2669
+ | 29 | DescribeAcls | 3 | 2 |
2670
+ | 30 | CreateAcls | 3 | 2 |
2671
+ | 31 | DeleteAcls | 3 | 2 |
2672
+ | 32 | DescribeConfigs | 4 | 1 |
2673
+ | 33 | AlterConfigs | 2 | 2 |
2674
+ | 36 | SaslAuthenticate | 2 | 1 |
2675
+ | 37 | CreatePartitions | 3 | 2 |
2676
+ | 42 | DeleteGroups | 2 | 2 |
2677
+ | 43 | ElectLeaders | 2 | 2 |
2678
+ | 44 | IncrementalAlterConfigs | 1 | 1 |
2679
+ | 47 | OffsetDelete | 0 | 0 |
2680
+ | 50 | DescribeUserScramCredentials | 0 | 0 |
2681
+ | 51 | AlterUserScramCredentials | 0 | 0 |
2682
+ | 68 | ConsumerGroupHeartbeat | 1 | 1 |
2683
+ | 69 | ConsumerGroupDescribe | 1 | 0 |
2684
+ | 71 | GetTelemetrySubscriptions | 0 | 0 |
2685
+ | 72 | PushTelemetry | 0 | 0 |
2686
+
2687
+ <a name="recommendations-for-language-binding-developers"></a>
2688
+ # Recommendations for language binding developers
2689
+
2690
+ These recommendations are targeted for developers that wrap librdkafka
2691
+ with their high-level languages, such as confluent-kafka-go or node-rdkafka.
2692
+
2693
+ <a name="expose-the-configuration-interface-pass-thru"></a>
2694
+ ## Expose the configuration interface pass-thru
2695
+
2696
+ librdkafka's string-based key=value configuration property interface controls
2697
+ most runtime behaviour and evolves over time.
2698
+ Most features are also only configuration-based, meaning they do not require a
2699
+ new API (SSL and SASL are two good examples which are purely enabled through
2700
+ configuration properties) and thus no changes needed to the binding/application
2701
+ code.
2702
+
2703
+ If your language binding/applications allows configuration properties to be set
2704
+ in a pass-through fashion without any pre-checking done by your binding code it
2705
+ means that a simple upgrade of the underlying librdkafka library (but not your
2706
+ bindings) will provide new features to the user.
2707
+
2708
+ <a name="error-constants"></a>
2709
+ ## Error constants
2710
+
2711
+ The error constants, both the official (value >= 0) errors as well as the
2712
+ internal (value < 0) errors, evolve constantly.
2713
+ To avoid hard-coding them to expose to your users, librdkafka provides an API
2714
+ to extract the full list programmatically during runtime or for
2715
+ code generation, see `rd_kafka_get_err_descs()`.
2716
+
2717
+ <a name="reporting-client-software-name-and-version-to-broker"></a>
2718
+ ## Reporting client software name and version to broker
2719
+
2720
+ [KIP-511](https://cwiki.apache.org/confluence/display/KAFKA/KIP-511%3A+Collect+and+Expose+Client%27s+Name+and+Version+in+the+Brokers) introduces a means for a
2721
+ Kafka client to report its implementation name and version to the broker, the
2722
+ broker then exposes this as metrics (e.g., through JMX) to help Kafka operators
2723
+ troubleshoot problematic clients, understand the impact of broker and client
2724
+ upgrades, etc.
2725
+ This requires broker version 2.4.0 or later (metrics added in 2.5.0).
2726
+
2727
+ librdkafka will send its name (`librdkafka`) and version (e.g., `v1.3.0`)
2728
+ upon connect to a supporting broker.
2729
+ To help distinguish high-level client bindings on top of librdkafka, a client
2730
+ binding should configure the following two properties:
2731
+ * `client.software.name` - set to the binding name, e.g,
2732
+ `confluent-kafka-go` or `node-rdkafka`.
2733
+ * `client.software.version` - the version of the binding and the version
2734
+ of librdkafka, e.g., `v1.3.0-librdkafka-v1.3.0` or
2735
+ `1.2.0-librdkafka-v1.3.0`.
2736
+ It is **highly recommended** to include the librdkafka version in this
2737
+ version string.
2738
+
2739
+ These configuration properties are hidden (from CONFIGURATION.md et.al.) as
2740
+ they should typically not be modified by the user.
2741
+
2742
+ <a name="documentation-reuse"></a>
2743
+ ## Documentation reuse
2744
+
2745
+ You are free to reuse the librdkafka API and CONFIGURATION documentation in
2746
+ your project, but please do return any documentation improvements back to
2747
+ librdkafka (file a github pull request).
2748
+
2749
+ <a name="community-support"></a>
2750
+ ## Community support
2751
+
2752
+ Community support is offered through GitHub Issues and Discussions.