libTorrent 調參


「P2P」 - libTorrent 調參


初步翻譯,不是很到位,先備註一下,後面再完善修正。


日誌信息收集

  • 1. 在 警報掩碼(alert mask)中啟用警報(alert)

settings_pack p;

//您將收到每個活動的torrent大約每秒一次的stats_alert。

//這些警報包含自上次該警報到現在所有統計計數器(statistics counters)。

p.set_int(settings_mask::alert_mask, alert::stats_notification);

ses.apply_settings(p);


  • 2. 然後將警報全部打印輸出到一個文件:

std::vector<alert> alerts;/<alert>

ses.pop_alerts(&alerts);

for (auto* a : alerts) {

std::cout << a->message() << "\\n";

}

如果要將常規警報和會話統計信息(session stats)分離開來,

可用 alert::category()篩選。

帶有數據的警報 有session_stats_alert,且系統啟動時發出session_log_alert,他包含所有的metrics. 記錄這一行將大大簡化對輸出的解釋。


  • 3. 日誌信息的圖表化

tools/parse_session_stats.py 可以解析結果文件並生成相關統計數據的圖表。它需要gnuplot。



減少內存佔用

預設函數 settings_pack min_memory_usage() 中可以獲得一些降低內存佔用的設置。

注意: 減少內存使用會影響性能。 應充分分析測試權衡是否值得使用。

假設libtorrent設置緩存大小為256blocks(256*16kB=4mB), 單個下載 典型的緩存使用情況:

read cache: 128.6 (2058 kiB)

write cache: 103.5 (1656 kiB)

receive buffers: 7.3 (117 kiB) # 與連接數成正比,最終受總連接數限制(總連接數默認200)

send buffers: 4.8 (77 kiB) # 與會話運行的上載槽(upload slots)數量呈正比,默認根據觀察到的上載速率自動配置

hash temp: 0.001 (19 Bytes) # 取決於是否針對速度和內存進行了優化,這兒是針對內存進行了優化。


  • 1. 禁用磁盤緩存

libtorrent使用大量的內存用於磁盤緩存。 緩存是客戶端使用多少內存的主因。

為了緩存保證內存的最大值,可以設置settings_pack::cache_size為0來禁用緩存。

若要使用緩存,可以僅禁用讀緩存,settings_pack::use_read_cache設置為false。

注意: 禁用緩存會降低性能。慎重權衡。

  • 2. 刪除種子(保存在內存中的種子)

添加到libtorrent中的種子不管處於什麼狀態始終會消耗內存。被添加的種子都會將整個torrent文件保存在內存中,它還會記住獲取到的所有peer列表(除非設置上限,否則可能很長)。

它還保留了關於磁盤上有哪些塊(block)和片段(piece)的信息(對於包含許多片段的torrent是非常重要的)。

若想最小化內存,則考慮從會話中(session)刪除而不是暫停它們,當然這對有大量種子的會話效果比較明顯。

缺點: 被刪除的將不再被自動管理(暫停卻則可以再有需要的時候自動激活播種)

  • 3. 套接字緩存區大小(socket buffer sizes)

我們可以設置該參數:settings_pack::recv_socket_buffer_size 和 settings_pack::send_socket_buffer_size

若設置低則吞吐量降低,連接延遲。但當有大量peer連接時確實可以為每個連接節省不少內存。該內存在進程中不可見,作用於套接字的內核內存。

  • 4.對等列表大小(settings_pack::max_peerlist_size)

默認最大值為4000.

簡單計算下 對等列表的內存:

a.每個IPv4對等端條目(peer)使用32字節,最終每個種子使用125 kB(32*4000),暫停狀態的種子同樣適應。

b.若播下4個流行種子,則需要500KB.

c.若播下1000個流行種子,則約122MB

c.若播下1w個流行種子,則約1.2GB

d.若播下30w個流行種子,則約31GB

這還僅僅只是 對等列表消耗的內存

如果你內存不足,建議設置小一些,500可能就夠了。


同樣需要針對暫停種子進行限制, 將settings_pack::max_paused_peerlist_size設置得低可能更具有意義,因為你只需要幾個對等點(peer)來啟動,同時等待tracker和DHT給你新的。


降低這個數字的缺點是,如果你最終處在一個tracker長時間處於關閉狀態的位置,那麼你找到活動的對等點(peer)的唯一希望就是查看你所見過的所有對等列表。

擁有一個大的對等列表也將有助於提高啟動時的性能,因為種子在開始與對等連接的同時連接到跟蹤器(tracker)。

  • 5. 發送緩衝區水位線(send buffer watermark)

控制libtorrent何時請求磁盤I/O線程從磁盤讀取塊,並將其附加到對等方的發送緩衝區。

當發送緩衝區的字節數小於或等於settings_pack::send_buffer_watermark時,對等方將要求磁盤I/O線程發送更多數據。這裡的折衷方案是:在發送緩衝區中有太多數據,從而浪費內存;在等待磁盤讀取操作完成時,耗盡套接字,從而降低發送速率。

如果僅關注內存使用但不關心能否實現高發送速率,則可以將它設置為9字節。這將保證對於所有對等點,每次在發送緩衝區上的塊(16KB) <= 1,這是發送緩衝區可能的最小內存量。

調整此設置時,應以最大發送速率作為參考基準。如果你有一個非常快的磁盤,你就不太可能看到性能受到影響。


  • 6. 減小可執行文件大小

6.1 通過禁用異常(-fno exceptions on GCC),您可以將可執行文件的大小減少45%。為了構建無異常支持,您需要修補boost的一部分。

6.2 禁用未使用的代碼。

有許多TORRENT_*宏可以控制libtorrent中包含的功能。若不需要則可以不編譯相關代碼。

還有一個宏TORRENT_NO_DEPRECATE,若定義,也可清除一些遺棄過時用不著的代碼。



高性能播種

在有海量種子的情況下,有兩個主要問題: 性能(高發送速率) 和 可擴展性(低內存和CPU使用率的對等連接)。

  • 1. 文件池(settings_pack::file_pool_size)

高性能種子,文件打開/關閉的頻率可能非常高,因此會造成很大的成本。因此,允許大文件描述符緩存可能是一個好主意。

且在您的進程中 設置可打開文件的數量的最大值(rlimit),要設置得儘可能大,以保持所有連接和文件處於打開狀態。

struct rlimit limit;

getrlimit(RLIMIT_NOFILE,&limit);

printf("current file limit is %d\\n",limit.rlim_cur);

printf("hard file limit is %d\\n",limit.rlim_max);

limit.rlim_max = 50000;

setrlimit(RLIMIT_NOFILE,&limit);

printf("hard file limit is %d\\n",limit.rlim_max);


  • 2. 磁盤緩存

通常需要將緩存大小設置為儘可能高。settings_pack::cache_size 以block(16KB)為單位。

settings_pack::use_read_cache設置為true,cache_size才會生效。

為了增加讀緩存命中率,請將設置_pack::cache_expiry設置為大的值。這不會降低任何東西,只要客戶端只是種子,而不是下載任何種子。

“導向性讀緩存”(settings_pack::guided_read_cache):存儲在緩存中的讀緩存線的大小取決於觸發讀操作的對等方的上載速率,基於該觀點 慢的對等點不會佔用緩存中不相稱的空間。


如果假設緩存僅用作預讀,並且其它對等點在緩存中時不會請求相同的塊,則可以將讀緩存設置為易失性。

這意味著從讀緩存中請求的每個塊都會立即被刪除。這節省了大量的緩存空間,可以用作其他對等機的預讀。settings_pack::volatile_read_cache設置為true。

  • 3. uTP-TCP混合模式

