libp 2 p-rsモニタリング指標の実現について


モジュールアドレス:https://github.com/netwarps/l...
libp 2 p-rsはp 2 pネットワークプロジェクトとして、ネットワークデータの送受信状況を観察し、収集し、まとめる必要がある場合があります.この前提に基づいて,metricモジュールを設計して関連コンテンツを実現した.
metric実現構想
libp 2 pは複数のpeerの接続をサポートするため、各peerがサポートするprotocolタイプも異なる.パケットを受信するデータをまとめるだけでなく、peer_に基づいてidとprotocolは、対応するネットワークトラフィックを分類して記録します.明らかに、これはkey-value構造であり、HashMapを使用して関連データを格納することを考えるのは当然ですが、HashMapはスレッドセキュリティのデータ構造ではありません.では、マルチスレッドセキュリティの同時性をサポートするHashMapを実現することを考慮する必要があります.
安全な同時実行
設計当初はArcでMutexを包む方式でスレッドセキュリティを保証することをまず考慮したが,現在の使用シーンはネットワーク送受信パケットの統計であるため,lockの操作を頻繁に行うと性能が極めて低下する.そこでgo-libp 2 pに関するmetric実装を参考にし,Goの下層にsyncを用いた.Mapの構造は,Atomic+Mutexによりマルチスレッド同時セキュリティを保証している.そこで設計された論理は,CASのような原子操作を用いてlock−freeのHashMapを実現できるかどうかとなる.
ごみ回収
スレッドのセキュリティに加えて、もう一つの状況も考慮する必要があります.JavaとGoでは、変数の使用が完了すると、GCが自動的にメモリを解放する操作を行います.Rustでは、裸ポインタはメモリアドレスを指すポインタであり、手動で解放することでメモリを回収するしかない.また、手動で回収する場合は、他のスレッドが裸ポインタでメモリアドレスを使用しているかどうかを考慮する必要があります.AtomicPtrのcompare_and_swap()メソッドが返すのはちょうど可変の裸ポインタ(すなわち*mut T)であり,これは間違いなく厄介な問題である.
crossbeam-epoch
上記の2つの状況に対して,Crossbeam−Opochを用いて遭遇した問題を解決することができる.Atomicの関連原子操作と遅延削除の機能を提供します.その名の通り、epochは世代と遅延キューを使用し、local epochとglobal epochが2世代異なる場合、キュー内の2世代前のメモリアドレスを安全に回収できることを表し、前述した裸ポインタ解放操作による脆弱性を補う.crossbeamはepochというメカニズムにより,すべてのオブジェクトが参照されていない場合にのみ削除されることを保証し,野ポインタの発生を回避した.
MetricMap
MetricMapはMetricのコアとして、内部実装はcrossbeamを包んでいます.epoch::AtomicのHashMap.crossbeamでepochが提供するpin(),load(),defer_destroy()など一連の方法でlock-freeのHashMapを実現した.
MetricMapの実装はgo−libp 2 pにおけるDeepCopyMapと類似しており,いずれもmap構造の置換を深いコピーにより実現している.Clone()操作はmapのデータ量が大きい場合,性能への影響が顕著であり,その後関連構造の最適化を考慮する.
store_でor_modify()メソッドの例:
  • まずpin()メソッド「pin」を使用して現在のthreadを居住し、グローバルepochアップグレードによって現在のスレッドのdrop()メソッドが呼び出されることを防止する.
  • は次にloopを開始し、AtomicのHashMapを循環的にロードする.
  • HashMapに対する参照はrustで裸のポインタの参照を解くのは安全ではないため、unsafe法で包む必要がある.
  • as_ref()メソッドは可変参照を返し,clone()によって新しいHashMapを得る必要がある.key値が存在する場合、閉パケットに値を伝達することによって新しい戻り値を取得し、valueを更新する.そうでなければ新しいkey-valueを挿入します.
  • Owned::newは新しいHashMapにスタック上のメモリアドレスを割り当て、CAS操作を実行する.
  • CASが成功した場合、消去対象リストに古いHashMapアドレスが追加されます.このリストは、前述した遅延削除のキューです.
  •     /// If map contains key, replaces original value with the result that return by F.
        /// Otherwise, create a new key-value and insert.
        pub fn store_or_modify V>(&self, key: &K, value: V, on_modify: F) {
            let guard = crossbeam_epoch::pin();
    
            loop {
                let shared = self.data.load(SeqCst, &guard);
    
                let mut new_hash = HashMap::new();
    
                match unsafe { shared.as_ref() } {
                    Some(old_hash) => {
                        new_hash = old_hash.clone();
                        if let Some(old_value) = new_hash.get(key) {
                            let new_value = on_modify(key, old_value);
                            new_hash.insert(key.clone(), new_value.clone());
                        } else {
                            new_hash.insert(key.clone(), value.clone());
                        }
                    }
                    None => {
                        new_hash.insert(key.clone(), value.clone());
                    }
                }
    
                let owned = Owned::new(new_hash);
    
                match self.data.compare_and_set(shared, owned, SeqCst, &guard) {
                    Ok(_) => {
                        unsafe {
                            guard.defer_destroy(shared);
                            break;
                        }
                        // break;
                    }
                    Err(_e) => {}
                }
            }
        }

    Metric
    Metricの主体は以下のように実現され,peerとprotocolに関連するデータ構造はいずれもMetricMapに基づいていることがわかる.合計パケット数とバイト数のサイズを区別する必要はありませんので、stdのAtomicUIzeをそのまま使用します.
    pub struct Metric {
        /// The accumulative counter of packets sent.
        pkt_sent: AtomicUsize,
        /// The accumulative counter of packets received.
        pkt_recv: AtomicUsize,
        /// The accumulative counter of bytes sent.
        byte_sent: AtomicUsize,
        /// The accumulative counter of bytes received.
        byte_recv: AtomicUsize,
    
        /// A hashmap that key is protocol name and value is a counter of bytes received.
        protocol_in: MetricMap,
        /// A hashmap that key is protocol name and value is a counter of bytes sent.
        protocol_out: MetricMap,
    
        /// A hashmap that key is peer_id and value is a counter of bytes received.
        peer_in: MetricMap,
        /// A hashmap that key is peer_id and value is a counter of bytes sent.
        peer_out: MetricMap,
    }

    まとめ
    以上、Metric関連構造の実現から完成まで、中に理解上の誤りがあれば、ご指導をお願いいたします.現在のところ、MetricMapの設計は、1回に複数回の変更を追加する場合に適しています.その後、1つのWebサーバを介して、Restful APIを介して関連監視データを暴露し、外部での表示を容易にすることを考慮する.
    Netwarpsは、金融、電力、通信、インターネット業界で非常に豊富な経験を持つ国内のベテランクラウドコンピューティングと分散技術開発チームから構成されています.Netwarpsは現在、深セン、北京に研究開発センターを設立し、チームの規模は30+で、その大部分は10年以上の開発経験を持つ技術者で、それぞれインターネット、金融、クラウドコンピューティング、ブロックチェーン、科学研究機関などの専門分野から来ている.
    Netwarpsは安全なストレージ技術製品の研究開発と応用に専念し、主な製品はデセンタ化ファイルシステム(DFS)、デセンタ化コンピューティングプラットフォーム(DCP)があり、デセンタ化ネットワーク技術に基づいて実現した分布式ストレージと分布式コンピューティングプラットフォームを提供することに力を入れ、高利用可能、低消費電力、低ネットワークの技術特徴を持ち、モノのインターネット、工業インターネットなどのシーン.
    公衆番号:Netwarps