Chủ đề thanh trừng Kafka


185

Có cách nào để thanh lọc chủ đề trong kafka?

Tôi đã đẩy một tin nhắn quá lớn vào chủ đề tin nhắn kafka trên máy cục bộ của mình, bây giờ tôi đang gặp lỗi:

kafka.common.InvalidMessageSizeException: invalid message size

Tăng fetch.sizekhông phải là lý tưởng ở đây, vì tôi thực sự không muốn chấp nhận những tin nhắn lớn như vậy.

Câu trả lời:


360

Tạm thời cập nhật thời gian lưu về chủ đề lên một giây:

kafka-topics.sh --zookeeper <zkhost>:2181 --alter --topic <topic name> --config retention.ms=1000

Và trong các bản phát hành Kafka mới hơn, bạn cũng có thể làm điều đó với kafka-configs --entity-type topics

kafka-configs.sh --zookeeper <zkhost>:2181 --entity-type topics --alter --entity-name <topic name> --add-config retention.ms=1000

sau đó chờ thanh trừng có hiệu lực (khoảng một phút). Sau khi thanh trừng, khôi phục retention.msgiá trị trước đó .


8
Đó là một câu trả lời tuyệt vời nhưng bạn có thể vui lòng thêm một mô tả làm thế nào để bắt đầu với việc kiểm tra giá trị hiện tại của chủ đề không?
Greg Dubicki

28
Tôi không chắc chắn về việc kiểm tra cấu hình hiện tại, nhưng tôi tin rằng việc đặt lại nó về mặc định trông giống như:bin/kafka-topics.sh --zookeeper localhost:2181 --alter --topic MyTopic --deleteConfig retention.ms
aspergillusOryzae

15
Hoặc tùy thuộc vào phiên bản:--delete-config retention.ms
aspergillusOryzae

3
chỉ là một fyi, đối với kafka v. -zookeeper localhost: 2181 --alter --topic room-data --config retained.ms = 1000 CẢNH BÁO: Thay đổi cấu hình chủ đề từ tập lệnh này đã không được chấp nhận và có thể bị xóa trong các bản phát hành trong tương lai. Sắp tới, vui lòng sử dụng kafka-configs.sh cho chức năng này
Alper Akture

54
Có vẻ như kể từ 0.9.0, sử dụng kafka-topics.sh để thay đổi cấu hình không được chấp nhận. Tùy chọn mới là sử dụng tập lệnh kafka-configs.sh. e.g. kafka-configs.sh --zookeeper <zkhost>:2181 --alter --entity-type topics --entity-name <topic name> --add-config retention.ms=1000 Điều này cũng cho phép bạn kiểm tra thời gian lưu hiện tại, ví dụ: kafka-configs --zookeeper <zkhost>: 2181 --describe - chủ đề loại -entity - tên chủ đề <- tên chủ đề>
RHE

70

Để xóa hàng đợi, bạn có thể xóa chủ đề:

bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic test

sau đó tạo lại nó:

bin/kafka-topics.sh --create --zookeeper localhost:2181 \
    --replication-factor 1 --partitions 1 --topic test

14
Hãy nhớ thêm dòng delete.topic.enable=truetrong tệp config/server.properties, như cảnh báo được in bởi lệnh được đề cập nóiNote: This will have no impact if delete.topic.enable is not set to true.
Patrizio Bertoni

3
Đây không phải là tức thời luôn luôn. Đôi khi nó sẽ chỉ đánh dấu để xóa và xóa thực tế sẽ xảy ra sau đó.
Gaurav Khare

48

Dưới đây là các bước tôi làm theo để xóa một chủ đề có tên MyTopic:

  1. Mô tả chủ đề và không lấy id của người môi giới
  2. Dừng trình nền Kafka Apache cho mỗi ID nhà môi giới được liệt kê.
  3. Kết nối với mỗi nhà môi giới và xóa thư mục dữ liệu chủ đề, vd rm -rf /tmp/kafka-logs/MyTopic-0 . Lặp lại cho các phân vùng khác và tất cả các bản sao
  4. Xóa siêu dữ liệu chủ đề: zkCli.sh sau đórmr /brokers/MyTopic
  5. Khởi động trình nền Kafka Apache cho mỗi máy đã dừng

Nếu bạn nhớ bạn bước 3, thì Apache Kafka sẽ tiếp tục báo cáo chủ đề như hiện tại (ví dụ khi bạn chạy kafka-list-topic.sh ).

Đã thử nghiệm với Apache Kafka 0.8.0.


2
trong 0.8.1 ./zookeeper-shell.sh localhost:2181./kafka-topics.sh --list --zookeeper localhost:2181
pdeschen