libtorrent支持uTP,uTP有一個基於延遲的擁塞控制器。為了避免單個TCP bt連接完全耗盡任何uTP連接,有一種混合模式算法。這將嘗試檢測uTP對等點上的擁塞,並限制TCP以避免它佔用所有帶寬。這平衡了兩個協議之間的帶寬資源。當在一個帶寬非常豐富的網絡上運行時,它實際上是無限的,這個算法不再是必要的,甚至可能對吞吐量有害。建議嘗試session_setting::mixed_mode_算法,將其設置為settings_pack::prefer_tcp。此設置完全禁用平衡並取消限制所有連接。在典型的家庭連接上,這意味著uTP的任何好處都不會保留(調制解調器的發送緩衝區將始終是滿的),而uTP連接在很大程度上會被TCP流量壓扁。

  • 4.發送緩衝區低水位線

libtorrent對發送緩衝區使用低水位線來確定何時應從磁盤I/O子系統請求新的塊,並將其追加到發送緩衝區。根據套接字的發送速率確定低水位線。

它需要足夠大,以便在磁盤操作完成之前不耗盡套接字的發送緩衝區。

水位線被綁定到最大值,以避免緩衝區大小失控。

默認的最大發送緩衝區大小可能不足以維持很高的上載速率,您可能需要增加它。它是在settings_pack::send_buffer_watermark中以字節為單位指定的。

  • 5.對等點

首先,為了允許多個連接,請將全局連接限制設置為“高”,即“settings_pack::connections_limit”。還將上載速率限制設置為無窮大,settings_pack::upload_rate_limit,0表示無窮大。

在處理大量對等方時,稍微嚴格一點的超時可能是一個好主意,以便儘快擺脫揮之不去的連接。

一組相關設置: settings_pack::request_timeout、settings_pack::peer_timeout和settings_pack::inactivity_timeout。

對於傳送系統至關重要的種子,您很可能希望允許來自同一IP的多個連接。這樣,同一NAT後面的兩個人可以同時使用該服務。settings_pack::allow_multiple_connections_per_ip.

要始終不阻塞(unchoke)對等方,請通過將settings_pack::choking_algorithm設置為fixed_slot_choker關閉自動不阻塞(unchoke),並通過settings_pack::unchoke_slots_limit將上載槽數設置為大值,或使用-1(這意味著無限)。

  • 6.種子限制

若要數千種子做種,您需要增加settings_pack::active_limit和settings_pack::active_seeds。

  • 7.SHA-1 哈希

當以非常高的速率下載時,CPU可能成為通過SHA-1傳遞每個下載字節的瓶頸。

為了能夠並行計算SHA-1散列,在多核系統上,將settings_pack::aio_threads設置為libtorrent應該執行I/O和進行SHA-1散列的線程數。

有當線程接近飽和一個核心時,增加線程數才有意義。



延伸

為了在同時運行大量種子時更有效地使用libtorrent接口,可以將session::get_torrent_status()調用與session::post_torrent_updates()一起使用。

請記住,每次調用libtorrent並返回一些值時,都必須在向主網絡線程發送消息時阻塞線程,然後等待響應。不返回任何數據的調用只會發送消息,然後立即返回,異步執行工作。一旦你到達幾百個torrent,所需的時間可能會變得非常重要,這取決於你給每個種子進行多少次調用以及頻率。

session::get_torrent_status()允許您在單個調用中查詢所有torrent的狀態。這實際上將遍歷所有種子並運行提供的函數(其參數),以確定是否將其包含在返回的vector數組中。

若要使用session::post_torrent_updates()發佈種子,需要設置標誌flag_update_subscribe 。調用post_torrent_updates()時,state_update_alert警報將被髮布,其中包含自上次調用此函數以來已更新的所有種子。客戶端必須保留其所有種子的狀態,並根據此警報進行更新。



基準化分析法

有一堆內置的libtorrent工具可以用來洞察它在做什麼以及表現如何。在編譯時定義預處理器符號來啟用這些工具。

還有許多腳本可以解析日誌文件並生成圖形(需要gnuplot和python)。


分享到:


相關文章: