俺流テキストデータベース #7 増幅したデータ対応と負荷計測

2018年11月23日

AWK テクノロジー プログラミング 特集

今回連載記事にしている「俺データベース」は、「概要編」で書いた通り、僕が以前勤めていた会社の開発で採用した手法なのですが、それまでのサーバーエラーや、システム障害のほとんどがSQLだったのに対し、この方式にしたところ、サーバー負荷での障害もほぼなくなりました。 そして、「データベース障害ゼロ」という結果と言ってもいいぐらいの安定感で、10年間僕が運営していた時には、ほぼ手離れした状態で運用する事ができ、なんで世の中のエンジニアがSQLにこだわっているのか非常に不思議でしたね。 今回はそんなサーバー負荷に関して、どの位の恩恵を受ける事ができるのかを検証してみます。 大容量データとして、手元にある開発環境に保持されているnginxのシスログデータを利用したいと思います。 error.logが128MBあったので、これを使って書き込みと読み込みの計算とその時のサーバーの負荷値を計測してみたいと思います。

処理時間検証

ログの計測時間を取得する処理で検証してみたいと思います。 はじめにこのデータ読み込みをするだけの処理速度を計測してみます。 time cat /var/log/nginx/error.log | awk '{print $1}' |wc -l > 916084 > real 0m1.613s > user 0m0.660s > sys 0m1.300s おなじみの"time"コマンドを使って計測してみたら、91万行ほど存在する事がわかりました。 そして、データ読み込みに1.6秒程度という事もわかります。 容量とレコード数を考えると非常にスペックがいい事がわかります。 ちなみに、環境は、MacBook1.7GhzのDocker-Linuxで行なっているんですが、CPUスペックやメモリ容量の大きなサーバーだともっと速度向上が狙えます。 あと、実はLinuxは一度読み込みをしたファイルをキャッシュしておく性質があり、2度目に同じコマンドを実行すると、処理速度が早くなります。 続けて2回同じコマンドを実行してみた結果が以下になります。 $ time cat /var/log/nginx/error.log | awk '{print $1}' |wc -l > 916084 > real 0m0.778s > user 0m0.640s > sys 0m0.150s $ time cat /var/log/nginx/error.log | awk '{print $1}' |wc -l > 916084 > real 0m0.621s > user 0m0.480s > sys 0m0.190s いかがでしょう?半分以下の処理速度が実現できました。 実際にシステムを構築する際の負荷テストは、最初の値を最大値になりそうですが、キャッシュをうまく利用できるシステム構築すれば、かなりのいいレスポンスシステムが作れそうですね。 次にデータ検索を行うためにawkに条件文を追加してみます。基本コマンドは以下を実行してみます。 $ cat /var/log/nginx/error.log | awk '{ if( $1 ~ /^[0-9]+\/[0-9]+\/[0-9]+/ ){print $1" "$2} }' | wc -l > 79139 > real 0m0.597s > user 0m0.450s > sys 0m0.210s 最初のカラムが日付になっている行を判別して、日時カラムを表示しています。 結果は8万件近くのデータが眠っているようですので、全体の9割ぐらいは、フォーマットがバラバラになっている事がわかります。 すでにキャッシュされている状態のためなのか、正規表現の条件文を1つ書いたぐらいでは、さほど速度に影響でないようですね。 次に、コマンドを付け足して日別の件数を表示してみたいと思います。 cat /var/log/nginx/error.log | awk '{ if( $1 ~ /^[0-9]+\/[0-9]+\/[0-9]+/ ){print $1} }' | sort | uniq -c 9 2018/01/07 18 2018/01/08 545 2018/01/09 335 2018/01/10 17 2018/01/11 11 2018/01/12 326 2018/01/13 7 2018/01/14 62 2018/01/15 15 2018/01/18 ... 全部で215件ぐらいの結果だったので、行数ではなくデータ表示をしてみました。(表示は端折っています) 日付の重複数を表現するのは、"sort | uniq -c"という記述で簡単に取得できてしまいます。 ちなみに、この処理速度も以下の通りです。 real 0m0.728s user 0m0.550s sys 0m0.170s このnginx環境は、僕の開発環境なので、dockerを使ってエラーログが溜まった件数になりますが、access.logに対して、公開サーバーのデータで行うと、日次のPV数(アクセス数)が簡単に取得できてしまいます。 awkを使うと、この条件文を書き込んでいくだけで、簡単に対象のデータにたどり着く事が可能で、シンプルにレコードデータの取得が行える事が理解できたでしょうか?

次回予告

今回はawkのみの検証でしたが、次回はjqの処理速度を検証してみたいと思います。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。