ksqlDB に関する問題のトラブルシューティング¶
このガイドには、 ksqlDB に関する多くの問題に対処するトラブルシューティングの情報を記載しています。
SELECT クエリが停止しない¶
ksqlDB ストリーミングクエリは、明示的に停止させる必要があります。CLI で、Ctrl + C を使用して非永続的なクエリ(SELECT * FROM myTable EMIT CHANGES
など)を停止させます。CREATE STREAM AS SELECT
または CREATE TABLE AS SELECT
により作成された永続的なクエリを停止させるには、TERMINATE ステートメントの TERMINATE query_id;
を使用します。詳細については、「TERMINATE」を参照してください。
SELECT クエリが結果を返さない¶
ksqlDB のクエリが結果を返さず CLI がハングする場合は、 Ctrl + C
を使用してクエリを停止させた後、以下のトピックを確認して問題を診断します。
クエリが正しいソーストピックに基づくものであることを検証する¶
DESCRIBE EXTENDED
ステートメントを使用して、ストリームの Apache Kafka® ソーストピックを表示します。たとえば pageviews
という名前の Kafka のトピックに pageviews
というストリームがある場合は、CLI で以下のステートメントを入力します。
DESCRIBE EXTENDED PAGEVIEWS;
出力例は、ソーストピックを示しています。
Name : PAGEVIEWS
[...]
Kafka topic : pageviews (partitions: 1, replication: 1)
ソーストピックにデータが入力されていることを検証する¶
Kafka ソーストピックにデータが入力されていないためにクエリの結果が空である可能性があります。kcat を使用してメッセージを消費し、サマリーをプリントします。
docker run --network ksql-troubleshooting_default --tty --interactive --rm \
confluentinc/cp-kafkacat \
kafkacat -b kafka:39092 \
-C -t pageviews \
-o beginning
出力例は、空のソーストピックを示しています。
% Reached end of topic pageviews [0] at offset 0
ソーストピックに新しいメッセージが到着していることを検証する¶
kcat がメッセージをプリントすると、トピックに入力されます。ただし 新しい メッセージを受信していない可能性はあります。デフォルトでは、ksqlDB はトピックの末尾から読み取ります。トピックに新しいメッセージが書き込まれていなければ、クエリは結果を返しません。
クエリを確認するために、以下のステートメントを使用して auto.offset.reset
プロパティに earliest
を割り当て、ksqlDB がトピックの先頭から読み取るように設定できます。
SET 'auto.offset.reset'='earliest';
出力例は、正しく行われた変更を示しています。
Successfully changed local property 'auto.offset.reset' from 'null' to 'earliest'
もう一度クエリを実行します。トピックの先頭から結果が得られるはずです。なお、クエリが最新のオフセットに到達しても新しいメッセージが到着していなければ、クエリがハングしているように見えることがあります。クエリは、単に次のメッセージを待っているだけです。Ctrl + C
を使用してクエリを停止します。
クエリの述語が限定的でありすぎないことを検証する¶
前述の方法で問題が解決されない場合、クエリの述語が限定的すぎるためにすべてのレコードが除外されている可能性があります。WHERE
句と HAVING
句を削除し、もう一度クエリを実行してください。
逆シリアル化エラーがないことを検証する¶
ksqlDB は、メッセージのデータを逆シリアル化できなければクエリの結果を書き込みません。DESCRIBE EXTENDED
ステートメントを使用して、ストリームの VALUE_FORMAT
が、kcat がトピックについてプリントしたレコードのフォーマットと一致していることを確認します。CLI で以下のステートメントを入力します。
DESCRIBE EXTENDED pageviews;
出力例:
Name : PAGEVIEWS
[...]
Value format : DELIMITED
DELIMITED トピックに関する kcat の出力例は以下のとおりです。
1541463125587,User_2,Page_74
1541463125823,User_2,Page_92
1541463125931,User_3,Page_44
% Reached end of topic pageviews [0] at offset 1538
1541463126232,User_1,Page_28
% Reached end of topic pageviews [0] at offset 1539
1541463126637,User_7,Page_64
% Reached end of topic pageviews [0] at offset 1540
1541463126786,User_1,Page_83
^C
シリアル化エラーについては メッセージ処理の失敗を確認する を確認してください。たとえば、クエリで VALUE_FORMAT
に対して JSON を指定している場合にベースのトピックが JSON フォーマットで生成されていなければ、ksqlDB サーバーログに JsonParseException
という警告が出力されます。以下に例を示します。
[2018-09-17 12:29:09,929] WARN task [0_10] Skipping record due to deserialization error. topic=[_confluent-metrics] partition=[10] offset=[70] (org.apache.kafka.streams.processor.internals.RecordDeserializer:86)
org.apache.kafka.common.errors.SerializationException: KsqlJsonDeserializer failed to deserialize data for topic: _confluent-metrics
Caused by: com.fasterxml.jackson.core.JsonParseException: Unexpected character ((CTRL-CHAR, code 127)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
ksqlDB CLI が ksqlDB サーバーに接続しない¶
CLI を起動すると以下の警告が表示される場合があります。
**************** WARNING ******************
Remote server address may not be valid:
Error issuing GET to KSQL server
Caused by: java.net.SocketException: Connection reset
Caused by: Connection reset
*******************************************
CLI を使用して ksqlDB クエリを作成する際にも同様のエラーが表示される場合があります。
Error issuing POST to KSQL server
Caused by: java.net.SocketException: Connection reset
Caused by: Connection reset
どちらの場合も CLI は ksqlDB サーバーに接続することができません。以下のトピックを確認して問題を診断します。
ksqlDB CLI が正しいポートを使用していること検証する¶
デフォルトでは、サーバーはポート 8088
をリッスンします。詳細については、 |ksqldb| CLI の起動 を参照してください。
ksqlDB サーバーの構成が正しいことを検証する¶
ksqlDB サーバーの構成ファイルで、リスナーのリストにあるホストアドレスとポートが正しく構成されていることを確認します。ファイル内で listeners
の設定を検索し、正しく設定されていることを検証します。
listeners=http://0.0.0.0:8088
または IPv6 経由で実行している場合は以下を確認します。
listeners=http://[::]:8088
詳細については、ksqlDB サーバーの起動 を参照してください。
ポートの競合がないことを検証する¶
ksqlDB サーバーがリッスンしているポートで別のプロセスが実行されている場合があります。以下のコマンドを使用して、ksqlDB サーバーに割り当てられたポートで実行されているプロセスのプロセス ID(PID)を取得します。以下のコマンドでは、デフォルトの 8088
ポートを確認します。
netstat -anv | egrep -w .*8088.*LISTEN
出力例:
tcp4 0 0 *.8088 *.* LISTEN 131072 131072 46314 0
この例では 46314
が、ポート 8088
上でリッスンしているプロセスの PID です。次のコマンドを実行してプロセス 46314
に関する情報を取得します。
ps -wwwp 46314
出力例:
io.confluent.ksql.rest.server.KsqlServerMain ./config/ksql-server.properties
KsqlServerMain
プロセスが表示されていなければ、KsqlServerMain
が通常使用するポートを別のプロセスが使用しています。ksqlDB サーバーの構成ファイルで listeners
の設定を検索し、正しいポートを取得します。正しいポートを使用して CLI を起動します。
詳細については、 ksqlDB サーバーの起動 および ksqlDB CLI の起動 を参照してください。
ウィンドウ化された集約の出力からストリームを作成できない¶
ksqlDB は構造化キーをサポートしていないため、ウィンドウ化された集約からストリームを作成できません。
ksqlDB が内部トピックをクリーンアップしない¶
Kafka クラスターに対して delete.topic.enable=true
が構成されていることを確認します。詳細については、「deleteTopics」を参照してください。
Avro スキーマで複製されたトピックによりエラーが発生する¶
Confluent Replicator は、レプリケーション時にトピックの名前を変更します。関連する Avro スキーマがある場合、レプリケーション完了後にAvro スキーマと名前変更されたトピックとの照合は自動では行われません。
複製されたトピックに対して PRINT
ステートメントを使用すると、Avro スキーマ ID が Schema Registry 内に存在することがわかります。ksqlDB は Avro メッセージを逆シリアル化できますが、CREATE STREAM
ステートメントは正しく動作せず、逆シリアル化エラーが発生します。以下に例を示します。
CREATE STREAM pageviews_original (viewtime bigint, userid varchar, pageid varchar) WITH (kafka_topic='pageviews.replica', value_format='AVRO');
逆シリアル化エラーの出力例は以下のとおりです。
[2018-06-21 19:12:08,135] WARN task [1_6] Skipping record due to deserialization error. topic=[pageviews.replica] partition=[6] offset=[1663] (org.apache.kafka.streams.processor.internals.RecordDeserializer:86)
org.apache.kafka.connect.errors.DataException: pageviews.replica
at io.confluent.connect.avro.AvroConverter.toConnectData(AvroConverter.java:97)
at io.confluent.ksql.serde.connect.KsqlConnectDeserializer.deserialize(KsqlConnectDeserializer.java:48)
at io.confluent.ksql.serde.connect.KsqlConnectDeserializer.deserialize(KsqlConnectDeserializer.java:27)
これを解決するには、複製されたトピックのサブジェクト名に対して Avro スキーマを手動で登録します。以下に例を示します。
# Original topic name = pageviews
# Replicated topic name = pageviews.replica
curl -X POST -H "Content-Type: application/vnd.schemaregistry.v1+json" --data "{\"schema\": $(curl -s http://localhost:8081/subjects/pageviews-value/versions/latest | jq '.schema')}" http://localhost:8081/subjects/pageviews.replica-value/versions
Snappy でエンコードされたメッセージが展開されない¶
/tmp
ディレクトリが noexec
に設定されていて書き込みアクセス権限がない場合は、書き込みアクセス権限があるディレクトリパスを snappy
へ渡す必要があります。
-Dorg.xerial.snappy.tempdir=/path/to/newtmp
メッセージ処理の失敗を確認する¶
ksqlDB クエリの正常性を確認することができます。確認は、処理したメッセージの数を表示し、処理失敗の発生回数をカウントすることにより行います。
DESCRIBE EXTENDED
ステートメントを使用して total-messages
と failed-messages-per-sec
を表示し、メッセージ処理のメトリクスを取得します。なおこのメトリクスは、DESCRIBE ステートメントを実行しているサーバーのみのメトリクスです。
DESCRIBE EXTENDED GOOD_RATINGS;
出力例:
[...]
Local runtime statistics
------------------------
messages-per-sec: 1.10 total-messages: 2898 last-message: 9/17/18 1:48:47 PM UTC
failed-messages: 0 failed-messages-per-sec: 0 last-failed: n/a
(Statistics of the local KSQL server interaction with the Kafka topic GOOD_RATINGS)
failed-messages
の数が増えている場合は、クエリに問題がある可能性があります。処理失敗の主な原因については、 逆シリアル化エラー を参照してください。
ksqlDB のサーバーログを確認する¶
デフォルトでは、ksqlDB は大半のログメッセージを stdout
に書き込みます。
Confluent CLI を使用して ksqlDB サーバーログでエラーを確認します。それには以下のコマンドを使用します。
confluent local services ksql-server log
詳細については、「Confluent CLI」を参照してください。
デフォルトのディレクトリ /usr/local/logs
または CLI 起動時に割り当てた LOG_DIR
にあるログを確認します。詳細については、 ksqlDB CLI の起動 を参照してください。
RPM または Debian パッケージを使用して Confluent Platform をインストールしている場合は、/var/log/confluent/
にログがあります。
Docker を使用して ksqlDB を実行している場合は、コンテナーのログに出力があります。以下はその例です。
docker logs <container-id>
docker-compose logs ksql-server