| | 1 | Some basic notes on performance: |
| | 2 | |
| | 3 | == Memory Footprint == |
| | 4 | |
| | 5 | The MemoryFootprint page has more specific information. |
| | 6 | |
| | 7 | The |
| | 8 | [http://allmydata.org/tahoe-figleaf-graph/hanford.allmydata.com-tahoe_memstats.html |
| | 9 | munin graph] shows our static memory footprint (starting a node but not doing |
| | 10 | anything with it) to be about 24MB. Uploading one file at a time gets the |
| | 11 | node to about 29MB. (we only process one segment at a time, so peak memory |
| | 12 | consumption occurs when the file is a few MB in size and does not grow beyond |
| | 13 | that). Uploading multiple files at once would increase this. |
| | 14 | |
| | 15 | == Network Speed == |
| | 16 | |
| | 17 | === test results === |
| | 18 | |
| | 19 | Using a 3-server testnet in colo and an uploading node at home (on a DSL line |
| | 20 | that gets about 150kBps upstream and has a 14ms ping time to colo) using |
| | 21 | 0.5.1-34 takes 820ms-900ms per 1kB file uploaded (80-90s for 100 files, 819s |
| | 22 | for 1000 files). |
| | 23 | |
| | 24 | 'scp' of 3.3kB files (simulating expansion) takes 8.3s for 100 files and 79s |
| | 25 | for 1000 files, 80ms each. |
| | 26 | |
| | 27 | Doing the same uploads locally on my laptop (both the uploading node and the |
| | 28 | storage nodes are local) takes 46s for 100 1kB files and 369s for 1000 files. |
| | 29 | |
| | 30 | |
| | 31 | |
| | 32 | === Roundtrips === |
| | 33 | |
| | 34 | The 0.5.1 release requires about 9 roundtrips for each share it uploads. The |
| | 35 | upload algorithm sends data to all shareholders in parallel, but these 9 |
| | 36 | phases are done sequentially. The phases are: |
| | 37 | |
| | 38 | 1. allocate_buckets |
| | 39 | 1. send_subshare (once per segment) |
| | 40 | 1. send_plaintext_hash_tree |
| | 41 | 1. send_crypttext_hash_tree |
| | 42 | 1. send_subshare_hash_trees |
| | 43 | 1. send_share_hash_trees |
| | 44 | 1. send_UEB |
| | 45 | 1. close |
| | 46 | 1. dirnode update |
| | 47 | |
| | 48 | We need to keep the send_subshare calls sequential (to keep our memory |
| | 49 | footprint down), and we need a barrier between the close and the dirnode |
| | 50 | update (for robustness and clarity), but the others could be pipelined. |
| | 51 | 9*14ms=126ms, which accounts for about 15% of the measured upload time. |
| | 52 | |
| | 53 | == Storage Servers == |
| | 54 | |
| | 55 | ext3 (on tahoebs1) refuses to create more than 32000 subdirectories in a |
| | 56 | single parent directory. In 0.5.1, this appears as a limit on the number of |
| | 57 | buckets (one per storage index) that any StorageServer can hold. A simple |
| | 58 | nested directory structure will work around this.. the following code would |
| | 59 | let us manage 33.5G shares: |
| | 60 | |
| | 61 | {{{ |
| | 62 | from idlib import b2a |
| | 63 | os.path.join(b2a(si[:2]), b2a(si[2:4]), b2a(si)) |
| | 64 | }}} |
| | 65 | |
| | 66 | This limitation is independent of problems of memory use and lookup speed. |
| | 67 | Once the number of buckets is large, the filesystem may take a long time (and |
| | 68 | multiple disk seeks) to determine if a bucket is present or not. The |
| | 69 | provisioning page suggests how frequently these lookups will take place, and |
| | 70 | we can compare this against the time each one will take to see if we can keep |
| | 71 | up or not. If and when necessary, we'll move to a more sophisticated storage |
| | 72 | server design (perhaps with a database to locate shares). |