Có thể sử dụng zookeeper-clientthay vì zkCli.sh(đã thử trên Cloudera CDH5)
Martin Tapp

1
Điều này xóa chủ đề, không phải dữ liệu bên trong nó. Điều này đòi hỏi Nhà môi giới phải dừng lại. Đây là tốt nhất một hack. Câu trả lời của Steven Appleyard thực sự là tuyệt vời nhất.
Jeff Maass

1
Đây là cách duy nhất tại thời điểm nó được viết.
Thomas Bratt

2
Làm việc cho tôi trên Kafka 0.8.2.1, mặc dù topis trong người quản lý vườn thú là dưới / môi giới / chủ đề / <tên chủ đề ở đây>
codecraig

44

Trong khi câu trả lời được chấp nhận là chính xác, phương pháp đó đã không được chấp nhận. Cấu hình chủ đề bây giờ nên được thực hiện thông qua kafka-configs.

kafka-configs --zookeeper localhost:2181 --entity-type topics --alter --add-config retention.ms=1000 --entity-name MyTopic

Các cấu hình được đặt thông qua phương thức này có thể được hiển thị bằng lệnh

kafka-configs --zookeeper localhost:2181 --entity-type topics --describe --entity-name MyTopic

2
Cũng đáng để thêm:kafka-configs --zookeeper localhost:2181 --entity-type topics --alter --delete-config retention.ms --entity-name MyTopic
NoBrainer

38

Đã thử nghiệm trong Kafka 0.8.2, cho ví dụ bắt đầu nhanh: Đầu tiên, Thêm một dòng vào tệp server.properIES trong thư mục cấu hình:

delete.topic.enable=true

Sau đó, bạn có thể chạy lệnh này:

bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic test

6

Từ kafka 1.1

Thanh lọc một chủ đề

bin/kafka-configs.sh --zookeeper localhost:2181 --alter --entity-type topics --entity-name tp_binance_kline --add-config retention.ms=100

Đợi 1 phút, để đảm bảo rằng kafka sẽ xóa chủ đề xóa cấu hình và sau đó chuyển đến giá trị mặc định

bin/kafka-configs.sh --zookeeper localhost:2181 --alter --entity-type topics --entity-name tp_binance_kline --delete-config retention.ms

1
Tôi nghĩ rằng bạn có một mũi tên thêm. Với tôi, tôi đã có thể chạybin/kafka-configs.sh --zookeeper localhost:2181 --alter --entity-type topics --entity-name my-topic --add-config rentention.ms=100
Will

4

kafka không có phương pháp trực tiếp cho chủ đề thanh lọc / dọn dẹp (Hàng đợi), nhưng có thể thực hiện việc này bằng cách xóa chủ đề đó và tạo lại chủ đề đó.

đầu tiên hãy chắc chắn rằng tập tin sever.properies có và nếu không thêm delete.topic.enable=true

sau đó, xóa chủ đề bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic myTopic

sau đó tạo lại nó

bin/kafka-topics.sh --zookeeper localhost:2181 --create --topic myTopic --partitions 10 --replication-factor 2

4

Đôi khi, nếu bạn đã có một cụm bão hòa (quá nhiều phân vùng hoặc sử dụng dữ liệu chủ đề được mã hóa hoặc sử dụng SSL hoặc bộ điều khiển nằm trên một nút xấu hoặc kết nối không ổn định, sẽ mất nhiều thời gian để lọc chủ đề đã nói .

Tôi làm theo các bước này, đặc biệt nếu bạn đang sử dụng Avro.

1: Chạy với các công cụ kafka:

bash kafka-configs.sh --alter --entity-type topics --zookeeper zookeeper01.kafka.com --add-config retention.ms=1 --entity-name <topic-name>

2: Chạy trên nút đăng ký Schema:

kafka-avro-console-consumer --consumer-property security.protocol=SSL --consumer-property ssl.truststore.location=/etc/schema-registry/secrets/trust.jks --consumer-property ssl.truststore.password=password --consumer-property ssl.keystore.location=/etc/schema-registry/secrets/identity.jks --consumer-property ssl.keystore.password=password --consumer-property ssl.key.password=password --bootstrap-server broker01.kafka.com:9092 --topic <topic-name> --new-consumer --from-beginning

3: Đặt duy trì chủ đề trở lại cài đặt ban đầu, khi chủ đề trống.

bash kafka-configs.sh --alter --entity-type topics --zookeeper zookeeper01.kafka.com --add-config retention.ms=604800000 --entity-name <topic-name>

Hy vọng điều này sẽ giúp được ai đó, vì nó không dễ dàng được quảng cáo.


Lưu ý: kafka-avro-console-consumerkhông cần thiết
OneCricketeer

4

CẬP NHẬT: Câu trả lời này có liên quan đến Kafka 0.6. Đối với Kafka 0.8 và sau đó xem câu trả lời của @Patrick.

Có, dừng kafka và xóa thủ công tất cả các tệp khỏi thư mục con tương ứng (thật dễ dàng tìm thấy nó trong thư mục dữ liệu kafka). Sau khi kafka khởi động lại, chủ đề sẽ trống.


Điều này đòi hỏi phải hạ Nhà môi giới, và tốt nhất là hack. Câu trả lời của Steven Appleyard thực sự là tuyệt vời nhất.
Jeff Maass

@MaasSql Tôi đồng ý. :) Câu trả lời này là hai năm, về phiên bản 0.6. Chức năng "thay đổi chủ đề" và "xóa chủ đề" đã được triển khai sau đó.
Cháy rừng

Câu trả lời của Steven Appleyard cũng giống như câu trả lời này.
Banjocat

Có một ứng dụng xử lý xóa dữ liệu của chính nó theo cách được hỗ trợ sẽ ít bị hack hơn nhiều so với tắt ứng dụng đã nói và xóa những gì bạn nghĩ là tất cả các tệp dữ liệu của nó sau đó bật lại.
Nick

3

Cách tiếp cận đơn giản nhất là đặt ngày của các tệp nhật ký riêng lẻ cũ hơn thời gian lưu. Sau đó, người môi giới sẽ dọn sạch chúng và loại bỏ chúng cho bạn trong vòng vài giây. Điều này cung cấp một số lợi thế:

  1. Không cần phải hạ nhà môi giới, đó là một hoạt động thời gian chạy.
  2. Tránh khả năng ngoại lệ bù không hợp lệ (nhiều hơn ở bên dưới).

Theo kinh nghiệm của tôi với Kafka 0.7.x, việc xóa các tệp nhật ký và khởi động lại nhà môi giới có thể dẫn đến các ngoại lệ bù không hợp lệ cho một số người tiêu dùng nhất định. Điều này sẽ xảy ra bởi vì nhà môi giới khởi động lại các giá trị bù ở mức 0 (trong trường hợp không có bất kỳ tệp nhật ký hiện có nào) và một người tiêu dùng đã tiêu thụ trước đó từ chủ đề sẽ kết nối lại để yêu cầu một khoản bù [cụ thể]. Nếu phần bù này xảy ra nằm ngoài giới hạn của nhật ký chủ đề mới, thì không có hại và người tiêu dùng sẽ tiếp tục ở đầu hoặc cuối. Nhưng, nếu phần bù nằm trong giới hạn của nhật ký chủ đề mới, người môi giới cố gắng tìm nạp bộ thông báo nhưng không thành công vì phần bù không phù hợp với thông điệp thực tế.

Điều này có thể được giảm nhẹ bằng cách xóa các khoản bù đắp của người tiêu dùng trong vườn thú cho chủ đề đó. Nhưng nếu bạn không cần một chủ đề mới và chỉ muốn xóa nội dung hiện có, thì chỉ cần 'chạm vào' một vài nhật ký chủ đề sẽ dễ dàng và đáng tin cậy hơn nhiều so với việc dừng môi giới, xóa nhật ký chủ đề và xóa một số nút của người quản lý vườn thú .


làm thế nào để "đặt ngày của các tệp nhật ký riêng lẻ cũ hơn thời gian lưu"? cảm ơn
bylijinnan

3

Lời khuyên của Thomas rất hay nhưng thật không may zkClitrong các phiên bản cũ của Zookeeper (ví dụ 3.3.6) dường như không hỗ trợ rmr. Ví dụ, so sánh việc thực hiện dòng lệnh trong Zookeeper hiện đại với phiên bản 3.3 .

Nếu bạn phải đối mặt với một phiên bản cũ của Zookeeper, một giải pháp là sử dụng thư viện máy khách như zc.zk cho Python. Đối với những người không quen thuộc với Python, bạn cần cài đặt nó bằng pip hoặc easy_install . Sau đó khởi động shell Python ( python) và bạn có thể làm:

import zc.zk
zk = zc.zk.ZooKeeper('localhost:2181')
zk.delete_recursive('brokers/MyTopic') 

hoặc thậm chí

zk.delete_recursive('brokers')

nếu bạn muốn xóa tất cả các chủ đề khỏi Kafka.


2

