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

multi: create split local/remote database structure #4348

Merged
merged 2 commits into from Aug 8, 2020

Conversation

Roasbeef
Copy link
Member

@Roasbeef Roasbeef commented Jun 3, 2020

In this follow up PR to the recent etcd backend PR, we modify our data storage to support a new hybrid system. For operations that require lower read latency, or which read data sources which can easily be re-populated (the graph as an example), we use a local bolt option. If a replicated database is active (in this case etcd), then we'll use that replicated database for just about everything else.

Admittedly, the current implementation is a bit crude in that it creates two new backends LocalDB and RemoteDB, which are then passed into the appropriate context based on the replication needs of the data. This results in two new pointers in the server, which will force the caller to decide on if the data should remain local for low latency access, or should be replicated along with other state like the channel state machine, payments, etc.

lnd.go Outdated Show resolved Hide resolved
Copy link
Contributor

@cfromknecht cfromknecht left a comment

Choose a reason for hiding this comment

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

nice changes, surprised how small the diff is! only thing that comes to mind is that graph info about our local chans will be stored in the non-replicated database, so if we lose that we won't be able to reconstruct or update our own channel with our peer or to the wider network.

in the past i looked into the idea of "source hints", which act like hop hints but connect your local node the rest of the channel graph (rather than the connecting the private destination). these are computed from the replicated storage and fed in-memory into path finding to allow the split to work properly. that was over a year ago tho and the router has changed significantly since then, so that would need to be rewritten almost entirely.

