apt update すると GPG error: The following signatures were invalid になったときにやったこと。
apt update すると GPG error: The following signatures were invalid になったときにやったことのメモ。
apt update すると GPG error: The following signatures were invalid に
MySQL の Docker コンテナで apt update
したら GPG error: The following signatures were invalid
みたいなメッセージが出て update に失敗した。
# apt update Get:1 http://repo.mysql.com/apt/debian stretch InRelease [21.6 kB] Ign:2 http://deb.debian.org/debian stretch InRelease Get:3 http://deb.debian.org/debian stretch-updates InRelease [91.0 kB] Get:5 http://deb.debian.org/debian stretch Release [118 kB] Get:6 http://deb.debian.org/debian stretch Release.gpg [2365 B] Err:1 http://repo.mysql.com/apt/debian stretch InRelease The following signatures were invalid: EXPKEYSIG 8C718D3B5072E1F5 MySQL Release Engineering <mysql-build@oss.oracle.com> Get:4 http://security-cdn.debian.org/debian-security stretch/updates InRelease [94.3 kB] Get:7 http://deb.debian.org/debian stretch-updates/main amd64 Packages [27.9 kB] Get:8 http://deb.debian.org/debian stretch/main amd64 Packages [7086 kB] Get:9 http://security-cdn.debian.org/debian-security stretch/updates/main amd64 Packages [514 kB] Reading package lists... Done W: GPG error: http://repo.mysql.com/apt/debian stretch InRelease: The following signatures were invalid: EXPKEYSIG 8C718D3B5072E1F5 MySQL Release Engineering <mysql-build@oss.oracle.com> E: The repository 'http://repo.mysql.com/apt/debian stretch InRelease' is not signed. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details.
やったこと
MySQL パッケージの鍵が期限切れになってるみたいなので apt-key
コマンドで W: GPG error: http://repo.mysql.com/apt/debian stretch InRelease: The following signatures were invalid: EXPKEYSIG 8C718D3B5072E1F5
のところの 8C718D3B5072E1F5
の新しい鍵をキーサーバーから取得する。
# apt-key adv --keyserver keys.gnupg.net --recv-keys 8C718D3B5072E1F5 Executing: /tmp/apt-key-gpghome.9ZCHkwdRZj/gpg.1.sh --keyserver keys.gnupg.net --recv-keys 8C718D3B5072E1F5 gpg: key 8C718D3B5072E1F5: "MySQL Release Engineering <mysql-build@oss.oracle.com>" 16 new signatures gpg: Total number processed: 1 gpg: new signatures: 16
新しい鍵を取得してから apt update
するとエラーが出なくなっている。
# apt update Ign:1 http://deb.debian.org/debian stretch InRelease Get:2 http://repo.mysql.com/apt/debian stretch InRelease [21.6 kB] Hit:3 http://deb.debian.org/debian stretch-updates InRelease Hit:4 http://deb.debian.org/debian stretch Release Hit:5 http://security-cdn.debian.org/debian-security stretch/updates InRelease Get:6 http://repo.mysql.com/apt/debian stretch/mysql-5.6 amd64 Packages [4798 B] Fetched 26.4 kB in 0s (41.9 kB/s) Reading package lists... Done Building dependency tree Reading state information... Done 31 packages can be upgraded. Run 'apt list --upgradable' to see them.
Redash の EC2 インスタンスのメモリが枯渇して CPU 使用率が高騰したときにやったこと。
Redash を動かしている EC2 インスタンスのメモリが枯渇して CPU 使用率が高騰したときにやったことのメモ。
EC2 インスタンスの CPU 使用率が高騰
ことの始まりは開発で使ってる EC2 インスタンスの CPU 使用率が60〜100%くらいをいったりきたりしているのに気が付いたときだった。
問題の EC2 インスタンスは t2.small
でここ数ヶ月は CPU クレジットが上限に張り付くくらい CPU 負荷が余裕がある感じだったので最近の変更が原因ぽいと思ったが、思い返してみると問題の EC2 インスタンスで動かしている Redash を少し前に v8 にアップデートしていた。
Redash のアップデートが関係してそうだなーと思いながらとりあえず ssh で問題の EC2 インスタンスに接続して状況を見てみた。
やったこと
kswapd0 プロセスが CPU を食いつぶす
ssh で問題の EC2 インスタンスに入れたので top コマンドを実行してみると kswapd0
という見慣れないプロセスが CPU を断続的に 50〜90% くらい使っていた。
調べてみるとメモリのスワップが発生しているときにときにスワップインしたりスワップアウトするカーネルスレッドっぽい。
メモリがスワップするということはメモリが枯渇している可能性が高いので free コマンドでメモリの状況を確認してみると used が 1.6GB くらいで free が 50MB くらいしかないようだった。
Redash の Docker コンテナがメモリをモリモリ食う
top, ctop コマンドを実行してしばらく様子をみていると Redash の server
と worker
の Docker コンテナが大量にメモリを使っているようだった。
問題の EC2 の Redash はあまり使っていないことが分かっているので、https://redash.io/help/open-source/admin-guide/env-vars-settings と Redashのメモリ使用量を節約する - ariarijp’s blog を参考にしながら REDASH_WEB_WORKERS
環境変数を 4 => 1 にして WORKERS_COUNT
環境変数を 2 => 1 にしてから Redash の Docker コンテナを再起動した。
Docker コンテナ再起動後に軽く Redash のクエリを発行したりダッシュボードを表示したりしてから free コマンドを実行してみると free が 100MB くらいになって少し余裕ができたが、まだスワップが発生するみたいで kswapd0
プロセスがときどき top コマンドに顔を出すようだった。
再び https://redash.io/help/open-source/admin-guide/env-vars-settings と Re:dashのキャッシュデータを削除する - Qiita を参考にして REDASH_QUERY_RESULTS_CLEANUP_MAX_AGE
環境変数を 7 => 1 にしてから Redash の Docker コンテナを再起動した。
REDASH_QUERY_RESULTS_CLEANUP_MAX_AGE
は過去のキャッシュを何日間保持するかを指定する環境変数だが、この EC2 の Redash はあまり使っていないのでキャッシュを保持する必要もあまりないのが分かっているので1日だけキャッシュを保持するようにしてみた。
Docker コンテナ再起動後にまた軽く Redash をいじってから free コマンドを実行してみると free が 350MB くらいになってだいぶ余裕ができたみたいで、 kswapd0
プロセスが top コマンドに顔を出すこともなくなった。
今後同じことが起きたら
とりあえず Redash を動かしている EC2 インスタンスのメモリが枯渇したり CPU 使用率が高騰することはなくなったけど、また同じ原因や違う原因でメモリが枯渇したりするようなら t2.small
=> t2.medium
にサイズアップすると思う。
今の使い方だと一ヶ月あたり 5USD くらい使用料金が高くなってしまうけど、調査したりとかの出費を一ヶ月あたり 5USD の出費でなくせるならむしろ安いと思うので。
参考にしたサイト
- https://redash.io/help/open-source/admin-guide/env-vars-settings
- Redashのメモリ使用量を節約する - ariarijp’s blog
- Re:dashのキャッシュデータを削除する - Qiita
とりあえずコレはやっておく
今回は Redash のミドルウェアのプロセス数を減らしたけど、参考にしたサイト Redashのメモリ使用量を節約する - ariarijp’s blog の ariarijp さんが「プラグインを無効にするともっとメモリを節約できますよ」と教えてくれたのでやっておく。
環境変数からプラグイン無効化すると、更に節約できると思います。以下は環境変数使った例ではないですが、メモリの節約具合は参考になるかとhttps://t.co/5f658WWF0r
— Takuya Arita (@ariarijp) 2019年12月13日
西暦と和暦を変換する wareki コマンドが Docker コンテナになりました。
はじめに
wareki コマンド が Docker コンテナ になりました。
もともと実行ファイル1つだけの構成でしたが、環境を汚したくないときの選択肢の1つとして Docker コンテナにしてみました。
もちろん、今までのように Releases ページからダウンロードしたり go get
とか HomeBrew でインストールして使うこともできます。
インストール方法
普通に docker image pull
でインストールします。
ただ、このあと docker conainer run
するときにイメージがローカルにないときは Docker が自動的にイメージを pull してくれるのでやらなくてもいいです。
$ docker image pull ebc2in2crc/wareki
使い方
普通に docker container run
します。
コマンドの実行が終わったらコンテナを削除するために --rm
オプションを付けるとよいと思います。
$ date "+%Y/%m/%d" 2019/05/01 $ docker container run --rm ebc2in2crc/wareki R1 $ docker container run --rm ebc2in2crc/wareki --kanji 令和1
参考にしたサイト
apk ファイルと ipa ファイルのバージョンを雑に確認するシェルスクリプトを書いた。
apk ファイルと ipa ファイルのバージョンを雑に確認するスクリプトを書いたときのメモ。
やりたいこと
apk ファイルで知りたいのは android:versionName
と android:versionCode
の2つ。
このあたりの情報は aapt
コマンドを使って apk ファイルから取得できるので、必要な情報だけを取得と出力するように。
ipa ファイルで知りたいのは CFBundleShortVersionString
と CFBundleVersion
の2つ。
このあたりの情報は plutil
コマンドを使って ipa ファイルから取得できるので、必要な情報だけを取得と出力するように。
書いたスクリプト
こんなシェルスクリプトを書いて packver.sh /path/to/hoge.apk
みたいな感じで使っている。
#!/bin/bash if [ "$1" = "" ]; then echo "usage: $(basename $0) package-path" exit 1 fi PACKAGE=$1 if [ "$(echo ${PACKAGE} | grep '.*apk$')" != "" ]; then VERSION_NAME=$(aapt l -a ${PACKAGE} | grep android:versionName | sed -E -e 's/^.*Raw: "//' -e 's/".*$//') echo "Version: ${VERSION_NAME}" VERSION_CODE=$(aapt l -a ${PACKAGE} | grep android:versionCode | sed -E -e 's/^.*)//') echo "Version Code: $(printf '%d' ${VERSION_CODE})" exit 0 fi if [ "$(echo ${PACKAGE} | grep '.*ipa')" != "" ]; then PLIST=$(unzip -p ${PACKAGE} Payload/*.app/Info.plist | plutil -convert json -o - -- -) SHORT_VERSION=$(echo ${PLIST} | jq -r .CFBundleShortVersionString) echo "CFBundleShortVersionString: ${SHORT_VERSION}" BUNDLE_VERSION=$(echo ${PLIST} | jq -r .CFBundleVersion | sed -E -e 's/^.*\.//') echo "CFBundleVersion: ${BUNDLE_VERSION}" exit 0 fi echo "Invalid package: ${PACKAGE}" exit 1
依存しているツール
シェルスクリプトの中で aapt とか plutil とか使っているので以下のコマンドは事前にインストールしておく。 Android とか iOS 向けの開発をしているなら普通に入っていそうだが。
pixela-client-go が v1.2.0 にバージョンアップしました。
pixela-client-go が v1.2.0 にバージョンアップしました。
v1.2.0 アップデート内容
Channel API に対応
Pixela v1.13.0 で追加された Channel API に対応しました。 Channel API の説明と使い方に関しては 公式ブログ と リリースノート にとても詳しく書かれているのでぜひ参照してみてください。
一応、Slack に通知するチャンネルを作成するコードの例は以下のようになります。
client := pixela.NewClient("notify-test", "thisissecret") detail := &pixela.SlackDetail{ URL: "https://hooks.slack.com/services/xxxx", UserName: "slack-user-name", ChannelName: "slack-channel-name", } result, err := client.Channel().CreateSlackChannel("my-channel", "My slack channel", detail) if err != nil { log.Fatal(err) } if result.IsSuccess == false { log.Fatal(result.Message) }
Notification API に対応
Pixela v1.13.0 で追加された Notification API に対応しました。 Channel API の説明と使い方に関しては 公式ブログ と リリースノート にとても詳しく書かれているのでぜひ参照してみてください。
一応、通知ルールを作成するコードの例は以下のようになります。
client := pixela.NewClient("notify-test", "thisissecret") result, err := client.Notification("test-graph").Create( "my-notify-rule", "my notification rule", pixela.TargetQuantity, pixela.ConditionGreaterThan, "3", "my-channel", ) if err != nil { log.Fatal(err) } if result.IsSuccess == false { log.Fatal(result.Message) }
現場からは以上です。
パーティションがある EBS のボリュームサイズの拡張方法。
EC2 を運用中にパーティションがある EBS ボリュームのサイズが足りなくなったのでボリュームサイズを拡張したときのメモ。
EBS ボリュームサイズの拡張前
まずは状態を確認していく。
lsblk コマンドで状態を確認するとルートボリュームは /dev/xvda があり、/dev/xvda ルートボリュームは /dev/xvda1 パーティションがあることが分かる。また、/dev/xvda ルートボリュームのサイズは 8GB で /dev/xvda1 パーティションのサイズは 8GB であることも分かる。
$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT xvda 202:0 0 8G 0 disk └─xvda1 202:1 0 8G 0 part /
df コマンドでファイルシステムの状態を確認すると /dev/xvda1 パーティションは割り当てている 8GB のうち 7.8GB とほぼすべてを使い切っている状態で、このままだと何をするにも支障があるので EBS のボリュームサイズを拡張していく。
$ df -h ファイルシス サイズ 使用 残り 使用% マウント位置 /dev/xvda1 8.0G 7.8G 200M 98% / # 省略
EBS ボリュームサイズの拡張方法
パーティションがある EBS ボリュームサイズを拡張するときは、EBS ボリュームサイズ自体の拡張のほかにパーティションの拡張とファイルシステムの拡張が必要になるので、それぞれやっていく。
EBS ボリュームサイズの拡張
まず一番最初に EBS のボリュームサイズを拡張していく。
AWS の EC2 コンソールのサイドバーで ボリューム
を押してボリューム一覧を表示して、ボリューム一覧の対象のボリュームを選択して アクション > ボリュームの変更
で ボリュームの変更
画面を表示する。
ボリュームの変更
画面は変更後のサイズ (ここでは 50GB) を入力して 変更
ボタンを押す。
拡張するサイズによっては拡張が完了するまで時間がかかることがあるので EBS ボリュームの 状態
が in-use
になるまで待つ。
EBS ボリュームの 状態
が in-use
であることを確認したら作業を続けていく。
lsblk コマンドで状態を確認すると /dev/xvda ルートボリュームは新しいサイズ (50 GB) が反映されているが /dev/xvda1 パーティションは元のサイズ (8 GB) のままであることが分かる。 そのため、ファイルシステムを拡張する前にパーティションを拡張していく。
$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT xvda 202:0 0 50G 0 disk └─xvda1 202:1 0 8G 0 part /
パーティションの拡張
/dev/xvda1 パーティションを拡張するために growpart コマンドを使う。
$ sudo growpart /dev/xvda 1 CHANGED: partition=1 start=4096 old: size=16773087 end=16777183 new: size=104853471,end=104857567
lsblk コマンドで状態を確認すると /dev/xvda1 パーティションが 50GB に拡張されていることが分かる。
$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT xvda 202:0 0 50G 0 disk └─xvda1 202:1 0 50G 0 part /
/dev/xvda1 パーティションのサイズは拡張されたが、df コマンドでファイルシステムの状態を確認するとファイルシステムは 8GB のままなので、続いてファイルシステムを拡張していく。
$ df -h ファイルシス サイズ 使用 残り 使用% マウント位置 /dev/xvda1 8.0G 7.8G 200M 98% / # 省略
ファイルシステムの拡張
ここまででボリュームサイズの拡張とパーティションサイズの拡張をしてきたので最後にファイルシステムを拡張していく。
ext2、ext3、ext4 ファイルシステムは resize2fs コマンドを使って拡張していき、XFS ファイルシステムは xfs_growfs コマンドを使って拡張していく。
使っているファイルシステムは df -T
コマンドで確認できる。
ここでは タイプ
のところが xfs
と出力されているので XFS ファイルシステムを使っていることが分かる。
$ df -T ファイルシス タイプ 1K-ブロック 使用 使用可 使用% マウント位置 /dev/xvda1 xfs 8376300 1435180 6941120 18% / # 省略
ファイルシステムが XFS ファイルシステムなので xfs_growfs コマンドを使って拡張していく。
xfs_growfs コマンドがないときは yum install xfsprogs
コマンドで XFS ファイルシステム管理ユーティリティをインストールしてから xfs_growfs コマンドを実行する。
$ sudo xfs_growfs / meta-data=/dev/xvda1 isize=512 agcount=4, agsize=524159 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=1 spinodes=0 data = bsize=4096 blocks=2096635, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=1 log =internal bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 data blocks changed from 2096635 to 13106683
xfs_growfs コマンドの実行後に df コマンドでファイルシステムの状態を確認するとファイルシステムが 50GB に拡張されていることが分かる。
$ df -h ファイルシス サイズ 使用 残り 使用% マウント位置 /dev/xvda1 50G 7.8G 42G 16% / # 省略
パーティションがある EBS のボリュームサイズの拡張方法は以上。
参考ページ
CSV や TSV を SQL ライクに select できる q コマンドが便利すぎた。
CSV や TSV などの表形式のデータを SQL ライクに select できる q コマンド が便利すぎたのでメモしておく。
q コマンドとは
とりあえず公式ドキュメント。
公式ドキュメントには以下のように書いてある。
q is a command line tool that allows direct execution of SQL-like queries on CSVs/TSVs (and any other tabular text files).
ようするに CSV とか TSV みたいなテキストデータを SQL ぽく select できるコマンドなのだが、非常に簡単に使えてしかも驚くほど強力。
インストール
$ brew install q
使い方
公式ドキュメントが分かりやすいくてざっと公式ドキュメントに目を通すだけで十分なのだけおd,よく使うオプションなどを備忘録までにメモしておく。
サンプルで使う CSV ファイルはこんな感じ。
$ cat prefectures.csv 都道府県,読み,地方,人口 愛知県,あいちけん,中部,7484094 青森県,あおもりけん,東北,1308649 秋田県,あきたけん,東北,1022839 石川県,いしかわけん,中部,1154343 茨城県,いばらきけん,関東,2917857 岩手県,いわてけん,東北,1279814 愛媛県,えひめけん,四国,1385840 大分県,おおいたけん,九州,1166729 大阪府,おおさかふ,近畿,8838908 岡山県,おかやまけん,中国,1922181
基本的な使い方
入力データはファイル名を from
に指定する。
$ q -d, -H 'select * from prefectures.csv' 愛知県,あいちけん,中部,7484094 青森県,あおもりけん,東北,1308649 秋田県,あきたけん,東北,1022839 石川県,いしかわけん,中部,1154343 茨城県,いばらきけん,関東,2917857 岩手県,いわてけん,東北,1279814 愛媛県,えひめけん,四国,1385840 大分県,おおいたけん,九州,1166729 大阪府,おおさかふ,近畿,8838908 岡山県,おかやまけん,中国,1922181
標準入力を入力データにするときは -
を from
に指定する。
$ cat prefectures.csv | q -d, -H 'select * from -' 愛知県,あいちけん,中部,7484094 青森県,あおもりけん,東北,1308649 秋田県,あきたけん,東北,1022839 石川県,いしかわけん,中部,1154343 茨城県,いばらきけん,関東,2917857 岩手県,いわてけん,東北,1279814 愛媛県,えひめけん,四国,1385840 大分県,おおいたけん,九州,1166729 大阪府,おおさかふ,近畿,8838908 岡山県,おかやまけん,中国,1922181
データの区切り文字を指定するときは -d
オプションを指定する。
サンプルの prefectures.csv は CSV フォーマットなので `-d,' を指定しているが入力データのフォーマットに合わせてタブでもなんでも指定できる。
入力データの1行目がヘッダー行のときは -H
オプションを指定する。
-H
オプションを指定するとヘッダー行から自動的にカラム名を検出してくれてクエリのなかで使うことができる。
$ q -d, -H 'select 都道府県 from prefectures.csv' 愛知県 青森県 秋田県 石川県 茨城県 岩手県 愛媛県 大分県 大阪府 岡山県
入力データにヘッダー行がなく1行目からデータ行のときは c1, c2, ... というカラム名になる。
$ cat prefectures.csv | sed 1d | q -d, 'select c1 from -' 愛知県 青森県 秋田県 石川県 茨城県 岩手県 愛媛県 大分県 大阪府 岡山県
クエリ
標準的な SQL はだいたい使える。
where
$ q -d, -H 'select * from prefectures.csv where 地方="東北"' 青森県,あおもりけん,東北,1308649 秋田県,あきたけん,東北,1022839 岩手県,いわてけん,東北,1279814
order by
$ q -d, -H 'select * from prefectures.csv order by 人口 desc' 大阪府,おおさかふ,近畿,8838908 愛知県,あいちけん,中部,7484094 茨城県,いばらきけん,関東,2917857 岡山県,おかやまけん,中国,1922181 愛媛県,えひめけん,四国,1385840 青森県,あおもりけん,東北,1308649 岩手県,いわてけん,東北,1279814 大分県,おおいたけん,九州,1166729 石川県,いしかわけん,中部,1154343 秋田県,あきたけん,東北,1022839
limit
$ q -d, -H 'select * from prefectures.csv order by 人口 desc limit 3' 大阪府,おおさかふ,近畿,8838908 愛知県,あいちけん,中部,7484094 茨城県,いばらきけん,関東,2917857
group by
$ q -d, -H 'select 地方, count(1) from prefectures.csv group by 地方' 中国,1 中部,2 九州,1 四国,1 東北,3 近畿,1 関東,1
having
$ q -d, -H 'select 地方, count(1) as cnt from prefectures.csv group by 地方 having cnt >= 2' 中部,2 東北,3
関数
関数も普通に使える。
sum
$ q -H -d, 'SELECT sum(人口) from prefectures.csv' 28481254
substr
$ q -H -d, 'SELECT substr(都道府県, 1, 1) from prefectures.csv' 愛 青 秋 石 茨 岩 愛 大 大 岡
その他のよく使うオプション
入力エンコーディングの指定
入力エンコーディングを指定するときは -e
オプションを使う。
たとえば入力エンコーディングが EUC-JP のときはエラーになってしまうが、
$ iconv -f UTF-8 -t EUC-JP prefectures.csv | q -d, -H 'select * from -' Could not parse the input. Please make sure to set the proper -w input-wrapping parameter for your input, and that you use the proper input encoding (-e). Error: 'utf8' codec can't decode byte 0xc5 in position 0: invalid continuation byte
-e EUC-JP
オプションを指定すると意図したとおりに動く。
$ iconv -f UTF-8 -t EUC-JP prefectures.csv | q -d, -H -e EUC-JP 'select * from -' 愛知県,あいちけん,中部,7484094 青森県,あおもりけん,東北,1308649 秋田県,あきたけん,東北,1022839 石川県,いしかわけん,中部,1154343 茨城県,いばらきけん,関東,2917857 岩手県,いわてけん,東北,1279814 愛媛県,えひめけん,四国,1385840 大分県,おおいたけん,九州,1166729 大阪府,おおさかふ,近畿,8838908 岡山県,おかやまけん,中国,1922181
出力エンコーディングの指定
出力エンコーディングを指定するときは -E
オプションを使う。
$ q -H -d, 'select * from prefectures.csv' | nkf -g UTF-8 $ q -H -d, -E EUC-JP 'SELECT * from prefectures.csv' | nkf -g EUC-JP
ヘッダー行を出力
デフォルトはヘッダー行は出力されないが -O
オプションを指定するとヘッダー行が出力される。
$ q -H -d, -O 'SELECT * from prefectures.csv' 都道府県,読み,地方,人口 愛知県,あいちけん,中部,7484094 青森県,あおもりけん,東北,1308649 秋田県,あきたけん,東北,1022839 石川県,いしかわけん,中部,1154343 茨城県,いばらきけん,関東,2917857 岩手県,いわてけん,東北,1279814 愛媛県,えひめけん,四国,1385840 大分県,おおいたけん,九州,1166729 大阪府,おおさかふ,近畿,8838908 岡山県,おかやまけん,中国,1922181