Extra tests to ensure that the cond collapser will not mask SQLA deprecations
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / Replicated / Introduction.pod
CommitLineData
212cc5c2 1=head1 NAME
2
3DBIx::Class::Storage::DBI::Replicated::Introduction - Minimum Need to Know
4
5=head1 SYNOPSIS
6
5529838f 7This is an introductory document for L<DBIx::Class::Storage::DBI::Replicated>.
212cc5c2 8
9This document is not an overview of what replication is or why you should be
5529838f 10using it. It is not a document explaining how to setup MySQL native replication
11either. Copious external resources are available for both. This document
212cc5c2 12presumes you have the basics down.
8273e845 13
212cc5c2 14=head1 DESCRIPTION
15
5529838f 16L<DBIx::Class> supports a framework for using database replication. This system
8273e845 17is integrated completely, which means once it's setup you should be able to
212cc5c2 18automatically just start using a replication cluster without additional work or
5529838f 19changes to your code. Some caveats apply, primarily related to the proper use
212cc5c2 20of transactions (you are wrapping all your database modifying statements inside
21a transaction, right ;) ) however in our experience properly written DBIC will
22work transparently with Replicated storage.
23
24Currently we have support for MySQL native replication, which is relatively
25easy to install and configure. We also currently support single master to one
26or more replicants (also called 'slaves' in some documentation). However the
27framework is not specifically tied to the MySQL framework and supporting other
28replication systems or topographies should be possible. Please bring your
29patches and ideas to the #dbix-class IRC channel or the mailing list.
30
31For an easy way to start playing with MySQL native replication, see:
32L<MySQL::Sandbox>.
33
48580715 34If you are using this with a L<Catalyst> based application, you may also want
8273e845 35to see more recent updates to L<Catalyst::Model::DBIC::Schema>, which has
212cc5c2 36support for replication configuration options as well.
37
38=head1 REPLICATED STORAGE
39
40By default, when you start L<DBIx::Class>, your Schema (L<DBIx::Class::Schema>)
41is assigned a storage_type, which when fully connected will reflect your
c1300297 42underlying storage engine as defined by your chosen database driver. For
212cc5c2 43example, if you connect to a MySQL database, your storage_type will be
8273e845 44L<DBIx::Class::Storage::DBI::mysql> Your storage type class will contain
212cc5c2 45database specific code to help smooth over the differences between databases
46and let L<DBIx::Class> do its thing.
47
48If you want to use replication, you will override this setting so that the
8273e845 49replicated storage engine will 'wrap' your underlying storages and present
48580715 50a unified interface to the end programmer. This wrapper storage class will
212cc5c2 51delegate method calls to either a master database or one or more replicated
52databases based on if they are read only (by default sent to the replicants)
8273e845 53or write (reserved for the master). Additionally, the Replicated storage
212cc5c2 54will monitor the health of your replicants and automatically drop them should
55one exceed configurable parameters. Later, it can automatically restore a
56replicant when its health is restored.
57
58This gives you a very robust system, since you can add or drop replicants
59and DBIC will automatically adjust itself accordingly.
60
61Additionally, if you need high data integrity, such as when you are executing
62a transaction, replicated storage will automatically delegate all database
63traffic to the master storage. There are several ways to enable this high
64integrity mode, but wrapping your statements inside a transaction is the easy
8273e845 65and canonical option.
212cc5c2 66
67=head1 PARTS OF REPLICATED STORAGE
68
69A replicated storage contains several parts. First, there is the replicated
d4daee7b 70storage itself (L<DBIx::Class::Storage::DBI::Replicated>). A replicated storage
212cc5c2 71takes a pool of replicants (L<DBIx::Class::Storage::DBI::Replicated::Pool>)
d95ec4a6 72and a software balancer (L<DBIx::Class::Storage::DBI::Replicated::Balancer>).
73The balancer does the job of splitting up all the read traffic amongst the
48580715 74replicants in the Pool. Currently there are two types of balancers, a Random one
212cc5c2 75which chooses a Replicant in the Pool using a naive randomizer algorithm, and a
76First replicant, which just uses the first one in the Pool (and obviously is
77only of value when you have a single replicant).
78
79=head1 REPLICATED STORAGE CONFIGURATION
80
81All the parts of replication can be altered dynamically at runtime, which makes
82it possibly to create a system that automatically scales under load by creating
83more replicants as needed, perhaps using a cloud system such as Amazon EC2.
84However, for common use you can setup your replicated storage to be enabled at
85the time you connect the databases. The following is a breakdown of how you
86may wish to do this. Again, if you are using L<Catalyst>, I strongly recommend
87you use (or upgrade to) the latest L<Catalyst::Model::DBIC::Schema>, which makes
88this job even easier.
89
ce854fd3 90First, you need to get a C<$schema> object and set the storage_type:
91
92 my $schema = MyApp::Schema->clone;
93 $schema->storage_type([
94 '::DBI::Replicated' => {
95 balancer_type => '::Random',
96 balancer_args => {
97 auto_validate_every => 5,
98 master_read_weight => 1
99 },
100 pool_args => {
101 maximum_lag =>2,
102 },
103 }
104 ]);
105
106Then, you need to connect your L<DBIx::Class::Schema>.
107
108 $schema->connection($dsn, $user, $pass);
212cc5c2 109
110Let's break down the settings. The method L<DBIx::Class::Schema/storage_type>
111takes one mandatory parameter, a scalar value, and an option second value which
112is a Hash Reference of configuration options for that storage. In this case,
113we are setting the Replicated storage type using '::DBI::Replicated' as the
114first value. You will only use a different value if you are subclassing the
115replicated storage, so for now just copy that first parameter.
116
117The second parameter contains a hash reference of stuff that gets passed to the
118replicated storage. L<DBIx::Class::Storage::DBI::Replicated/balancer_type> is
119the type of software load balancer you will use to split up traffic among all
120your replicants. Right now we have two options, "::Random" and "::First". You
121can review documentation for both at:
122
123L<DBIx::Class::Storage::DBI::Replicated::Balancer::First>,
124L<DBIx::Class::Storage::DBI::Replicated::Balancer::Random>.
125
126In this case we will have three replicants, so the ::Random option is the only
127one that makes sense.
128
129'balancer_args' get passed to the balancer when it's instantiated. All
130balancers have the 'auto_validate_every' option. This is the number of seconds
131we allow to pass between validation checks on a load balanced replicant. So
8273e845 132the higher the number, the more possibility that your reads to the replicant
c1300297 133may be inconsistent with what's on the master. Setting this number too low
212cc5c2 134will result in increased database loads, so choose a number with care. Our
135experience is that setting the number around 5 seconds results in a good
136performance / integrity balance.
137
5529838f 138'master_read_weight' is an option associated with the ::Random balancer. It
212cc5c2 139allows you to let the master be read from. I usually leave this off (default
140is off).
141
142The 'pool_args' are configuration options associated with the replicant pool.
143This object (L<DBIx::Class::Storage::DBI::Replicated::Pool>) manages all the
144declared replicants. 'maximum_lag' is the number of seconds a replicant is
145allowed to lag behind the master before being temporarily removed from the pool.
48580715 146Keep in mind that the Balancer option 'auto_validate_every' determines how often
212cc5c2 147a replicant is tested against this condition, so the true possible lag can be
148higher than the number you set. The default is zero.
149
150No matter how low you set the maximum_lag or the auto_validate_every settings,
151there is always the chance that your replicants will lag a bit behind the
152master for the supported replication system built into MySQL. You can ensure
48580715 153reliable reads by using a transaction, which will force both read and write
212cc5c2 154activity to the master, however this will increase the load on your master
155database.
156
157After you've configured the replicated storage, you need to add the connection
158information for the replicants:
159
ce854fd3 160 $schema->storage->connect_replicants(
161 [$dsn1, $user, $pass, \%opts],
162 [$dsn2, $user, $pass, \%opts],
163 [$dsn3, $user, $pass, \%opts],
164 );
212cc5c2 165
166These replicants should be configured as slaves to the master using the
167instructions for MySQL native replication, or if you are just learning, you
168will find L<MySQL::Sandbox> an easy way to set up a replication cluster.
169
170And now your $schema object is properly configured! Enjoy!
171
a2bd3796 172=head1 FURTHER QUESTIONS?
212cc5c2 173
a2bd3796 174Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
212cc5c2 175
a2bd3796 176=head1 COPYRIGHT AND LICENSE
212cc5c2 177
a2bd3796 178This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
179by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
180redistribute it and/or modify it under the same terms as the
181L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
212cc5c2 182