Evangelism - informing about FoundationDB's new open source status where it fits into the DB landscape

Kicking this off here.
After searching for reviews, comparisons, etc on FoundationDB, I found there are a lot of sites with outdated info.

Combined, we could reach out to get sites to update or post new content to avoid confusion, and get the internet community on board after open sourcing.

Let’s starting a list below of sites and people that would be valuable to get on board to help inform about FoundationDB being opensourced, and to coordinate efforts.

https://db-engines.com/en/system/FoundationDB%3BMongoDB - I wrote them, but haven’t heard back. Maybe persistence (more people reaching out to hem) or someone here around can figure out better ways to contact and incentivize them to include FoundationDB among the list of “good as in opensource” list of DBs.

Thanks, Simon! Looks like DB-Engines has recently updated their records on FoundationDB:

In April 2018, Apple open-sourced FoundationDB and it therefore reappears in the ranking.

Any other places that stand out where info is still out-of-date?

Here https://stackshare.io/foundationdb the news section is from 2015, but there are more recent news, so possibly just putting some traffic on there will make that problem fix itself. I’ll keep vigilant :slight_smile:

I also noticed https://news.ycombinator.com/item?id=16880917 that might need some more attention - maybe if F DB has some official Y-comb account to join the discussion with there.

Evangelism – Good idea!

I have a suggestion – may seem off-the-wall, but here goes:

Almost everything you read about FDB emphasizes its server-side performance and distributed scalability.

But there may be greater potential for FDB on the client-side where:

  • upward scalability is not required
  • good enough performance is acceptable
  • efficiency is important

Consider the following from the Benchmarking Docs https://apple.github.io/foundationdb/benchmarking.html

That’s as far as I took it with the FDB Benchmarking suggestions – you’ll see why in a bit.

So, 8,650 writes/second – this may be good enough performance for a client-side app – especially considering all the other capabilities that FDB provides,

To experiment with FDB I began with the Python Class Scheduling app. I used a class of 2,659 students – the number of students in my youngest grandson’s high school. This gave:

Schedule Students to Classes 
----------------------------------------------------------
threads:  5318
Scheduled 2659 students for 5 classes each (10 attempts) --  26590 transactions
Schedule time --- 15.4640290737 seconds 1719.47426335 transactions per second

That’s 15 seconds to schedule the entire school!

Sound pretty good so far?.. keep reading:

There’s this guy named Chris Lattner who has Python running in a Swift Playground…

Why not… I didn’t try the class scheduling app, but I could approximate loading an FDB db of 10,000 k/v pairs with a single transaction… with Python… on a Swift playground:

I took 0.63 seconds or 15,786 random writes per second.

