Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite pinning to store pins in IPFS objects #1225

Closed
wants to merge 19 commits into from
Closed

Rewrite pinning to store pins in IPFS objects #1225

wants to merge 19 commits into from

Conversation

tv42
Copy link
Contributor

@tv42 tv42 commented May 11, 2015

Still needs a migration. Notes for that:

There's two parts:

  1. 1009aeb
    The keys for that looked like /local/pins/{direct,recursive,indirect}/keys/* and can be just removed.
  2. 1673b9c
    The keys for that look like /local/pins/{direct,recursive,indirect}/keys (parents of the above), contain json, and can be fed to the new pinning mechanism to generate the new state.
    The direct and recursive json are arrays, the indirect json is a dict {key: refcount}.

@jbenet jbenet added the status/in-progress In progress label May 11, 2015
@tv42
Copy link
Contributor Author

tv42 commented May 13, 2015

Travis failures look like OOM and timeouts.

@chriscool When you say "all", that makes me think "out of scope for this issue" ;)

@whyrusleeping @jbenet Let me know if there's anything unclear here, or something I can help with. I'm basically waiting to hear back from you two.

PinWithMode(util.Key, PinMode)
// RemovePinWithMode is for manually editing the pin structure.
// Use with care! If used improperly, garbage collection may not
// be successful.
RemovePinWithMode(util.Key, PinMode)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, youre probably right about moving these together.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'd think the other way was safer for users, but shrug

@whyrusleeping
Copy link
Member

A few things that are confusing to me, but other than that, this looks really nice. Removes a bunch of things i wanted removed, and makes bunch of change towards a more sensible pinning setup

@chriscool
Copy link
Contributor

@tv42 what I wanted to say is that as far as I know the other file comparison functions, like test_cmp, test_sort_cmp, are supposed to take the expected file first and the actual file second, and it would be nice if the comparison functions you introduce were following the same pattern too.

@tv42
Copy link
Contributor Author

tv42 commented May 13, 2015

@chriscool Hmm. Sharness's test_cmp is documented to take arguments in the order expected, actual. The preexisting code was test_sort_cmp gc_out_actual2 gc_out_exp2, and I just kept that order. You're right, this is probably worth fixing.

@chriscool
Copy link
Contributor

@tv42 great! Thanks for fixing it!

}
rootKey := util.Key(rootKeyI.([]byte))

ctx := context.TODO()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this need to be wired up?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but that changes the Pinner API -> later.

@jbenet
Copy link
Member

jbenet commented May 15, 2015

@tv42 minor comments above o/ -- aside, this LGTM.

@whyrusleeping whyrusleeping mentioned this pull request May 16, 2015
@vitzli
Copy link
Contributor

vitzli commented May 17, 2015

Debian Stretch inside virtualbox, 2 GB RAM, 2 CPU cores allocated for VM (Core 2 Quad 9550).

HW config 1

VM is located on HDD. Guest root partition and guest /srv partition are located on separate physical HDDs (both SATA2). Test files located at /srv/test1, IPFS_PATH points to /srv/ipfs_conf.

user@deb-stretch-ipfs:/srv/test1$ time sha256sum random.dat
2dc9095156bf916fc1cd07d98bf9e0d330cfbefedf9f037a65e378cbc9e70ab1  random.dat

real    0m19.488s
user    0m13.504s
sys 0m5.732s

sha256sum speed: 102.6 MB/s

Adding urandom junk to ipfs:

user@deb-stretch-ipfs:/srv/test1$ time ipfs add random.dat 
added QmfQDSXnxvjVPDzhwmHK83CWFaCUwyYLTnjEf5dZm1wJqb random.dat

real    3m39.620s
user    1m10.676s
sys 0m43.760s

Around 03:27:39 progress bar finishes, but ipfs does something, no output to console window. Process completes around 03:29:13. Average speed: 9.1 MB/s, iotop log
Adding the same file again requires only 28.3 s. Average speed: 70 MB/s. iotop log
iotop columns: TID | PRIO | USER | DISK READ | DISK WRITE | SWAPIN | IO> | COMMAND

Adding file full of 0xFF:

user@deb-stretch-ipfs:/srv/test1$ time ipfs add notsorandom.dat 
added QmNmKeTsXeeLHA8TYeZg6DyWx96hhfSiqWBsoSM7wec3ck notsorandom.dat                                     

real    0m26.844s
user    0m22.704s
sys 0m11.288s

Average speed: 74.6 MB/s, iotop log

@vitzli
Copy link
Contributor

vitzli commented May 17, 2015

HW config 2 (host OS)

Core 2 Q9550, 4 CPU cores, 8 GB RAM, test file and ipfs_path on the same SSD.
Adding random.dat:

added QmfQDSXnxvjVPDzhwmHK83CWFaCUwyYLTnjEf5dZm1wJqb random.dat

real    5m11.659s
user    0m53.792s
sys 0m8.120s

Progress bar finishes at 10:55:15, process ends around 10:58, iotop log, average speed: 6.43 MB/s

HW config 3 (host OS)

IPFS_PATH on (fragmented?) HDD, test file on SSD:
Doing ipfs add gave estimated time around 10 minutes for the same 2GB file, I assume that it is caused by the fragmentation of HDD partition (20 GB left out of 300GB). Also, there were very slow read/write speeds in iotop:

11:04:17  1895 be/4 alex        7.98 K/s 3112.68 K/s  0.00 %  1.50 % ipfs add random.dat
11:04:17  1895 be/4 alex        7.98 K/s 3113.39 K/s  0.00 %  1.49 % ipfs add random.dat
11:04:18  1895 be/4 alex        0.00 K/s 3631.49 K/s  0.00 %  1.70 % ipfs add random.dat

I would discard this test.

@whyrusleeping
Copy link
Member

@vitzli nice! so this appears to be a little bit faster than master, right?

@vitzli
Copy link
Contributor

vitzli commented May 17, 2015

@whyrusleeping I'm sure now that I've made a mistake, I commented on it in #1216, results are somewhat disappointing, pin branch seems to be slower than master, but I need somebody to verify my results.
1 core, random.dat file, pin branch, test file and ipfs dir on the same separate HDD:

TEST 1  3m13.276s
TEST 2  3m12.529s
TEST 3  3m24.626s
TEST 4  3m31.363s
TEST 5  3m44.372s
TEST 6  3m49.319s
TEST 7  3m43.692s
TEST 8  4m3.791s
TEST 9  3m42.013s
TEST 10 3m41.873s

Average time: 3m36.6s, 9.2 MB/s
2 cores:

TEST 1  3m39.991s
TEST 2  3m47.141s
TEST 3  3m50.335s
TEST 4  3m56.028s
TEST 5  4m2.825s
TEST 6  4m5.213s
TEST 7  3m57.563s
TEST 8  4m5.529s
TEST 9  4m0.147s
TEST 10 4m2.940s

Average time 3m56.7s, 8.5 MB/s

@whyrusleeping
Copy link
Member

@vitzli hrm.. thats what @tv42 said might be the case. a little disappointing... but I'm sure there is plenty of room for optimization.

Could you maybe put together a script to run these benchmarks? would be great to have a 'ipfs-add-benchmark' thing around.

@tv42
Copy link
Contributor Author

tv42 commented May 17, 2015

Round 1 of the pinning rework was explicitly done so it doesn't change the APIs much. Any other way would have been too much chaos in the codebase.

@whyrusleeping
Copy link
Member

So further revisions wont require any sort of a migration, correct?

@tv42
Copy link
Contributor Author

tv42 commented May 17, 2015

It's always possible we discover the format was bad. I'd be surprised if that happened soon.

@tv42
Copy link
Contributor Author

tv42 commented May 18, 2015

Uhh, I added more tests and may or may not have found a bug. Please don't merge while I diagnose. Preparing migration code should still be safe.

tv42 and others added 11 commits June 8, 2015 20:49
Pinner had method GetManual that returned a ManualPinner, so every
Pinner had to implement ManualPinner anyway.
Platform-dependent behavior is not nice, and negative refcounts are
not very useful.
WARNING: No migration performed! That needs to come in a separate
commit, perhaps amended into this one.

This is the minimal rewrite, only changing the storage from
JSON(+extra keys) in Datastore to IPFS objects. All of the pinning
state is still loaded in memory, and written from scratch on Flush. To
do more would require API changes, e.g. adding error returns.

Set/Multiset is not cleanly separated into a library, yet, as it's API
is expected to change radically.
@tv42
Copy link
Contributor Author

tv42 commented Jun 9, 2015

I saw it too, now. Looking..

@tv42
Copy link
Contributor Author

tv42 commented Jun 9, 2015

@jbenet @whyrusleeping That's a dagmodifier error branch that explicitly unpins an object.

        // We found the correct child to write into
        if cur+bs > offset {
            // Unpin block
            ckey := key.Key(node.Links[i].Hash)
            dm.mp.RemovePinWithMode(ckey, pin.Indirect)

            child, err := node.Links[i].GetNode(dm.ctx, dm.dagserv)
            if err != nil {
// THIS TRIGGERS
                return "", false, err
            }
            k, sdone, err := dm.modifyDag(child, offset-cur, data)
            if err != nil {
                return "", false, err
            }

//NEVER GETS HERE
            // pin the new node
            dm.mp.PinWithMode(k, pin.Indirect)

@tv42
Copy link
Contributor Author

tv42 commented Jun 9, 2015

Well, the error at that point is a missing block too -- but that's the cause of the other missing block, that's what the test really craps out on. Lovely.

@tv42
Copy link
Contributor Author

tv42 commented Jun 9, 2015

Found it.

@tv42
Copy link
Contributor Author

tv42 commented Jun 9, 2015

Should be good again. @whyrusleeping FYI the dagmodifier changes.

@whyrusleeping
Copy link
Member

@tv42 good catch, thanks!

@whyrusleeping
Copy link
Member

merged into dev0.4.0

@tv42
Copy link
Contributor Author

tv42 commented Jul 15, 2015

Can this be closed now?

@jbenet
Copy link
Member

jbenet commented Jul 16, 2015

I think so yep :) 👍 thanks @tv42

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants