So-net無料ブログ作成

インフラエンジニアのためのHadoop情報 ログの切捨て [Hadoop]

Hadoopはlog4jを使って、大量のログを生成しています。連日ジョブを走らせている
ような環境では、NameNodeのログ領域はGバイト単位で肥大化してディスクを圧迫します。
ログの出力ディレクトリをシステム領域と共有している場合などは、ディスク残容量
不足でシステムトラブルの原因にもなりえます。
見落としがちですが、ログの管理もやっておきましょう。
ローテーションについては、Hadoopがやってくれているので、不要なログを抑制して
不要になった古いログは削除するようにします。
ログの抑制についてですが、CDHを使う限りHDFSへのアクセスにパーミッションを設定して
はいないので、HDFSへの監査ログは不要と思われます。
しかも、この監査ログがHDFSへのアクセスの度に記録されるので、肥大化の原因になって
ます。
log4j.properties中に定義されている「SNamesystem Audit logging」をデフォルトの
INFO(全て)からWARNに切り替えます。
以下の行をlog4j.propertiesに追加します。
log4j.logger.org.apache.hadoop.hdfs.server.namenode.FSNamesystem.audit=WARN

ちなみに、log4j.propertiesのコメント中には、
#log4j.logger.org.apache.hadoop.fs.FSNamesystem.audit=WARN

の記述がありますが、これを設定してもログに変化は見られませんでした。
次に、古いログを削除しましょう。
例えば、以下のようなスクリプトを/etc/cron.dailyに作成しておき、指定した日にちが
経過したログは削除するようにします。
#!/bin/bash
# 15日前のHadoopログを削除する。
CDATE=15
LOGS=/var/log/hadoop-0.20
/bin/rm -r `find $LOGS -ctime +$CDATE`


インフラエンジニアのためのHadoop情報 CDH2のアップデート [Hadoop]

Cloudera版のCDH2パッケージは、不定期にマイナーバージョンアップをしているようです。
ここでは、CDH2のバージョンアップ方法について書いておきます。
但し、HDFSのレイアウト変更を伴うようなメジャーバージョンのアップについては、それぞれ
の版ごとに注意事項があるはずなので、それらについてはここでは触れません。
Hadoopのアップデートで気をつけなければいけない点は、以下のとおり。
複数ノードで運用中、1台づつアップグレードすることができません。たとえマイナーバージョンアップといえども、NameNodeとDataNodeの間でバージョン番号のチェックが行われて、アップデートしたノードは古いバージョン
のクラスタに登録できないからです。
もう一点は、一度新しいバージョンでサービスを起動すると、たとえHadoopサービスを前の
バージョンに戻しても、起動しなくなります。新しいバージョンの起動時にローカルのデータ
ストアにバージョン番号が書き込まれているようです。
そういう理由で、バージョンアップはクラスタ全体を停止して、いっぺんに全てのノードを
アップデートする必要があります。
きちんと計画的に実施しましょう。
作業の前には、fsckコマンドを実施してHDFSが健全な状態であることを確認します。
$ hadoop fsck /
 :
The filesystem under path '/' is HEALTHY

Hadoopの全ノードを停止します。
停止順は、NameNode、JobTracker、DataNode、TaskTracker、SecondaryNameNodeです。
サービスの停止が確認できたら、yumコマンドでアップデートを実施します。
$ sudo yum install hadoop
   :
================================================= ======================================
 Package                    Arch        Version               Repository          Size
================================================= ======================================
Updating:
 hadoop-0.20               noarch      0.20.1+169.113-1      cloudera-cdh2       21 M
Updating for dependencies:
 hadoop-0.20-conf-pseudo    noarch      0.20.1+169.113-1      cloudera-cdh2       10 k

Transaction Summary
================================================= ======================================
Install       0 Package(s)
Upgrade       2 Package(s)

Total download size: 21 M
Is this ok [y/N]: y

無事バージョンがあがっているこを確認します。(必ず起動前に)
$ hadoop version
Hadoop 0.20.1+169.113
Subversion  -r 6c765a47a9291470d3d8814c98155115d109d715
Compiled by root on Sun Sep 12 01:29:03 EDT 2010

全てのノードでアップデートが完了したら、全ノードを起動します。
起動順は、停止順と同じです。



