トップ ソフト 雑記 日記 リンク

2020年9月12日土曜日

ArduinoのSPIが上手く動かなかった話(解決?済)

結論:SPIの信号線を完全に分離しろ。

以前、Arduinoで二酸化炭素計を作ったのですが、最近どうも動きが怪しい。 PCに繋いだ状態で、シリアルモニタを有効にしていないと動かず、スタンドアロンでは動作しない状態でした。 シリアルモニタで状況を見ると動いて、状況を見ないと動かない・・・。まるで開発環境では動くのに、本番環境では動かないという良くあるアレです。
しかし、本当にこれでは困るので、なんとかしてスタンドアロンの状態で動作状況を確認したい。ということで、以前から購入していたものの使っていなかったLCDを追加して、状況表示をすることにしました。
使用するLCDは、PCD8544。Nokiaの携帯電話5110で使われていたディスプレイのため、5110という型番で呼ばれることも多いようです。
同じ液晶を使用している方のブログを参照してみると、液晶はだいたい同じなのですが、液晶が実装されている基板が異なるようで、ピンの番号や順番に違いがあるようです。このあたりは、手元にある部品のシルク印刷と照らし合わせながら合わせていきます。

そして実装。

これが、なぜか動いたり動かなかったりする。
正確には、最初は動くんだけど、すぐに動かなくなってしまう。
この症状には見覚えがあります。Arduinoのメモリが不足して処理が途中で転けているパターンです。
イーサネット&SDカードシールド、温度湿度気圧計、二酸化炭素計を搭載して既にライブラリでメモリがカツカツのところに、LCDのライブラリまで入ってきて、メモリが70%以上を消費しています。
LCDだけで動かすと問題が無いので、これはメモリ不足で間違いないと予測して、DHCP処理を外したり、ローカル変数で必要なメモリ量が動的になり後から必要になるメモリ量が読めない部分をグローバル変数にしてみたり、色々やってみたのですが、一向に解決しませんでした。

違う原因ではないかと、色々検索していたところ、別の機材とイーサネット&SDカードシールドの組み合わせで上手く動かないという現象と解決方法でした。
Arduinoのイーサネット&SDカードシールドと、PCD8544はSPI(Serial Peripheral Interface)という仕組みでArduino本体と通信をしています。
これは信号線とタイミング用のクロック線を共有し、相手先選択の線を利用して、通信相手を決定するというものです。

シリアル・ペリフェラル・インタフェース - Wikipediaより SPI three slavesen:User:Cburnett / CC BY-SA
  • MOSI(Master Out Slave In)
  • MISO(Master In Slave Out)
  • SCK(Serial Clock)
  • SS(SlaveSelect)
MOSI、MISO、SCKの3本を共有し、SSを機器別に1本ずつ用意してやれば、機械が一台増えるごとにSSを1本追加するだけでピンの数が節約できるというものです。
実際、イーサネット&SDカードシールドは、3本を共有し、残り2本のSSでSDカードとイーサネットの通信を切り替えているそうです。
ここで、PCD8544も同様に3本を共有し、PCD8544用のSSを1本追加して実装していたのですが、上手く動かないと書いていたブログでは、完全に信号線を分離したことで解決したと書かれていたので、こちらも分離してみることにしました。

あっさり稼働。
どうも、イーサネット&SDカードシールドのSPIに癖があるようです。
ということで、使用ピン数もだいぶギリギリの中、なんとか一台のArduinoの中に組み込むことができました。

ただ、シリアルモニタを開けないと動作しない点については、まだ何も解決していないのですが・・・。

2020年6月11日木曜日

