[Ultramonkey-l7-develop 774] Re: [Ultramonkey-l7-devel 454] SSLID問題のチケット発行依頼

アーカイブの一覧に戻る

中野 宏朗 nakan****@nttco*****
2012年 1月 4日 (水) 10:33:18 JST


中野@幕張です。

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間でメインメモリ介したコピーが走ってる?でもそんなに
>> # 影響するかなぁ・・・
>> ## 脳みそ沸騰中
>>
> 

-- 
中野 宏朗 (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	(リビジョン 11540)
+++ module/protocol/protocol_module_sslid.cpp	(作業コピー)
@@ -38,6 +38,8 @@
 const int protocol_module_sslid::ACCEPT_END_FLAG_ON = 1;                // accept flag on
 const int protocol_module_sslid::SORRY_FLAG_ON = 1;                        // sorry flag on
 const int protocol_module_sslid::SORRY_FLAG_OFF = 0;                       // sorry flag off
+const int protocol_module_sslid::SELECTED_FLAG_ON = 1;                     // realserver selected flag on
+const int protocol_module_sslid::SELECTED_FLAG_OFF = 0;                     // realserver selected flag off
 
 //! constructor
 protocol_module_sslid::protocol_module_sslid()
@@ -956,6 +958,7 @@
                 threaddata_up->sorry_flag = SORRY_FLAG_OFF;                     // set sorry_flag OFF
                 threaddata_up->end_flag = END_FLAG_OFF;                         // set end_flag OFF
                 threaddata_up->accept_flag = ACCEPT_END_FLAG_OFF;               // set accept_flag OFF
+		threaddata_up->selected_flag = SELECTED_FLAG_OFF;               // set selected_flag OFF
                 threaddata_up->thread_division = THREAD_DIVISION_UP_STREAM;     // up thread division
                 threaddata_up->pair_thread_id = down_thread_id;
                 threaddata_up->last_status = ACCEPT;
@@ -966,7 +969,7 @@
                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_sslid::"
                                                 "handle_session_initialize() : session_thread_data_sslid(upthread) : "
                                                 "data_begin_offset = %d, data_size = %d, current_record_rest_size = %d, "
-                                                "hello_message_flag = %d, sorry_flag = %d, end_flag = %d, accept_flag = %d, "
+                                                "hello_message_flag = %d, sorry_flag = %d, end_flag = %d, accept_flag = %d, selected_flag = %d, "
                                                 "thread_division = %d, pair_thread_id = %d, last_status = %d.");
                         formatter % threaddata_up->data_begain_offset
                         % threaddata_up->data_size
@@ -975,6 +978,7 @@
                         % threaddata_up->sorry_flag
                         % threaddata_up->end_flag
                         % threaddata_up->accept_flag
+                        % threaddata_up->selected_flag
                         % threaddata_up->thread_division
                         % threaddata_up->pair_thread_id
                         % threaddata_up->last_status;
@@ -999,6 +1003,7 @@
                 threaddata_down->sorry_flag = SORRY_FLAG_OFF;                   // set sorry_flag OFF
                 threaddata_down->end_flag = END_FLAG_OFF;                       // set end_flag OFF
                 threaddata_down->accept_flag = ACCEPT_END_FLAG_OFF;             // set accept_flag OFF
+		threaddata_down->selected_flag = SELECTED_FLAG_OFF;               // set selected_flag OFF
                 threaddata_down->thread_division = THREAD_DIVISION_DOWN_STREAM; // down thread division
                 threaddata_down->pair_thread_id = up_thread_id;
                 threaddata_down->last_status = REALSERVER_RECV;
@@ -1009,7 +1014,7 @@
                         boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_sslid::"
                                                 "handle_session_initialize() : session_thread_data_sslid(downthread) : "
                                                 "data_begin_offset = %d, data_size = %d, current_record_rest_size = %d, "
-                                                "hello_message_flag = %d, sorry_flag = %d, end_flag = %d, accept_flag = %d, "
+                                                "hello_message_flag = %d, sorry_flag = %d, end_flag = %d, accept_flag = %d, selected_flag = %d, "
                                                 "thread_division = %d, pair_thread_id = %d, last_status = %d.");
                         formatter % threaddata_down->data_begain_offset
                         % threaddata_down->data_size
@@ -1018,6 +1023,7 @@
                         % threaddata_down->sorry_flag
                         % threaddata_down->end_flag
                         % threaddata_down->accept_flag
+                        % threaddata_down->selected_flag
                         % threaddata_down->thread_division
                         % threaddata_down->pair_thread_id
                         % threaddata_down->last_status;
@@ -1312,7 +1318,8 @@
                                 /*------DEBUG LOG END------*/
 
                                 // move the data from data start pos to buffer start pos
-                                memmove(databuf, databuf + threaddata->data_begain_offset, threaddata->data_size);
+                                //memmove(databuf, databuf + threaddata->data_begain_offset, threaddata->data_size);
+				databuf += threaddata->data_begain_offset;
 
                                 /*-------- DEBUG LOG --------*/
                                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
@@ -1514,7 +1521,8 @@
                 }
 
                 // the first connection or connected successful
-                if (realserver_selected(threaddata->selected_realserver)) {
+                //if (realserver_selected(threaddata->selected_realserver)) {
+                if (realserver_selected(threaddata)) {
                         /*-------- DEBUG LOG --------*/
                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_sslid::"
@@ -1582,6 +1590,7 @@
                                 if (temp_endpoint != comp_endpoint) {
                                         // success for get the endpoint by reschedule
                                         threaddata->selected_realserver = temp_endpoint;
+					threaddata->selected_flag = SELECTED_FLAG_ON;
                                         rs_endpoint = temp_endpoint;
                                         status = REALSERVER_CONNECT;
                                 } else {
@@ -1638,6 +1647,7 @@
                                         if (is_match) {
                                                 // get the endpoint successfully
                                                 rs_endpoint = threaddata->selected_realserver;
+						threaddata->selected_flag = SELECTED_FLAG_ON;
                                                 status = REALSERVER_CONNECT;
                                         } else {
                                                 // failed to get the endpoint
@@ -1653,6 +1663,7 @@
                                                         if (temp_endpoint != comp_endpoint) {
                                                                 // get the endpoint by reschedule successfully
                                                                 threaddata->selected_realserver = temp_endpoint;
+								threaddata->selected_flag = SELECTED_FLAG_ON;
                                                                 rs_endpoint = temp_endpoint;
                                                                 status = REALSERVER_CONNECT;
                                                         } else {
@@ -1728,6 +1739,7 @@
                                                         if (temp_endpoint != comp_endpoint) {
                                                                 // get the endpoint by reschedule successfully
                                                                 threaddata->selected_realserver = temp_endpoint;
+								threaddata->selected_flag = SELECTED_FLAG_ON;
                                                                 rs_endpoint = temp_endpoint;
                                                                 status = REALSERVER_CONNECT;
                                                         } else {
@@ -2626,6 +2638,8 @@
                         /*-------- DEBUG LOG --------*/
                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
                                 std::string datadump;
+				// get the c-style pointer from data buffer
+				//char *databuf = threaddata->data_buffer.c_array();
                                 dump_memory(databuf + threaddata->data_begain_offset, threaddata->data_size, datadump);
 
                                 boost::format formatter("function : protocol_module_base::EVENT_TAG protocol_module_sslid::"
@@ -2637,7 +2651,8 @@
                         /*------DEBUG LOG END------*/
 
                         // move the data from data start pos to buffer start pos
-                        memmove(databuf, databuf + threaddata->data_begain_offset, threaddata->data_size);
+                        //memmove(databuf, databuf + threaddata->data_begain_offset, threaddata->data_size);
+			databuf += threaddata->data_begain_offset;
 
                         /*-------- DEBUG LOG --------*/
                         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
@@ -4129,19 +4144,20 @@
 //! @param[in] endpoint reference
 //! @return false if endpoint is not selected
 //! @return true if endpoint is selected
-bool protocol_module_sslid::realserver_selected(const boost::asio::ip::tcp::endpoint &rs_endpoint)
+bool protocol_module_sslid::realserver_selected(const thread_data_ptr &threaddata)
 {
         /*-------- DEBUG LOG --------*/
         if (unlikely(LOG_LV_DEBUG == getloglevel())) {
                 boost::format formatter("in_function : bool protocol_module_sslid::realserver_selected("
                                         "const boost::asio::ip::tcp::endpoint& rs_endpoint) : rs_endpoint = [%s]:%d.");
-                formatter % rs_endpoint.address().to_string() % rs_endpoint.port();
+                formatter % threaddata->selected_realserver.address().to_string() % threaddata->selected_realserver.port();
                 putLogDebug(300169, formatter.str(), __FILE__, __LINE__);
         }
         /*------DEBUG LOG END------*/
 
-        boost::asio::ip::tcp::endpoint temp_endpoint;
-        if (temp_endpoint ==  rs_endpoint) {
+        //boost::asio::ip::tcp::endpoint temp_endpoint;
+        //if (temp_endpoint ==  rs_endpoint) {
+        if (threaddata->selected_flag ==  SELECTED_FLAG_OFF) {
                 /*-------- DEBUG LOG --------*/
                 if (unlikely(LOG_LV_DEBUG == getloglevel())) {
                         putLogDebug(300170, "out_function : bool protocol_module_sslid::realserver_selected("



Ultramonkey-l7-develop メーリングリストの案内
アーカイブの一覧に戻る