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

[WIP] Badger datastore #4007

Merged
merged 11 commits into from
Sep 8, 2017
Merged

[WIP] Badger datastore #4007

merged 11 commits into from
Sep 8, 2017

Conversation

magik6k
Copy link
Member

@magik6k magik6k commented Jun 24, 2017

Depends on:

TODO:

  • Put badger/badger-ds into gx

@Kubuxu Kubuxu added the status/in-progress In progress label Jun 24, 2017
@magik6k magik6k changed the base branch from feat/datastore-configs to master June 24, 2017 22:17
p = filepath.Join(r.path, p)
}

os.MkdirAll(p, 0755) //TODO: find better way
Copy link
Member

Choose a reason for hiding this comment

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

i would check errors here

Copy link
Member Author

Choose a reason for hiding this comment

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

This was unpushed for some reason.

@Kubuxu
Copy link
Member

Kubuxu commented Jun 27, 2017

Please rebase.

@whyrusleeping
Copy link
Member

some initial numbers, adding all of ipfs dists (~2GB)

badgerds: 19.88 seconds, 9% cpu
flatfs(sync): 109.46 seconds, 2% cpu
flatfs(nosync): 11.91 seconds, 12% cpu

So badger is significantly faster than flatfs, and comparable to flatfs-nosync, while still actually syncing data to disk. This is really great stuff :)

@whyrusleeping
Copy link
Member

downside is that querying the datastore (ipfs repo gc ipfs refs local etc) are much slower.

@whyrusleeping
Copy link
Member

Also, for context:

sha256 hashing all the files from the above experiment took 5.43 seconds
and copying them all to another directory (same disk) took 0.80 seconds

@Kubuxu
Copy link
Member

Kubuxu commented Jun 29, 2017

It seems for me like badger isn't syncing.

@Kubuxu
Copy link
Member

Kubuxu commented Jun 29, 2017

Can you try running the sync test and doing manual sync latter.

License: MIT
Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
License: MIT
Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
License: MIT
Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
License: MIT
Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
License: MIT
Signed-off-by: Jeromy <jeromyj@gmail.com>
License: MIT
Signed-off-by: Jeromy <jeromyj@gmail.com>
@whyrusleeping
Copy link
Member

Some more benchmark numbers, adding ipfs dists again:

sha256sum everything: 0:05.62
add with badgerds: 0:17.06
add with flatfs: 0:34.58
filestore add w/badger: 0:13.14
filestore add w/flatfs: 0:18.14
add badger+blake2b: 0:11.92
add flatfs+blake2b: 0:33.25

License: MIT
Signed-off-by: Jeromy <jeromyj@gmail.com>
License: MIT
Signed-off-by: Jeromy <jeromyj@gmail.com>
@whyrusleeping
Copy link
Member

This looks like its ready to go. Just probably wanting some code review, cc @magik6k @Stebalien @kevina @Kubuxu

Also, thank you to @manishrjain and the badger crew for implementing the error handling and pushing more improvements to this. Its looking all around better than our current filesystem based blockstore.

@whyrusleeping whyrusleeping added this to the Ipfs 0.4.11 milestone Sep 5, 2017
@manishrjain
Copy link

Glad that it's working for you guys!

I looked at the Badger code usage, you are not setting SyncWrites=true. Did you set it during the benchmarks that you run above? (By default, we set it to false for better performance.)

Also, can you ensure that you set GOMAXPROCS=128 -- a value large enough so that if you're running this on SSD, you'll be able to see the max IOPS allowed by the SSD. This is useful for key-value iteration and random Get throughput.

Also, Badger writes work best if you do batch + goroutines. You can also now do BatchSetAsync, without the goroutines which would give you good performance (and give back a callback when the write is done).

We're also working on mmap of value log, which would significantly improve the random Get latency.

@whyrusleeping
Copy link
Member

@manishrjain ah, no. We arent setting SyncWrites to true. We should proably do that by default, and then add that to our configuration blob. Why the need for so many threads? That seems odd to me.

Our calling code probably isnt taking advantage of the parallelism of the batch put as much as we should. I can look at tweaking that some and see how it affects the performance.

"path": "badgerds",
}
return nil
},
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I may be missing something, but won't this config bypass the measure datastore? If so will this create a problem?

Copy link
Member Author

Choose a reason for hiding this comment

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

IIRC there is global measure in fsrepo

@manishrjain
Copy link

manishrjain commented Sep 5, 2017

Why the need for so many threads? That seems odd to me.

