Closed ckcr4lyf closed 1 year ago
"Normal" behavior - sub millisecond latency, not too many FIN_WAIT
or ESTABLISHED
I would suggest you look at Axum. I've ditched Actix for having also some memory leak issues. Seeing you already follow my Torrust-Axum project, you probably are maybe already aware :)
Yep, need to dig deeper into whether the cheap VPS is limiting or it really is Actix
Yep, need to dig deeper into whether the cheap VPS is limiting or it really is Actix
I've got my own hardware I put in a datacenter, although it runs in a VM.
VM is most likely the culprit, I would suggest you monitor also the amount of active packets, and/or drops through /var/log/syslog
, and you can use the command ss -s
to see active TCP and UDP connections.
Most possible, you would see some info in the syslog file, just use a command like tail -f /var/log/syslog
to 'watch' the file with additions ;)
Triage: Seems this is due to redis sets. Currently, for any torrent, we call ZRANGEBYSCORE
to get the seeders & leechers on two ZSET
s:
https://github.com/ckcr4lyf/kiryuu/blob/bf6d0bad158a8c558b775e2ffd98c2b487a3d7f4/src/main.rs#L71-L74
Redis has a useful --bigkeys
command, using which we can find the largest ZSET:
$ redis-cli --bigkeys --pattern '*_seeders'
[...truncated]
Sampled 427012 keys in the keyspace!
Total key length in bytes is 20496576 (avg len 48.00)
Biggest zset found '"17d0442b088a570dd94f98c6b367b98494704171_seeders"' has 30452 members
This torrent has ~30k seeders. As a result, whenever any of those 30k seeders (or ~10k leechers I also discovered) announces, kiryuu
calls ZRANGEBYSCORE
on two ZSET
s with ~30k & ~10k members.
Additionally the leechers are also shuffled, which can be CPU expensive: https://github.com/ckcr4lyf/kiryuu/blob/bf6d0bad158a8c558b775e2ffd98c2b487a3d7f4/src/main.rs#L86
This is most evident when we see stats for mywaifu. Notice how the average number of commands redis executes stays the same throughout the ~30hr time period.
However, ~2022-01-17T19:00:00 onwards, the HTTP announce latency skyrockets. The redis netwok I/O also increases massively, and most time is spent by the ZRANGEBYSCORE
command. This is most likely due to the massive number of peers on the torrent, which are very expensive on the CPU (executing ZRANGEBYSCORE on a ZSET with 30k+ members by Redis, as well as shuffling within kiryuu probably)
ZRANGEBYSCORE
This will reduce network traffic & CPU load on redis. The time complexity is "O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements returned." (Ref: https://redis.io/commands/zrange/)
Instead , we can get the last N elements of the ZSET
, and then shuffle those.
Pros:
ZRANGEBYSCORE
)rand
shuffle)Cons:
ZRANGEBYSCORE
(since it is incomplete). Instead we would need to make another redis call, probably ZSCORE
(as it is O(1)).BitTorrent works by announcing at fixed intervals, usually every 30 min.
If Peer A announces at t = 0, And then N
peers announce at 5 <= t <= 25 , and then Peer B announces at t=29, then Peer B will be limited to N
peers, and would not see Peer A. This isn't a massive downside, especially with DHT & such aiding in peer discovery once you have a few peers.
FYI: COmparing the CPU load (on VPS) with redis queries... gg...
This has been fixed by:
Some other micro optimizations include:
Vec<u8>
to [u8; 6]
(https://github.com/ckcr4lyf/kiryuu/pull/24)String
to [u8; 40]
, and redis keys to use [u8; _]
instead of allocating String
s . (https://github.com/ckcr4lyf/kiryuu/pull/27)Overall result: Can now process ~2500 announce per second while maintaining sub millisecond latency
2 week view:
need to investigate cause... Announce latency goes upto 7+ seconds!