謎の上から目線なjp講評

 mstdn.jpがいよいよ終わってしまうのかというところで、劇的な逆転でしたね。多くの日本人がjpをきっかけにFediverseへ飛び出したということもあり、いつも騒ぎになりやすいところではありますが、何かしら思い入れがある場所なのだと思います。

 きぼうソフト、DSNOについては、次の運営者にバトンを渡すということで、とてもよく頑張ってくれたと思います。自らの身を削って支えるという姿勢は、日本的な姿として一方では大変美しく目に映りますが、先行きの不安感という空気に対しての会社ごっこのような収支表では、とてもそれを払拭できたとは思えませんでした。新しい運営者による管理指標などの不安に対して、言葉で丁寧に対応している姿勢を見ていると、こんな解決方法もあったのではないかなと感じました。

 分散SNSにおいて、よそのサーバーに移動できるということは、安心できるところにひとは集まりやすくなるものです。サーバの管理者というのは、そのサーバの一番目のユーザーでもあります。自分が安心できる場所作りたい、そして同じ場所を提供したいという気持ちで公開しているのではないでしょうか。例え引き継いだとしても、それは変わらないでしょう。

 管理者以外のユーザーは、そこが安心できる場所かどうか、管理者を見ているのです。先代の管理者が方針に迷っている時にそのことを投稿したところ、フラフラするなという怒りを表す人がいたのを見ました。そのため極力人間味を出さない方針になってしまったのかなとも思え、このあたりはとても難しいバランスだったのだと思います。

 管理者が利用者に媚びろとか、イエスマンを集めろと言いたいわけではありません。ただ普段の行動から、そのサーバーの空気感というものを作っていけるのではないかなと思いました。漏れ伝わってくるjpの運営に対するギスギスしたものが、どうにも悲しく感じていました。

 つぎにまた新しい遊び場を用意してくれることがあれば、そのあたりも少し考えてもらえたらいいなと思いました。あとまだ3週間ほどありますが、ひとまずお疲れ様でした。

P.S.寄付窓口は結局無いままなんでしょうか。前に送ったメールに全く反応がなかったので、いきなりアマギフを送りつけるのもちょっと躊躇いがあります。

さらに追記:jp管理者による空気作りが、jpを踏み台にして別のサーバーへ進出していくために、あえて作られているのだとしたら、この記事は完全に的外れな恥ずかしい文章となります。

2020年4月12日日曜日

マイキーID作成・登録準備ソフトがインストールできない(解決済)

結論:作業用ディレクトリを指定するTMP・TEMP環境変数を元に戻せ

マイナンバーカード、使ってますか?
ていうか使うところがe-taxしかない。

いや、せっかく国が用意してくれた認証基盤ですし、使えるところが増えてくれば便利にはなると思うのですが、利用者が少ないものを使えるようにする予算はないということで、全て不況が悪いのです。

さて、マイナンバーカードがポイントカードになるというマイナポイントというサービスができました。
これを使うためには登録が必要とのことで、わたしも準備をしてみたのですが、インストーラーが途中で止まってしまって進まなくなります。

ここで止まる。

全くエラーなどは出ず、プログレスバーが100%まで進んだところから反応がなくなります。
タスクマネージャーを見ても暴走しているわけでは無く、全く負荷は掛かっていない。
キャンセルボタンを押しても反応しない。
タスクマネージャーから強制終了する必要があります。

InstallShieldを使っているので、どこかにログは出ていないか探してみたり、コマンドラインからログを出力するオプションを指定してみたり、圧縮されているexeファイルを分解して中のインストーラーを取り出して調べてみたりしたのですが原因が分からず、問い合わせ窓口に投げてみました。

まあ、Windowsを更新しろとか、ウイルスチェックを外せとか一般的な回答だったのですが、うちは素のWindows10環境だったので充分テストされている環境だろうと、一応言うとおりにしてみたものの全く効果はありませんでした。

ダメだったよーと返事を返しつつ、こっちでも他に調べてみた結果などを付けて「ただの素人では無い、分かっている人間」感を出してみたのですが、メールが行って返ってくるのに1ヶ月掛かり、3ヶ月(計6通)で解決に辿り着きました。

解決方法は最初に書いたとおり、どうやらインストーラーが展開する作業用ディレクトリと、実際に実行されるディレクトリが違うようで、これはインストーラースクリプトの不具合だよなぁと。
システムドライブが小さい、SSDを劣化させたくない、など色々な理由で作業用ディレクトリを変更している玄人はいると思います。今まであまりインストーラーで転けるという現象に出会ったことが無かったので、思わぬところでつまずいた感がありました。

この記事が誰かのお役に立てば、という思いで残しておきます。


2020年1月10日金曜日

zabbixの設定画面で、大量のグラフ項目を表示する

わたしは普段システムの監視にzabbixを使っているのですが、ずっと不満点がありました。

ディスカバリで生成される大量のグラフ項目のせいで、目的のグラフが見つけられないという問題です。


zabbixの管理画面では、アイテムやトリガーなどは絞り込み検索ができるのですが、グラフだけは絞り込みができず、表示される最大件数の1000件を超えてしまうことがありました。

この1000件制限を緩和したく調べてみたところ、データベースのconfigテーブルのsearch_limitカラムに記録されていました。


パフォーマンス的な理由で制限が掛けられているのだと思いますが、わたしのところでは増やしても問題は感じませんでした。

これWebUIから変更できないんですよね。
アカウントの設定画面にあった「ページあたりの表示行数」を増やしても、1ページの表示件数が増えるだけで1000件制限は変わらず最大ページ番号が縮むだけでした。

2019年12月9日月曜日

換気、足りてますか?

わたしは季節に関係なく頭が痛くなったりする事があるのですが、そういうときは大抵乾燥が酷いときだったりします。部屋にぶら下がっている湿度計を見ると50%を下回っていて、慌てて加湿機を動かします。

冬場になると、 加湿をしても効果が無いときがあり、他になにがあるだろうかと考えたところ、換気が足りていないのではないかというのを思い出しました。
しかし、息苦しいとか頭がクラクラするとかいうのは感じたことがありません。実際にどのくらい換気が足りていないのか、測ってみないことには分からないということで、arduinoとCO2センサーを組み合わせて測ってみました。

使った部品は、arduino unoと、CO2センサー「MH-Z14A」、気温湿度気圧センサー「BME280」です。



結線とソースコードはググったら出てくるでしょう。
CO2センサーはMH-Z19が欲しかったのですが、Amazonでもどこも海外発送ばかりで、到着まで2週間掛かるということだったので、国内のAmazon倉庫から発送できると書かれていたMH-Z14Aにしました。

arduinoのEthernetライブラリを使って自宅のサーバに計測値を投げてファイルに保存し、zabbixからファイルを読み取るという仕組みにしています。2000ppmをトリガーにして、Slackへ通知を送信。
少しはまった部分としては、計測値を投げる処理を1分に一回にすると、なぜか処理が止まってしまうため、30秒に一回にしています。keepaliveあたりのなにかなのか、調べ切れていません。


二酸化炭素濃度は、自然界でだいたい400ppm、よく換気されている部屋で1000ppm以下、2000ppmからは換気が必要だそうです。
実際「建築物における衛生的環境の確保に関する法律」でも1000ppm以下にすることが求められています。

実際に測ってみて分かったこととしては、意外と簡単に2000ppmに達するということです。
私が普段作業をしている部屋は、 14畳ほどの広さのリビング・ダイニング・キッチン一室。古い建物で、外の風が強いときなどはドアの下から風が入ってきて寒いぐらいなのですが、穏やかな天気の時は意外と密封度は高いらしいです。

冬場は、この部屋で小型のガスファンヒーターをつけています。6畳用だったか、8畳用だったか忘れてしまいましたが、能力からすると不足気味の機械なのですが、2時間ぐらいで400ppmから2000ppmぐらいまで上がります。

冒頭で頭がクラクラしないなんて書きましたが、もっと高い濃度で発生するもので、それより前に作業の能力などにも影響が出てくるそうです。
よく見かける注意書きも、死亡事故なんていうぐらいだから「うっ、苦しい」みたいなことになるレベルを想定してしまいますが、じわじわと身体を蝕んで気が付いたときには手遅れということにならないよう、早め早めの換気が必要ですね。


1月30日 追記
arduino用ユニバーサル基板を買ってきて、組み立ててみました。
EthernetシールドのLAN端子がかなり大きくて、基板を切る必要がありましたが、これでブレッドボードと違って蹴飛ばしても配線が外れる心配が無くなりました。






2019年3月3日日曜日

システム稼働状況ページを作った

Service status osa-p.net を作った話。

元々、zabbixでシステムの状況はモニタリングしているのだが、それを外部に公開する仕組みを用意していなかった。zabbixのページをそのまま公開したくなかったので、必要な情報だけ抽出して表示できる仕組みが欲しかった。


SNSでつぶやいてみると

UptimeRobotというサービスを紹介してもらえた。

早速設定してみたところ、格好良い稼働状況ページが出来上がったのだが、うちのシステム上、ウェブサーバとデータベースが分離しており、データベースを使う処理は動かないが、ウェブサーバだけで完結する処理は動くという状況があり得て、その表示がしにくいなと感じた。

そこで、やはり自前で処理を作るかと、ついでに使ったことのなかったVueも試しに取り入れてみた。普段仕事でもまだまだjQueryを使うことが多く、また思い付いたサービスを個人で作るときにも早く公開したくて慣れているjQueryを使ってしまうことが多い。今回は急ぐものでもなかったので、サンプル程度しか動かしたことのなかったVueを使ってみた。といっても、やはりサンプルの継ぎはぎではあるのだけど。

処理自体は問題無くできて、さて公開するかというところで問題があった。
稼働状況ページは、自分が管理しているシステムの中で動かしてしまうと、一緒に落ちたときに肝心の状況が見えなくなってしまうので、公開ページは別のサービスで動かしたかった。まず最初に選んだのがS3で、ここでは静的サイトを公開する情報も整っていたので簡単に設定して公開。あとはネームサーバとして使っているCloudflareでCNAMEを張ってやれば動くだろうと考えていた。

実際に公開してみたところ、httpでは繋がるのだが、httpsでは接続ができなかった。S3の公開では、「https://S3ドメイン/バケット名/」だとhttpsが使えるのだが「https://バケット名.s3ドメイン」ではhttpsが使えない。Cloudflare側でHTTP Proxyを有効にしていたら、オリジンサーバーがhttpでも使えたような記憶があったのだけど、どうも上手く行かないので間にCloudFrontを挟んでhttpsでも繋がるようになった。

しかし別の問題が発生した。ページの作りとしては、zabbixから出力したSLAの情報をS3に5分毎にアップロードし、静的ページ側でそれを読み込んで表示する。CloudFrontは読み込んだ情報をキャッシュしてしまうので、いつまでも古い情報が表示されてしまうのだ。もちろんCloudFrontの設定にも用意されているので、TTLの設定を5分にしてみたり、クエリが付いていたらキャッシュしない設定にしたり、キャッシュをクリアしてみたりしたのだが、どうにも解消できなかった。

結局Netlifyで静的ページ部分を配信しつつ、データはS3から読み込むという仕組みで解決した。このやり方ならGitHub Pagesでも大丈夫だろうが、最初すべてをGitHub Pagesで配信しようと考えてしまい、5分毎にコミットとプッシュをしたら怒られそうだなと思って頭の中からGitHubを使うことを取り除いてしまっていた。

ひとまず大枠の仕組みが完成したので、これを応用して、zabbixに入力したメンテナンス情報を各サービスで表示したり、自動でメンテモードに切り替えたりもできるだろう。今はデータベースを止めるメンテナンスがあるときに、各サービスのcronを止めたり、フラグを立てたりと手動で処理してアクセスが止んだのを確認してから作業したりしているので、この辺りも自動化してしまいたいと考えている。



2019年1月27日日曜日

PostgreSQLのshared_buffers設定とZFSのARCの関係を調べた

いつも個人のプロジェクトではPostgreSQLを使っており、自宅サーバで大きいデータベースを運用しています。最近まではmdadmで組んだRAID-5の上に、ext4でファイルシステムを作って、その中にデータベースのテーブルスペースを置いていました。
しかし、最近ZFSを使い始め、同じようにRAID-Zでファイルシステムを作ってテーブルスペースを置くようになりチューニングを再確認していたのですが、少し気になることが出てきたので調べてみました。

PostgreSQLのshared_buffers設定

PostgreSQLの設定には、shared_buffersというものがあり、搭載されているメモリから共有メモリを確保して、PostgreSQLの各プロセスが利用しています。この値は
1GB以上のRAMを載せた専用データベースサーバを使用している場合、shared_buffersに対する妥当な初期値はシステムメモリの25%です。 shared_buffersをこれよりも大きな値に設定することが有効なワークロードもあります。 しかし、PostgreSQLはオペレーティングシステムキャッシュにも依存するため、shared_buffersにRAMの40%以上を割り当てても、それより小さい値の時より動作が良くなる見込みはありません。(PostgreSQL日本語ドキュメント 19.4. 資源の消費より)
とあり、あまり大きくしても効果が無いとまで書かれています。
実際にext4でテーブルスペースを管理していた時は、この設定でhtopをみると搭載メモリの利用状況を示すバーの約25%が緑色、約75%が黄色となり、キャッシュが有効に働いていることが確認できました。

ZFSのARC設定

ZFSにはARCと呼ばれるメモリ上のキャッシュ機構を持っています。これは空きメモリから使用され、ディスクから読み出した際にARCにも格納され、同じデータの読み出しが発生した場合はディスクを参照せずここから読み出すことによって高速化を行います。ZFSを開発したSunのエンジニアが、MySQLで使う場合のチューニング指標として
ZFS上でMySQL/InnoDBを利用する場合、利用されるキャッシュにはいくつかの階層が存在します。InnoDB自身がバッファプールを持っていますし、ZFSにはARCがあります。そして、それらのキャッシュは個別に何をキャッシュまたはフラッシュすべきかということを判断するようになっています。そして、それらが同じデータをキャッシュするというような状況が生じてしまうこともあるでしょう。InnoDB内でキャッシュすると、データへたどり着くまでにより短い(そして高速な)コードパスで済むでしょう。そして、InnoDB内でキャッシュミスが生じれば、例えそのデータがARCに存在していたとしてもダーティページのフラッシュが生じてしまうことになります。これは不要な書き込みを生じさせる原因となります。ARCは利用可能なメモリの容量によって(自)動的に縮退・拡張しますが、単にそれを制限する方がより効率的です。我々が実施したテストでは、ZFS内でキャッシュするよりInnoDB内でデータをキャッシュしたほうが7〜200%の性能向上が見込めることを確認しています。(翻訳を紹介している漢(オトコ)のコンピュータ道: 違いが分かるエンジニアのためのMySQL/InnoDB/ZFSチューニング!より)
と紹介されています。このため、データベースでZFSを利用する場合ARCのキャッシュ情報はallではなくmetadataのみをキャッシュするように設定するという紹介をあちこちで見かけます。