Để dọn sạch tất cả các tin nhắn từ một chủ đề cụ thể bằng nhóm ứng dụng của bạn (GroupName phải giống với tên nhóm kafka của ứng dụng).

./kafka-path/bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic topicName --from-beginning --group application-group


Có một vấn đề với cách tiếp cận này (được thử nghiệm trong 0.8.1.1). Nếu một ứng dụng đăng ký hai (hoặc nhiều) chủ đề: topic1 và topic2 và người tiêu dùng giao diện điều khiển dọn sạch topic1, thật không may, nó cũng xóa phần bù của người tiêu dùng không liên quan cho topic2, điều này gây ra phát lại tất cả các tin nhắn từ topic2.
jsh

2

Theo câu trả lời của @steven appleyard, tôi đã thực hiện các lệnh sau trên Kafka 2.2.0 và chúng đã làm việc cho tôi.

bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name <topic-name> --describe

bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name <topic-name> --alter --add-config retention.ms=1000

bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name <topic-name> --alter --delete-config retention.ms

Điều này dường như trùng lặp các câu trả lời khác
OneCricketeer

2

Rất nhiều câu trả lời tuyệt vời ở đây nhưng trong số đó, tôi không tìm thấy câu trả lời nào về docker. Tôi đã dành một chút thời gian để nhận ra rằng việc sử dụng container môi giới là sai đối với trường hợp này (rõ ràng !!!)

## this is wrong!
docker exec broker1 kafka-topics --zookeeper localhost:2181 --alter --topic mytopic --config retention.ms=1000
Exception in thread "main" kafka.zookeeper.ZooKeeperClientTimeoutException: Timed out waiting for connection while in state: CONNECTING
        at kafka.zookeeper.ZooKeeperClient.$anonfun$waitUntilConnected$3(ZooKeeperClient.scala:258)
        at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
        at kafka.utils.CoreUtils$.inLock(CoreUtils.scala:253)
        at kafka.zookeeper.ZooKeeperClient.waitUntilConnected(ZooKeeperClient.scala:254)
        at kafka.zookeeper.ZooKeeperClient.<init>(ZooKeeperClient.scala:112)
        at kafka.zk.KafkaZkClient$.apply(KafkaZkClient.scala:1826)
        at kafka.admin.TopicCommand$ZookeeperTopicService$.apply(TopicCommand.scala:280)
        at kafka.admin.TopicCommand$.main(TopicCommand.scala:53)
        at kafka.admin.TopicCommand.main(TopicCommand.scala)

và tôi nên sử dụng zookeeper:2181thay vì --zookeeper localhost:2181theo tập tin soạn thảo của tôi

## this might be an option, but as per comment below not all zookeeper images can have this script included
docker exec zookeper1 kafka-topics --zookeeper localhost:2181 --alter --topic mytopic --config retention.ms=1000

lệnh chính xác sẽ là

docker exec broker1 kafka-configs --zookeeper zookeeper:2181 --alter --entity-type topics --entity-name dev_gdn_urls --add-config retention.ms=12800000

Hy vọng nó sẽ tiết kiệm thời gian của ai đó.

Ngoài ra, hãy lưu ý rằng các tin nhắn sẽ không bị xóa ngay lập tức và nó sẽ xảy ra khi đoạn nhật ký sẽ bị đóng.


Bạn có thể thực hiện vào môi giới tốt. Vấn đề là localhost:2181... Ví dụ: Bạn đang hiểu nhầm các tính năng mạng Docker. Ngoài ra, không phải tất cả các container Zookeeper đều có kafka-topics, vì vậy tốt nhất không nên sử dụng theo cách đó. Cài đặt Kafka mới nhất cho phép --bootstrap-serversthay đổi một chủ đề thay vì--zookeeper
OneCricketeer

