今回連載記事にしている「俺データベース」は、「概要編」で書いた通り、僕が以前勤めていた会社の開発で採用した手法なのですが、それまでのサーバーエラーや、システム障害のほとんどが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の処理速度を検証してみたいと思います。
0 件のコメント:
コメントを投稿