The LiveJournal code provides a directory service that enables users to search for other users based on various criteria, including AOL Instant Messenger screen name, ICQ number, Jabber address, and others. These values are all stored as userprops.
Userprops themselves can either be stored on the global database or on the user's cluster. Putting things on the cluster is generally better, especially when the things relate to the user in such an integral way. However, that does not work so well with the userprops that are used for searching, because then you'd have to hit every cluster and repeat the search, which causes a lot of extra work to be done. Therefore, the properties that are used for searching have remained on the global database.
This is a problem too, though: while searching is done fairly often, most of the time properties are loaded for such purposes as displaying the user's profile page. This doesn't require a search through all data, so should really be done using just the user's cluster.
Thus, multihomed userprops were born. Basically, a multihomed userprop is one that is stored in two locations for the express purpose of making it easier to load these properties in the majority of cases. The two locations are on the global database on the “ userprop” table and on the user clusters in the “ userproplite2” tables.
When a property is defined as multihomed (multihomed = '1' in the userproplist table), LJ::set_userprop and LJ::load_user_props know how to deal with it. No differences in coding style are required. It is completely transparent to the rest of the system.
Pseudo-logic for saving a multihomed userprop goes like this:
Save data to global (standard behavior, empty values are not saved)
Save data to cluster (empty values ARE saved as ")
Pseudo-logic for loading a multihomed userprop goes like this:
Load data from cluster
If data not found, try loading from master
If we had to load from master, save data to cluster (empty values saved)
The only real difference between the old and new way of doing things is that empty userprops, which were previously just deleted from the table, are instead saved. This is to prevent hitting up the cluster and thinking that we have not got this property from the global before and hitting the global repeatedly. Instead, we save it locally as blank, and don't hit the global ever again.