1
Tuy nhiên, thực hiện vào container Zookeeper có vẻ sai. you can use --zookeeper zookeeper: 2181` từ container Kafka là quan điểm của tôi. Hoặc thậm chí grep ra dòng Zookeeper từ tệp server.properations
OneCricketeer

@ cricket_007 này, cảm ơn vì điều này thực sự, tôi đã sửa câu trả lời, cho tôi biết nếu có gì đó vẫn còn sai ở đó
Vladimir Semashkin

1

Không thể thêm dưới dạng nhận xét vì kích thước: Không chắc chắn điều này có đúng không, ngoài việc cập nhật retained.ms và retained.bytes, nhưng tôi nhận thấy chính sách dọn dẹp chủ đề nên là "xóa" (mặc định), nếu "compact", nó sẽ giữ tin nhắn lâu hơn, nghĩa là, nếu nó "nhỏ gọn", bạn cũng phải chỉ định xóa.retention.ms .

./bin/kafka-configs.sh --zookeeper localhost:2181 --describe --entity-name test-topic-3-100 --entity-type topics
Configs for topics:test-topic-3-100 are retention.ms=1000,delete.retention.ms=10000,cleanup.policy=delete,retention.bytes=1

Cũng phải theo dõi các lần bù sớm nhất / muộn nhất phải giống nhau để xác nhận điều này xảy ra thành công, cũng có thể kiểm tra du -h / tmp / kafka-log / test-topic-3-100- *

./bin/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list "BROKER:9095" --topic test-topic-3-100 --time -1 | awk -F ":" '{sum += $3} END {print sum}' 26599762

./bin/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list "BROKER:9095" --topic test-topic-3-100 --time -2 | awk -F ":" '{sum += $3} END {print sum}' 26599762

Vấn đề khác là, bạn phải có cấu hình hiện tại trước để bạn nhớ hoàn nguyên sau khi xóa thành công: ./bin/kafka-configs.sh --zookeeper localhost:2181 --describe --entity-name test-topic-3-100 --entity-type topics


1

Một cách tiếp cận khác, khá thủ công, để thanh trừng một chủ đề là:

trong môi giới:

  1. dừng môi giới kafka
    sudo service kafka stop
  2. xóa tất cả các tệp nhật ký phân vùng (nên được thực hiện trên tất cả các nhà môi giới)
    sudo rm -R /kafka-storage/kafka-logs/<some_topic_name>-*

trong vườn thú:

  1. chạy giao diện dòng lệnh Zookeeper
    sudo /usr/lib/zookeeper/bin/zkCli.sh
  2. sử dụng zkCli để xóa siêu dữ liệu chủ đề
    rmr /brokers/topic/<some_topic_name>

trong môi giới một lần nữa:

  1. khởi động lại dịch vụ môi giới
    sudo service kafka start

Bạn cần dừng và xóa các tệp khỏi mỗi nhà môi giới bằng một bản sao, điều đó có nghĩa là bạn có thể có thời gian chết của máy khách khi thực hiện việc này
OneCricketeer

1
bạn đã đúng, điều này chỉ cho phép bạn thực sự thấy nơi một số thứ được lưu trữ và quản lý bởi Kafka. nhưng phương pháp vũ phu này chắc chắn không dành cho một hệ thống chạy sản xuất.
Daniel Mor

1
./kafka-topics.sh --describe --zookeeper zkHost:2181 --topic myTopic

Điều này sẽ cung cấp cho retention.mscấu hình. Sau đó, bạn có thể sử dụng lệnh thay đổi ở trên để thay đổi thành 1 giây (và sau đó trở lại mặc định).

Topic:myTopic   PartitionCount:6        ReplicationFactor:1     Configs:retention.ms=86400000

1

Từ Java, sử dụng cái mới AdminZkClientthay vì không dùng nữa AdminUtils:

  public void reset() {
    try (KafkaZkClient zkClient = KafkaZkClient.apply("localhost:2181", false, 200_000,
        5000, 10, Time.SYSTEM, "metricGroup", "metricType")) {

      for (Map.Entry<String, List<PartitionInfo>> entry : listTopics().entrySet()) {
        deleteTopic(entry.getKey(), zkClient);
      }
    }
  }

  private void deleteTopic(String topic, KafkaZkClient zkClient) {

    // skip Kafka internal topic
    if (topic.startsWith("__")) {
      return;
    }

    System.out.println("Resetting Topic: " + topic);
    AdminZkClient adminZkClient = new AdminZkClient(zkClient);
    adminZkClient.deleteTopic(topic);

    // deletions are not instantaneous
    boolean success = false;
    int maxMs = 5_000;
    while (maxMs > 0 && !success) {
      try {
        maxMs -= 100;
        adminZkClient.createTopic(topic, 1, 1, new Properties(), null);
        success = true;
      } catch (TopicExistsException ignored) {
      }
    }

    if (!success) {
      Assert.fail("failed to create " + topic);
    }
  }

  private Map<String, List<PartitionInfo>> listTopics() {
    Properties props = new Properties();
    props.put("bootstrap.servers", kafkaContainer.getBootstrapServers());
    props.put("group.id", "test-container-consumer-group");
    props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

    KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
    Map<String, List<PartitionInfo>> topics = consumer.listTopics();
    consumer.close();

    return topics;
  }

Bạn không cần Zookeeper. Sử dụng AdminClienthoặcKafkaAdminClient
OneCricketeer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.