鵜呑みにして設定

わたしもこれを読んで同じように設定していたのですが、思った以上にパフォーマンスが上がらず、はてどうしたものかと悩んでいました。そしてふと気が付いたのが、htopで表示されるメモリの使用状況バーは搭載メモリの25%だけが緑でキャッシュが全く使われていない状況でした。つまりメモリの25%しか使っていない状態でした。

ということは、ext4ではOSの標準設定によりキャッシュが働いているからshared_buffersを増やさなくても良いということなのですが、ZFSでキャッシュを最低限にしている場合、shared_buffersを確保した方がいいのではないか?ということです。

そこで、PostgreSQLにおいてZFSを使用する場合、shared_buffersを増やしたときと、ARCのすべてキャッシュするときのベンチマークを取ってみました。

以下の環境でテストを行いました。
  • Core i7-6700(3.4GHz) Windows 10 Pro上のHyper-Vで実行されるCentOS7
  • カーネル 3.10.0-957.1.3.el7.x86_64
  • CPU割り当て4
  • メモリ 4GB(Hyper-Vの動的メモリは使用しない)
  • ZFS 0.7.12(RPMからインストール)
    zfs set recordsize=128K tank(初期値)
    zfs set compression=off tank(初期値)
    zfs set dedup=off tank(初期値)
  • PostgreSQL 11.1(ソースからビルド)
  • pgbench -i -s 100 bench(1000万件)
  • SELECT pg_database_size('bench'); → 1,576,528,895(データベースサイズは約1.5GB)
  • 設定変更後に再起動。一度pgbench -l -T 60 -c 2 -j 2 -P 10 benchで60秒間のベンチを回して、その後5回分のトランザクション数を記録

テストパターンは以下の4種類です。
  1. 両方鵜呑みにする
    shared_buffers=1GB
    zfs set primarycache=metadata tank
  2. ZFSの言うとおりにデータベースのキャッシュを増やす
    shared_buffers=3GB
    zfs set primarycache=metadata tank
  3. PostgreSQLの言うとおりにファイルシステムのキャッシュを増やす
    shared_buffers=1GB
    zfs inherit primarycache tank(デフォルトがallなので)
  4. 一応両方増やす(サイズ的にshared_buffersが優先になるはず)
    shared_buffers=3GB
    zfs inherit primarycache tank

結果


回数\パターン1234
1656590758773
2552670835822
3613543663644
4586656788794
54766741016987
平均値577627812804
中央値586656788794

ZFSのキャッシュをした方が良いという結果になりました。
パターン2はパターン4と同じになるかと思ったのですが、パターン1よりは性能が良いがパターン3より性能が出ないということで、やはりshared_buffersの設定は増やしすぎても効果が無いようです。
またパターン3とパターン4でも差がないことからshared_buffersを増やすぐらいならARCに回した方が良いという結果になりました。

MySQLでZFSを使うシーンに出会っていないので、今回はPostgreSQLの設定だけですが、やはり実際に測ってみないと分からないものだなと感じました。


ちなみに、ZFSのレコードサイズをデータベースとあわせた方が良いという意見を見かけるので、8Kと16Kを試してみたのですが、

zfs set recordsize=8K tank
回数\パターン1234
1696688681689
2701688690704
3686674631716
4627621639654
5683633678657
平均値679661664684
中央値686674678689

zfs set recordsize=16K tank
回数\パターン1234
1678609682683
2713543682688
3543612604668
4592682680663
5667690689717
平均値639627667684
中央値667612682683

大した有意差が見られず、また128Kの方が成績が良かったことから、うちでも8Kにしていたのを128Kに戻しました。
ARCが効きやすいレコードサイズの設定があるのかと思って検索してみたりしたのですが、それらしいドキュメントは見つけられませんでした。ソースをあたるしかなさそうです。

広告