インフラエンジニアのためのHadoop情報 PuppetとHadoop [Hadoop]

Hadoopでは、各ノードの設定ファイルを基本的に同一にしておく必要があります。
(ローカル特有な設定は除く)
クラスタに係わる設定を変更したい時は、全てのノードの設定ファイルを変更しなければ
いけないので、大変です。
しかも、Cloudera版Hadoopは全てのノードのサービスを再起動する必要もあります。
Hadoopクラスタ内のどこか1台をマスタにして、他のホストと設定を同期するようにしましょう。使用するのは、システム管理ツールとして知られるPuppet。
Puppetのインストールと基本設定については、
http://gihyo.jp/admin/serial/01/puppet
に詳しく紹介されているので、参考にしてインストールします。
ここでは、Hadoopの設定ファイル同期について紹介します。
puppetにはpushモードとpullモードがあります。
pullモードは、各ノードが30分おきにサーバへ同期をとりにいきます。
Hadoopの設定ファイルをそんなに頻繁に書き換えることは無いだろうし、再起動のからみも
あるので、ここはpushモードにします。
マスタとしてインストールしたPuppetのあるノードで、Hadoopの設定ファイルを書き換えたら
その都度、手動でpuppetrunコマンドで同期します。
site.ppの設定は、
$path = '/etc/hadoop-0.20/conf.cluster'
file { $path:
       source  => 'puppet://srv1.example.com/hadoop/conf.cluster',
       recurse => true,
}

fileserver.confには、
[hadoop]
       path /etc/hadoop-0.20
       allow [Hadoopノードのアドレス]

allowの指定にはワイルドカードが使えるので、全ノードを指定します。
同期される側の各ノードの設定は、namespaceauth.confに
[puppetrunner]
       allow [マスタサーバのアドレス]

とします。
各ノード側のPuppetの起動時には、puppetrun待ちのオプション「--listen --no-client」を
付けます。
例)
$ /usr/sbin/puppetd --server [マスタサーバのアドレス] --listen --no-client

Hadoopの設定ファイルを更新後、同期を実施するには
$ sudo /usr/bin/puppetrun --host [Hadoopノードのアドレス]

とすれば、マスタサーバでの変更がノードの設定ファイルにも反映されます。
このままでは、設定ファイルが書き換わるだけで、再起動をしていないノードのHadoopには反映
されません。
そこで、同期と同時にノード側のHadoopサービスを再起動させましょう。
site.ppに以下の設定を追加します。
exec { '/etc/init.d/hadoop-0.20-datanode restart':
        subscribe => File['/etc/hadoop-0.20/conf.cluster'],
        refreshonly => true
}
exec { '/etc/init.d/hadoop-0.20-tasktracker restart':
        subscribe => File['/etc/hadoop-0.20/conf.cluster'],
        refreshonly => true
}

こうすると、設定ファイルのあるディレクトリ以下のファイルが更新されていたらDataNodeと
TaskTrackerのサービスが再起動されます。

実際の運用を想定したサンプルを以下に置いておきます。
https://github.com/so-net-developer/Hadoop/tree/master/puppet/
Puppet自身を含めた設定ファイルの同期と、サービスの再起動、ノードの追加が自動化されます。

インフラエンジニアのためのHadoop情報 Gangliaその2 [Hadoop]

Hadoopノード側のGangliaのインストールです。JMXメタデータを採取する側です。
ライブラリのインストール。
$ sudo yum install libconfuse
$ sudo yum install rrdtool

前回作ったrpmパッケージをインストール。
$ sudo rpm -ivh ganglia-3.1.7-1.i386.rpm

起動スクリプトは、監視サーバのものをコピー。
$ sudo cp gmond /etc/init.d/

設定ファイルも監視サーバのものをコピー。
$ cp gmond.conf /etc/ganglia/

起動します。
$ sudo /sbin/service gmond start

