Flourish PHP Unframework
This is an archived copy of the forum for reference purposes

Multiple databases

posted by chemdream 7 years ago

I always run multiple mysql servers that are circular replicated.

I then use HyperDB to extend flourish's db class.

With HyperDB, I can add all my mySQL servers as master read/write servers. If one server fails, another takes over. ie: load balancing + high availability.

I wish this was just built into Flourish. HyperDB is actually not that many lines of code. It seems like something that could be added easily into flourish?

chemdream, although I'm not familiar with HyperDB, generally the way that various libraries or third-party multi-master solutions take care of this is by creating offsets for IDs. This works fine if all you ever do is auto-increment numeric IDs. It falls apart pretty quickly when you start using natural keys, particularly if replication is not speedy enough or if the natural load balancing causes duplicate entries to occur.

It may also be the case that HyperDB doesn't actually do writing to more than a single server at once, and just fails over to write to another in the event the currently selected write server is down. While Flourish doesn't handle this directly, it is possible to add roles to flourish, and you could likely use a simple wrapper.

In general I don't feel like this is something flourish should handle. Flourish handles read/write differentiations for databases. If you wanted to add say 10 write servers, and have one selected at any given point this would likely best be done outside of the library where you can decide how to share state across multiple client connections.

posted by mattsah 7 years ago

Exactly,

I use HyperDB to write to only one DB at a time. the replication takes care of the rest. If one server goes down, HyperDB will choose another server.

I just figured since it's a quick(ish) thing to do, why not have it in the lib?

Just a suggestion...

posted by chemdream 7 years ago

@chemdream

My point is that this is much more fitting in the framework since it is highly dependent on storing a user state and the mechanism to do so should not be determined by Flourish. It may be simple to have flourish run through a number of configured databases, but then you get into "where does it keep the list of what is active, disabled, currently online, currently in use, currently used by X vs. Y users, etc".

Storing it in a session may resolve this, but other people will want to use full fledged databases, others will want to use caches, etc. Then you also get into "schema dependence" unless you're going to have 800 configuration methods related simply to this.

inKWell handles this simply by allows you to define the roles (as flourish allows) but then you can set an array of hosts. It will choose a host at random when the user connects and stick with that host for that user.

<?php

	return iw::createConfig('Core', array(
		//
		// By default database support is disabled.  You should not set this to FALSE unless you
		// configure at least one database below.
		//
		'disabled'  => TRUE,

		'databases' => array(
			//
			// Multiple databases can be configured.  If database support is
			// enabled above the default database is always 'default', but it
			// is possible to add independent databases and then configure
			// ActiveRecords/models to use those databases using the 'database'
			// configuration element in their independent configurations.
			//
			// Database names are reflected by the keys and optionally can have
			// a '::role' string appended to them, example: 'default::both'.
			// If the role is ommitted the default role is both.
			//
			// For more information about roles, please see Flourish's
			// fORM Documentation.
			//
			'default::both' => array(
				//
				// The database types used/allowed by inKWell reflect whatever
				// is currently supported by Flourish, examples at the time of
				// creating this file include: db2, mssql, mysql, oracle,
				// postgresql, and sqlite.
				//
				// Both the type and name are required and should be a string
				// value.
				//
				'type' => NULL,
				'name' => NULL,
				//
				// Authentication information if required
				//
				'user'     => NULL,
				'password' => NULL,
				//
				// If the host parameter is configured as an array then inKWell
				// will select a random host to pull data from.  This can be
				// good for "round-robin" hunting.  The particular database
				// server which a visitor connects to for the first time will
				// be stored in their session to ensure any effect they have on
				// the data will be reflected instantly to them.  Replication
				// between databases must be handled elsewhere, and is presumed
				// to be for the most part on-the-fly.
				//
				// You can specify ports with each host in standard syntax:
				//
				// <address>:<port>

				'hosts' => array('127.0.0.1'),
			),
		),
	));
posted by mattsah 7 years ago