td-agentを使ってMysqlにLogを格納する Part 2 [td-agentの導入]
前回に続き、
最近作っているTCPハニーポットのLogをtd-agentを使ってMysqlに格納していきます。
td-agent (fluentd)でmongodbにVPSのTCPスキャンログを取っていたのですが、なんとなくMysqlに移行して行こうと思います。
td-agent (Fluentd)って?
Fluentdの安定リリースだそうです。 knowledge.sakura.ad.jp
以下、OSはcentos 6.8です。rubygemでfluentdをインストールする方法もありますが、今回は公式からyumリポジトリを追加し、インストールしました。
td-agentのインストールと起動
$ curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh $ sudo service td-agent start Starting td-agent: td-agent [ OK ] $ sudo service td-agent status td-agent is running [ OK ]
td-agentのmysqlプラグインをインストール
$ sudo td-agent-gem install fluent-plugin-mysql
rubyでテストコードを作成
require 'fluent-logger' Fluent::Logger::FluentLogger.open(nil, host: 'localhost', port:12345) Fluent::Logger.post('td.honeypot.log', { TIME: "#{Time.new}", IP: "127.0.0.1", PORT: "22", COUNTRY: "TEST", DATA: "hogehoge" }
td-agentの設定ファイル変更
$ sudo vim /etc/td-agent/td-agent.conf
あらかじめMysqlでcreate tableしておきます。rubyのプログラムに合わせて設定していきます。
<source> @type forward port 12345 </source> <match td.honeypot.log> @type copy <store> @type mysql_bulk host 127.0.0.1 port 12346 username XXXX password xxxx database honeypot table log column_names time,ip,port,country,data key_names TIME,IP,PORT,COUNTRY,DATA </store> </match>
最後にtd-agentに設定ファイルをreloadさせて終わり。
$ sudo service td-agent reload
td-agentを使ってMysqlにLogを格納する Part 1 [mysqlの導入]
修士論文も終盤をむかえ、余裕がでてきました。kazunyaaanです。
最近作っているTCPハニーポットのLogをtd-agentを使ってMysqlに格納していきます。
td-agent (fluentd)でmongodbにVPSのTCPスキャンログを取っていたのですが、なんとなくMysqlに移行して行こうと思います。
とりあえずmysqlを導入します。
Mysqlのインストール
$ sudo yum install -y mysql-server
設定変更
$ sudo vim /etc/my.cnf
ローカルのみアクセスを許可とポート番号の変更を追記。
[mysqld] bind-address=127.0.0.1 port=12346
Mysqlの起動と自動起動
$ sudo service mysqld start Starting mysqld: [ OK ] $ sudo chkconfig mysqld on $ sudo netstat -tlpn | grep mysqld tcp 0 0 127.0.0.1:12346 0.0.0.0:* LISTEN xxxx/mysqld
あとは適当にデータベース作っときます。
C++で円周率(PI)を1億桁計算してみた Part1
修士課程でプログラムの最適化or高速化という題でプレゼンしてくれということで・・・
なんとなく円周率を計算するプログラムを作成&高速化(※学生レベルの範囲で)してみました!
そもそも1億の円周率の計算になにが必要かを簡単にまとめると、
・多倍長整数
・高速な円周率の計算式
・それなりに大きいメモリ
といったかんじですね。
なぜ円周率(3.141592…)の計算に浮動小数点型ではなく整数型なのかというと…
主な理由は「計算の高速化」ですね。浮動小数点演算は整数演算よりコストが大きい傾向があるからです。
それじゃあ多倍長整数をつかおう!
任意桁数あつかえる多倍長整数を1から作ってもいいのですが…高速な四則演算扱える形にするには骨が折れますので、 今回はライブラリを使用していきたいと思います。
有名な物には、
・GMP
・Boost.Multiprecision
・LibTomMath
などがありますね。
それぞれメモリ効率や演算アルゴリズム等が違い、一長一短があります。 次回Part2でどの多倍長整数をつかうか決めていきたいとおもいます。
RubyのFork + Socketを利用したプロセス間通信 その1
どうも、kazunyaaanです。
今回は双方向の通信ができるUnixSocketを使ってみます。
インターネットドメインソケットと類似してますが、ネットワークプロトコルは使用していない等のため、
高速な通信を可能としています。(たぶん...後々確認予定...)
初めは、UnixSocketを使った基礎的なプログラムから。
今回はUNIXSocket.pair(Socket::SOCK_DGRAM)
とし、コネクションレス型通信(データグラム)を扱います。
以下、実行結果。
$ ruby Test_unixsocket.rb [P] I am parent processe. [C] I am child processe. [P] C -> P : 0 [P] C -> P : 1 [P] C -> P : 2 [P] C -> P : 3 [P] C -> P : 4 [C] P -> C : 0 [P] C -> P : 5 [C] P -> C : 1 [P] C -> P : 6 [P] C -> P : 7 [P] C -> P : 8 [C] P -> C : 2 [P] C -> P : 9 [C] P -> C : 3 [C] P -> C : 4 [C] P -> C : 5 [C] P -> C : 6 [C] P -> C : 7 [C] P -> C : 8 [C] P -> C : 9
こんな感じですかね。やっぱり、Rubyで組むと楽ですね。
多プロセスの場合、やっぱり、unixsocketを共有しちゃうと駄目なのかな...?
RubyにおけるThreadとForkの速度比較
こんばんは、kazunyaaanです。今回は並列処理の速度比較を行います。
(個人的に専門が数値計算で、MPI等でごりごり並列化をおこなっているのでとてもわくわくです(笑))
前回の記事で、RubyにおけるThreadは多くの場合にて
"並行処理となる"
ことに簡単にふれてみました。
今回は、Threadだけでなく、Forkも含めた、
Rubyでのマルチスレッドおよびマルチプロセスのプログラムとその速度比較を行ってみたいとおもいます。
まず実験環境
今回は贅沢に
Intel Xeon E5-2690 v3 @ 2.60GHz (Turbo Boost時 3.5) 12Core × 1
DDR4 ECC 16GByte @ 2133MHz × 4
の計算機サーバを使って、CentOS7、Ruby 2.2.0 の実験環境を用意しました。
コード
今回は、
Normal : 普通に書いた場合
Thread : Threadを用いたマルチスレッド
Fork : Forkを用いたマルチプロセス
の3つの浮動小数点の加算の速度比較を行います。
以下、Rubyにおけるコードです。
これを実行すると、こんな感じで結果が得られます。
$ruby add_speed.rb 12 0.000 0.001 0.095 24 0.000 0.001 0.116 48 0.000 0.001 0.119 96 0.000 0.001 0.152 192 0.000 0.001 0.185 384 0.000 0.001 0.109 768 0.000 0.001 0.166 1536 0.000 0.001 0.127 3072 0.000 0.001 0.093 6144 0.000 0.002 0.144
結果
では、今回行ったRubyのNormal, Thread, Forkの速度比較の結果を見ていきます。
gnuplotでプロットした結果です。まずはそのまま結果をプロット。
続いて、Normalに対する速度向上比を見てみます。
考察
それぞれ普通に書く場合、マルチスレッドの場合、マルチプロセスの場合を比較しました。
やはりRubyのThreadクラスを用いたマルチスレッドでの処理では、仕様上、複数のプロセスを活かす並列処理を行えませんでした。
(詳しくはこちらRubyのスレッド周りの話 - Qiita)
また、ThreadとForkに関してそれぞれの生成コストがとても大きいことがわかりますね。
(rubyにおいて、普通に書いた、シングルスレッドは相当優秀ですね...)*1
ただ、かなり大掛かりな処理になると、Forkは約10倍の速度向上も見られます。
.
以下、個人的なおまけ。(偏見込み)
おk。重い処理はForkで組めばいいのね。
これは、良くない考えかと思います。
Forkでプログラムを組むと確かに、Rubyで複数のコアを活かせる処理ができます。
しかし、デメリットとして、
- マルチプロセスの為、メモリ空間がプロセス毎に分けられる。
- 結果等を受け取るには、プロセス間通信が必要。(socketやパイプ)
- 何より、並列化等実装のコストが...
などなど...。
そもそもRubyに処理速度を求めるのは間違いですね。
速さが重要なら、C++等でGPGPUやMPIですかね。
じゃあ、Threadのメリットって?
今回は活かしきれないThreadですが、
- クローラー
- Thread + Queue を使ったプログラム 等に、大きなメリットがあるかと思います。
このへんは、後日簡単なプログラムでメリットを見ていきたいとおもいます。
*1:今回は、Threadが活かしにくいプログラムとなっています
Rubyでマルチスレッド <Thread>
どうも、こんにちは。kazunyaaanです。
年は明けましたが、まだまだ、大雪が続いております...
マルチスレッドやマルチプロセス
Haswell世代にて物理18コアを達成したE5-2699v3など、マルチコア化が進む中、
マルチスレッド or マルチプロセスは重要なキーワードではないでしょうか?
そこで、数回にわたってRubyにおけるマルチスレッドプログラミングを取り扱っていこうかと思います。
Rubyにおけるマルチスレッド処理
RubyではThreadクラスを用いて、以下のように比較的簡単に"並列"処理を行うことができます。
a_thread = Thread.new do 5.times do |i| puts "#{i} : I am A." end end b_thread = Thread.new do 5.times do |i| puts "#{i} : I am B." end end a_thread.join b_thread.join
メインスレッド、a_thread、b_threadの3つのスレッドがプログラム実行中に存在し、 実行結果は、マルチスレッドで実行しているため毎回異なりますが、
0 : I am B. 1 : I am B. 2 : I am B. 3 : I am B. 0 : I am A. 4 : I am B. 1 : I am A. 2 : I am A. 3 : I am A. 4 : I am A.
のようになりますね。
Threadクラスを使ったRubyのプログラムは"並列"に処理をしていることが確認できるかと思います。
しかし、Rubyのスレッドはある時点に1つのスレッドを処理しているもので、複数コアでの並列処理はできていないのです。
(top
コマンド等で確認してみてください)
Rubyのスレッドに関する(メモ)
(~1.8) -> グリーンスレッド http://docs.ruby-lang.org/ja/1.8.7/doc/spec=2fthread.html
(1.9~) -> ネイティブスレッド http://docs.ruby-lang.org/ja/2.2.0/doc/spec=2fthread.html
2.2.0のThreadクラスの実装の一部を見てみると...
ネイティブスレッドを用いて実装されていますが、 現在の実装では Ruby VM は Giant VM lock (GVL) を有しており、同時に実行される ネイティブスレッドは常にひとつです。
となってるんですよね...
次回、そこらへんを見ていきます。では。