Edited at

InfluxDBのディスクがいっぱいになったので古いデータを削除した

こんにちは、InfluxDB初心者のかめねこです。

Prometheusでは、RemoteStorageという機能があり、収集したメトリクスを外部に保存することができます。

これ用に、InfluxDBを立てていたのですが、マウントしているディスクがいっぱいになってしまったので、とりあえず最低限の対応ということで不要な古いデータを削除しましたってお話です。


About

今回は作業にあたって、次の記事を参考にしました。

InfluxDBの内部構造入門 パート1 | Yakst


前提



  • 私はInfluxDBの素人です(重要

  • 多分いい方法があったのかもしれません

  • あくまでもとりあえずの対応です

  • PrometheusとInfluxDBともにKubernetes上に展開しています

  • InfluxDBは専有ホストと言う形で展開しています


目標


  • ディスクの空き容量を増やす


背景

PrometheusのRemoteStorage用に使用していたInfluxDBのNodeから、ディスクの空き容量が不足しているというアラートが飛んできました。

ミッションクリティカルでもなかったので、週明けにやろうと思ったのですが、結構進行が早いようで、週末のうちにディスクがフルになりそうでした。

なので、細かいことは週明けにやるとして、とりあえず今はディスクの容量を確保しなければなりません。

本来であれば、Retention Policyを使って自動でデータの削除等を行うのですが、それを忘れてしまっていたようで、デフォルトのポリシーがあたっていました。

デフォルトでは、autogenというポリシーが作成されるのですが、これはデータは永続的に保存されるというものです。

最終的には、正しいポリシーを当てますが、その前にまずは現状回復ということで、古いデータを削除します。


やってみる


状態の確認

とりあえずPodにexecしてディスクの容量を見てみます。

root@influxdb-green-cdfb77948-d2tk9:/# df -h | grep influx

/dev/vdb 98G 83G 11G 89% /var/lib/influxdb

90%近くを消費しているようです。

最初に思いついたのは、特定の日付より前のデータをまとめてDropすることでした。

InfluxDBは時系列データベースなので、全てのSeriesに対して必ずタイムスタンプが存在します。


InfluxDBのデータベースはポイント(point)を保存します。ポイントは4つの要素から構成されます。メジャメント(measurement)、タグセット(tagset)、フィールドセット(fieldset)、そしてタイムスタンプ(timestamp)です。


なので、それっぽいクエリを投げてあげれば簡単に削除できるのではないかと思ったのですが、そもそもデータベース内には大量のmeasurementが存在するため、それら一つ一つに対してクエリを投げる必要がありました。

データベース内の全てのmeasurementに対してクエリを投げるようなことができれば良かったのですが、ド素人なのでそんなことは知りません。

そこで「もしかして時系列データベースということは、各ディレクトリも時系列に保存されているのでは…?」と思い、調べてみることに。

すると、まさにビンゴでした。


具体的には、データベースは次の物理配置でディスク上にデータを作成します。

'' Database director  /db

'' Retention Policy directory /db/rp
'' Shard Group (time bounded). (Logical)
'' Shard directory (db/rp/Id#)
'' TSM0001.tsm (data file)
'' TSM0002.tsm (data file)
'' …

これを元に、ディレクトリを移動してみます。

/var/lib/influxdb/data/prometheus/autogenが該当のディレクトリのようです。

/var/lib/influxdbがPod側でマウントしているディレクトリ

data/がデータが格納されているディレクトリ

prometheus/がデータベース名

autogenがRetentionPolicy名という感じです。

その下には、次のようなディレクトリがありました。

root@influxdb-green-cdfb77948-d2tk9:/var/lib/influxdb/data/prometheus/autogen# ls -la 

total 20
drwx------ 5 root root 4096 Sep 9 00:00 .
drwx------ 5 root root 4096 Sep 14 11:17 ..
drwxr-xr-x 3 root root 4096 Sep 2 13:07 1
drwxr-xr-x 3 root root 4096 Sep 14 12:18 17
drwxr-xr-x 3 root root 4096 Sep 9 04:40 9

各ディレクトリのタイムスタンプを見る限り、ファイル名の若い順に古いデータのようです。

ディレクトリごとの容量も見てみます。

root@influxdb-green-cdfb77948-d2tk9:/var/lib/influxdb/data/prometheus/autogen# du -h -d 1

22G ./17
24G ./9
23G ./1
68G .

とりあえず1のディレクトリを削除すれば週明けまでは問題なさそうです。

しかし、ディレクトリを直接削除しても問題ないのでしょうか?

メタ情報と整合性が取れなってしまう可能性もありますが、記事を見てみると、問題なさそうです。


列指向ストレージからポイントを削除するのは高コストですので、InfluxDBでは列指向の形式を時間で区切ったチャンクとして再構成しています。保存期間が過ぎたら永続化されたデータに対して大規模な更新処理をする必要はなく、ファイルシステム上から時間で区切られたファイルがただ単に削除されます。


つまり、RetentionPolicyでの削除処理は、ファイルシステム上でファイルを削除するのと変わらないとのことです。

ということで、対象のディレクトリを削除してみましょう。


削除してみる

ディレクトリの削除が問題ないとのことなので、早速やってみましょう。

ディレクトリを削除します。

root@influxdb-green-cdfb77948-d2tk9:/var/lib/influxdb/data/prometheus/autogen# rm -rf 1

ディスクの容量が減ったか確認してみます。

root@influxdb-green-cdfb77948-d2tk9:/# df -h | grep influx

/dev/vdb 98G 83G 11G 89% /var/lib/influxdb

おや…?

どうやら容量は変化していません。

これは、Linuxのファイルシステムの問題で、プロセスが利用しているディレクトリやファイルを削除しても、lsなどでは消えたように見えても、実は消えていないということのようです。

では、どうしたら消えるのかというと、単純にプロセスを再起動すればOKです。

つまり、Podを削除すればOKです。

今回は、複数のInfluxDBを構築し、それぞれにPrometheusから接続していたので、片側ずつ落とせば問題ありません。

root@influxdb-green-cdfb77948-d2tk9:/var/lib/influxdb/data/prometheus/autogen# exit

exit
command terminated with exit code 130
> kubectl delete pod influxdb-green-cdfb77948-d2tk9
pod "influxdb-green-cdfb77948-d2tk9" deleted

Podが再作成されたので、再びexecして確認してみます。

k exec -it influxdb-green-cdfb77948-w24c4 bash                                                                                                                                  [00:37:49]

root@influxdb-green-cdfb77948-w24c4:/# df -h | grep influx
/dev/vdb 98G 60G 34G 64% /var/lib/influxdb

無事容量が減っていました!

続けて、正常にクエリが実行できるかも確認してみます。

root@influxdb-green-cdfb77948-w24c4:/# influx

Connected to http://localhost:8086 version 1.7.7
InfluxDB shell version: 1.7.7
> use prometheus
Using database prometheus
> show measurements
name: measurements
name
----
ALERTS
ALERTS_FOR_STATE
APIServiceOpenAPIAggregationControllerQueue1_adds
APIServiceOpenAPIAggregationControllerQueue1_depth
APIServiceOpenAPIAggregationControllerQueue1_longest_running_processor_microseconds
APIServiceOpenAPIAggregationControllerQueue1_queue_latency
APIServiceOpenAPIAggregationControllerQueue1_queue_latency_count
APIServiceOpenAPIAggregationControllerQueue1_queue_latency_sum
APIServiceOpenAPIAggregationControllerQueue1_retries
APIServiceOpenAPIAggregationControllerQueue1_unfinished_work_seconds
APIServiceOpenAPIAggregationControllerQueue1_work_duration
APIServiceOpenAPIAggregationControllerQueue1_work_duration_count
APIServiceOpenAPIAggregationControllerQueue1_work_duration_sum
APIServiceRegistrationController_adds
APIServiceRegistrationController_depth

measurementsの一覧が問題なく取得できていますね

適当にクエリを実行してみます。

select * from up limit 2

name: up
time __name__ app app_kubernetes_io_instance app_kubernetes_io_name category chart cluster container_name endpoint heritage hostname instance istio istio_mixer_type job mentionID namespace node node_ip object_storage_cluster object_storage_env pod pod_name pod_phase pod_ready pod_template_hash prometheus prometheus_replica release service target value
---- -------- --- -------------------------- ---------------------- -------- ----- ------- -------------- -------- -------- -------- -------- ----- ---------------- --- --------- --------- ---- ------- ---------------------- ------------------ --- -------- --------- --------- ----------------- ---------- ------------------ ------- ------- ------ -----
1568450954073000000 up influxdb-green 10.233.123.211:8086 influxdb-green monitoring influxdb-green-cdfb77948-rptbs monitoring/k8s prometheus-k8s-0 influxdb-green 1
1568450960170000000 up prometheus-k8s web 10.233.77.129:9090 prometheus-k8s monitoring prometheus-k8s-0 monitoring/k8s prometheus-k8s-0 prometheus-k8s 1
>

めちゃくちゃ横に長いですが、問題なくクエリも実行でき、結果が帰ってきました。


終わりに

このあとめちゃくちゃRetentionPolicy適用した