It's got to do with the fact that disk reads block OS threads, and how many threads can be scheduling disk reads at the same time. Full discussion here:

https://groups.google.com/forum/#!topic/golang-nuts/jPb_h3TvlKE

We set Dgraph by default to 128 threads. It doesn't add that much overhead, so it's a safe change to do.

Consider either using BatchSetAsync, or calling BatchSet from multiple goroutines. Doing a single Set would always be way slower, because every write call to Badger has to hit the disk. So, the more calls we can batch, the more disk cost can be amortized, and a much higher throughput achieved.

For values below 100 bytes, we have seen 400K key-value writes per second on the cheapest i3 instance (with local SSD).

P.S. Sent a PR to go-ipfs-badger. Small changes to how Badger is accessed.

@magik6k
Copy link
Member Author

magik6k commented Sep 5, 2017

We might want to put this in experimental-features doc with some info on how to use this.

@Stebalien
Copy link
Member

We can also increase GOMAXPROCS from within go (runtime.GOMAXPROCS).

License: MIT
Signed-off-by: Jeromy <jeromyj@gmail.com>
License: MIT
Signed-off-by: Jeromy <jeromyj@gmail.com>
@whyrusleeping
Copy link
Member

I think this is good to go now. Thoughts? @magik6k @Stebalien @kevina ?

@magik6k
Copy link
Member Author

magik6k commented Sep 6, 2017

LGTM, though badger-ds could be updated to 0.2.1 (see https://github.com/ipfs/go-ds-badger/commits/master)

@kevina
Copy link
Contributor

kevina commented Sep 6, 2017

This LGTM but I have not been following the Badger datastore discussion so I am not really qualified to review this.


badgerds "gx/ipfs/QmNWbaGdPCA3anCcvh4jm3VAahAbmmAsU58sp8Ti4KTJkL/go-ds-badger"
levelds "gx/ipfs/QmPdvXuXWAR6gtxxqZw42RtSADMwz4ijVmYHGS542b6cMz/go-ds-leveldb"
badger "gx/ipfs/QmQL7yJ4iWQdeAH9WvgJ4XYHS6m5DqL853Cck5SaUb8MAw/badger"
Copy link
Member

Choose a reason for hiding this comment

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

This isn't declared in package.json. However, if you update to go-ds-badger 0.2.1, you can use the re-exported badgerds.DefaultOptions and badgerds.Options and avoid this import altogether.

@hoffmabc
Copy link

hoffmabc commented Sep 7, 2017

Is there going to be a guide to show how to use this?

@whyrusleeping
Copy link
Member

@Stebalien Could you handle updating the badger-ds dependency?

@hoffmabc Yes, We will add docs around this. But the simple of case of making a new ipfs node that uses this is just ipfs init --profile=badgerds. I'm curious though, What sort of structure would you expect docs for this to be in? Its generally pretty easy for us to write "how to use a thing", but its hard to know what users would expect.

(and use the re-exported options instead of importing badger directly)

License: MIT
Signed-off-by: Steven Allen <steven@stebalien.com>
@Stebalien
Copy link
Member

@whyrusleeping done.

@hoffmabc
Copy link

hoffmabc commented Sep 7, 2017

I'm not sure @whyrusleeping to be honest. That seems pretty straightforward for using this.

@hoffmabc
Copy link

hoffmabc commented Sep 7, 2017

Do any tests need to be written for this out of curiosity?

@whyrusleeping
Copy link
Member

whyrusleeping commented Sep 7, 2017 via email

@hoffmabc
Copy link

hoffmabc commented Sep 7, 2017

Also we initialize ipfs using a config file where leveldb is the only option. Will this be extended to support this datastore?

EDIT: I see the pre-requisite now above.

@magik6k
Copy link
Member Author

magik6k commented Sep 7, 2017

For tests: we can/should try running whole sharness over this datastore. To not make it take forever to run on travis/circle it could be done as jenkins pipeline stage which would pass additional profiles to ipfs/iptb init in sharness.

@magik6k
Copy link
Member Author

magik6k commented Sep 7, 2017

Datastore section in docs/config.md needs correcting too.

@hoffmabc
Copy link

hoffmabc commented Sep 8, 2017

is this getting merged today?

@whyrusleeping whyrusleeping merged commit 71d72e2 into master Sep 8, 2017
@whyrusleeping whyrusleeping deleted the feat/badger-ds branch September 8, 2017 19:53
@whyrusleeping
Copy link
Member

@hoffmabc Yeap! :)

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

Successfully merging this pull request may close these issues.

7 participants