حالت تاریک
فصل ۱۲ — پردازش جریانی با Kafka Streams و ksqlDB
این فصل شامل
- شروع کار با Kafka Streams
- استفاده از APIهای پایه Kafka Streams
- استفاده از state store برای ذخیره پایدار
- غنیسازی جریان تراکنشها
تا اینجا در مسیر یادگیری Kafka روی اجزایی تمرکز کردیم که پلتفرم event-streaming کامل میسازند: brokerهای Kafka، producer و consumer. با این پایه، لایه بعدی اکوسystem Kafka — پردازش جریانی با Kafka Streams و ksqlDB — را میفهمیم. این فناوریها abstraction، API و DSL (زبانهای domain-specific) بر پایهای که در فصلهای قبل ساختیم ارائه میدهند.
این فصل اپلیکیشن بانکی سادهای معرفی میکند که وجوه ورودی و خروجی حسابها را پردازش میکند. topology Kafka Streams برای پردازش atomically درخواستهای تراکنش ارسالی به topic transaction-request پیاده میشود.
NOTE نیاز کسبوکار: قبل از بهروزرسانی balance حساب، برای هر درخواست کافی بودن وجوه بررسی شود. اپلیکیشن نمیتواند دو تراکنش همزمان برای یک حساب پردازش کند — race condition که تضمین بررسی balance قبل از برداشت را از بین میبرد.
با تضمین ordering بین partitionهای Kafka، پردازش serializable (ordered) تراکنشهای یک حساب پیاده میشود. برنامه data generator درخواستهای شبیهسازیشده را با key برابر شماره حساب به topic مینویsd؛ پس همه تراکنشها توسط یک instance سرویس تراکنش پردازش میشوند، هرچند چند اپلیکیشن همزمان اجرا شوند. Kafka Streams تا تکمیل منطق کسبوکار مدیریت درخواست تراکنش offset پیام را commit نمیکند.
Processor API با پیادهسازی transformer از Kafka Streams معرفی میشود — پردازش رویداد بهرویداد با state store برای persist کردن balance حساب در RocksDB embedded. پردازشگر جریان دوم statement تراکنش غنیشده با جزئیات حساب تولید میکند. بهجای اپلیکیشن Kafka Streams دیگر، ksqlDB stream processor اعلامی برای enrich real-time داده تراکنش با داده مرجع topic حساب استفاده میشود.
این بخش نشان میدهد چطور با زبان شبیه SQL stream processor (مشابه Kafka Streams) بدون compile و اجرای کد بسازیم. پس از مفاهیم اپلیکیشن stream-processing به جزئیات API Kafka Streams میرویم.
۱۲.۱ Kafka Streams
بهطور کلی stream processing (یا streaming) فرایند یا اپلیکیشنی است که جریان بیوقفه داده را handle و بهمحض رسیدن کار انجام میدهد (فصل ۲). روی schedule منظم اجرا نمیشود و لزوماً از DB query نمیگیرد. view از داده ساخته میشود، اما به snapshot لحظهای محدود نیستیم. Kafka Streams!
Kafka Streams کتابخانه است، نه کلاستر standalone [۱]. کلمه library یعنی پردازش جریانی در اپلیکیشنهای خودمان. زیرساخت اضافی جز کلاستر Kafka موجود لازم نیست [۲]. کتابخانه Kafka Streams بخشی از اپلیکیشن JVM است.
بدون component اضافی، API برای تست اپلیکیشن جدید آسان است. فریمورکهای دیگر ممکن است component مدیریت کلاستر بیشتری بخواهند؛ اپلیکیشن Kafka Streams با هر ابزار یا پلتفرمی که JVM اجرا کند deploy میشود.
NOTE اپلیکیشن روی brokerهای کلاستر اجرا نمیشود. بیرون کلاستر Kafka اجرا میکنیم تا separation of concerns منابع broker و stream processor حفظ شود.
Streams API پردازش per-record یا per-message [۳] انجام میدهد. اگر واکنش فوری به رویداد مهم است، منتظر batch یا تأخیر نمیمانید.
یکی از اولین سؤالات: producer/consumer برای کتابخانه Kafka Streams. Producer API برای کنترل دقیق ارسال و Consumer API برای consume عالیاند، اما شاید نخواهیم هر جنبه framework stream-processing را خودمان بسازیم. بهجای API سطح پایین، abstraction میخواهیم که با topic کارآمدتر باشد.
Kafka Streams اگر نیاز به transformation با منطق پیچیده و consume/produce برگشت به Kafka دارید گزینه مناسبی است. انتخاب بین DSL تابعی و Processor API imperative [۲]. نگاه اول به Kafka Streams DSL.
زبانهای domain-specific (DSL)
DSL زبان مخصوص موضوعی برای کار آسانتر است. SQL (DB) و HTML (صفحات وب) مثالهای DSL هستند (https://martinfowler.com/dsl.html). مستندات رسمی Kafka Streams API سطح بالا را DSL مینامد؛ ما fluent API یا fluent interface مارتین فاولر (https://martinfowler.com/bliki/FluentInterface.html) ترجیح میدهیم.
۱۲.۱.۱ KStreams API DSL
اولین API: KStreams. Kafka Streams سیستم پردازش داده حول گراف بدون cycle [۲] — node شروع و پایان؛ داده از شروع به پایان جریان مییابد و processorها در مسیر transform میکنند.
اپلیکیشنی تراکنش از سیستم پرداخت میگیرد. در ابتدای گراف منبع داده لازم است؛ topic Kafka نقطه شروع — source processor (source node). سرویس موجود تراکنش را از سیستم پرداخت خارجی capture و رویداد درخواست تراکنش در topic میگذارد.
NOTE این رفتار را با data generator ساده شبیهسازی میکنیم.
رویداد درخواست تراکنش balance حساب را بهروز میکند. نتیجه processor تراکنش در دو topic: موفق در transaction-success، ناموفق در transaction-failed. انتهای مسیر: جفت sink processor (sink node).
NOTE بعضی nodeها به sink وصل نیستند — side effect جای دیگر (console، state store) و ارسال برگشت به Kafka لازم نیست.
شکل ۱۲.۱ DAG (directed acyclic graph) جریان داده را نشان میدهد. شکل ۱۲.۲ نگاشت DAG به topology Kafka Streams.
Source
processor
Transform Print To table
processor processor processor
Filter Filter
processor processor
Transaction- Transaction-
success sink failed sink
processor processorشکل ۱۲.۱ DAG اپلیکیشن stream-processing
"transaction-request"
Kafka streams instance
TransactionProcessor
"latest- TransactionTransformer
transactions" funds store
change-log-2 change-log-1
"transaction-success" "transaction-failed"شکل ۱۲.۲ Topology اپلیکیشن پردازش تراکنش
با DSL کد اپلیکیشن را میبینیم. برخلاف مثالهای قبل، مستقیم consumer نمیخوانیم؛ با builder stream میسازیم. listing 12.1 ساخت source processor.
IMPORTANT topology را تعریف میکنیم، اما هنوز invoke نشده — پردازش شروع نشده.
StreamsBuilder stream از topic transaction-request میسازد — نقطه منطقی شروع.
Listing 12.1 تعریف source topic در DSL
java
StreamsBuilder builder = new StreamsBuilder()
KStream<String, Transaction> transactionStream =
builder.stream("transaction-request",
Consumed.with(stringSerde, transactionRequestAvroSerde));گام بعد افزودن به topology با KStream از source processor — listing 12.2.
Listing 12.2 تعریف processor و sink topic
java
final KStream<String, TransactionResult> resultStream =
transactionStream.transformValues(
() -> new TransactionTransformer()
);
resultStream
.filter(TransactionProcessor::success)
.to(this.transactionSuccessTopicName,
Produced.with(Serdes.String(), transactionResultAvroSerde));
resultStream
.filterNot(TransactionProcessor::success)
.to(this.transactionFailedTopicName,
Produced.with(Serdes.String(), transactionResultAvroSerde));
KafkaStreams kafkaStreams =
new KafkaStreams(builder.build(), kaProperties);
kafkaStreams.start();
...
kafkaStreams.close();یک processing node بدون read/write مستقیم؛ زنجیره node آسان است. در listing 12.2 مستقیم consumer (فصل ۵) و producer (فصل ۴) نمیبینید — abstraction روی منطق تمرکز میکند.
مثال عملی: log درخواست تراکنش در console بدون پردازش — listing 12.3.
Listing 12.3 Transaction tracker KStream
java
KStream<String, Transaction> transactionStream =
builder.stream("transaction-request",
Consumed.with(stringSerde, transactionRequestAvroSerde));
transactionStream.print(Printed.<String, Transaction>toSysOut()
.withLabel("transactions logger"));
KafkaStreams kafkaStreams = new KafkaStreams(builder.build(), kaProperties);
kafkaStreams.cleanUp();
kafkaStreams.start();
...جریان ساده — فقط console؛ میتوان SMS یا email API هم زد. cleanUp() قبل از start state store محلی را پاک میکند — فقط قبل از start یا بعد از close.
KStreams تنها راه نیست. KTable API جایگزینی برای همیشه append کردن رویداد — داده بهعنوان update.
۱۲.۱.۲ KTable API
KStream: رویداد همیشه به log append. KTable: topic log-compacted [۲] — موازی با جدول DB با update in-place. از فصل ۷، compacted topic به key نیاز دارد. listing 12.4 — همه order event دیده نمیشود، فقط orderهای متمایز.
Listing 12.4 Transaction KTable
java
StreamsBuilder builder = new StreamsBuilder();
KTable<String, Transaction> transactionStream =
builder.stream("transaction-request",
Consumed.with(stringSerde, transactionRequestAvroSerde),
Materialized.as("latest-transactions"));
KafkaStreams kafkaStreams = new KafkaStreams(builder.build(), kaProperties);ساخت stream با builder آشناست؛ تا start چیزی پردازش نمیشود. recordهای KTable در state store latest-transactions materialize میشوند.
۱۲.۱.۳ GlobalKTable API
شبیه KTable اما GlobalKTable از همه partitionهای topic [۲] پر میشود. دانش topic و partition برای abstraction مهم است — instanceهای KafkaStreams هر partition را consume میکنند. listing 12.5 join با GlobalKTable: stream بهروزرسانی بسته پستی مشتری؛ join روی customer table برای email و ارسال پیام.
Listing 12.5 Mailing notification GlobalKTable
java
...
StreamsBuilder builder = new StreamsBuilder();
final KStream<String, MailingNotif> notifiers =
builder.stream("kinaction_mailingNotif");
final GlobalKTable<String, Customer> customers =
builder.globalTable("kinaction_custinfo");
lists.join(customers,
(mailingNotifID, mailing) -> mailing.getCustomerId(),
(mailing, customer) -> new Email(mailing, customer))
.peek((key, email) ->
emailService.sendMessage(email));
KafkaStreams kafkaStreams = new KafkaStreams(builder.build(), kaProperties);
kafkaStreams.cleanUp();
kafkaStreams.start();
...globalTable GlobalKTable میسازد. table غیر global شاید همه partition را consume نکند؛ global table همه partition را برای کد در حال اجرا consume میکند [۲].
NOTE ایده global table: داده بدون توجه به partition mapped در اپلیکیشن در دسترس باشد.
Streams DSL برای use case سریع عالی است؛ گاهی Processor API کنترل بیشتر میدهد — تنها یا همراه DSL.
۱۲.۱.۴ Processor API
کد اپلیکیشن streaming دیگر یا سطح abstraction پایینتر ممکن است Processor API باشد — کمتر آسان از DSL اما گزینه و قدرت بیشتر [۲]. listing 12.6 topology و تفاوتها.
Listing 12.6 Processor API source
java
import static org.apache.kafka.streams.Topology.AutoOffsetReset.LATEST;
public static void main(String[] args) throws Exception {
//...
final Serde<String> stringSerde = Serdes.String();
Deserializer<String> stringDeserializer = stringSerde.deserializer();
Serializer<String> stringSerializer = stringSerde.serializer();
Topology topology = new Topology();
topology = topology.addSource(LATEST,
"kinaction_source",
stringDeserializer,
stringDeserializer,
"kinaction_source_topic");
//...گراف با Topology [۴]. offset LATEST و deserializer key/value از فصل ۵ آشناست. node kinaction_source از topic kinaction_source_topic میخواند. گام بعد processing node — listing 12.7.
Listing 12.7 Processor API processor node
java
topology = topology.addProcessor(
"kinactionTestProcessor",
() -> new TestProcessor(),
"kinaction_source");نام node، logic از ProcessorSupplier، و node(های) مبدأ داده. listing 12.8 دو sink برای تکمیل topology.
Listing 12.8 Processor API processor sink
java
topology = topology.addSink(
"Kinaction-Destination1-Topic",
"kinaction_destination1_topic",
stringSerializer,
stringSerializer,
"kinactionTestProcessor");
topology = topology.addSink(
"Kinaction-Destination2-Topic",
"kinaction_destination2_topic",
stringSerializer,
stringSerializer,
"kinactionTestProcessor");
...در Processor سفارشی جریان داده را هدایت میکنیم — listing 12.9.
Listing 12.9 کد سفارشی Processor
java
public class KinactionTestProcessor
extends AbstractProcessor<String, String> {
@Override
public void process(String key, String value) {
context().forward(key, value,
To.child("Kinaction-Destination2-Topic"));
}
}کد verboseتر از DSL؛ کنترل بیشتر — زمانبندی پردازش یا commit. Processor API پیچیدهتر برای schedule و commit.
۱۲.۱.۵ راهاندازی Kafka Streams
مثال فقط یک instance؛ با thread بیشتر و instance بیشتر scale میشود. مثل consumer در یک group، parallelism به partition topic مبدأ [۵] وابسته است — topic هشت partition: حداکثر هشت instance؛ بیشتر بدون traffic مگر standby برای failure.
processing guarantee مهم است. Kafka Streams at-least-once و exactly-once [۶].
NOTE در 2.6.0 exactly-once beta معرفی شد — throughput و scalability بالاتر با کاهش utilization منابع.
اگر منطق به exactly-once وابسته است، Kafka Streams در اکوسystem Kafka کمک میکند. با ارسال به سیستم خارجی، delivery آن سیستم را بررسی کنید. Streams API خواندن topic، بهروز store و نوشتن topic دیگر atomic؛ سیستم خارجی نه. مرز سیستم روی guarantee اثر دارد.
at-least-once: داده گم نشود اما duplicate ممکن — منطق اپلیکیشن duplicate را handle کند. در زمان نگارش at-least-once پیشفرض است.
Kafka Streams fault-tolerant: state store با topic Kafka replicated و partitioned پشتیبان میشود. replay پس از failure بدون بازسازی دستی state. برای عمق بیشتر: Kafka Streams in Action (https://www.manning.com/books/kafka-streams-in-action) ویلیام P. Bejeck Jr. (Manning, 2018).
۱۲.۲ ksqlDB: پایگاهداده event-streaming
ksqlDB (https://ksqldb.io) پایگاهداده event-streaming. ابتدا KSQL نام داشت؛ نوامبر ۲۰۱۹ rename شد. Kafka کلاینتهای مختلف برای کار با داده ساخت.
ksqlDB قدرت Kafka را برای کسانی که SQL میدانند expose میکند — بدون Java/Scala. driver دیگر: Kafka بخشی از flow بود نه کل معماری. شکل ۱۲.۳ یک استفاده از Kafka.
Moving data out of
kinaction_alerttrend,
Web user End user
Kafka cluster for example
Order External Kafka Kafka External
database Connect Connect database
Reporting UIشکل ۱۲.۳ جریان نمونه اپلیکیشن Kafka
برای serve کاربر، داده از Kafka به data store خارج منتقل میشود. e-commerce: رویداد هر مرحله سفارش status برای گزارش خریدار.
قبل از ksqlDB رویدادهای سفارش در Kafka (Kafka Streams یا Spark) پردازش و با Connect به DB خارج میرفت؛ اپلیکیشن view از event stream را بهعنوان state لحظهای نشان میداد. با pull query و connector management در ksqlDB، مسیر ماندن در اکوسystem برای materialized view به کاربر. شکل ۱۲.۴ نمای کلی.
Kafka cluster
Web user
Event to
ksqlDB
ksqlDB
End users
Push/pull
queries
Using connectors
and streams Reporting UIشکل ۱۲.۴ جریان نمونه Kafka با ksqlDB
انواع query — از pull query شروع.
۱۲.۲.۱ Queryها
Pull query و push query برای ساخت اپلیکیشن. Pull query برای flow همگام request-response [۷] — state فعلی view materializeشده با رویدادهای رسیده؛ پاسخ و پایان query. snapshot لحظه query.
Push query برای الگوی ناهمگام [۷] — subscribe شبیه consumer؛ با رسیدن رویداد واکنش.
۱۲.۲.۲ توسعه محلی
سادهترین راه محلی ksqlDB: imageهای Docker Confluent. https://ksqldb.io/quickstart.html — setup کامل Kafka یا فقط ksqldb-server و ksqldb-cli.
با Docker: docker-compose up. سپس ksqldb-cli برای session تعاملی. پس از DB، داده را define کنید. Docker در پیوست A. listing 12.10 session تعاملی ksqlDB [۸].
Listing 12.10 session تعاملی ksqlDB
bash
docker exec -it ksqldb-cli \
ksql http://ksqldb-server:8088
> SET 'auto.offset.reset'='earliest';extension transaction processor: از داده تراکنش پردازششده گزارش statement با enrich اطلاعات حساب — join تراکنش موفق با داده حساب. stream از topic موفق — listing 12.11.
NOTE داده قبلاً در topic از Kafka Streams بود — شاید
SET 'auto.offset.reset' = 'earliest';قبل از CREATE لازم باشد.
Listing 12.11 stream برای تراکنشهای موفق
sql
CREATE STREAM TRANSACTION_SUCCESS (
numkey string KEY,
transaction STRUCT<guid STRING, account STRING,
amount DECIMAL(9, 2), type STRING,
currency STRING, country STRING>,
funds STRUCT<account STRING,
balance DECIMAL(9, 2)>,
success boolean,
errorType STRING
) WITH (
KAFKA_TOPIC='transaction-success',
VALUE_FORMAT='avro');ksqlDB داده تو در تو — نوع تو در تو Transaction در TransactionResult Kafka Streams. STRUCT ساختار nested. یکپارچه با Schema Registry؛ Avro، Protobuf، JSON، JSON-schema. schema ساختار stream/table را infer میکند — همکاری microservice.
اطلاعات جامع حساب لازم است. تاریخچه تغییر حساب نه — lookup با account ID. TABLE در ksqlDB — listing 12.12.
Listing 12.12 ساخت table ksqlDB
sql
CREATE TABLE ACCOUNT (number INT PRIMARY KEY)
WITH (KAFKA_TOPIC = 'account', VALUE_FORMAT='avro');populate table — listing 12.13. تفاوت: EMIT CHANGES push query میسازد — در پسزمینه اجرا، نه بازگشت فوری به prompt.
Listing 12.13 stream statement تراکنش با اطلاعات حساب
sql
CREATE STREAM TRANSACTION_STATEMENT AS
SELECT *
FROM TRANSACTION_SUCCESS
LEFT JOIN ACCOUNT
ON TRANSACTION_SUCCESS.numkey = ACCOUNT.numkey
EMIT CHANGES;برای تست، instance جدید ksqldb-cli برای insert در stream و تولید تراکنش تست. Kafka Streams پردازش؛ در موفقیت به transaction-success — ksqlDB در TRANSACTION_SUCCESS و TRANSACTION_STATEMENT.
۱۲.۲.۳ معماری ksqlDB
با Docker معماری را رد کردیم. برخلاف Streams API، ksqlDB component اضافی میخواهد. component اصلی ksqlDB server [۹] — اجرای SQL و داده از/به Kafka. REST API برای ksqldb-cli [۹].
deployment mode headless: query از CLI ممنوع [۱۰]. --queries-file یا ksql-server.properties + فایل query. listing 12.14 headless [۱۰].
Listing 12.14 راهاندازی ksqlDB در حالت headless
bash
bin/ksql-server-start.sh \
etc/ksql/ksql-server.properties --queries-file kinaction.sqlKafka Streams یا ksqlDB برای task جدید؟ prototype سریع با ksqldb-cli. ksqlDB برای غیر JVM (بدون Java/Scala) feature set Streams با SQL. microservice: Streams API مناسبتر.
۱۲.۳ ادامه مسیر
منابع بیشتر برای یادگیری Kafka.
۱۲.۳.۱ Kafka Improvement Proposals (KIPs)
دنبال کردن KIP یکی از بهترین راههای بهروز ماندن. همه پیشنهادها implement نمیشوند، اما use case در حال تغییر را نشان میدهد. فصل ۵ KIP 392 (http://mng.bz/n2aV) — fetch وقتی leader partition در datacenter غیرمحلی است. KIP در keynote مثل Kafka Summit 2019 — KIP 500 (http://mng.bz/8WvD) جایگزینی ZooKeeper.
۱۲.۳.۲ پروژههای Kafka برای کاوش
جستجوی GitHub/GitLab برای استفاده real-world. کیفیت یکسان نیست؛ فصلهای قبل قطعات را توضیح دادند. مثال: Apache Flume (https://github.com/apache/flume).
۱۲.۳.۳ کانال Slack جامعه
Confluent Community (https://www.confluent.io/community/) — Slack با کانالهای clients، Connect و موضوعات Kafka. forum برای معرفی و آشنایی.
در این فصل KStreams و ksqlDB و ارتباط با دانش core Kafka را گسترش دادید. با تکامل اکوسystem Kafka، پایههای این کتاب به درک داخلی کمک میکند. موفق باشید در ادامه یادگیری Kafka!
خلاصه
- Kafka Streams پردازش per-record در اپلیکیشن — abstraction روی producer و consumer.
- انتخاب DSL تابعی یا Processor API.
- Streamها بهعنوان topology با DSL Kafka Streams مدل میشوند.
- ksqlDB پایگاهدادهای که قدرت Kafka را برای کاربران SQL expose میکند. queryهای ksqlDB continuous و prototype سریع.
- KIPها تغییرات درخواستی و implementشده در نسخههای آینده را نشان میدهند.
منابع
- «Documentation: Kafka Streams.» Apache Software Foundation (n.d.). https://kafka.apache.org/documentation/streams/ (accessed May 30, 2021).
- «Streams Concepts.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/streams/concepts.html (accessed June 17, 2020).
- «Documentation: Kafka Streams: Core Concepts.» Apache Software Foundation (n.d.). https://kafka.apache.org/26/documentation/streams/core-concepts (accessed June 25, 2021).
- «Kafka Streams Processor API.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/streams/developer-guide/processor-api.html#streams-developer-guide-processor-api (accessed August 22, 2021).
- «Streams Architecture.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/streams/architecture.html (accessed June 17, 2020).
- «Documentation: Streams API changes in 2.6.0.» Apache Software Foundation. https://kafka.apache.org/26/documentation/streams/upgrade-guide#streams_api_changes_260 (accessed August 22, 2021).
- «ksqlDB Documentation: Queries.» Confluent documentation (n.d.). https://docs.ksqldb.io/en/latest/concepts/queries/ (accessed May 5, 2021).
- «ksqlDB: Configure ksqlDB CLI.» Confluent documentation (n.d.). https://docs.ksqldb.io/en/0.7.1-ksqldb/operate-and-deploy/installation/cli-config/ (accessed August 23, 2021).
- «Installing ksqlDB.» Confluent documentation (n.d.). https://docs.confluent.io/platform/current/ksqldb/installing.html (accessed June 20, 2020).
- «Configure ksqlDB Server.» Confluent documentation (n.d.). https://docs.ksqldb.io/en/latest/operate-and-deploy/installation/server-config/ (accessed August 23, 2021).
پیوست A — نصب
با وجود feature set پیچیده، نصب Apache Kafka straightforward است. ابتدا نگرانیهای setup.
A.1 نیازمندیهای سیستمعامل (OS)
Linux محتملترین خانه Kafka است. macOS با Bash (قبل Catalina) یا zsh (پس از Catalina) استفاده شده. Windows® برای development قابل قبول؛ production توصیه نمیشود [۱].
NOTE بخش بعد نصب با Docker (http://docker.com).
A.2 نسخههای Kafka
پروژه فعال ASF؛ نسخهها بهروز میشوند. backward compatibility جدی گرفته میشود. نسخه جدید و deprecatedها را update کنید.
TIP ZooKeeper و Kafka روی یک سرور فیزیکی در production برای fault tolerance توصیه نمیشود. در کتاب تمرکز روی یادگیری feature است نه مدیریت چند سرور.
A.3 نصب Kafka روی ماشین محلی
یکی از گزینههای ساده: کلاستر single-node دستی. Michael Noll «Running a Multi-Broker Apache Kafka 0.8 Cluster on a Single Node» [۲]. Docker در انتهای پیوست.
حداقل پیشنهادی workstation (نتایج متفاوت):
- حداقل CPU (فیزیکی یا logical): 2
- حداقل RAM: 4 GB
- فضای آزاد دیسک: 10 GB
Java و Apache Kafka (شامل ZooKeeper) را نصب کنید.
A.3.1 پیشنیاز: Java
JDK 11 در مثالها. https://jdk.dev/download/. SDKMAN CLI: http://sdkman.io.
A.3.2 پیشنیاز: ZooKeeper
Kafka به ZooKeeper نیاز دارد — در bundle دانلود Kafka. نسخه سازگار در distribution؛ دانلود جدا لازم نیست. اسکریپت start/stop در distribution.
A.3.3 پیشنیاز: دانلود Kafka
نسخه 2.7.1 در مثالها. mirror ASF: http://mng.bz/aZo7. نام فایل: kafka_2.13-2.7.1 — Kafka 2.7.1 پس از خط تیره.
کلاستر سهnode روی یک ماشین برای یادگیری (production نیست).
NOTE چرا سه node؟ بخشهای توزیعشده Kafka با بیش از یک node واضحتر میشوند.
A.3.4 راهاندازی سرور ZooKeeper
listing A.2 ZooKeeper قبل از broker.
Listing A.2 راهاندازی ZooKeeper
bash
$ cd ~/kafka_2.13-2.7.1
$ bin/zookeeper-server-start.sh config/zookeeper.propertiesA.3.5 ساخت و پیکربندی دستی کلاستر
سه broker: server0، server1، server2. listing A.3 کپی server.properties؛ listing A.4 ویرایش.
Listing A.3 ساخت چند broker Kafka
bash
$ cd ~/kafka_2.13-2.7.1
$ cp config/server.properties config/server0.properties
$ cp config/server.properties config/server1.properties
$ cp config/server.properties config/server2.propertiesListing A.4 پیکربندی server 0
$ vi config/server0.properties
broker.id=0
listeners=PLAINTEXT://localhost:9092
log.dirs= /tmp/kafkainaction/kafka-logs-0
$ vi config/server1.properties
broker.id=1
listeners=PLAINTEXT://localhost:9093
log.dirs= /tmp/kafkainaction/kafka-logs-1
$ vi config/server2.properties
broker.id=2
listeners=PLAINTEXT://localhost:9094
log.dirs= /tmp/kafkainaction/kafka-logs-2NOTE هر broker پورت و log directory جدا؛ ID یکتا — معمولاً از 0 (zero-based).
listing A.5 start brokerها [۲].
Listing A.5 راهاندازی Kafka در پنجره console
bash
$ cd ~/kafka_2.13-2.7.1
$ bin/kafka-server-start.sh config/server0.properties
$ bin/kafka-server-start.sh config/server1.properties
$ bin/kafka-server-start.sh config/server2.propertiesTIP terminal بسته یا process hang —
jps[۴] برای یافتن process Java.
listing A.6 خروجی jps.
Listing A.6 خروجی jps برای ZooKeeper و سه broker
2532 Kafka
2745 Kafka
2318 Kafka
2085 QuorumPeerMainA.4 Confluent Platform
Confluent Inc. (https://www.confluent.io/) — packaging enterprise-ready مکمل Kafka: Docker، Kubernetes، Ansible و غیره. کلاینت C++، C#/.NET، Python، Go. Schema Registry (فصل ۳ و ۱۱). Community Edition شامل ksqlDB (فصل ۱۲). سرویس managed cloud-native. Confluent 6.1.1 شامل Kafka 2.7.1. نصب: http://mng.bz/g1oV.
A.4.1 CLI خط فرمان Confluent
ابزار start/manage Confluent Platform. README: https://github.com/confluentinc/confluent-cli — نصب http://mng.bz/RqNR.
A.4.2 Docker
Kafka image رسمی ASF فعلاً ندارد؛ Confluent دارد. در repository مثالهای کتاب docker-compose.yaml. docker-compose up -d — listing A.7.
NOTE Docker: https://www.docker.com/get-started
Listing A.7 Docker image
bash
$ git clone \
https://github.com/Kafka-In-Action-Book/Kafka-In-Action-Source-Code.git
$ cd ./Kafka-In-Action-Source-Code
$ docker-compose up -d
Creating network "kafka-in-action-code_default" with the default driver
Creating Zookeeper... done
Creating broker2 ... done
Creating broker1 ... done
Creating broker3 ... done
Creating schema-registry ... done
Creating ksqldb-server ... done
Creating ksqldb-cli ... done
$ docker ps --format "{{.Names}}: {{.State}}"
ksqldb-cli: running
ksqldb-server: running
schema-registry: running
broker1: running
broker2: running
broker3: running
zookeeper: runningA.5 کار با مثالهای کتاب
IDE: IntelliJ IDEA Community، Apache Netbeans، VS Code for Java، Eclipse STS.
A.5.1 Build از خط فرمان
Java 11 با Maven 3.6.3. ./mvnw verify یا ./mvnw --projects KafkaInAction_Chapter2 verify. Maven Wrapper: http://mng.bz/20yo.
NOTE JAR با همه dependency برای اجرای موفق.
Listing A.8 اجرای producer فصل ۲ از خط فرمان
bash
java -cp target/chapter2-jar-with-dependencies.jar \
replace.with.full.package.name.HelloWorldProducerA.6 عیبیابی
Source code: https://github.com/Kafka-In-Action-Book/Kafka-In-Action-Source-Code
- کلاستر قبل از اجرای کد و مثالهای CLI بالا باشد.
- shutdown نادرست — process قدیمی پورت را نگه داشته؛
jpsیاlsof. - دستورات از داخل directory نصب، مگر خلافش گفته شده.
- command not found — executable بودن فایلها،
chmod -R 755، PATH شامل bin. Commands.mdوREADME.mdهر فصل.
منابع پیوست A
- J. Galasyn. «How to Run Confluent on Windows in Minutes.» Confluent blog (March 26, 2021). https://www.confluent.io/blog/set-up-and-run-kafka-on-windows-and-wsl-2/ (accessed June 11, 2021).
- M. G. Noll. «Running a Multi-Broker Apache Kafka 0.8 Cluster on a Single Node.» (March 13, 2013). https://www.michael-noll.com/blog/2013/03/13/running-a-multi-broker-apache-kafka-cluster-on-a-single-node/ (accessed July 20, 2021).
- «Apache Kafka Quickstart.» Apache Software Foundation (n.d.). https://kafka.apache.org/quickstart (accessed August 22, 2021).
- README.md. Confluent Inc. GitHub (n.d.). https://github.com/confluentinc/customer-utilities (accessed August 21, 2021).
پیوست B — مثال کلاینت
مثالهای کتاب روی Java Kafka clients متمرکزند؛ برای کاربر جدید، مثال در زبان آشنا مفید است. Confluent Platform کلاینتهای پشتیبانیشده [۱]. کلاینت Python Kafka و یادداشت تست Java.
B.1 کلاینتهای Python Kafka
Confluent Python Client [۲] — سازگاری با Kafka و platform Confluent. producer و consumer. نصب Python.
B.1.1 نصب Python
Python 3. در غیر این صورت librdkafka — Homebrew: brew install librdkafka [۲]. pip install confluent-kafka [۲].
B.1.2 مثال producer Python
listing B.1 — دو پیام به kinaction-python-topic.
Listing B.1 مثال producer Python
python
from confluent_kafka import Producer
producer = Producer(
{'bootstrap.servers': 'localhost:9092'})
def result(err, message):
if err:
print('kinaction_error %s\n' % err)
else:
print('kinaction_info : topic=%s, and kinaction_offset=%d\n' %
(message.topic(), message.offset()))
messages = ["hello python", "hello again"]
for msg in messages:
producer.poll(0)
producer.produce("kinaction-python-topic",
value=msg.encode('utf-8'), callback=result)
producer.flush()
# Output
#kinaction_info: topic=kinaction-python-topic, and kinaction_offset=8
#kinaction_info: topic=kinaction-python-topic, and kinaction_offset=9import confluent_kafka؛ Producer با config شامل broker. callback result پس از produce. iterate روی messages؛ flush() برای ارسال واقعی نه فقط buffer.
B.1.3 consumer Python
listing B.2 — خواندن پیامهای listing B.1.
Listing B.2 مثال consumer Python
python
from confluent_kafka import Consumer
consumer = Consumer({
'bootstrap.servers': 'localhost:9094',
'group.id': 'kinaction_team0group',
'auto.offset.reset': 'earliest'
})
consumer.subscribe(['kinaction-python-topic'])
try:
while True:
message = consumer.poll(2.5)
if message is None:
continue
if message.error():
print('kinaction_error: %s' % message.error())
continue
else:
print('kinaction_info: %s for topic: %s\n' %
(message.value().decode('utf-8'),
message.topic()))
except KeyboardInterrupt:
print('kinaction_info: stopping\n')
finally:
consumer.close()
# Output
# kinaction_info: hello python for topic: kinaction-python-topicConsumer با config؛ subscribe؛ loop poll؛ finally close() و commit offset. ساده اما نشان میدهد Kafka با Python و اکثر زبانها ممکن است — همه کلاینتها feature برابر Java ندارند.
B.2 تست کلاینت
EmbeddedKafkaCluster در فصل ۷. گزینههای دیگر قبل از production.
B.2.1 unit testing در Java
unit test یک واحد نرمافزار — ideally بدون وابستگی. تست کلاینت Kafka بدون کلاستر واقعی؟
Mockito — mock producer. کتابخانه رسمی MockProducer implementing Producer [۴] — بدون کلاستر واقعی. clear برای test بعدی [۴]. consumer هم mock [۴].
B.2.2 Kafka Testcontainers
Testcontainers (https://www.testcontainers.org/modules/kafka/) — فصل ۷. EmbeddedKafkaCluster in-memory؛ Testcontainers روی Docker image.
منابع پیوست B
- «Kafka Clients.» Confluent documentation (n.d.). https://docs.confluent.io/current/clients/index.html (accessed June 15, 2020).
- confluent-kafka-python. Confluent Inc. GitHub (n.d.). https://github.com/confluentinc/confluent-kafka-python (accessed June 12, 2020).
- consumer.py. Confluent Inc. GitHub (n.d.). https://github.com/confluentinc/confluent-kafka-python/blob/master/examples/consumer.py (accessed August 21, 2021).
- MockProducer<K,V>. Kafka 2.7.0 API. Apache Software Foundation (n.d.). https://kafka.apache.org/27/javadoc/org/apache/kafka/clients/producer/MockProducer.html (accessed May 30, 2021).
فهرست
A
- authentication (احراز هویت) ۱۸۳
- authorization (مجوزدهی) ۱۸۳، ۱۸۹–۱۹۱
AbstractPartitionAssignorabstract class ۱۰۱acksproperty ۸۳- ACLs (access control lists) ۱۸۹–۱۹۰
- administration clients ۱۵۹–۱۶۳
AdminClient۱۵۹–۱۶۱- Confluent REST Proxy API ۱۶۲–۱۶۳
- kcat ۱۶۱–۱۶۲
advertised.listeners۱۶۷Alertclass ۶۳، ۷۷–۷۸- Alert data object ۷۸
Alertobject ۲۴، ۶۲- Alert producer ۱۷۱
--bootstrap-serveroption ۲۰bootstrap.serversparameter ۳۴، ۷۱، ۸۳، ۱۶۰- broker list ۷۱–۷۲
- brokers (بروکرها) ۱۸–۲۲
- adding to cluster ۱۲۲
AlertProducerclass ۱۷۲- backups ۱۲۳
- cluster maintenance ۱۲۱
- configurations ۱۱۳–۱۱۶
- application logs ۱۱۵
- controller ۱۱۶
- server log ۱۱۵–۱۱۶
- overview ۱۱۱–۱۱۲
- partition replica leaders ۱۱۷–۱۱۹
- upgrading clients ۱۲۲
- upgrading cluster ۱۲۲
- version, generating code for ۸۴
- analytical data ۱۵۱
- Apache Flume ۱۴۷–۱۴۸
- application logs ۱۱۵، ۱۶۴–۱۶۶
- architectures ۱۵۲–۱۵۵
- Kappa architecture ۱۵۴–۱۵۵
- ksqlDB ۲۲۲–۲۲۳
- Lambda architecture ۱۵۳–۱۵۴
assignmethod ۱۰۷
C
- at-least-once semantics ۶
- at-most-once semantics ۶
Callbackinterface ۸۲- audit log, sensor event design ۵۴–۵۷
- CDC (change data capture) ۱۴۹، ۱۹۹
cleanup.policy۱۳۹- CLI (command line interface) ۱۴۹
- building from ۲۳۲–۲۳۳
- Confluent Platform ۲۳۱
- client library, Schema Registry ۲۰۳–۲۰۴
client.idproperty ۱۶۰، ۱۹۲- clients (کلاینتها)
- client testing ۲۳۶–۲۳۷
- Kafka Testcontainers ۲۳۷
- unit testing in Java ۲۳۶–۲۳۷
- overriding ۱۷۳–۱۷۴
- upgrading ۱۲۲
- version, generating code for ۸۴
- client testing ۲۳۶–۲۳۷
- clusters (کلاسترها)
- adding broker to ۱۲۲
- cluster maintenance ۱۲۱
- creating and configuring by hand ۲۲۹–۲۳۱
- multiple cluster setups ۱۵۵
- upgrading ۱۲۲
- commit log ۲۹–۳۰
- compacted topics ۱۳۹–۱۴۱
- compatibility ۲۰۲
- configurations
- brokers ۱۱۳–۱۱۶
- consumers ۸۹–۹۲
- producers ۷۰–۷۶
- Schema Registry ۲۰۱–۲۰۲
- Confluent Platform ۲۳۱–۲۳۲
- Confluent REST Proxy API ۱۶۲–۱۶۳
- Confluent Schema Registry ۲۰۱
confluent_kafkadependency ۲۳۵–۲۳۶- console-consumer command ۴۶
- consumer logic ۱۷۲–۱۷۳
__consumer_offsetstopic ۱۰۳، ۱۴۰ConsumerConfigclass ۸۹، ۱۷۳ConsumerInterceptorinterface ۱۷۳ConsumerRecords۲۵- consumers ۲۳–۲۶
- controllers ۱۱۲، ۱۱۶
- coordinates ۹۲–۹۶
- CQRS ۱۵۵
- create action ۱۳۳
CreateTimefield ۱۳۵- CRUD ۸
- curl command ۱۶۳
D
- DAG (directed acyclic graph) ۲۱۲
- data loss, partition replica leaders and ۱۱۹
- data silos ۵۰
- data storage
- architectures ۱۵۲–۱۵۵
- data movement ۱۴۶–۱۴۷
- importing data back into Kafka ۱۵۱–۱۵۲
- multiple cluster setups ۱۵۵
- retention ۱۴۵–۱۴۶
- scaling ۱۵۵
- tiered storage ۱۵۲
- tools ۱۴۷–۱۵۱
- DDoS (distributed denial-of-service) ۱۹۱
--deleteoption ۱۳۴delete-configparameter ۱۹۳delete.topic.enableoption ۱۳۲--describeflag ۱۲۵- designing Kafka projects
- DSLs (domain-specific languages) ۳۰، ۲۰۹
E
- EmbeddedKafkaCluster ۱۳۷–۱۳۹
- ensembles ۲۸
- ESB (enterprise service bus) ۱۹۸
- ETL ۳، ۱۴۶، ۱۹۹
- exactly-once semantics ۶، ۳۸
F
- fast data ۱۰
FileStreamSourceclass ۴۵- firewalls ۱۶۶–۱۶۷
- formatting data ۵۷–۶۴
G
- GlobalKTable API ۲۱۶
- group coordinator ۹۴، ۹۸–۱۰۰
H
- HDFS ۱۰، ۱۴۶
- headless mode ۲۲۲
I
- installing Kafka ۲۲۷–۲۳۱
- interceptor.classes property ۱۷۲–۱۷۳
- ISRs (in-sync replicas) ۲۰، ۷۳، ۱۱۵، ۱۱۸
J
- JAAS files ۱۸۷
- Java clients ۳۳–۳۶
- JMX console ۱۶۷–۱۷۰
K
- Kafka
- application logs ۱۶۴–۱۶۶
- brokers ۱۸–۲۲
- commit log ۲۹–۳۰
- consumers ۲۳–۲۶
- exactly-once semantics ۳۸
- high-level architecture ۲۸–۲۹
- Java clients ۳۳–۳۶
- myths about ۱۰–۱۱
- online resources ۱۵
- overview ۴–۸
- producers ۲۳–۲۶
- stream processing ۳۶–۳۸
- topics ۲۶–۲۷
- ZooKeeper usage ۲۷–۲۸
- Kafka Improvement Proposals. See KIPs
- Kafka Streams ۳۰–۳۱، ۲۱۰–۲۱۹
- Kafka Testcontainers ۲۳۷
kafka-acls.shCLI tool ۱۹۰- Kerberos ۱۸۷–۱۸۹، ۱۹۱
- keystore ۱۸۶
- keytab ۱۸۸
- KIPs ۱۹۴، ۲۲۳
- ksqlDB ۳۲–۳۳، ۲۱۹–۲۲۳
- KStreams API DSL ۲۱۱–۲۱۵
- KTable API ۲۱۵
L
- Lambda architecture ۱۵۳–۱۵۴
- leader ۲۶
- listeners property ۱۶۷
- local development, ksqlDB ۲۲۰–۲۲۲
- log compaction ۵۶
M
- maturity levels
- Kafka maturity model ۱۹۸–۲۰۰
- Marz, Nathan ۱۵۳
N
- network bandwidth quota ۱۹۲–۱۹۳
- NONE type ۲۰۵
O
- offsets ۲۷، ۹۲
offsetsForTimesmethod ۱۰۴
P
- partition assignment strategy ۱۰۰–۱۰۱
Partitionerinterface ۸۱- partitions ۲۶، ۱۳۴–۱۳۷
- Processor API ۲۱۶–۲۱۸
Producerinterface ۲۳۷- producers ۴، ۲۳–۲۶
- push queries ۲۲۰، ۲۲۲
- Python Kafka client example ۲۳۴–۲۳۶
Q
--queries-filecommand line argument ۲۲۲- queries, ksqlDB ۲۲۰
- quotas ۱۹۱–۱۹۴
- network bandwidth quota ۱۹۲–۱۹۳
- request rate quotas ۱۹۳–۱۹۴
R
- range assigner ۱۰۰
- RBAC ۱۹۰–۱۹۱
- recoverability ۵۰
- Red Hat Debezium ۱۴۹
- REPL ۲۲۳
- replica leader ۲۱
- replication-factor parameter ۱۳۲
- request rate quotas ۱۹۳–۱۹۴
- REST API ۲۰۲–۲۰۳
- retention, data ۱۴۵–۱۴۶
- round-robin strategy ۱۰۰
S
- SASL ۱۸۷–۱۸۹
- Schema Registry ۲۰۰–۲۰۲
- alternative to ۲۰۷
- client library ۲۰۳–۲۰۴
- compatibility rules ۲۰۵–۲۰۶
- configurations ۲۰۱–۲۰۲
- REST API ۲۰۲–۲۰۳
schema.registry.urlproperty ۶۲_schemastopic name ۲۰۱- Secor ۱۴۹–۱۵۰
- security (امنیت)
- authorization ۱۸۹–۱۹۱
- basics ۱۸۳–۱۸۷
- data management options ۱۹۴–۱۹۵
- Kerberos ۱۸۷–۱۸۹
- quotas ۱۹۱–۱۹۴
- ZooKeeper ۱۹۱
security.protocol۱۸۷- sensor event design ۴۹–۵۷
- Serde ۷۸
- SimpleAclAuthorizer class ۱۸۹
- single sign-on. See SSO
- SinkCallback class ۸۴
- Slack group channel ۲۲۴
- source processor ۲۱۱
- stateful systems, brokers and ۱۲۳–۱۲۴
- stream processing ۳۶–۳۸
- community Slack channel ۲۲۴
- Kafka Improvement Proposals ۲۲۳
- Kafka Streams ۲۱۰–۲۱۹
- ksqlDB ۲۱۹–۲۲۳
StreamsBuilderobject ۲۱۳STRUCTkeyword ۲۲۱- subjects ۲۰۲
- systemctl commands ۱۶۴
- systemd service ۱۶۳–۱۶۴
T
- tar command ۲۲۹
- tiered data storage ۱۵۲
- timestamps ۷۴–۷۵
- tools ۱۴۷–۱۵۱، ۱۵۹–۱۶۳
- topics ۱۲۹–۱۳۴
- Topology object ۲۱۷
- tracing option ۱۷۰–۱۷۴
- tracking data ۹۶–۱۰۱
- transaction-request topic ۲۰۹، ۲۱۳–۲۱۴
- transaction-success topic ۲۲۱–۲۲۲
TransactionResultclass ۲۲۱
U
- UnderReplicatedPartitions name attribute ۱۷۰
V
value.deserializerkey ۸۹value.serializerparameter ۳۴، ۲۰۳
W
- wakeup method ۹۲
- Warren, James ۱۵۳
- WorkerSinkTask class ۲۵
Z
- ZooKeeper ۱۹۱
- application logs ۱۶۶
- as prerequisite for installing Kafka ۲۲۸
- brokers ۱۱۲–۱۱۳
- Kafka's use of ۲۷–۲۸
- Kerberos setup ۱۹۱
- starting server ۲۲۹
zookeeper.set.aclvalue ۱۹۱ZkData.scalaclass ۱۱۳zkNodesproperty ۱۱۲
عناوین مرتبط Manning
Kubernetes in Action, Second Edition
by Marko Lukša — ISBN 9781617297618 — تابستان ۲۰۲۲ (تخمینی)
Algorithms and Data Structures for Massive Datasets
by Dzejla Medjedovic, Emin Tahirovic, and Ines Dedovic — ISBN 9781617298035 — آوریل ۲۰۲۲ (تخمینی)
Apache Pulsar in Action
by David Kjerrumgaard — ISBN 9781617296888 — دسامبر ۲۰۲۱
برای سفارش: www.manning.com
liveBook
liveBook پلتفرم خواندن آنلاین Manning است — یادداشت، bookmark، کپی یککلیکی کد، forum بحث، ضبط صوتی و تمرین تعاملی. نسخه liveBook با هر کتاب Manning رایگان است.
- جستجو در همه کتابها و ویدیوهای Manning — حتی آنهایی که ندارید (خواندن باز تا ۱۰ دقیقه در روز per book)
www.manning.com/livebook-program
درباره کتاب Kafka in Action
Apache Kafka را bus نرمافزاری پرformance بالا برای event streaming، logging، analytics و pipeline داده بدانید. Kafka in Action featureهای core و مثالهای real-world را معرفی میکند — logging، مدیریت streaming data، taskهای developer و admin در تیم Kafka-focused.
نویسندگان: Dylan Scott، Viktor Gamov، Dave Klein (Confluent)
پیشگفتار: Jun Rao
ISBN: 978-1-61729-523-2
برای دسترسی رایگان به همه فرمت ebook: https://www.manning.com/freebook