It used only 1 thread, and AFICT used only 1 core on my iMac (|Intel Core i7 4 GHz.

That sounds pretty good to me for a lot of needs.

But there’s more, maybe even greater potential for fdbLite – consider running:

  • locally, used by apps like Siri, AR, ML, Point Clouds, File System, etc.
  • embedded systems
  • ARM APUs
  • billions of iPhones and iPads, etc.

fdbLite could be really, really big!

Thoughts?

1 Like

Nice numbers! Is there a blog post with those numbers? It could then be posted on ycombinatior or HN, to see how it stands up to the relentless sysadmins and hackers over there.
I’m still mostly in the dark on how/where I’d want to start using FDB. Is my hunch about right that it is usable as an embeddable DB like how sqlite is often used?

Are you referring to my fdbLte post?

If so, no blog…

The numbers are just things I’ve generated and posted previously to: threads here ad FDB:

https://forums.foundationdb.org/t/swift-language-support/53/18

and at the Swift org.

(https://forums.swift.org/t/se-0195-introduce-user-defined-dynamic-member-lookup-types/8658/154)

As to where to start usingFDB – I suggest you download Chris Lattner’s Swift Python playground. It’s an interactive tutorial and REPL which allows you to experiment with FDB by entering FDB primitives. Here’s the link:

(https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20171204/042029.html)

Here’s copy f a post to the FDB Swift Language thread that may help get you started with the syntax and the FDB primitives.

More progress getting FDB to run in a Swift Playground (calling Python thru Chris Lattner’s Swift + Python Interoperability Tutorial).

It appears that most FDB calls to Python can be made with syntax like:

FDBConstruct.call(member: “FDB Command”, args: “arg1”, “arg2”…)

for example, the set k/v shown below as:

tr.call(member: “set”, args:“myKey111”,“poop deck party time again”)

var tr = dbSwift.call(member: “create_transaction” )
print("\n1 tr: (tr)")
tr.call(member: “set”, args:“myKey111”,“poop deck party time again”)
tr.call(member: “get”, args:“myKey111”)
tr.call(member: “commit”).call(member:“wait”)

Haven’t figured out, in Swift, how to define Python Functions or the @fdb.transactional decoration – but I don’t think I need to – you can call fdb constructs within a Swift func and the:

tr.call(member: “commit”).call(member:“wait”)

shown seems to do the job for transactions!

Here’s the latest:

As I mentioned before Chris has suggested some syntactical sugar that would make the Swift Python calls Swiftier.

Final, once you get the hang of it, it’s pretty easy to prototype FDB as I did in my initial post to this thread.

HTH

Do note that this is 15,786 sequential appends, though. FDB responds success to a client when the commit is sync’d to the transaction log, not when it’s applied on a storage server. There’s up 15,786 random writes that still need to happen to disk after the 0.63 seconds that you’ve recorded before the written data can be read. These writes will actually be repeated, because they’ll be recorded both in the sqlite WAL and the sqlite btree.

I believe the topic of embedded FoundationDB has come up before, and was cautioned as unlikely to be a fruitful direction.

I am learning FDB and just using primitives with no error checking…

I don’t understand your comment about sequential appends.

Based in what you said.I changed the Swift/Python playground to:

  • init the db with 10,000 random k/v keys, commit/wait.
  • extend the db with an additional 10,000 k/v keys, commit/wait.

In this setup it took 1.55 sec for 12,875 wrrtes per sec.

The Swift REPL for the whole process took about 5 sec to display according to the clock.

If I don’t issue the wait(), the records don’t show up in the db.

If you have any suggestions to get more realistic/accurate timings – or you could just use my code (below).

Finally, I don’t plan on using Swift/Python playgrounds – it’s only a means to learn FDB until a Swift FDB API becomes available.

Here’s the meat of the revised run"

and the code:

import Foundation

// import needed Python and FDB files
let itertools = Python.import("itertools")
let traceback = Python.import("traceback")

let fdb = Python.import("fdb")
let fdbTuple = Python.import("fdb.tuple")

// initialize a range FDB value for Python
var range = PyVal("")

// set the fdb api_version to enable fdb use
fdb.call(member: "api_version", args: PyVal(510))

//------- FDB Primitaves -------//

// open a db called dbSwift
let dbSwift = fdb.call(member: "open")
print("\ndbSwift: \(dbSwift)")
// clear the db
dbSwift.call(member: "clear_range",args: "", "\u{255}")

// display contents of db
range = dbSwift.call(member: "get_range",args: "","\u{255}")
print("\n01 range.count: \(range.count) after db clear")

// load  db with k/v pairs
func initDb() {
    let tr = dbSwift.call(member: "create_transaction")
    for i in 0..<10000 {
        tr.call(member: "set",args: "myKey" + String(i),"myKey" + String( Int(arc4random_uniform(UInt32(10000)))) + " value from Swift")
    }
    tr.call(member: "commit").call(member:"wait")
}

// expand db with k/v pairs
func expandDb() {
    let tr = dbSwift.call(member: "create_transaction")
    for i in 0..<10000 {
        tr.call(member: "set",args: "myKey" + String(i+10000),"myKey" + String( Int(arc4random_uniform(UInt32(10000)))) + " value from Swift")
    }
    tr.call(member: "commit").call(member:"wait")
}

let timeBegin = Date.timeIntervalSinceReferenceDate
initDb()
let timeLoadEnd = Date.timeIntervalSinceReferenceDate
let loadCount = Double(dbSwift.call(member: "get_range",args: "","\u{255}").count)
range = dbSwift.call(member: "get_range",args: "","\u{255}")
print("\n02 range.count: \(range.count) after db init")

expandDb()
let timeEnd = Date.timeIntervalSinceReferenceDate
let expandCount = Double(dbSwift.call(member: "get_range",args: "","\u{255}").count) - Double(loadCount)
range = dbSwift.call(member: "get_range",args: "","\u{255}")
print("\n03 range.count: \(range.count) after db expand")

let dbloadTime = String(format: "%.5f", (timeLoadEnd - timeBegin))
let dbExpandTime = String(format: "%.5f", (timeEnd - timeLoadEnd))
let totalTime = String(format: "%.5f", (timeEnd - timeBegin))

//print("\ntimeEnd: \(timeEnd)")
print("\ndbloadTime: \(dbloadTime) sec, \(loadCount / (timeLoadEnd - timeBegin)) wrrtes per sec")
print("\nexpandDbTime: \(dbloadTime) sec, \(expandCount / (timeEnd - timeLoadEnd)) wrrtes per sec")
print("\ntotalTime: \(totalTime) sec, \((loadCount + expandCount) / (timeEnd - timeBegin))) wrrtes per sec")
print("\n\n")

range = dbSwift.call(member: "get_range",args: "",PyVal(String(44)))
range = dbSwift.call(member: "get_range",args: "","\u{255}")