Gangliaはデフォルトではマルチキャストで監視側と通信するので、Ganglia監視サーバ
が同一セグメントにいれば、これでノード側のサーバ情報はグラフで見れるようになる
はずです。
無事動いたところで、本題のHadoopのJMXデータを拾います。
Cloudera版のHadoopは設定ファイル「hadoop-metrics.properties」の中にGangliaContext
が定義されています。今回は、ganglia-3.1.7なので、GangliaContext31を有効にします。
dfs.class=org.apache.hadoop.metrics.ganglia.GangliaContext31
dfs.period=10
dfs.servers=[Ganglia監視側ホストのIP]:8649
mapred.class=org.apache.hadoop.metrics.ganglia.GangliaContext31
mapred.period=10
mapred.servers=[Ganglia監視側ホストのIP]:8649
jvm.class=org.apache.hadoop.metrics.ganglia.GangliaContext31
jvm.period=10
jvm.servers=[Ganglia監視側ホストのIP]:8649

サービスを再起動します。
$ sudo /sbin/service hadoop-0.20-datanode restart
$ sudo /sbin/service hadoop-0.02-tasktracker restart

しばらくすると、gangliaの画面にJMXの情報が表示されます。

インフラエンジニアのためのHadoop情報 Gangliaその1 [Hadoop]

これまではHadoopの死活監視が目的のNagios設定を見てきましたが、HadoopはJMX
を通してメモリ使用状況、ジョブ(MapReduce)の進行状況を詳細に見ることができます。
このJMXの値を、Gangliaというグラフ表示の監視ツールを使って可視化しましょう。
ジョブの投入状況に合わせて、メモリやCPUの利用率が各ノード毎にグラフ化されて
見えるので、ボトルネックの発見に役立つはずです。
Gangliaのインストールは終わっているものとして・・・としたいところですが
Nagiosと違って、Hadoopの各ノード側全てにインストールしなければいけないので
ちょっと面倒。
rpmパッケージを作って、各ノードに配布しちゃいましょう。
まずは、Ganglia監視サーバ側を作成。
rpm化にはcheckinstallを使います。あらかじめインストールしておきます。
ビルドに必要なものを片っ端からインストール。
$ sudo yum install rpm-build
$ sudo yum install checkinstall
$ sudo yum install libconfuse
$ sudo yum install libconfuse-devel
$ sudo yum install rrdtool
$ sudo yum install rrdtool-devel
$ sudo yum install gcc
$ sudo yum install apr-devel
$ sudo yum install expat-devel
$ sudo yum install pcre-devel
$ sudo yum install php
$ sudo yum install php-gd
$ sudo yum install httpd

次にGangliaのサイトから「ganglia-3.1.7.tar.gz」を取得してきてビルド。
$ tar xvf ganglia-3.1.7.tar.gz
$ cd ganglia-3.1.7
$ ./configure --with-gmetad --sysconfdir=/etc/ganglia
$ make
$ sudo /usr/sbin/checkinstall

出来上がった「ganglia-3.1.7-1.i386.rpm」をインストール。
$ sudo rpm -ivh ganglia-3.1.7-1.i386.rpm

このあと、設定ファイル、作業ディレクトリ作成、パーミッション設定、起動スクリプト作成
その他いろいろしないと起動しないのですが、これらもrpm化したパッケージを作ったので
それで早道しちゃいます。

http://github.com/so-net-developer/Hadoop/blob/master/tools/ganglia-conf-1.0-0.noarch.rpm

rpm化に使ったSPECファイルも置いておくので、何をやっているかはこれを見てください。

http://github.com/so-net-developer/Hadoop/blob/master/tools/ganglia-conf-1.0.spec

$ sudo rpm -ivh ganglia-conf-1.0-0.noarch.rpm

Ganglia監視サーバの起動。
$ sudo /sbin/service gmetad start
$ sudo /sbin/service gmond start
$ sudo /sbin/service httpd start

