From nakano.hiroaki @ nttcom.co.jp Thu Jan 5 16:00:13 2012 From: nakano.hiroaki @ nttcom.co.jp (=?ISO-2022-JP?B?GyRCQ2ZMbiEhOShPLxsoQg==?=) Date: Thu, 05 Jan 2012 16:00:13 +0900 Subject: [Ultramonkey-l7-develop 775] Re: =?iso-2022-jp?b?W1VsdHJhbW9ua2V5LWw3LWRldmVsIDQ1NF0gU1NMSUQ=?= =?iso-2022-jp?b?GyRCTGRCaiROJUElMSVDJUhILzlUME1NahsoQg==?= In-Reply-To: <4F03AC5E.2000709@nttcom.co.jp> References: <4EBCDAD2.2040106@nttcom.co.jp> <4EE86274.302@nttcom.co.jp> <4F03AC5E.2000709@nttcom.co.jp> Message-ID: <4F054A7D.7040305@nttcom.co.jp> 中野@幕張です。 ついでに、今はdown threadのhandle_client_connection_check()で、 常に上書きしているsslidとrealserver endpointとのmapを、endpointが 更新されている時だけ上書きするようにしました。 RFC的に言うと、「同じendpointから返って来たserver helloのsslidであっても、 更新される時がある、ということですが、mapがsslidをキーとしているので、 sslidで検索して、endpointを比較するというコードになっています。 その場合、返り値は0でも1でもあまり関係ない(0でも1でもendpoint更新しないと いけない場合がある)ので、返り値は見てません。 # -1の時って、エラー処理だか、FINALIZE状態にするとかしたほうがいいのかな? get_endpoint_from_session_data()はmapをロックしませんが、write_session_data()は mapをロックするので、ロックを少しでも減らすためにこうしてみました。 ・・・でも、あまり速度変わってないorz # つか、計測環境がいまいちうまく構築できてない気がす(泣) (2012/01/04 10:33), 中野 宏朗 wrote: > 中野@幕張です。 > > sslidの既存のコードですが、一応自分のアルゴリズム通りになっているっぽいので、 > 既存のコードベースで改善をしてみることにしました。 > > ・memmoveの除去 > →単なるオフセットのためだけにmemmoveしてる。memmoveは内部で2回メモリコピー走るので、 >  コストがでかい。んなもん、ポインタアドレス書き換えるだけでいい。 > ・realserver_selectedのフラグ化 > →boostのendpoint型のnullというか、0というか、それの比較のためだけに >  型宣言と暗黙の初期化を使って比較している。そのためだけに、パケットくるたびに >  インスタンス起こすなんて無駄。ほんとはビット演算が一番良いが、他のフラグに >  あわせてとりあえずint型のflag変数に置き換え。 > > パフォーマンス低下に支配的なのは、たぶんsslid用mapのロックなんですが、 > そこを変えるのは今の設計を大幅に変えることになるので、とりあえず > やりやすいところから。 > > memcopyもすごく無駄なので無くしたいのですが、ここを変えるとなると > threaddata->data_bufferを無くして、ポインタ管理に切り替えるような > 根本的対処が必要になるので、とりあえず放置・・・ > # クライアントから受け取ったデータは、そのまま一度もコピーとかすることなく > # リアルサーバ用ソケットにアドレス渡せばいいのに。わざわざメインメモリに > # 入出力アクセスしてるから、CPUキャッシュからも外れて遅くなってる。 > > > (2011/12/14 17:46), 中野 宏朗 wrote: >> 中野@幕張%別仕事でコードからどんどん離れる・・・です。 >> >> sslidのパーシステント部分をごっそり無効にしたコードで >> 検証しようとしていて、よくわからないコード見つけました。 >> >> protocol_module_sslid.cpp >> protocol_module_sslid::handle_realserver_select( >> の >> 1517 if (realserver_selected(threaddata->selected_realserver)) { >> の中身。 >> >> 4143 boost::asio::ip::tcp::endpoint temp_endpoint; >> 4144 if (temp_endpoint == rs_endpoint) { >> >> ・・・これ、なにを比較しようとしたいの?temp_endpointの存在意義って・・・ >> threaddata->selected_realserverって、どこで入るんだろう・・・ >> >> あと、 >> >> 1543 (get_ssl_session_id(threaddata->data_buffer.data() + threaddata->data_begain_offset, >> 1544 threaddata->data_size, session_id) == -1)) { >> >> の中身って、リターンコードは0と1と-1返してるけど、-1しか使ってないよね。 >> まあ、 >> >> 1572 if (session_id.empty()) { >> >> で見てるんだろうけど。でもC++なら暗黙に初期化されるとはいえ、session_id初期化してないし。 >> >> コード見て何がしたいのかわかんなかったので、外部設計書とか確認したけど、 >> アルゴリズムがRFCベースとは違ってる感じ。 >> UltraMonkey使わないときのSSL IDのプロトコルをまずはベースにして、 >> そこにUM-L7入れたときにどういう手順にするかしないと。 >> >> もともとのSSL IDは、RFC2246の7.3節あたり。 >> >> http://www5b.biglobe.ne.jp/~type-aya/rfc/rfc2246j.txt >> >> そこにUM-L7を噛ませた場合のアルゴリズムを、もう一度考えてみました。 >> ====== >> 1. ClientHelloのパケットをupthreadで捕まえる。 >> 2. SSLIDが付与されているかどうか、見る。 >> 3. 付与されていなければ、スケジュールモジュールによりendpointを決めて、6にいく。 >> 4. 付与されていれば、session_endpoint_mapに問い合わせて、endpointをゲットし、6にいく。 >> 5. 4でゲットできなければ、session_endpoint_mapにSSLIDとendpointを登録して、3にいく。 >> 6. リアルサーバにぶんなげる。 >> 7. ServerHelloのパケットをdownスレッドで捕まえる。 >> 8. 捕まえたパケットのSSLIDをぶっこ抜く。 >> 9. ぶっこ抜いたSSLIDが、upthreadで捕まえたClientHelloのSSLIDを同じかチェックする。 >> 10. 同じならば、12にいく。 >> 11. 違ったら、session_endpoint_mapの該当endpointのセッションIDのほうを更新する。 >>   あ、単に追加するだけでもいいか。できれば、古いのを消す。 >> 12. クライアントにぶんなげる。 >> ====== >> >> 要は、SSL IDが入っていたら、まずはsession_endpoint_mapを見なければ始まらないはず。 >> realserver_selectedって何者なんだ。sslidやmap見る前に格納されるデータに見えないんだけど。 >> あと、RFC2246によると、SSLIDがリアルサーバ側でヒットしなければ、Server Helloで >> 異なるIDを付与して送ってくるはず。 >> そしたら、downthreadでmapを更新しなければいけないはず。その処理ないよね? >> >> まずは上記アルゴリズム案で直してみようと思いますが、どうでしょう。 >> 速度が出るかどうかは未保障w >> >> つか、session_endpoint_mapをスレッドまたがりのデータとして持って、 >> mutex lock掛けながらスレッドが参照しなきゃいけないから、かなり >> 遅くなると思う。セッションレスより遅くなるんじゃないかな。 >> >> session_endpoint_mapをスレッド固有データとして持てるデータ構造というか >> 仕組みを考案できたら、速くなるだろうけど。 >> >> あと問題は、自分がコードいじれるまとまった時間がないってこと・・・ >> >> (2011/11/11 17:20), 中野 宏朗 wrote: >>> 中野@幕張です。 >>> >>> SSLIDモジュールで通信した時、性能が極端に悪いという事象について、 >>> どなたかチケットを発行してもらえないでしょうか。 >>> # 自分でやってもいいですが(出来るのかな?)、自分は上記以上の経緯は >>> # 知らないので・・・ >>> >>> で、自分がとりあえず担当しますので、hiroakinakanoにアサイン >>> してもらえればと思います。 >>> >>> ちなみに、まだ糸口はつかめていませんorz >>> >>> # sslidのhandler系にrdtsc仕掛けてみたんですが、時間かかっているところは >>> # 見つからなかったので、ハンドラ内で時間かかっているわけではなさそう。 >>> # となると、ハンドラを起動するのに時間かかっている?それだと他の >>> # プロトコルでも再現しそうなきもするし・・・ >>> >>> # 他に固有なところといえば、ssl_protocol_module_base?といっても、 >>> # 特定のオフセットのデータをみてるだけだよな〜・・・ >>> # ひょっとして、protocolモジュールをVirtualServiceからロードし、 >>> # sessionスレッドで呼び出すから、パケットデータであるthreaddataの >>> # 参照で、CPU間でメインメモリ介したコピーが走ってる?でもそんなに >>> # 影響するかなぁ・・・ >>> ## 脳みそ沸騰中 >>> >> > > > > _______________________________________________ > Ultramonkey-l7-develop mailing list > Ultramonkey-l7-develop @ lists.sourceforge.jp > http://lists.sourceforge.jp/mailman/listinfo/ultramonkey-l7-develop -- 中野 宏朗 (NAKANO Hiroaki) NTTコムウェア 品質生産性技術本部 技術SE部 基盤ソフトSE・OSS部門 OSS適用推進担当 Tel: 043-211-2452 (Ext: 特番+26-8341), Fax: 043-211-5086 Zip/Address: 261-0023 千葉県千葉市美浜区中瀬1-6 NTT幕張ビル21F-En -------------- next part -------------- Index: module/protocol/protocol_module_sslid.cpp =================================================================== --- module/protocol/protocol_module_sslid.cpp (リビジョン 11581) +++ module/protocol/protocol_module_sslid.cpp (作業コピー) @@ -3166,12 +3166,17 @@ if (!session_id.empty()) { // session id exist - time_t now; - time(&now); - session_data_processor->write_session_data(session_id, - threaddata->selected_realserver, - now); - + boost::asio::ip::tcp::endpoint temp_endpoint; + session_data_processor->get_endpoint_from_session_data( + session_id, + temp_endpoint); + if (threaddata->selected_realserver != temp_endpoint) { + time_t now; + time(&now); + session_data_processor->write_session_data(session_id, + threaddata->selected_realserver, + now); + } /*-------- DEBUG LOG --------*/ if (unlikely(LOG_LV_DEBUG == getloglevel())) { std::string buffer;