lncfg/db.go Show resolved Hide resolved
chainregistry.go Outdated
@@ -220,7 +220,7 @@ func newChainControlFromConfig(cfg *Config, chanDB *channeldb.DB,
var err error

// Initialize the height hint cache within the chain directory.
hintCache, err := chainntnfs.NewHeightHintCache(chanDB)
hintCache, err := chainntnfs.NewHeightHintCache(remoteDB)
Copy link
Contributor

Choose a reason for hiding this comment

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

would think that height hints belong in a local db, they are not critical data and can be recomputed. in the past we've had cases where we wanted people to be able to delete their source hints to force a rescan

lnd.go Show resolved Hide resolved
lnd.go Outdated Show resolved Hide resolved
@@ -323,7 +325,8 @@ func noiseDial(idKey keychain.SingleKeyECDH,

// newServer creates a new instance of the server which is to listen using the
// passed listener address.
func newServer(cfg *Config, listenAddrs []net.Addr, chanDB *channeldb.DB,
func newServer(cfg *Config, listenAddrs []net.Addr,
localChanDB, remoteChanDB *channeldb.DB,
Copy link
Contributor

Choose a reason for hiding this comment

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

one day we'll make a Config struct..

lnd.go Outdated Show resolved Hide resolved
lnd.go Outdated Show resolved Hide resolved
lnd.go Outdated Show resolved Hide resolved
lnd.go Outdated Show resolved Hide resolved
server.go Outdated
sharedSecretPath := filepath.Join(cfg.localDatabaseDir(), "sphinxreplay.db")
// the same directory as the channel graph database. We don't need to
// replicate this data, so we'll store it locally.
graphDir := localChanDB.Path()
Copy link
Collaborator

Choose a reason for hiding this comment

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

note: eventually we could remove the path from the channeldb. I think apart from here it's only used in tests.

server.go Outdated Show resolved Hide resolved
@Roasbeef Roasbeef added this to the 0.11.0 milestone Jun 9, 2020
@Roasbeef Roasbeef requested review from bhandras and cfromknecht and removed request for halseth June 9, 2020 20:42
Copy link
Collaborator

@bhandras bhandras left a comment

Choose a reason for hiding this comment

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

Changes look good to me, but the local/remote db replacements seem to make the itests fail right now.

lncfg/db.go Outdated Show resolved Hide resolved
lncfg/db.go Outdated Show resolved Hide resolved
// initializeDatabases extracts the current databases that we'll use for normal
// operation in the daemon. Two databases are returned: one remote and one
// local. However, only if the replicated database is active will the remote
// database point to a unique database. Otherwise, the local and remote DB will
Copy link
Contributor

Choose a reason for hiding this comment

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

the local and remote DB will both point to the same local database.

since RemoteDB isn't necessarily remote, I could see this naming being pretty confusing. might consider using location-independent names like GraphDB and ChanDB/SafuDB/EverythingElseDB to reflect what is stored in the databases. the rest of the codebase doesn't really care where the data is being stored (by design)

Copy link
Member Author

Choose a reason for hiding this comment

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

With the change to move the height hints to the local DB, GraphDB doesn't quite work here. I agree in general though, as then the "functional" splits let us start to abstract away those portions, so being able to manipulate the graph on an interface level which'll let us use more specific DB features rather than mapping everything unto the kvdb interface. In any case I don't think this is blocking, since we're not exposing any new config options, they're (for now) just internal variable names.

lnd.go Outdated Show resolved Hide resolved
lnd.go Outdated Show resolved Hide resolved
lnd.go Show resolved Hide resolved
@cfromknecht cfromknecht added this to In progress in v0.11.0-beta via automation Jun 26, 2020
@cfromknecht cfromknecht added v0.11 database Related to the database/storage of LND labels Jun 26, 2020
@cfromknecht
Copy link
Contributor

@Roasbeef still targeting 0.11?

@cfromknecht cfromknecht moved this from In progress to Review in progress in v0.11.0-beta Jun 26, 2020
@cfromknecht cfromknecht modified the milestones: 0.11.0, 0.12.0 Jun 29, 2020
@cfromknecht cfromknecht removed this from Review in progress in v0.11.0-beta Jun 29, 2020
@cfromknecht cfromknecht added v0.12 and removed v0.11 labels Jun 29, 2020
@Roasbeef
Copy link
Member Author

Changes look good to me, but the local/remote db replacements seem to make the itests fail right now.

Fixed! Was a pathing issue, so all the nodes tried to open the same sphinx replay DB.

@Roasbeef Roasbeef added this to Review in progress in v0.12.0-beta Jul 22, 2020
Copy link
Collaborator

@bhandras bhandras left a comment

Choose a reason for hiding this comment

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

LGTM, I think this is a great first step towards data separation. 💾

Some last comments (nb for this PR):

  • I agree with @cfromknecht that it would be desirable to have functional separation rather than local/remote as that'd allow us to think about design more clearly.
  • As a first step towards that larger goal, perhaps we could introduce interfaces for cleaner separation of local/remote functionality. This would also be helpful for future contributors by enforcing some level of correctness at compile time.

@Roasbeef Roasbeef moved this from Review in progress to Reviewer approved in v0.12.0-beta Aug 4, 2020
server.go Show resolved Hide resolved
peer/config.go Show resolved Hide resolved
lnd.go Outdated Show resolved Hide resolved
lnd.go Show resolved Hide resolved
lnd.go Show resolved Hide resolved
lnd.go Show resolved Hide resolved
lnd.go Show resolved Hide resolved
v0.12.0-beta automation moved this from Reviewer approved to Review in progress Aug 5, 2020
@cfromknecht cfromknecht added this to In progress in v0.11.0-beta via automation Aug 7, 2020
@cfromknecht cfromknecht added v0.11 and removed v0.12 labels Aug 7, 2020
@cfromknecht cfromknecht modified the milestones: 0.12.0, 0.11.0 Aug 7, 2020
@Roasbeef Roasbeef force-pushed the etcd-local-graph-db branch 2 times, most recently from b7486fd to 47bec5f Compare August 7, 2020 22:34
Copy link
Contributor

@cfromknecht cfromknecht left a comment

Choose a reason for hiding this comment

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

latest version looks solid, just one lingering nit

lnd.go Show resolved Hide resolved
In this commit, we modify the existing `GetBackend` method to now be
called `GetBackends`. This new method will populate a new `RemoteDB`
attribute based on if the replicated backend is active or not. As is,
the local backend is used everywhere. An upcoming commit will once again
re-enable the remote backend, in a hybrid manner.
In this commit, we split the database storage into two classes: remote
and local data. If etcd isn't active, then everything is actually just
local though we use two pointers everywhere. If etcd is active, then
everything but the graph goes into the remote database.
Copy link
Contributor

@cfromknecht cfromknecht left a comment

Choose a reason for hiding this comment

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

LGTM 🏄‍♂️

v0.11.0-beta automation moved this from In progress to Reviewer approved Aug 8, 2020
v0.12.0-beta automation moved this from Review in progress to Reviewer approved Aug 8, 2020
@Roasbeef Roasbeef merged commit 38265b9 into lightningnetwork:master Aug 8, 2020
v0.11.0-beta automation moved this from Reviewer approved to Done Aug 8, 2020
v0.12.0-beta automation moved this from Reviewer approved to Done Aug 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
database Related to the database/storage of LND
Projects
No open projects
v0.11.0-beta
  
Done
v0.12.0-beta
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

3 participants