参考までに、SPECファイルを使ってganglia-conf-1.0-0.noarch.rpmを作る方法を書いて
おきます。
まず、下に示すようなディレクトリを作り、ファイルを配置します。設定ファイルや起動
スクリプトもgangliaのソースを展開すると見つかるので、環境に合わせて修正したものを
配置します。
|-- ganglia-conf-1.0
|   |-- etc
|   |   |-- ganglia                 ←ganglia(gmond)用設定ファイル
|   |   |   `-- gmond.conf
|   |   `-- init.d                  ←gangliaの起動スクリプト
|   |       |-- gmetad
|   |       `-- gmond
|   `-- var
|       `-- www
|           `-- html
|               `-- ganglia         ←gangliaのソース中にあるwebディレクトリ以下全部
|                   |-- index.php
|                   |-- 省略
|                   `-- version.php.in
`-- rpm
    |-- BUILD
    |-- RPMS
    |-- SOURCES
    |-- SPECS
    |   `-- ganglia-conf-1.0.spec
    `-- SRPMS

そして、homeディレクトリに上に示したrpmディレクトリを示すファイル「.rpmmacros」
を作ります。
$ echo "%_topdir /home/so-net/rpm" > .rpmmacros

そして、以下のようにtarファイルをSOURCES以下に作成します。
$ tar czvf rpm/SOURCES/ganglia-conf-1.0.tar.gz ganglia-conf-1.0

最後にrpmbuildコマンドでspecファイルを指定すればrpm/RPMS以下にrpmファイルが作られます。
$ rpmbuild -ba rpm/SPECS/ganglia-conf-1.0.spec

次回は、Hadoopノード側のインストール。

インフラエンジニアのためのHadoop情報 状態監視その2 [Hadoop]

TaskTrackerもDataNodeと同じように監視できます。
JobTrackerのWebUI(http://[JobTrackerのIP]:50030/jobtracker.jsp)画面中に表示されている
TaskTrackerのノード数を確認することで監視を行います。
チェックプログラムはこちら。

http://github.com/so-net-developer/Hadoop/blob/master/scripts/check_hadoop-task.pl
http://exchange.nagios.org/directory/Plugins/Others/check-Hadoop-tasktrackers/details

commands.cfgはこうなる。
define command {
       command_name  check_remote_tasktracker
       command_line   /usr/local/bin/check_hadoop-task.pl $HOSTADDRESS$ $ARG1$ $ARG2$
       }

ARG1、ARG2はDataNodeのときと同じ。
services.cfgの例は
define service {
       use             generic-service
       host_name       [JobTrackerホスト名]
       service_description     check_remote_tasktracker
       contact_groups                  admins
       check_command   check_remote_tasktracker!15!13
       }


SecondaryNameNodeの稼動状況の確認は、ステータスを確認する機能が見当たらないので、
メタデータファイルの更新状況を確認して判断します。
ファイルの更新は、SecondaryNameNode内で行われるので、Nagiosサーバからそれを直接見に
いくことができません。そこでNagios用nrpeの登場です。
監視対象のSecondaryNameNode側にnrpeを設定してNagiosサーバに通知してもらいます。
SecondaryNameNodeへのnrpeのインストール、基本設定は済ませてください。
メタデータファイルの更新状況を確認するスクリプトを以下に挙げておきます。

http://github.com/so-net-developer/Hadoop/blob/master/scripts/secondarynamenode_check.sh
http://exchange.nagios.org/directory/Plugins/Others/check-Hadoop-secondarynamenode/details

120分以上更新されていないファイルが見つかったら、SecondaryNameNodeのチェックポイントに
異常が発生しているとみなして、アラートを発します。
SecondaryNameNode上のnrpeの設定ファイルnrpe.cfgに以下の行を追加する。
command[check_checkpoint]=/usr/local/bin/secondarynamenode_check.sh

そして、Nagios側のcommands.cfgはこうなる。
define command {
       command_name    check_nrpe_secondarynamenode
       command_line    $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$
       }

ARG1には、nrpeコマンドの識別子「check_checkpoint」を代入するので、services.cfgの例は
define service {
       use             generic-service
       host_name       sdh02
       service_description     check_nrpe_secondarynamenode
       contact_groups                  admins
       check_command   check_nrpe_secondarynamenode!check_checkpoint
       }


Nagios監視の最後にHadoopのHDFSについてです。HadoopのHDFSは、付属ツールの
「hadoop fsck」コマンドを実行すると、HDFSブロックの整合性やレプリケーションの状態、
DataNode数などが表示されます。
実行例)
$ hadoop fsck /
Total size:    2235588327935 B
Total dirs:    127
Total files:   454
Total blocks (validated):      33584 (avg. block size 66567065 B)
Minimally replicated blocks:   33584 (100.0 %)
Over-replicated blocks:        0 (0.0 %)
Under-replicated blocks:       0 (0.0 %)
Mis-replicated blocks:         0 (0.0 %)
Default replication factor:    3
Average block replication:     3.001608
Corrupt blocks:                0
Missing replicas:              0 (0.0 %)
Number of data-nodes:          16
Number of racks:               1


The filesystem under path '/' is HEALTHY

最後の行に、「HEALTHY」と出てくると安心します。
どうせだから、これもNagiosで監視してしまいましょう。
nrpeでコマンドを起動し、「HEALTHY」が表示されなければ、アラートをあげるようにします。
nrpeでfsckコマンドを起動して、「HEALTHY」表示を確認するチェックスクリプトはこちら。

http://github.com/so-net-developer/Hadoop/blob/master/scripts/check_hdfs.sh
http://exchange.nagios.org/directory/Plugins/Others/check-Hadoop-HDFS-healthy/details

(hadoopコマンドにパスが通っていること、HDFSブロック数が非常に多いとnrpeのタイムアウトに注意)

nrpeはPrimaryNameNodeで動かします。(そこでしかfsckが通らないから)
nrpeの設定ファイルnrpe.cfgに以下を追加。
command[check_hdfs]=/usr/local/bin/check_hdfs.sh

Nagiosサーバ側の設定もいつものように。
commands.cfg
define command {
       command_name    check_nrpe_hdfs
       command_line    $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$ -t 30
       }

services.cfg
define service {
       use             generic-service
       host_name       sdh01
       service_description     check_nrpe_hdfs
       contact_groups                  admins
       check_command   check_nrpe_hdfs!check_hdfs
       }


インフラエンジニアのためのHadoop情報 状態監視その1 [Hadoop]

Hadoopを運用するノードもそれなりの台数になってくると、ノードの稼動状態を監視する
必要が出てきます。10台以上にもなるとそれぞれにログインしてプロセスを確認するのも
かなり面倒です。
ここでは、監視ツールとしてポピュラーな「Nagios」を使って、Hadoopノードを監視する
方法について書いておきます。
使うのは「check_http」コマンドです。このコマンドは、指定ポートに接続してhttpを
getして、得られるレスポンス文字列を調べて状態を判定します。
これを使ってHadoopの各サービスの状態を見てみましょう。
NameNode用のWebUI(http://[NameNodeのIP]:50070/dfshealth.jsp)には、レスポンス中に
「NameNode」の文字列が入っています。
この文字列を取得できたら、少なくともNameNodeは止まってはいないと判断できます。
このチェックを実現するNagiosのcommands.cfgの設定は以下のようになります。
define command {
       command_name  check_remote_namenode
       command_line   $USER1$/check_http -H $HOSTADDRESS$ -u http://$HOSTADDRESS$:$ARG1$/dfshealth.jsp -p $ARG1$ -r NameNode
       }

引数ARG1にはポート番号50070が入るので、service.cfgは以下のようになる。
define service {
       use             generic-service
       host_name       [NameNodeホスト名]
       service_description     check_remote_namenode
       contact_groups                  admins
       check_command   check_remote_namenode!50070
       }

JobTrackerも同じようにチェックできます。こちらは、「Map/Reduce」という文字列をチェック。
define command {
       command_name  check_remote_jobtracker
       command_line   $USER1$/check_http -H $HOSTADDRESS$ -u http://$HOSTADDRESS$:$ARG1$/jobtracker.jsp -p $ARG1$ -r Map/Reduce
       }

define service {
       use             generic-service
       host_name       [JobTrackerホスト名]
       service_description     check_remote_jobtracker
       contact_groups                  admins
       check_command   check_remote_jobtracker!50030
       }

DataNodeを監視したい場合は、各ノードにはWebUIが無いので、NameNodeの
WebUI(http://[NameNodeのIP]:50070/dfshealth.jsp)の画面から、稼動中の台数を示す文字列を
拾ってチェックします。
チェックプログラムはこちら。

http://github.com/so-net-developer/Hadoop/blob/master/scripts/check_hadoop-dfs.pl
http://exchange.nagios.org/directory/Plugins/Others/check-Hadoop-datanodes/details

commands.cfgはこうなる。
define command {
       command_name  check_remote_datanode
       command_line   /usr/local/bin/check_hadoop-dfs.pl $HOSTADDRESS$ $ARG1$ $ARG2$
       }

ARG1、ARG2にはDataNodeの台数を指定し、それぞれ指定台数を下回る(ノード停止)と
「WARNING」、「CRITICAL」のアラートを発生する。
services.cfgの例は
define service {
       use             generic-service
       host_name       [NameNodeホスト名]
       service_description     check_remote_datanode
       contact_groups                  admins
       check_command   check_remote_datanode!15!13
       }

となり、この場合は稼動しているDataNodeの台数が15台以下になると「WARNING」アラートが、
13台以下になると、「CRITICAL」アラートが出る。


インフラエンジニアのためのHadoop情報 障害復旧のために [Hadoop]

これまでの障害復旧の話で分かるように、Hadoopの障害復旧には、NameNodeのメタデータが
きちんとバックアップされて、いつでも復旧のために使えることが大事です。
ここで少しメタデータついて記しておきます。
HadoopのNameNodeメタデータとは、ファイルシステムに関する情報のことで、通常はNameNode
のメモリ上にあり、チェックポイントごとに編集ログと同期されて、専用のファイルに記録
されます。
専用のファイルとは、edits、fsimage、fstimeの3つあり、それぞれ編集ログ、ファイル情報
チェックポイント時刻情報となります。
editsファイルはファイルへの操作が発生するたびログが記録され、どんどん大きくなって
いきます。editsファイルのログをファイル情報であるfsimageに適用するのは、Secondary
NameNodeの仕事です。PrimaryNameNodeがfsimageを更新するのは、再起動のときだけです。
SecondaryNameNodeは(デフォルトで)1時間おきのチェックポイントでPrimaryNameNodeから
edits,fsimageを取得して、edits中の編集ログをfsimageへ適用し、PrimaryNameNodeへ返却
します。その際、適用済みファイルをSecondaryNameNodeの所定のディレクトリにコピーされ
ます。
このコピーされたedits、fsimage、fstimeの3つのファイルを定期的に他のディレクトリなり
他のホストへ退避しておくと良いでしょう。退避するときには以前のファイルを履歴として
保存するようにしておけば、ある程度任意の時点のファイル構造へ戻すことができます。
参考までに、SendondaryNameNodeのチェックポイント適用済みファイルを指定ディレクトリへ
退避するバッチファイルを挙げておきます。

http://github.com/so-net-developer/Hadoop/blob/master/scripts/nmbackup.pl

インフラエンジニアのためのHadoop情報 障害復旧その2 [Hadoop]

PrimaryNameNodeの障害が取り除けず、サーバをあきらめてSecondaryNameNodeをPrimary
として入れ替える場合の手順を紹介します。
この場合は、クラスタ中のホストが指し示していたプライマリNameNodeのアドレスを、これまで
SecondaryNameNodeだったアドレスに切り替えます。手順を以下に示します。セカンダリをプラ
イマリに昇格するイメージです。
PrimaryNameNodeは停止しているものとする。(停止していない場合は停止する)
$ sudo /sbin/service hadoop-0.20-namenode stop

SecondaryNameNodeを停止します。
$ sudo /sbin/serivce hadoop-0.20-secondarynamenode stop

チェックポイントのメタデータをNameNodeのメタデータとしてコピーする。
$ cd /var/lib/hadoop-0.20/cache/hadoop/dfs/name/current
$ sudo cp ../../namesecondary/previous.checkpoint/* .

NameNodeのアドレスを変更する。(srv2.example.comが新しいPrimaryNameNode)
$ sudo vi /etc/hadoop-0.20/conf/core-site.xml

 
   fs.default.name
   hdfs://srv1.example.com:8020
 
   ↓
 
   fs.default.name
   hdfs://srv2.example.com:8020
 

新プライマリNameNodeとして起動する。
$ sudo /sbin/service hadoop-0.20-namenode start

他のデータノードでも、新プライマリNameNodeのアドレスを参照するように変更する。
全てのデータノードで以下の設定を変更します。
$ sudo vi /etc/hadoop-0.20/conf/core-site.xml

 
   fs.default.name
   hdfs://srv1.example.com:8020
 
   ↓
 
   fs.default.name
   hdfs://srv2.example.com:8020
 

$ sudo /sbin/service hadoop-0.20-datanode restart

DataNodeの起動直後に、fsckコマンドを実行すると「Under replicate」のエラーが出
ます。しばらくすると再配置が行われ、エラーは解消します。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。

×

この広告は1年以上新しい記事の更新がないブログに表示されております。